Programming Guide:xppguide

Basics of DatabaseEngines Foundation

The architecture of the Xbase++ DatabaseEngines (DBE) is designed to be applicable to any database model. This includes both record oriented databases (for example, Xbase databases) as well as set oriented and relational databases (for example, SQL databases). A database can be described abstractly as having four components:

DATA component

This component describes the database model or how the data itself is stored. "Database" here can be considered analogous to a "table" in the relational model or a "structure" in the hierarichal database model.

ORDER component

This component makes a mechanism available to allow the definition of logical sort orders based on expressions. This allows leaving the pre-existing physical order of the tables intact.

RELATION component

This component defines the relationships between data. It links tables either physically or logically based on expressions. The task of this component can be considered analogous to the "JOIN operator" in the relational model or the "Set-pointer" in the file-based network database model.

DICTIONARY component

This component describes the database structure and/or integrity rules.

A DatabaseEngine represents one or more of these four components and defines how they interact with the underlying database. The DBE itself is contained in a DLL file and is loaded at runtime of a program. For example, the file DBFDBE.DLL contains the DBE which provides the component for managing DBF files (DATA component). The file NTXDBE.DLL contains a DBE which represents a component for orders (ORDER component) that is valid for record oriented databases (for example, DBF files). This DBE manages index files in the NTX format. The DBFDBE and the NTXDBE are DatabaseEngines which each contain only one component for data and file management. They are each designated as a "component DBE".

Two component DBEs which provide different components can be assembled into one new DatabaseEngine which then controls both components and combines all the characteristics of the component DBEs within the new DBE. Such an assembled DatabaseEngine is called a "compound DBE". A compound DBE exists only in memory and is not saved in a file on the hard disk. Component DBEs, on the other hand, are stored in files.

Compound DBEs are generally needed when programming with databases and must be created at the start of the program. The appropriate component DBEs are loaded into memory using the function DbeLoad() and the compound DBE is created using the function DbeBuild(). The following program example shows the basic approach:

IF .NOT. DbeLoad( "DBFDBE", .T. )          // load component DBE 
   Alert( "DatabaseEngine DBFDBE not loaded", {"OK"} ) 
ENDIF 

IF .NOT. DbeLoad( "NTXDBE", .T. )          // load component DBE 
   Alert( "DatabaseEngine NTXDBE not loaded", {"OK"} ) 
ENDIF 
                                           // create compound DBE 
IF .NOT. DbeBuild( "DBFNTX", "DBFDBE", "NTXDBE" ) 
   Alert( "DBFNTX DatabaseEngine not created", {"OK"} ) 
ENDIF 

In the example, two component DBEs stored in the files DBFDBE.DLL and NTXDBE.DLL are loaded into memory. From these two component DBEs a compound DBE is created with the name "DBFNTX". This compound DBE can manage DBF files (DATA component) as well as NTX files (ORDER component).

The example uses only two of the four basic functions available for programming using DatabaseEngines. The next table lists all four functions:

Functions for the preparation of DatabaseEngines
Function Description
DbeLoad() Loads component DBE into memory
DbeBuild() Creates compound DBE and defines it as current DBE
DbeSetDefault() Defines default DBE for file operations
DbeUnLoad() Removes DBE from memory

The function DbeLoad() loads a component DBE into main memory. Such a DBE can be loaded in two ways: hidden and visible. A component DBE which is loaded as "hidden" can only be used for creating compound DBEs and not directly used for data and file management.

DbeLoad( "DBFDBE", .F. )           // load component DBE as visible 
USE Customer                       // open DBF file 
Browse()                           // perform file operations 

In this example, the component DBE is loaded as visible (.F. means not "hidden" here). Therefore the DBE can be used to open a DBF file, and execute file operations. The following example shows the opposite:

DbeLoad( "DBFDBE", .T. )           // load component DBE as hidden 
USE Customer                       // runtime error 

Here the component DBE is loaded as "hidden" and any attempt to use it for file management leads to a runtime error. The DBE can only be used to create a compound DBE using the function DbeBuild().

The compound DBE "DBFNTX" is created by default each time an Xbase++ program is started. This means that all file and index commands and functions work with this DatabaseEngine by default. The DBFNTX DBE is created in the file DBESYS.PRG. The function DbeSys() contained in this file is called each time an Xbase++ program starts.

The DBFNTX DatabaseEngine consists of only two components and is able to mimic the database model of Clipper in how it handles DBF files and NTX files. The RELATION component is unique in this database model in that no DBE is required for the RELATION component. Also there is no DICTIONARY component, because this is not supported by the database model.

Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.