IonicWind Software

Aurora Compiler => Database => Topic started by: Ionic Wind Support Team on February 18, 2006, 01:16:39 PM

Title: Address book example
Post by: Ionic Wind Support Team on February 18, 2006, 01:16:39 PM
Something to learn from.  A complete addressbook using the database class and lots of dialog stuff.


#autodefine "off"
import int EnableWindow(unsigned int hwnd,int bEnable);
//constants for menus and controls
#define IDE_FIRST 10
#define IDE_STREET1 12
#define IDE_LAST 11
#define IDE_STREET2 13
#define IDE_CITY 14
#define IDE_STATE 15
#define IDE_POSTAL 16
#define IDE_PHONE 17
#define IDE_EMAIL 18
#define IDB_PREV 30
#define IDB_NEXT 31
#define IDS_RECNO 37
#define IDS_RECID 35
#define IDB_UPDATE 32
#define IDB_NEW 33
#define IDM_QUIT 100
#define IDM_NEW 33
#define IDM_UPDATE 32
#define IDM_DELETE 34

class AddressBook:CDialog
{
//the class constructor
declare AddressBook();
//virtual overrides
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
declare OnMenuInit(unsigned int hMenu),int;
declare OnMenuPick(int nID),int;
declare OnTimer(int nIDEvent),int;
//methods
declare UpdateData(int bDirection);
declare OpenDatabase(),int;
declare CloseAll();
declare SetupControls();
declare DoUpdate();
declare DoNew();
declare DoDelete();
declare DoIdle();
declare InitSelect();
//member variables
//variables for recieving and updating
dstring m_lname[41],m_fname[41],m_street[256],m_street2[256],m_city[41],m_state[11],
m_phone[21],m_email[256],m_zipcode[10],m_date[41];

int m_id,m_count;
int hstmt_select,hstmt_update,hstmt_insert,hstmt_delete;
//The database object
CDatabase m_db;
//for future use
string m_filter;
//to mark a new entry as unsaved
int m_bDirty;
//access to control classes
CEdit *m_editFirst,*m_editLast,*m_editStreet1,*m_editStreet2,
*m_editCity,*m_editState,*m_editPostal,*m_editEmail,
*m_editPhone;
CStatic *m_staticID,*m_staticRECNO;
CButton *m_buttonNext,*m_buttonPrev,*m_buttonUpdate;
}

global sub main()
{
AddressBook mainwin;
mainwin.Create(0,0,505,273,0x80CA0080,0,"The Address Book",0);
mainwin.AddControl(CTEDIT,"",99,24,130,20,0x50810080,0x200,IDE_FIRST);
mainwin.AddControl(CTEDIT,"",300,24,130,20,0x50810080,0x200,IDE_LAST);
mainwin.AddControl(CTEDIT,"",99,51,331,20,0x50810080,0x200,IDE_STREET1);
mainwin.AddControl(CTEDIT,"",99,78,331,20,0x50810080,0x200,IDE_STREET2);
mainwin.AddControl(CTSTATIC,"First Name",39,27,57,17,0x5000010B,0x0,25);
mainwin.AddControl(CTSTATIC,"Last Name",241,28,55,18,0x5000010B,0x0,27);
mainwin.AddControl(CTSTATIC,"Street1",54,54,38,17,0x5000010B,0x0,23);
mainwin.AddControl(CTSTATIC,"Street2",54,83,38,17,0x5000010B,0x0,20);
mainwin.AddControl(CTEDIT,"",99,105,130,20,0x50810080,0x200,IDE_CITY);
mainwin.AddControl(CTSTATIC,"City",68,110,24,17,0x5000010B,0x0,19);
mainwin.AddControl(CTEDIT,"",314,105,116,20,0x50810080,0x200,IDE_STATE);
mainwin.AddControl(CTSTATIC,"State/Province",237,108,76,17,0x5000010B,0x0,21);
mainwin.AddControl(CTSTATIC,"Postal Code",30,136,62,17,0x5000010B,0x0,22);
mainwin.AddControl(CTEDIT,"",99,133,130,20,0x50810080,0x200,IDE_POSTAL);
mainwin.AddControl(CTSTATIC,"Phone",237,137,39,17,0x5000010B,0x0,24);
mainwin.AddControl(CTEDIT,"",278,133,152,20,0x50810080,0x200,IDE_PHONE);
mainwin.AddControl(CTSTATIC,"Email Address",20,163,74,17,0x5000010B,0x0,26);
mainwin.AddControl(CTEDIT,"",99,160,331,20,0x50810080,0x200,IDE_EMAIL);
mainwin.AddControl(CTBUTTON,"<<",75,222,70,20,0x5000000B,0x0,IDB_PREV);
mainwin.AddControl(CTBUTTON,">>",154,222,70,20,0x5000000B,0x0,IDB_NEXT);
mainwin.AddControl(CTSTATIC,"Number of Records:",67,192,97,17,0x5000010B,0x0,36);
mainwin.AddControl(CTSTATIC,"REC_NO",167,193,70,15,0x50000000,0x0,IDS_RECNO);
mainwin.AddControl(CTSTATIC,"Record ID:",269,192,59,17,0x5000010B,0x0,34);
mainwin.AddControl(CTSTATIC,"REC_ID",325,192,70,17,0x50000000,0x0,IDS_RECID);
mainwin.AddControl(CTBUTTON,"Update",280,222,70,20,0x5000000B,0x0,IDB_UPDATE);
mainwin.AddControl(CTBUTTON,"New",359,222,70,20,0x5000000B,0x0,IDB_NEW);

mainwin.ShowDialog();
do{wait();}until mainwin.m_hwnd = 0;
return 0;
}

