adb(n) 1.0 "Tcl database"

NAME

adb - Database implementation for Tcl/Tk programs

SYNOPSIS

package require Tcl 8

ADB::AddGlobalListener func
ADB::Add table record
ADB::ArrayToRecord table arr
ADB::Change table record
ADB::ChangedReset
ADB::Changed
ADB::Count table
ADB::Empty table
ADB::FirstKey table
ADB::GetArray table recordKey arrayname
ADB::GetEmptyArray table arrayname
ADB::GetField table field record
ADB::GetRecord table recordKey
ADB::Headerline table -ignoreheader list
ADB::Init table struc init_keyfunc
ADB::NextKey table
ADB::ReadCompositeFile filename ?rootname? ?parselogName?
ADB::ReadCompositeXMLFile filename
ADB::RecordToArray table arrayname record
ADB::RemoveGlobalListener func
ADB::RemoveKey table recordkey
ADB::Remove table record
ADB::SetChanged
ADB::SetField table field recordvar content
ADB::StoreAsXML filename rootname table
ADB::StoreCompositeFile filename listoftables
ADB::StoreCompositeXMLFile filename rootname listoftables
ADB::Structure table
ADB::Textline table recordkey -ignoreheader list

DESCRIPTION

This package provides an implementation of a database for Tcl/Tk applications. The package is pure-Tcl, but it allows XML importing and exporting facilities if the tdom package is available. The additional package adbsql allows for an interface to mysql, via the tclmysql package.

To use this package, make sure the source directory (where "adb.tcl" and "pkgIndex.tcl" are stored) is included in the auto_path directory. Use can you the command lappend to add this direcotry to your current path

Context of the different commands

Here is a short summary of the main commands of ADB and how they are used:

COMMANDS

ADB::AddGlobalListener func
Add a global listener function func. This function will be called if the database is changed and not yet written to storage. A listener function may be useful to indicate to the user that changes are not yet saved to non-volatile storage.

ADB::Add table record
Add an array or record to the database. The record argument should either be the content of a record or the content of an array passed on as a list using the {array get arrayName} expression. Internally is checked (based upon the size of the given list) what way is used by the programmer.

This function does not replace an already existing record.

Returns 0 if everything ok or a string with a error message if something is wrong.

See ADB::GetEmptyArray for an example of ADB::Add with an array.

ADB::ArrayToRecord table arr
Converts an array to a record of the given table type. The array must be passed on as a list using the [array get arrayName] expression.

ADB::Change table record
Change an array or record of the database. The record argument should either be the content of a record or the content of an array passed on as a list using the [array get arrayName] expression. Internally is checked (based upon the size of the given list) what way is used by the programmer.

This function only replaces a record according to the primary fields.

Returns 0 if everything ok or a string with a error message if something is wrong.

ADB::ChangedReset
Indicate that the internal database is saved. This function should be called to indicate you have used one of the ADB::SaveCompositeFile or ADB::SaveCompositeXMLFile to save the database. These two functions do not call this function internally!

ADB::Changed
Returns boolean indicating of database has been changed, since it was read or written to a file. The value TRUE or 1 indicates that a change occured.

ADB::Count table
Count the number of records in this table. If this table does not exist or is empty, 0 is returned.

Example:

 
puts "Records in table Athletes: [ADB::Count Athletes]"



ADB::Empty table
Empty the defined table. All data in the table is removed, except for the defined structure.

Note that the table should first be defined using the ADB::Init command.

ADB::FirstKey table
Get for the first record the first unique, primary key for the given table. After calling this function, use ADB::NextKey to get the subsequent next key.

This function together with ADB::NextKey is used as an iterator.

You can perform destructive action upon this record without changing the rest of the iterators. The iteration records are determined during this ADB::FirstKey call. However, if you add records, they will not be included in the current iteration until you do a FirstKey call again.

Note Expect a dictionary sorting order for the primary keys.

Note You can use multiple FirstKey/NextKey operations at the same time as long as they are for different tables.

Example:

 

proc ForAllAthletes { } {
    set atlkey [ADB::FirstKey Athletes]

    while { "$atlkey" != "" } {
        ADB::GetArray Athletes $atlkey athletearr
        
        # Do something with array athletearr, for instance:
        puts "Surname is $athletearr(surname)" 

        set atlkey [ADB::NextKey Athletes]
    }
}



ADB::GetArray table recordKey arrayname
Store the fields of the record indicated by recordKey of table table into the array arrayname. Returns 0 if everything ok or a string with a error message if something is wrong.

Note See ADB::FirstKey for an example.

Note The array is passed on as a variable name.

ADB::GetEmptyArray table arrayname
Store an empty record of the table into the array pointed to by variable name arrayname.

Example:

 
ADB::GetEmptyArray Athletes new_arr
set new_arr(no) 12445
set new_arr(firstname) John
set new_arr(surname) Doe
set new_arr(birthday) "01-01-2001"
ADB::Add Athletes [array get new_arr]



ADB::GetField table field record
Get the value of a specified field within the given record of the named table. The record must be a list that contains the record, as it is gotten via a GetRecord call.

ADB::GetRecord table recordKey
Return a record indicated by the recordKey of the given table. If the record cannot be found, an empty string is returned ("").

ADB::Headerline table -ignoreheader list
This somewhat ackward function returned a text line containing the descriptions of the fields as they are given via the ADB::Init command. The size of each field description is exactly as long as the size of the given field length at the ADB::Init. This function may be useful to print as header line of a listing of the table contents. Use the function ADB::Textline to output a record as a one line text line.

The -ignoreheader list argument can be given to specify a list of fields that will not be outputted.

