Introduction
Previous Topic  Next Topic 

This CLIPPER Database Llibrary (CXDBF.DLL) allows for searching and manipulating DBaseIII tables using CLIPPER indexes.       In many cases it is simpler and faster to have a flat DBF table with CLIPPER indexes to carry out simple table lookup and index searching, rather than have a separate SQL database server.      Not only does this often provide a quicker and faster method of implementing an application,  but it reduces the costs and maintenance required to implement a full SQL server solution.


Database files in DBF format are supported by many PC applications, including dBase, Clipper, FoxPro and others. These files have the .DBF file extension.     All DBF database file consists of a header followed by a number of fixed length records.


The header contains a list of the field names and types, the record length and the number of records stored in the DBF file.


All fields are stored as characters strings and can be one of the following field types:



Type

Name

Description

C

Character

An ASCII character string

N

Numeric

A numerical value with a fixed number of places.   The field is right justified and is padded with blanks on the left and the there are n decimal places then the last n characters are assumed to be following the decimal point.      For example if there a 3 decimal places then 123456 represents 123.456

L

Logical

Contains a single character T or F for TRUE or FALSE.    A blank character can also represent FALSE.

D

Date

An Eight character string YYYYMMDD



All fields are numbered from zero for the first field and all TE functions which require a field as an argument will accept either field number or a field name.   


All records witrhin a DBF table are numbered from one as the first record.


When a database is opened by a call to db_open() then this function will return a handle to the database table which is then used in subsequent calls to other db_xxx() functions.            Zero or more associated indexes can then also be opened with calls to db_ixopen() for any indexes associated woth the DBF file.


When a record is read from the table using db_get() or a new record is appended using db_append() then a copy of the record is placed in memory and is referenced by a record handle.            All changes made to the record using db_fput() and any field values retrieved by db_fget() are actually done using the copy that is held in memory.       The underlying record on the disk will not be updated with any changes until a call is made to db_rls().


Note however that if an index key field is changed using db_fput() then the underlying index key value will be change immediately.     It is important to make use of record locks when accessing and updating shared database tables to ensure that data integrity is maintained.


Another issue that should be considered when updating DBF records is to ensure that a hangup signal does not cause a jump to the onsignal program before all of the data in a record and been updated correctly.         Use of functions such as CCsigctl() (from the Aculab function library) or sc_sigctl() (from the dialogic function libary) should be used to ensure that sections of code cannot be interrupted by hangup signals.



Index files are files that contain a list of <index key values> and the corresponding <DBF record number>.       For example if we had a DBF table with the following entries:


Record Number

Index Field Value

1

London

2

Birmingham

3

Leeds

4

Manchester

5

Newcastle



The corresponding index file would have the following index key list


Index Key Value

Record Number

Birmingham

2

Leeds

3

London

1

Manchester

4

Newcastle

5



Notice that the Index file holds the records in alphabetical order.        If a call is made to db_first() with a search_term set to "Aberdeen" then the db_first() function will fail to find an exact match and will return 0 and will position the index pointer to a position just before the first index entry.     A call to db_next() will then cause the index pointer to move to the first index key entry ("Birmingham") and the db_next() call will return 2 for the corresponding record number.



If a call is to db_first() with the search_term set to "London" then and exact match will be found and the function will return the record number 1 (and the index pointer will be set to the "London" index entry.          However if we set the search_term to "Lond", then an exact match will not be found and the db_first() function will return a record number of 0 and the index pointer will be set to point between the "Leeds" and "London" key entries.    A subsequent call to db_next() would then return recrod number 1 (for "London") or a call to db_prev() will return record number 3 (for "Leeds").


Note that when a call to db_first() is made the search_term is always padded with spaces on the right up to the full width of the index key field.


All database handles  and record handles (and their associated locks) are owned by the TE task that first obtained those handles.    If an attempt is made by another task to release a record handle or close a database handle that it does not own then an error will be generated.       Also if a task is killed for any reason (e.g. a stop, restart, endmain, endsignal statement is encountered or task_kill() or task_chain() causes the task to end) then all records owned by the task will be released (as if a call to db_rls() had been made) and all database handles will be closed (as if a call to db_close() had been made).


If an error is encountered by the library then an error message is written to the error log and a negative error value is returned.     Below is a list of the possible error values that can be returned by the functions:


-1        General Error (see error message for reason)

-5        No free database handles.   (see limits)

-6        File system error (E.g. bad path or file name)

-9        Invalid database handle given

-10        Invalid record handle given

-11        Invalid record number given

-13        No free record handles (see limits)

-14        Invalid field name or number given

-22        Index error

-24        Locking conflict



There are certain limits that have been hard-coded into the library with respect to the maximum number of open database jhandles or record handles.     these limits are shown below:


Maximim database handles        2048

Maximum open indexes                4096

Maximum record handles        4096