AddressBook::AddressBook()
{
m_bDirty = false;
hstmt_select = NULL;
hstmt_update = NULL;
hstmt_insert = NULL;
hstmt_delete = NULL;
m_lname = "";
m_fname = "";
m_street = "";
m_street2 = "";
m_city = "";
m_state = "";
m_zipcode = "";
m_email = "";
m_phone = "";
m_date = "";
m_filter = "";
m_id = 0;
m_count = 0;
}

AddressBook::OnClose(),int
{
if m_bDirty DoUpdate();
CloseAll();
return true;
}

AddressBook::OnInitDialog(),int
{
//add the menu
menu m;
m.BeginMenu();
m.MenuTitle( "&File");
m.MenuItem( "&Quit",0,IDM_QUIT);
m.MenuTitle( "&Edit");
m.MenuItem( "&Update",0,IDM_UPDATE);
m.MenuItem( "&New",0,IDM_NEW);
m.MenuItem( "&Delete",0,IDM_DELETE);
m.EndMenu();
SetMenu(m.Detach());
/* Initialize any controls here */
m_editFirst = GetControl(IDE_FIRST);
m_editLast = GetControl(IDE_LAST);
m_editStreet1 = GetControl(IDE_STREET1);
m_editStreet2 = GetControl(IDE_STREET2);
m_editCity = GetControl(IDE_CITY);
m_editState = GetControl(IDE_STATE);
m_editPostal = GetControl(IDE_POSTAL);
m_editEmail = GetControl(IDE_EMAIL);
m_editPhone = GetControl(IDE_PHONE);
m_staticID = GetControl(IDS_RECID);
m_staticRECNO = GetControl(IDS_RECNO);
m_buttonUpdate = GetControl(IDB_UPDATE);
m_buttonNext = GetControl(IDB_NEXT);
m_buttonPrev = GetControl(IDB_PREV);
CenterWindow();
//open our database
if(OpenDatabase() = 0)
return false;
SetupControls();
if(hstmt_select) m_db.GetFirst(hstmt_select);
UpdateData(1);
//start the idle time
StartTimer(1000);
return true;
}

AddressBook::OnTimer(int nIDEvent),int
{
DoIdle();
return True;
}

AddressBook::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case IDE_FIRST:
case& IDE_STREET1:
case& IDE_LAST:
case& IDE_STREET2:
case& IDE_CITY:
case& IDE_STATE:
case& IDE_POSTAL:
case& IDE_PHONE:
case& IDE_EMAIL:
/* respond to edit notifications here */
if nNotifyCode = ENCHANGE
m_bDirty = TRUE;
case IDB_PREV:
if(nNotifyCode = 0)
{
/*button clicked*/
IF m_bDirty DoUpdate();
if(hstmt_select)
{
if m_db.GetPrev(hstmt_select)
EnableWindow(m_buttonNext->m_hWnd,1)
else
{
m_db.GetFirst(hstmt_select);
EnableWindow(m_buttonPrev->m_hWnd,0);
}
UpdateData(1);
}
}
case IDB_NEXT:
if(nNotifyCode = 0)
{
/*button clicked*/
IF m_bDirty DoUpdate();
if(hstmt_select)
{
if m_db.GetNext(hstmt_select)
EnableWindow(m_buttonPrev->m_hWnd,1)
else
{
m_db.GetLast(hstmt_select);
EnableWindow(m_buttonNext->m_hWnd,0);
}
UpdateData(1);
}
}
case IDB_UPDATE:
if(nNotifyCode = 0)
{
/*button clicked*/
DoUpdate();
}
case IDB_NEW:
if(nNotifyCode = 0)
{
IF m_bDirty DoUpdate();
DoNew();
/*button clicked*/
}
}
return true;
}

