Determine information about DatabaseEngines Foundation
At runtime of a program it is sometimes necessary to determine information about loaded DBEs, work areas, or individual fields in work areas. Xbase++ provides the four functions listed in the following table for this:
|DbeList()||Determines which DBEs are loaded|
|DbeInfo()||Returns information about the current DBE|
|DbInfo()||Returns information about a work area|
|FieldInfo()||Determines information about a field based on ordinal position|
For a deeper understanding of these functions, knowledge of the internal mechanisms used for opening files with USE or DbUseArea() is required. These mechanisms are not immediately recognizable at the language level. A file can only be opened when at least one DBE is loaded that provides the DATA component for the requested file format. Only after such a component is available can a file be opened in a work area, otherwise a runtime error occurs. Whether or not a DBE is currently available can be determined at runtime using the function DbeList(). DbeList() returns a two column array: the first column contains the names of DBEs and the second column contains logical values representing the "hidden-flag" (see previous section).
Opening a file using the current DBE creates an instance of the DBE which is called a "database object" (DBO). The DBO makes use of all the characteristics of the current DBE and it is actually the database object that opens and manages files. A DBO represents the work area where the files are opened.
It is helpful to distinguish between the DatabaseEngine, which provides the functionality that allows files to be opened in a work area and the database object which exists only while the file is open in the work area. The database object is created by the DatabaseEngine when the file is opened. It manages the file and is automatically discarded when the file is closed.
The function DbeInfo() provides information about the current DBE. Therefore, it can only be executed when a DBE is loaded. It is similar to the functions DbInfo() and FieldInfo() that can only be called when a file is open in the current work area. Otherwise a runtime error occurs.
As well as returning information, DbeInfo() also allows a DBE to be configured in specific ways. Several settings of a DBE are changeable and can be redefined using DbeInfo(). As an example, the default extension for files can be changed:
In this example, the default extensions for two different kinds of files are redefined using DbeInfo(). This affects the files managed by the DATA component of the DBFNTX DBE (the DBF file is created as a FBD file) and the files which are managed by the ORDER component (the NTX files are created as XTN files). All this happens in just two lines of the example:
A special aspect of DbeInfo() is shown: if the function is called with parameters, the first parameter must always be a #define constant from the file DMLB.CH specifying one of the four components that can be contained in a DBE. Also, the second parameter must be a #define constant. There some constants that are universally valid and can be used with every DBE and other constants that may be used only with a specific DBE. The difference can be recognized by the prefix of the #define constant. The prefix DBE_ identifies universally valid constants and the prefix DBFDBE_ identifies constants which are only valid for the DBFDBE (more precisely, for the DATA component which manages DBF files). Constants containing the prefix DBFDBE_ are defined in the #include file DBFDBE.CH. The third parameter specifies the value which is to be set for the specific setting (in the example, the file extension) of a DBE.
Not all settings of a DBE are changeable, so the third parameter is only processed by DbeInfo() when the DBE allows the corresponding setting to be changed. The following table gives an overview of the universally valid settings that exist for all DBEs. The only setting which can be changed is the file extension:
|DBE_DATATYPES||ro||C||Supported data types|
|DBE_EXTENSION||a||C||Default file extension|
|DBE_MANUFACTURER||ro||C||Producer of the DBE|
|DBE_NAME||ro||C||Name of the DBE|
|DBE_VERSION||ro||C||Version of the DBE|
Along with these general constants, most DatabaseEngines have specific #define constants that can only be used for the specific DBE (more precisely, for a specific component). In the chapter "Database Engines" DBE specific constants for DbeInfo() are described.
When a file is opened in a work area, a database object (DBO) is created by the current DatabaseEngine to manage the file open in the work area. The DBO represents the work area and the function DbInfo() can read information about the DBO and can change settings of the DBO. DbInfo() requires that a file be open in the corresponding work area.
DbInfo(), as well as DbeInfo(), receives parameters that are constants defined in an #include file. Universally valid constants can be found in the file DMLB.CH and are listed in the next table:
|DBO_FILENAME||ro||C||Name of the open file|
|DBO_ORDERS||ro||N||Number of orders (indexes)|
|DBO_RELATIONS||ro||N||Number of relations|
|DBO_SHARED||ro||L||.T. if data is accessed in SHARED mode|
|DBO_REMOTE||ro||L||.T. if the data is stored on a remote drive|
|DBO_SERVER||ro||L||.T. if the data is managed by a server|
|DBO_DBENAME||ro||L||Name of the DatabaseEngine managing this workarea|
The universally valid #define constants for DbInfo() starts with the prefix DBO_ (for database object). There are also constants which can be used only with DBOs created by a specific DatabaseEngine. An example of constants that can be passed to DbInfo() is given in the following program code:
The example illustrates that the first parameter passed to DbInfo() is a #define constant which is either a universally valid constant (prefix DBO_) or a specific DBE constant. In the case of the DBFDBE, the specific constants for the function DbInfo() start with the prefix DBFDBO_ and are contained in the #include file DBFDBE. (To summarize: constants which contain DBE_ are valid for a DatabaseEngine, and for the function DbeInfo(). Constants which contain DBO_ are valid for database objects and for the function DbInfo()). The constants for DbInfo() that are dependent on the current DatabaseEngine are listed in the chapter "Database Engines".
A DBO is initialized with all the current settings of the DBE when the file is opened. If changes are later made to the DBE using DbeInfo(), all DBOs remain unaffected by the change. This means that all work areas where files are open are not affected by changes made to a database engine. Such changes affect only those work areas where a file is opened after the change is made.
As soon as a file is opened in a work area, field variables (fields) exist within this work area. Similar to Clipper, information about a field can be determined using the functions FieldName() or FieldPos(). Xbase++ also includes the function FieldInfo() to read or change information about an individual field in a work area. The function FieldInfo() behaves in a manner similar to DbeInfo() and DbInfo(), and takes a #define constant as the second parameter. The valid constants for FieldInfo() are listed in the following table:
|FLD_LEN||ro||N||Length of field|
|FLD_DEC||ro||N||Number of decimal places|
|FLD_TYPE||ro||C||Data type of field variable on the Xbase++ language level|
|FLD_TYPE_AS_NUMERIC||ro||N||as character and numeric value|
|FLD_NATIVETYPE||ro||C||Original data type of field variable as defined in the DBE|
|FLD_NATIVETYPE_AS_NUMERIC||ro||N||as character and numeric value|
FieldInfo() provides important pieces of information about fields in the database such as the length and the number of decimal places. Example:
(In this example, it is assumed that the DBFDBE is loaded)
The first parameter of the function FieldInfo() is the ordinal position of a field (as returned by FieldPos()) and the second parameter is a #define constant designating what information is being requested. To determine the length of a field or its decimal places, two simple pseudo functions can be defined for translation by the preprocessor into calls to FieldInfo():
The data type of a field is also important information and can be determined by passing the constant FLD_TYPE or FLD_NATIVETYPE. In both cases FieldInfo() returns a character value identifying the data type. Using the two constants, the data type which is available to be manipulated by the appropriate Xbase++ commands and functions can be distinguished from the original data type stored in the database. They are often, but not always identical. For example, at the language level of Xbase++ only a single numeric type exists. When numbers are stored in fields, however, integers and floating point numbers might be treated differently. Xbase++ recognizes the different representations for numbers and other data internally and distinguishes between data types that can exist on the language level and on the database level. Correspondingly, FieldInfo() can read the data type of a field as it exists on the language level (FLD_TYPE) or on the database level (FLD_NATIVETYPE). To determine the data type of a field on the Xbase++ language level, the constant FLD_TYPE is passed to FieldInfo(). The data type is returned by FieldInfo() equivalent to the return values of Valtype() or Type().
The numeric identification of data types uses constants defined in the #include file TYPES.CH. The constants from the following table are available for determining data types using FieldInfo() along with FLD_TYPE_AS_NUMERIC and FLD_NATIVETYPE_AS_NUMERIC:
|XPP_BLOCK *)||Code block|
|XPP_DOUBLE *)||Numeric value as double|
|XPP_ILLEGAL *)||Invalid data type|
|XPP_UNDEF *)||Undefined value (NIL)|
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.