Database Function Library Graham .A. Kennedy (gakennedy@cix.compulink.co.uk) Version: 1.0 (20/02/95) Library Number : 10 (needs real number defining) ------------------- Database Library Documentation --------------------- Introduction: This library is provided to supply Blitz Basic with a number of simple Database functions, which may be used either, obviously within a database application (eg. the enclosed Address book program) or any program which needs an array which can expand upto the size of the free memory available. It also includes a number of functions which may be of use to anyone wishing to use fixed length strings within a newtype. Concepts: Some of the features of the database probably need some additional description before we launch straight into the command syntax, so here we go... hope it's not too boring... Database structure - The database is controlled by a Blitz Object, which can be accessed from the compiler options requester. Initially the number of databases is set to 16, but this can be increased (or decreased) depending on your requirements. The database itself is stored as a standard Amiga Exec name list, and uses the internal internal functions to create, add and remove entries. A database may be 'KEYED' ie. all or part of the record could be used as a key. If you add data to a keyed file it will be inserted in key order. Therefore, a keyed database is automatically in ascending order, and requires no sorting. Fixed length strings - These are a bit of a cludge to get around the fact that Blitz only stores a pointer to a string inside a newtype variable. Storing a string within the newtype itself, allows allsorts of interesting tricks, such as passing a database to a GTListview gadget to display, or saving a whole newtype to disk with one command. They are implemented by using a byte array within the newtype. eg. NewType.mytype name.b[30]:; Fixed length string 30 characters in length addrs.b[60]:; " " " 60 " " " age.l end newtype deftype.mytype test:; make test a variable of mytype. I will use this example when trying to describe the function of some of the following commands. ***** N O T E ***** Please not you CANNOT use standard strings within a database Newtype. Known Bugs: As far as I can tell there is only one known bug, which I hope will not be too much of a problem. If a database is filled so that it automatically expands, the total size of the new database is then used whenever the database is reloaded from disk, therefore taking up more memory than actually required. eg. a database is created with 500 records, and expands by 100 records each time it fills up. If 700 records are added then 600 deleted (leaving 100 records in the database). Whenever this database is saved to disk and reloaded it will allocate space for 700 records when reloading, even though only 100 records are loaded). So far I havn't found too many problems with this situation, I do know how to fix this, and probably will if anyone thinks the library is worthwhile. ------------------------------ Command Documentation --------------------- Database Commands: Statement : StrToFls Syntax : StrToFls string$,flspointer,length[,padchar] Description : This allows you to set a fixed length string to a value contained in a string. If the string is shorter than the length requested the fixed length string will be padded using the character defined by 'padchar'. If 'padchar' is ommitted '0' is used. If the string is longer than 'length', only 'length' bytes will be copied. Example : ; copies "Joe Bloggs" to field \name in test variable and ; pads field with spaces. a$="Joe Bloggs" StrToFls a$,test\name,30,32 ----------------- Function : FlsToStr Syntax : ret$=FlsToStr$(flspointer,length) Description : This allows you to convert a Fixed length string to a standard Blitz string. The string created is returned in ret$. The string will be copied either until the first '0' byte is found or 'length' bytes have been copied. Example : ; Copies "Joe Bloggs" back to a$ a$=FlsToStr$(test\name,30) ----------------- Function : DBinit Syntax : ret.b=DBinit(db#,primary,secondary,recvar[,keylen[,offset]]) Description : This command initialises and builds a database, if the database is already in use it will be destroyed and a new one created. If the database is created the function will return 1, if it fails it will return 0. db# = Database number primary = Number of record initially allocated to database secondary = Number of record to add if database fills up recvar = variable to use to define record structure keylen = key database on this number of bytes offset = Offset the key this number of bytes from the start of the record. Example : ; define database number 1, give it space for 100 records ; initially, and expand the database by 10 records each time ; it fills up. Use our example newtype to define its structure ; and key it on the name field. ret=DBinit{1,100,10,test,30) if ret=1 then Nprint "Yippee, database defined" ----------------- Function : DBlistaddr Syntax : ret.l=DBlistaddr(db#) Description : This returns the address of the head of the Nodelist which can then be passed to functions which require a standard Amiga namelist as a parameter. Example : ; display our list of names in a GTlistview Gadget ; nb. to use this example my GTLIB mod is required. GTChangeListM 1,2,DBlistaddr(1) ----------------- Command : DBfirst Syntax : ret.b = DBfirst(DB#) DBfirst DB# Description : This command sets the current record pointer to the first record in the database, if the database is empty or undefined the function will return 0, otherwise it will return 1. Example : ; Set pointer to first record in our database ok=DBfirst(1) ----------------- Command : DBlast Syntax : ret.b = DBlast(DB#) DBlast DB# Description : This command sets the current record pointer to the last record in the database, if the database is empty or undefined the function will return 0, otherwise it will return 1. Example : ; Set pointer to last record in our database ok=DBlast(1) ----------------- Command : DBnext Syntax : ret.b = DBnext(DB#) DBnext DB# Description : This command sets the current record pointer to the next record in the database, if the database is empty, undefined or there are no more records the function will return 0, otherwise it will return 1. Example : ; Scan our database records, start to finish ok=DBfirst(1) while (ok) ok=DBnext(1) wend ----------------- Command : DBprev Syntax : ret.b = DBprev(DB#) DBprev DB# Description : This command sets the current record pointer to the previous record in the database, if the database is empty, undefined or there are no more records the function will return 0, otherwise it will return 1. Example : ; Scan our database records, finish to start ok=DBlast(1) while (ok) ok=DBprev(1) wend ----------------- Command : DBadd Syntax : ret.b = DBadd(DB#,recvar) DBadd DB#,recvar Description : This adds the values stored in the record variable to the database at the current position. If it cannot be added, the function will return 0. If it adds OK, 1 will be returned. (In addition, if the add had to expand the size of the database, this function will return a 2, this is for information Only). If the database is keyed, the data is added at the correct position, to keep the database in order. Example : ; Add a record to our database StrToFls "Joe Bloggs",test\name,30 StrToFls "Joes House",test\addrs,60 test\age=32 ok=DBadd(1,test) If ok then Nprint "Yippee, added a record" ----------------- Command : DBaddLast Syntax : ret.b = DBaddLast(DB#,recvar) DBaddLast DB#,recvar Description : This adds the values stored in the record variable to the end of the database. If it cannot be added, the function will return 0. If it adds OK, 1 will be returned. (In addition, if the add had to expand the size of the database, this function will return a 2, this is for information Only). If the database is keyed, the data is added at the correct position rather than at the end. Example : ; Add a record to our database StrToFls "Joe Bloggs",test\name,30 StrToFls "Joes House",test\addrs,60 test\age=32 ok=DBaddLast(1,test) If ok then Nprint "Yippee, added a record" ----------------- Command : DBaddFirst Syntax : ret.b = DBaddFirst(DB#,recvar) DBaddFirst DB#,recvar Description : This adds the values stored in the record variable to the start of the database. If it cannot be added, the function will return 0. If it adds OK, 1 will be returned. (In addition, if the add had to expand the size of the database, this function will return a 2, this is for information Only). If the database is keyed, the data is added at the correct position rather than at the start. Example : ; Add a record to our database StrToFls "Joe Bloggs",test\name,30 StrToFls "Joes House",test\addrs,60 test\age=32 ok=DBaddFirst(1,test) If ok then Nprint "Yippee, added a record" ----------------- Function : DBrecs Syntax : ret.l=DBrecs(DB#) Description : Returns how many records are stored in the database. Example : Nprint "Database has ",DBrecs(1)," records in it" ----------------- Command : DBget Syntax : ret.b=DBget(DB#,recvar) DBget DB#,recvar Description : Retrieve the current record from the database into the record variable. If ok, the function returns 1, if the database is empty or undefined 0 is returned Example : ; lets get some data ok=DBfirst(1) if ok DBget 1,test Nprint "Name :",FlsToStr$(test\name,30) Nprint "Address:",FlsToStr$(test\addrs,60) Nprint "Age :",test\age end if ----------------- Statement : DBkill Syntax : DBkill DB# Description : Remove the current database from memory, if you do not remove a database it will be removed automatically when the program finishes. Example : ; I don't want ya no more, o database of mine DBkill 1 ----------------- Statement : DBdelete Syntax : DBdelete DB# Description : Delete the current record from the database. NB. To keep the speed of the library at a maximum, deleted records are NOT reallocated. Therefore if you do a large number of deletes it may be worth reorganising the database. This can be performed by saving it off (eg. to ram:) and reloading it. Example : ; I hate that first record ok=DBfirst(1) if ok then DBdelete 1 ----------------- Command : DBsetpos Syntax : ret.b=DBsetpos(DB#,record#) DBsetpos DB#,record# Description : Positions the record pointer at record#, if record# is greater than the number of records in the database it will make the last record current. Example : ; I wanna be, at record number 3 DBsetpos 1,3 ----------------- Statement : DBcasesense Syntax : DBcasesense ON|OFF Description : Switch case sensitivity on or off for database searches and adds to keyed databases. ----------- Statement : DBsetkey Syntax : DBsetkey ON|OFF Description : Switch keying on or off for database additions. NB. If you switch off case sensitivity then add a record to a keyed database the database may no longer be in order, as yet there is no sort command to reverse this situation. Additions to an unkeyed database are MUCH faster. ----------- Function : DBmemtype Syntax : DBmemtype memtyp Description : Set type of memory to be used when creating new databases. FASTRAM = 0 CHIPMEM = 2 CLRMEM = 65536 ----------- Function : DBfind Syntax : ret.b=DBfind(DB#,search$[,length,offset[,startrec]]) Description : Search database from the beginning for a string. if length and offset are not supplied, the whole record is searched. If a record is found, 1 is returned and the record is made current. 0 is returned if the search fails. If you only want to search part of the record, use the offset to indicate how many bytes from the start of the record you want to start, and set length to the number of bytes to search. If startrec is supplied the search will start from the indicated record. Example : ; Find joes house by searching address fields ok=DBfind(1,"Joe",60,30) if ok DBget 1,test NPrint "Yeehaaa, joes still here" Nprint "Name :",FlsToStr$(test\name,30) Nprint "Address:",FlsToStr$(test\addrs,60) Nprint "Age :",test\age end if ----------- Function : DBfindnext Syntax : ret.b=DBfindnext(DB#) Description : Search for the next occurance of search$ in the database. If a record is found, 1 is returned and the record is made current. 0 is returned if the search fails. Example : ; Find all joes houses ok=DBfind(1,"Joe",60,30) while (ok) DBget 1,test NPrint "Yeehaaa, joes still here" Nprint "Name :",FlsToStr$(test\name,30) Nprint "Address:",FlsToStr$(test\addrs,60) Nprint "Age :",test\age ok=DBfindnext(1) wend ----------- Statement : DBupdate Syntax : DBupdate DB#,recvar Description : Updates the current record with the data held in recvar. If the database is keyed, it will be reinserted at the correct position. Example : ; Let Jim have Joes House DBget 1,test StrToFls "Jimmy Jones",test\name,30 DBupdate 1,test ----------------- Command : DBload Syntax : ret.b=DBload(DB#,filename$) DBload DB#,filename$ Description : Load a database from disk. If the database is already in use it will be destroyed. If the load fails the function will return 0, if OK it will return 1. ----------------- Command : DBsave Syntax : ret.b=DBsave(DB#,filename$) DBsave DB#,filename$ Description : Save a database to disk. The database is reorganized as it is saved, removing any deleted records. If the save is OK, 1 will be returned, if it fails 0 will be returned. ----------------- Function : DBisnext Syntax : ret.b=DBisnext(DB#) Description : Tells you if there is a next record in the database. See, the example program for possible uses. ----------------- Function : DBisprev Syntax : ret.b=DBisprev(DB#) Description : Tells you if there is a previous record in the database. See, the example program for possible uses. ----------------- Function : DBcurrent Syntax : ret.l=DBcurrent(DB#) Description : Returns the current record number (0=database empty or not defined) ----------------- Function : DBmodified Syntax : ret.l=DBmodified(DB#) Description : Returns TRUE if the database has been modified since it was loaded or created. ----------------- Function : DBactive Syntax : ret.b=DBactive(DB#) Description : Returns True if the database is active (ie. defined) returns false otherwise ----------------- Statement : DBpush Syntax : DBpush Description : stores the current database pointer position ----------------- Statement : DBpop Syntax : DBpop Description : sets database pointer to the last record stored by DBpush ---------------- End Of Library Documentation -----------------