AddressBook::OnMenuPick(int nID),int
{
select(nID)
{
case IDM_QUIT:
IF m_bDirty DoUpdate();
CloseAll();
case IDM_DELETE:
DoDelete();
case IDM_NEW:
DoNew();
case IDM_UPDATE:
DoUpdate();
}
return true;
}

AddressBook::OnMenuInit(unsigned int hMenu),int
{
menu m;
m.Attach(hMenu);
m.EnableMenuItem(IDM_UPDATE,m_bDirty);
m.EnableMenuItem(IDM_DELETE,m_count <> 0);
m.Detach();
return true;
}

AddressBook::UpdateData(int bDirection),int
{
IF bDirection = 1
{
//from variables to edit controls
m_staticID->SetText(TrimLeft(NumToStr(m_id)));
m_staticRECNO->SetText(TrimLeft(NumToStr(m_count)));
m_editFirst->SetText(m_fname);
m_editLast->SetText(m_lname);
m_editStreet1->SetText(m_street);
m_editStreet2->SetText(m_street2);
m_editCity->SetText(m_city);
m_editState->SetText(m_state);
m_editPostal->SetText(m_zipcode);
m_editPhone->SetText(m_phone);
m_editEmail->SetText(m_email);
//setting a controls text also sends the ENCHANGE notification
//so mark the form as not modified
m_bDirty = FALSE;
}
else
{
//from edit controls to variables
m_id = StrToNum(m_staticID->GetText());
m_fname = m_editFirst->GetText();
m_lname = m_editLast->GetText();
m_street = m_editStreet1->GetText();
m_street2 = m_editStreet2->GetText();
m_city = m_editCity->GetText();
m_state = m_editState->GetText();
m_zipcode = m_editPostal->GetText();
m_phone = m_editPhone->GetText();
m_email = m_editEmail->GetText();
}
}

AddressBook::OpenDatabase(),int
{
int nReturn = 0;
unsigned int hStmt=0;
nReturn = m_db.Connect("Microsoft Access Driver (*.mdb)",GetStartPath() + "addressbook.mdb","",this);
IF nReturn = 0
{
//couldn't open so try creating
m_db.CreateMDB(GetStartPath() + "addressbook.mdb");
nReturn = m_db.Connect("Microsoft Access Driver (*.mdb)",GetStartPath() + "addressbook.mdb","",this);
IF nReturn
{
//add a table
hStmt = m_db.ExecSQL("CREATE TABLE addresses (id counter(1,1),fname varchar(40),lname varchar(40),street varchar(255),street2 varchar(255) )");
//check for errors
IF LEN(m_db.GetErrorCode(hstmt))
MessageBox( this,m_db.GetErrorText(hstmt),m_db.GetErrorCode(hstmt));
m_db.FreeSQL(hStmt);
//alter the table
hStmt = m_db.ExecSQL("ALTER TABLE addresses ADD city varchar(40),state varchar(10),zip varchar(9),phone varchar(20),email varchar(255),dtadded date");
//check for errors
IF LEN(m_db.GetErrorCode(hstmt))
MessageBox(this,m_db.GetErrorText(hstmt),m_db.GetErrorCode(hstmt));
m_db.FreeSQL(hstmt);
}
ELSE
MessageBox(this,"Could not connect/create database","Error");


}
//are we open?
IF nReturn
//get the initial count of records
m_count = m_db.Cardinality("addresses");

RETURN nReturn;
}