ADB::Init table struc init_keyfunc
Initialise a table for the database by specifying the struc and providing a function that returns the primary key based opon the given record.

This command is always needed if you want to read or write a database. The internal structure of the database is not stored in that database, so even if your first action would be to read in a database, you first have to specify this ADB::Init. Note that this should not be a big problem because in order to access the database, you (as a programmer) must already have an understanding of the layout of the database and the tables.

The structure provided is a list containing a list for each field of the database. The following fields are mandatory for each field:

  1. A unique field name that is used to refer to this field, for instance, if the record is stored as an array: the fields is then the index

  2. A string describing the field. This string is used in ADB::Headerline.

  3. A integer number indicating the size of the field. At this moment, this size is not always enforced when storing a field, but with MySQL connectivity it is and the length is truncated.

  4. A value indicating if this is a primary field. Specify p for primary or just {} if not.

  5. The type of the field. This can be alphanum (alphanumeric), alpha (alphabetical), int (integer), date (a date), time (a time), or float (a floating point). This field is mainly used to determine the right SQL datatype if you choose for SQL connectivity. How you fill in the actual field value should therefore be consistent in the way SQL stores these values.


Example:

 

proc InitAthletes { } {

    set structure { 
	{no        "Licence number" 10 p alphanum}
	{firstname "First name" 20 {} alphanum}
	{surname   "Surname" 20 {} alphanum}
        {sex       "Sex" 10 {} alpha}
        {birthday  "Birthday" 4 {} int}
	{club      "Club" 30 {} alphanum}
	{category  "Category" 10 {} alphanum}
    }
    ADB::Init Athletes $structure AthletesDBKey
}

proc AthletesDBKey { rec } {
    return [lindex $rec 0]
}



ADB::NextKey table
Get the next iteration key. Always first do a call to ADB::FirstKey to initialise the iterator. See also this function for further details and behaviour.

ADB::ReadCompositeFile filename ?rootname? ?parselogName?
Reads an ADB-specific file (written by the ADB::WriteCompositeFile command) and stores it in the database.

If the rootname is given, the root (or main element) of the XML is compared to this value. Then, if they do not match, an error is reported. If not given or if "" is specified, the main element name is not checked and always accepted.

If the parselogName is given, additional elements in the XML file are reported here as a list of strings. For instance, if extra elements, comments, etc. are encountered they are reported here. If you want to enforce that no extra elements occur, specify the name of a variable here and later check that the list stored in this variable is empty.

Returns either 0 if ok, or a string indicating an error.

ADB::ReadCompositeXMLFile filename
Reads the XML-formated ADB database file (written by the ADB::WriteCompositeXMLFile command) and stores it in the database. Returns either 0 if ok, or a string indicating an error.

Note The tdom XML package should be installed for this function to work, otherwise an error is returned.

ADB::RecordToArray table arrayname record
Converts a database record to a database array given by the arrayname variable name.

Example:

 

set licence_no 12445
set rec [ADB::GetRecord Athletes $licence_no]
ADB::RecordToArray Athletes arr $rec
puts "Birthday is $arr(birthday)"



ADB::RemoveGlobalListener func
Remove a previously added global listener call (via the ADB::AddGlobalListener) from the list.

ADB::RemoveKey table recordkey
Remove record with given recordkey. Returns 0 is removed successfully or a text string if an error occurred.

ADB::Remove table record
Remove record specified by given record (or array passed on as a list using the [array get arrayName] expression).

ADB::SetChanged
Explicitly set that the database has been changed. If afterwards a call is made to ADB::Changed, then TRUE is returned. Functions within ADB that change the content of the database already call this function internally (such as ADB::Change or ADB::Add)

ADB::SetField table field recordvar content
Replaces contents of field with content from recordvar.

Note This is one of the rare functions where the record is passed on via the record variable name instead of the content of the record. So specify the record name, not the content of the record.

Example:

 

set licence_no 12445
set rec [ADB::GetRecord Athletes $licence_no]
ADB::SetField Athletes club rec "Fortis"
ADB::Change Athletes $rec



ADB::StoreAsXML filename rootname table
Store table of database as XML file using the rootname as the main (root) XML element. This function is also internally used to store the complete database using DBA::StoreCompositeXMLFile.

ADB::StoreCompositeFile filename listoftables
Stores the database as a file that can be later be read via the ADB::ReadCompositeFile.

ADB::StoreCompositeXMLFile filename rootname listoftables
Writes the database to an XML-formatted file, that can later be read by the ADB::ReadCompositeXMLFile. Returns either 0 if ok, or a string indicating an error.

Note The tdom XML package should be installed for this function to work, otherwise an error is returned.

ADB::Structure table
Return the structure of the table in the database.

ADB::Textline table recordkey -ignoreheader list
This somewhat ackward function returned a text line containing the content of a single record. The size of each field description is exactly as long as the size of the given field length at the ADB::Init. This function may be useful to print a listing of the table contents. Use the function ADB::Headerline to output a header containing the description of each field.

The -ignoreheader list argument can be given to specify a list of fields that will not be outputted.

Example:

 

proc table_to_listbox { scroll_frame table } {
    listbox $scroll_frame.list

    set i 0
    set objectptr [ADB::FirstKey $table]

    while { $objectptr != "" } {
	$scroll_frame.list insert end [ADB::Textline $table $objectptr]
	incr i
	set objectptr [ADB::NextKey $table] 
    }
    return $scroll_frame.list
}

KEYWORDS

XML, database, mysql, puretcl, sql, tcl

COPYRIGHT

Copyright © Roalt Aalmoes, 2007