AddressBook::CloseAll()
{
//check and close all statments just to be on the safe side
IF hstmt_select
m_db.FreeSQL(hstmt_select);
IF hstmt_update
m_db.FreeSQL(hstmt_update);
IF hstmt_insert
m_db.FreeSQL(hstmt_insert);
IF hstmt_delete
m_db.FreeSQL(hstmt_delete);
IF m_db.m_hDBC <> NULL
m_db.Disconnect();
StopTimer();
CloseDialog(1);
}

AddressBook::SetupControls()
{
m_staticRECNO->SetText(TrimLeft(NumToStr(m_count)));
EnableWindow(m_buttonUpdate->m_hWnd,0);

IF m_count = 0
{
EnableWindow(m_buttonPrev->m_hWnd,0);
EnableWindow(m_buttonNext->m_hWnd,0);
DoIdle();
}
ELSE
{
EnableWindow(m_buttonPrev->m_hWnd,0);
InitSelect();
}
m_editFirst->SetLimitText(40);
m_editLast->SetLimitText(40);
m_editStreet1->SetLimitText(255);
m_editStreet2->SetLimitText(255);
m_editCity->SetLimitText(40);
m_editState->SetLimitText(10);
m_editPostal->SetLimitText(9);
m_editPhone->SetLimitText(20);
m_editEmail->SetLimitText(255);
}

AddressBook::DoNew()
{
//insert a blank record
IF hstmt_select
m_db.FreeSQL(hstmt_select);
hstmt_select = NULL;
hstmt_insert = m_db.ExecSQL("INSERT INTO addresses (fname,lname,street,street2,city,state,zip,phone,email) VALUES('','','','','','','','','')");
m_db.FreeSQL(hstmt_insert);
hstmt_insert = NULL;
m_count = m_db.Cardinality("addresses");
InitSelect();
m_db.GetLast(hstmt_select);
UpdateData(1);
EnableWindow(m_buttonNext->m_hWnd,0);
EnableWindow(m_buttonPrev->m_hWnd,1);
EnableWindow(m_buttonUpdate->m_hWnd,1);
//make sure the edit controls are enabled
EnableWindow(m_editFirst->m_hWnd,1);
EnableWindow(m_editLast->m_hWnd,1);
EnableWindow(m_editStreet1->m_hWnd,1);
EnableWindow(m_editStreet2->m_hWnd,1);
EnableWindow(m_editCity->m_hWnd,1);
EnableWindow(m_editState->m_hWnd,1);
EnableWindow(m_editPostal->m_hWnd,1);
EnableWindow(m_editPhone->m_hWnd,1);
EnableWindow(m_editEmail->m_hWnd,1);
//set focus to the first control
m_editFirst->SetFocus();
m_bDirty = TRUE;
}

AddressBook::DoUpdate()
{
//save the currently displayed record
UpdateData(0);
hstmt_update = m_db.PrepareSQL("UPDATE addresses SET fname=?,lname=?,street=?,street2=?,city=?,state=?,zip=?,phone=?,email=?,dtadded=? WHERE id="+NumToStr(m_id));
m_db.BindParameter(hstmt_update,1,m_fname,TYPE_STRING,40);
m_db.BindParameter(hstmt_update,2,m_lname,TYPE_STRING,40);
m_db.BindParameter(hstmt_update,3,m_street,TYPE_STRING,255);
m_db.BindParameter(hstmt_update,4,m_street2,TYPE_STRING,255);
m_db.BindParameter(hstmt_update,5,m_city,TYPE_STRING,40);
m_db.BindParameter(hstmt_update,6,m_state,TYPE_STRING,10);
m_db.BindParameter(hstmt_update,7,m_zipcode,TYPE_STRING,10);
m_db.BindParameter(hstmt_update,8,m_phone,TYPE_STRING,20);
m_db.BindParameter(hstmt_update,9,m_email,TYPE_STRING,255);
m_db.BindParameter(hstmt_update,10,m_date,TYPE_STRING,40);
m_date = FormatDate();
m_db.Execute(hstmt_update);
m_db.FreeSQL(hstmt_update);
hstmt_update = NULL;
m_bDirty = FALSE;
}

AddressBook::DoDelete()
{
IF m_count AND hstmt_select
{
m_db.FreeSQL(hstmt_select);
hstmt_select = NULL;
hstmt_delete = m_db.ExecSQL("DELETE FROM addresses WHERE id =" + NumToStr(m_id));
m_db.FreeSQL(hstmt_delete);
hstmt_delete = NULL;
m_count = m_db.Cardinality("addresses");
if(m_count)
{
InitSelect();
m_db.GetFirst(hstmt_select);
UpdateData(1);
EnableWindow(m_buttonNext->m_hWnd,1);
EnableWindow(m_buttonPrev->m_hWnd,0);
}
else
{
EnableWindow(m_buttonNext->m_hWnd,0);
EnableWindow(m_buttonPrev->m_hWnd,0);
EnableWindow(m_buttonUpdate->m_hWnd,0);
m_lname = "";m_fname="";m_street="";m_street2="";m_city="";
m_state="";m_zipcode="";m_phone="";m_email="";
UpdateData(1);
}
}
}

AddressBook::DoIdle()
{
STRING strCaption = GetCaption();
INT pos = StrFind(strCaption,"*");
IF m_bDirty
{
IF pos = 0
{
strCaption += "*";
SetCaption(strCaption);
EnableWindow(m_buttonUpdate->m_hWnd,1);
}
}
ELSE
{
IF pos <> 0
{
strCaption = StrLeft(strCaption,pos-1);
SetCaption(strCaption);
EnableWindow(m_buttonUpdate->m_hWnd,0);
}
}
//if count = 0 then disable the edit controls
IF m_count = 0
{
EnableWindow(m_editFirst->m_hWnd,0);
EnableWindow(m_editLast->m_hWnd,0);
EnableWindow(m_editStreet1->m_hWnd,0);
EnableWindow(m_editStreet2->m_hWnd,0);
EnableWindow(m_editCity->m_hWnd,0);
EnableWindow(m_editState->m_hWnd,0);
EnableWindow(m_editPostal->m_hWnd,0);
EnableWindow(m_editPhone->m_hWnd,0);
EnableWindow(m_editEmail->m_hWnd,0);
m_staticID->SetText("*");
}
}

AddressBook::InitSelect()
{
string sel;
sel = "SELECT * FROM addresses";
IF LEN(m_filter)
sel += " WHERE " + m_filter;
hstmt_select = m_db.ExecSQL(sel);
IF hstmt_select
{
m_db.BindVariable(hstmt_select,1,m_id,TYPE_INT);
m_db.BindVariable(hstmt_select,2,m_fname,TYPE_STRING);
m_db.BindVariable(hstmt_select,3,m_lname,TYPE_STRING);
m_db.BindVariable(hstmt_select,4,m_street,TYPE_STRING);
m_db.BindVariable(hstmt_select,5,m_street2,TYPE_STRING);
m_db.BindVariable(hstmt_select,6,m_city,TYPE_STRING);
m_db.BindVariable(hstmt_select,7,m_state,TYPE_STRING);
m_db.BindVariable(hstmt_select,8,m_zipcode,TYPE_STRING);
m_db.BindVariable(hstmt_select,9,m_phone,TYPE_STRING);
m_db.BindVariable(hstmt_select,10,m_email,TYPE_STRING);
}
}


Title: Re: Address book example
Post by: Doc on February 18, 2006, 01:31:10 PM
Nifty!
Works well and will prove to be a lot of help down the road.

Thanks!
-Doc-
Title: Re: Address book example
Post by: Ionic Wind Support Team on February 18, 2006, 06:18:01 PM
It's just one of many ways to approach application design.  Works well enough.
Title: Re: Address book example
Post by: donh on February 21, 2006, 02:49:08 PM
Paul

On the case statement what does the case& mean I have not seen that before
just curious so I can add to my notes.

Don
Title: Re: Address book example
Post by: LarryMc on February 21, 2006, 03:00:59 PM
It's like case 1 or case 2 or case 3 so that if you take the same action for multiple cases you can group them together.
Title: Re: Address book example
Post by: Parker on February 21, 2006, 03:08:27 PM
Since we don't need to use break at the end of each case - the compiler does it automatically, we need the case& to let it know all of those conditions can fall through. In C you would just write a bunch of case labels and put break at the end of the action block. In Aurora you use case& to combine cases and no break.
Title: Re: Address book example
Post by: donh on February 21, 2006, 04:55:45 PM
thanks a bunch I understan now
Title: Re: Address book example
Post by: Ionic Wind Support Team on February 21, 2006, 08:15:05 PM
I find the reverse logic to C to be more natural.  Can't tell you how many times I've forgotten a 'break' and having unpredictable results that are hard to debug.