DataReelDataReelC++ Toolkit Documentation

Relational Database Management System

Contents

Overview
Tables, Fields and Keys
Table Definitions
Key Definitions
Definition Files
Adding, Finding, Changing and Deleting Records
Indexes and B-trees
File Layout
Usage Example
Type Definitions
Constants
Enumerations
Data Structures
gxRDBMS Functions
gxRDBMSHeader Functions
gxrdRecordHeader Functions
gxrdTableHeaderField Functions
gxrdTableHeader Functions
gxrdExcludeFields Functions
gxrdDatabaseRecord Functions
gxrdDatabaseTable Functions
gxrdDatabaseKey_t Functions
gxrdDatabaseKey Functions
Standalone Functions
Definition File Functions
SQL Functions

Overview

The gxRDBMS class is a small relational database manager. It stores the records of one table in a data file and keeps one or more index files used to find records quickly. The data file is created by the 32/64-bit database engine. The index files are B-tree files. Both kinds of file are opened and managed through a POD (Persistent Object Database) manager that the gxRDBMS object owns.

The relational layer is made up of four headers. The "gxrdbms.h" header declares the gxRDBMS class and a few standalone process ID file functions. The "gxrdbhdr.h" header declares the type definitions, constants, field types and the helper classes used by gxRDBMS: the file header (gxRDBMSHeader), the record header (gxrdRecordHeader), the persistent table header (gxrdTableHeader and gxrdTableHeaderField), the in-memory record (gxrdDatabaseRecord), the table (gxrdDatabaseTable), the field exclude list (gxrdExcludeFields) and the B-tree key (gxrdDatabaseKey_t and gxrdDatabaseKey). The "gxrdbdef.h" header declares functions that read table, key and other definitions from a text definition file. The "gxrdbsql.h" header is reserved for future SQL functions and declares nothing.

A table is described by two strings. The table definition names the table and lists its fields. The key definition says which field is the primary key, which fields are secondary keys, and sets a few options. You pass both strings to gxRDBMS::CreateTable(). This call parses the strings, builds the file names, and creates or opens the data and index files. You then build gxrdDatabaseRecord objects from the table's record definition and pass them to the add, find, change and delete functions.

Tables, Fields and Keys

Tables. Each gxRDBMS object works with one table. The table name is used to build the data and index file names, so it may not contain any of these characters: / \ * | : " < > ?. Every record written to the data file starts with a record header. The record header holds a table ID, which is the CRC-32 of the table name, and the number of fields.

Fields. A table has at least one field. The table header can hold up to 255 fields (tableMAX_FIELDS), but the definition string parser stops at 255 comma separated words, and the first word is the table name, so a table definition can describe at most 254 fields. Each field has a name, a display column length, a type, an optional array length and an optional format specifier. The field types are listed in the gxrdFIELD_TYPES enumeration. In memory, each field of a gxrdDatabaseRecord is held in its own MemoryBuffer as a one byte type ID, a four byte length and the field data. This lets a field grow or shrink without moving the other fields. On disk, the fields are written one after another after the record header, in the same type, length and data form.

Field numbers. Field numbers are not used the same way everywhere. The gxrdDatabaseRecord functions use zero-based column numbers. The key definition string uses one-based column numbers ("COL 1" is the first field). The gxRDBMS::Search() and gxRDBMS::SortOrderList() functions take one-based field numbers. The gxRDBMS::Find() function takes a zero-based field number. In several places the value -1 means "all fields".

Keys. A key is not the field value itself. A key is a 32-bit CRC of the key field data, made by gxrdDatabaseRecord::CreateKey(). If no primary key column is given ("PRI: COL NONE"), the key is the CRC of all fields. String fields are converted to upper case before the CRC is made when case is ignored. Each B-tree entry stores the key CRC, the table ID and the block address of the record in the data file. Because keys are CRC values, the B-tree is ordered by CRC and not by field value. Two different values can have the same CRC. When duplicates are not allowed, only one of them can be stored. NOTE: 10/14/2026: Fixed: a record found through its key is now read and its key fields are compared with the search record, so a value with the same CRC is no longer reported as found or deleted.

Table Definitions

A table definition is a comma separated string. The first word is the table name. Each word after that defines one field, in this form:

FieldName{ColumnLength}TYPE[ArrayLength].FormatSpecifier

The parts are:

FieldName - The name of the field. It is stored in the table header. Names longer than 254 characters are cut short so that the stored name always ends with a null.
{ColumnLength} - Required. The number of characters used to display the field. A column length of 0 tells a user interface to hide the field. A word without both braces is rejected with gxDBASE_BAD_COL_LENGTH.
TYPE - Required. One of CHAR, INT16, INT32, INT64, FLOAT, BOOL, VCHAR, BINARY, BLOB, CURRENCY or DATE. The name must be in upper case. An unknown type is rejected with gxDBASE_BAD_FIELD_TYPE.
[ArrayLength] - Optional. The number of elements. The field data size is the type size times the array length. For CHAR and VCHAR fields the type size is one byte, so "CHAR[64]" reserves 64 bytes. Without an array length a CHAR, VCHAR, BOOL, BINARY or BLOB field starts with one byte.
.FormatSpecifier - Optional. A number or a single letter that tells an application how to show the field. If the text after the dot is a non-zero number, the number is stored. Otherwise the first character is stored. See the format specifier constants.

Leading and trailing spaces around each word are removed. Escape sequences in the table name that start with "%" are converted and tab characters are removed. The table definition below defines a table named "contacts" with three fields:

contacts, Name{30}VCHAR[64], Phone{15}CHAR[16], Age{3}INT32

When the table definition is parsed by gxrdDatabaseTable::CreateTable(), the table builds a shorter record definition that keeps only the table name, the types and the array lengths. The record definition for the table above is:

contacts,VCHAR[64],CHAR[16],INT32

Records are created from the record definition. The record definition string is also used to test that a record belongs to the table. The gxRDBMS write, delete and change functions reject a record whose record definition is not exactly the same string (gxDBASE_BAD_RECORD).

Key Definitions

A key definition is a comma separated string parsed by gxRDBMS::DefineKeys(). The words are not case sensitive. The string must contain "PRI". The words are:

PRI: COL n          Primary key is field n (one-based).
PRI: COL NONE       The primary key is made from all the fields.
SEC: COL n          Field n is a secondary key. Repeat for more secondary keys.
ATTRIB: NOCASE      Ignore string case when keys are made and compared.
ATTRIB: ANCOMPARE   Use alphanumeric string compares.
ATTRIB: ALLOWDUP    Allow duplicate keys. The block address is then part of the key. Records with the same key values can be added, and a lookup by key returns the first record whose key fields match (10/24/2026, version 6.0).
ATTRIB: ORDER=n     Set the B-tree node order (default 64).
ATTRIB: RECLAIM=x   Set the deleted block reclaim method: NONE, BEST or FIRST.

Each ATTRIB word sets one attribute. Any other ATTRIB word, a PRI or SEC word without "COL", or a column number of 0 makes the call fail with gxDBASE_BAD_KEY_DEF. For example:

PRI: COL 1, SEC: COL 2, ATTRIB: NOCASE, ATTRIB: RECLAIM=BEST

The gxRDBMS constructor sets the stored key definition string to "PRI: COL 1,ATTRIB: NOCASE, ATTRIB: ANCOMPARE". This string is not parsed by the constructor. If you create a table with gxRDBMS::Create(), which does not take a key definition, the key settings stay at the constructor defaults: the primary key is made from all fields, case is compared, and there are no secondary keys. The default string is still written to the table header.

Definition Files

The functions in "gxrdbdef.h" read definitions from a text file. Each definition is a block that starts with a tag line and ends with "};". Lines that start with "#" and blank lines are skipped. Leading and trailing spaces are removed from each line and the lines in a block are joined with no separator, so each field must end with a comma. Everything up to and including the first "{" and everything from "};" on is removed. The tags are "DEFINE TABLE", "DEFINE KEYS", "DEFINE FORM", "DEFINE FKEYS", "DEFINE USER ACCESS" and "DEFINE GROUP ACCESS". The tag search does not depend on case. A short definition file looks like this:

# Contacts table
DEFINE TABLE {
  contacts,
  Name{30}VCHAR[64],
  Phone{15}CHAR[16],
  Age{3}INT32
};
DEFINE KEYS {
  PRI: COL 1,
  ATTRIB: NOCASE
};

The block must have a "{" on or after the tag line and before the first field, because the first "{" in the joined text is treated as the start of the block.

Adding, Finding, Changing and Deleting Records

Creating a record. Construct a gxrdDatabaseRecord from gxRDBMS::RecordDef(). Set each field with gxrdDatabaseRecord::SetField(), using zero-based column numbers. SetField() copies the bytes you give it and changes the stored field length to that number of bytes, so a string field should include its null terminator if you want it stored.

Adding. gxRDBMS::AddRecord() first looks for the record's primary key and then each secondary key. If any key is found the record is not added and the data file error is set to gxDBASE_RECORD_EXISTS. Otherwise gxRDBMS::Write() stores the record in one block of the data file and inserts the primary key into B-tree 0 and each secondary key into B-tree 1, 2, and so on. If a key cannot be inserted, the data file block is deleted again.

Finding. gxRDBMS::FindRecord() builds the keys from the record you pass in, searches the indexes, and passes back the block address of the record. By default it also reads the record from disk into the object you passed in. Only the key fields of the search record need to be set.

Changing. gxRDBMS::ChangeRecord() takes a "from" record that identifies the existing record and a "to" record with the new values. If the two records are the same size on disk the block is overwritten in place. Otherwise the old record and its keys are deleted and the new record is written to a new block. When any primary or secondary key value changes, the keys are deleted and added again. gxRDBMS::ChangeOrAdd() does the same but adds the "to" record when the "from" record is not found. gxRDBMS::ChangeRecordField() changes a single field of the record at a known block address.

Deleting. gxRDBMS::DeleteRecord() finds the record by its keys, removes the primary and secondary keys from the B-trees, and deletes the data file block. Deleted blocks are reused according to the reclaim method (first fit by default).

Errors. Most functions that return int return 1 (true) for success and 0 (false) for failure. Functions that return gxDatabaseError return gxDBASE_NO_ERROR (zero) for success. In both cases the error code is usually also stored in the POD object. Use gxRDBMS::GetDatabase() with POD::GetDataFileError() or POD::GetIndexFileError() to read it.

Indexes and B-trees

All tables use at least one index. Index number 0 always holds the primary key. When the key definition has a primary key column and one or more secondary keys, there is one more index for each secondary key, in the order the SEC words appear. If the primary key is "COL NONE", secondary keys are parsed but no secondary indexes are made.

With a single index the index file name is the table name plus the index file extension, for example "contacts.gix". With secondary keys each index is a separate file and a number is added to the name, starting at 1: "contacts.gix1" holds the primary key, "contacts.gix2" the first secondary key, and so on. The data file name is the table name plus the data file extension, for example "contacts.gxd". If a directory is given, it is put in front of each name. When the tables are opened and some but not all of the index files exist, or the data file does not exist, the existing index files are removed and created again.

The B-tree key type is gxrdDatabaseKey. All indexes use the same key type and node order. The index files are only an aid to searching. They can be checked with CheckIndex() and VerifyIndex() and rebuilt from the data file with RebuildIndex(). Search() and SortOrderList() walk one B-tree, read each record from the data file, and put the records they keep into an in-memory gxBStree list. That list is ordered by the primary key field, compared by value, not by CRC.

File Layout

The data file reserves a static area just after the database engine file header. Its size is returned by gxRDBMS::HeaderSize(). The static area holds, in order: the gxRDBMSHeader file ID ("GXRDBMS", a revision letter and a version number), the table name, the key definition, the form definition, the foreign key definition, the number of fields, one gxrdTableHeaderField for each field, and an application space of tableAPPLICATION_SPACE bytes. The table header is written when a new data file is created. When an existing file is opened and the field names, lengths or format specifiers in the file do not match the table definition, the header is written again from the definition. Each record is stored in its own data file block: a gxrdRecordHeader followed by the fields.

Usage Example

No program in this repository uses gxRDBMS, so the example below is a minimal program written for this page. It only calls functions declared in these headers.

#include <iostream>
#include "gxrdbms.h"

int main()
{
  gxRDBMS db;
  gxString tdef = "contacts, Name{30}VCHAR[64], Age{3}INT32";
  gxString kdef = "PRI: COL 1, ATTRIB: NOCASE";

  // Parse the definitions and create or open contacts.gxd/contacts.gix
  gxDatabaseError err = db.CreateTable(tdef, kdef);
  if(err != gxDBASE_NO_ERROR) {
    std::cout << gxDatabaseExceptionMessage(err) << "\n";
    return 1;
  }

  // Build a record from the table's record definition and add it
  gxrdDatabaseRecord rec(db.RecordDef());
  gxINT32 age = 42;
  rec.SetField("Alice", 6, 0);           // Zero-based column 0, with the null
  rec.SetField(&age, sizeof(age), 1);
  if(!db.AddRecord(&rec)) {
    std::cout << "Record not added\n";
  }

  // Find it again. Only the key field needs to be set.
  gxrdDatabaseRecord found(db.RecordDef());
  found.SetField("ALICE", 6, 0);         // NOCASE: case does not matter
  FAU_t block_address;
  if(db.FindRecord(&found, block_address)) {
    std::cout << (char *)found.GetField(0) << "\n";

    // Change the age
    gxrdDatabaseRecord changed(found);
    gxINT32 new_age = 43;
    changed.SetField(&new_age, sizeof(new_age), 1);
    db.ChangeRecord(&found, &changed);

    // Delete the record
    db.DeleteRecord(&changed);
  }

  db.Close();
  return 0;
}

Type Definitions

#if defined (__64_BIT_DATABASE_ENGINE__)
typedef gxINT64 gxrdKeyID;       // Persistent RDBMS key ID type
typedef __LLWORD__ gxrdKeyID_t;  // Native RDBMS key ID type

#else // Use the 32-bit version by default
typedef gxINT32 gxrdKeyID;     // Persistent RDBMS key ID type
typedef __LWORD__ gxrdKeyID_t; // Native RDBMS key ID type
#endif

typedef gxUINT32 gxrdTableID;     // Persistent RDBMS table ID type
typedef __ULWORD__ gxrdTableID_t; // Native RDBMS table ID type

typedef gxUINT32 gxrdKeyType;     // Persistent RDBMS Btree key type
typedef __ULWORD__ gxrdKeyType_t; // Native RDBMS Btree key type 

The key ID holds the block address of a record in the data file. The table ID holds the CRC-32 of the table name. The key type holds the CRC-32 of the key field data.

Constants

// Table Constants
const int tableFIELD_NAME_LEN = 255; // Max number of bytes for a field name

// Maximum number bytes allowed for table/file names
const int tableNAME_LEN = 255;

// Minimum number of bytes allocated for persistent definitions
const int tableDEF_LEN = 2048;

const int tableAPPLICATION_SPACE = 64*255; // Scratch pad area for application
const int tableMIN_FIELDS = 1; // Every table must have at least one field
const int tableMAX_FIELDS = 255; // Allow up to 255 fields per table

// Record Constants
const int recordMIN_FIELDS = tableMIN_FIELDS;
const int recordMAX_FIELDS = tableMAX_FIELDS;

// gxRDBMS Constants
const int gxrdFILE_ID_STR_LEN = 8; // Number of bytes used for signature string

// B-tree constants
const int gxrdDEFAULT_ORDER = 64; // Default B-tree node order
const int gxrdMAX_TREES = tableMAX_FIELDS; // Max number of B-trees per file

Format specifiers used by applications to modify field types. They are stored in the table header and are not used by the database itself. Note that 'D' is used both for gxrdDOC and gxrdDollar.

// Common string modifiers
const char gxrdMultiLine = 'M'; // Multi-line text
const char gxrdPassword = 'P';  // Password string
const char gxrdURL = 'U';       // Uniform resource locator

// Common BLOB modifiers
const char gxrdASCII = 'A'; // ASCII text file
const char gxrdDOC = 'D';   // Docutment text file
const char gxrdHTML = 'H';  // HTML text file
const char gxrdImage = 'I'; // Image text file
const char gxrdMM = 'm';    // Multimedia file
const char gxrdXML = 'X';   // XML text file
const char gxrdComp = 'Z';  // Compressed file

// Common boolean modifiers
const char gxrdCheckBox = 'C';  // Checked or unchecked
const char gxrdTrueFalse = 'T'; // True or false
const char gxrdYesNo = 'Y';     // Yes of no

// Common currency modifiers
const char gxrdDollar = 'D'; // Dollar symbol

Database engine constants

Enumerations

Field types. The value of each type is stored as the one byte type ID of a field.

enum gxrdFIELD_TYPES {
  gxrdINVALID_TYPE = 0, // Invalid data type specified

  // Built-in relational field types
  gxrdCHAR,  // Fixed length character string type
  gxrdINT16, // 16-bit integer type
  gxrdINT32, // 32-bit integer type
  gxrdINT64, // 64-bit integer type
  gxrdFLOAT, // Floating point type

  // Extended relational field types
  gxrdBOOL,   // Boolean type
  gxrdVCHAR,  // Variable length character string type
  gxrdBINARY, // User defined type
  gxrdBLOB,   // Large binary object type

  // Application specific field types
  gxrdCURRENCY, // Currency data type
  gxrdDATE      // Date data type
};

Default data sizes set by gxrdDatabaseRecord::GetRecordTypeSize(): BOOL, CHAR, VCHAR, BINARY and BLOB use 1 byte per element. INT16 uses sizeof(gxINT16), INT32 uses sizeof(gxINT32), INT64 uses 8 bytes, FLOAT and CURRENCY use sizeof(gxFLOAT64), and DATE uses sizeof(CDate). Every field also has 5 bytes of overhead: a one byte type ID and a four byte length. BLOB fields are skipped when keys are made. When one BLOB field is compared it never compares as equal. When all fields are compared, BLOB fields are skipped.

Database engine enumerations

Data Structures

The data members of the helper classes are shown below. Their member functions are listed in the function sections that follow.

The gxRDBMS file header is written at the start of the data file static area. It identifies the file as a gxRDBMS data file.

class gxRDBMSHeader
{
  ...
private:
  char file_id[gxrdFILE_ID_STR_LEN];
  gxUINT32 file_version;
};

The record header is stored at the start of every record in the data file.

struct gxrdRecordHeader
{
  ...
  gxUINT32 table_id;   // Unique table ID created with CRC32 of table name
  gxUINT32 num_fields; // Number of field this contained in this record
};

One table header field is stored in the data file for each field in the table.

struct gxrdTableHeaderField
{
  ...
  // Persistent field information when printing or displaying a table
  char field_type_id;     // Data type for this field
  char format_specifier;  // Optional field modifier, 0 if not set
  gxUINT32 column_length; // Num of chars required to display the field name
  gxUINT32 array_length;  // Optional array len of fixed types, 0 if not set
  char field_name[tableFIELD_NAME_LEN]; // Name of this field
};

The table header holds the persistent table information stored in the data file static area.

struct gxrdTableHeader
{
  ...
  // Table infomation null terminated strings.
  char table_name[tableNAME_LEN]; // Name of this table
  char key_def[tableDEF_LEN];     // Key definition
  char form_def[tableDEF_LEN];    // Form definition
  char fkey_def[tableDEF_LEN];    // Foreign key definition

  // Table fields
  gxUINT32 num_fields; // Number of fields in this header
  gxrdTableHeaderField *fields; // Array of header fields

  // Application specific static storage area
  char app_space[tableAPPLICATION_SPACE];
};

The exclude fields structure lists fields that are not copied to or from the disk record.

struct gxrdExcludeFields
{
  ...
  gxUINT32 num_fields; // Number of field to exclude
  gxUINT32 *fields;    // Zero-based array of field numbers
};

The database record holds one record in memory. Its data members are private except for the exclude list.

class gxrdDatabaseRecord
{
  ...
private:
  gxString table_name;   // Associated table name
  gxString record_def;   // Record sting definition
  __ULWORD__ num_fields; // Number of record fields
  int compare_field;     // Field(s) used for comparison
  int compare_case;      // True if comparing string case
  int compare_alpha;     // True if comparing alphanumeric strings

  // The record fields will be stored in an array of non-contiguous memory.
  // This allows each field to be resized with having to resize the entire
  // array.
  MemoryBuffer *db_record; // Array of record fields

public:
  // Public memeber used to allow specified fields to be excluded
  // when disk records are created and loaded.
  gxrdExcludeFields exclude_fields;
};

The database table holds the parsed table definition.

class gxrdDatabaseTable
{
  ...
public:
  gxString table_name; // Name of this table
  gxString record_def; // Record definition
  gxString table_def;  // Table definition
  gxrdTableHeader table_header; // Persistent table header
};

The primary key type stored in every gxRDBMS B-tree entry. The member order must not change, because the structure is written to disk as it is laid out in memory.

struct gxrdDatabaseKey_t
{
  ...
  gxrdKeyType k;   // gxRDBMS key
  gxrdTableID tid; // Key table identification number
  gxrdKeyID kid;   // Key data file address/identification number
};

The key class used by the B-tree. It is derived from DatabaseKeyB.

class gxrdDatabaseKey : public DatabaseKeyB
{
  ...
private: // Non-persistent data members
  int allow_dup_names;

private: // Persistent data members
  gxrdDatabaseKey_t key;
};

The gxRDBMS class keeps these protected data members.

class gxRDBMS
{
  ...
protected:
  POD *pod; // Pointer to this objects POD manager
  gxrdDatabaseTable table; // Database table
  gxString db_dir;     // Absolute path directory name
  gxString key_def;    // Database key definition
  gxString form_def;   // Form definition
  gxString fkey_def;   // Foreign key definition
  int num_trees;       // Total number of B-tree index files used
  int num_sec_keys;    // Total number of secondary keys defined
  int *sec_key_fields; // Secondary key fields
  int primary_key;     // Primary key field
  int compare_case;    // True if comparing string case
  int compare_alpha;   // True if comparing alphanumeric strings
  int dup;             // Variable used to allow duplicate names
  gxString datafile_name;    // Name of data file used to store tables
  gxString *indexfile_names; // Array of index file names
  gxDatabaseAccessMode mode; // Variable used to toggle read/write file access
  BtreeNodeOrder_t order;    // Variable used to set the B-tree order
  __SBYTE__ df_rev_letter;   // Variable used to set the data file rev letter
  __SBYTE__ if_rev_letter;   // Variable used to set the index file rev letter
  gxString datafile_ext;     // Data file dot extension
  gxString indexfile_ext;    // Index file dot extension

  // Database deleted/removed block reclamation method
  gxDatabaseReclaimMethod method;
};

gxRDBMS Functions

The gxRDBMS class creates, opens and maintains one table. It owns a POD object, which owns the data file and the index files. Functions that use the POD object directly, such as NumRecords(), IsEmpty(), NumKeys(), TestDatabase(), GetBtree(), GetDataFile() and UsingIndex(), do not check for an open database and must only be called after the table has been created or opened.

gxRDBMS::AddKey()
gxRDBMS::AddRecord()
gxRDBMS::AllowDup()
gxRDBMS::AlphaCompare()
gxRDBMS::CaseCompare()
gxRDBMS::ChangeOrAdd()
gxRDBMS::ChangeRecord()
gxRDBMS::ChangeRecordField()
gxRDBMS::CheckDataFile()
gxRDBMS::CheckIndex()
gxRDBMS::Close()
gxRDBMS::Create()
gxRDBMS::CreateTable()
gxRDBMS::DataFileExt()
gxRDBMS::DataFileName()
gxRDBMS::DataFileRev()
gxRDBMS::DefineKeys()
gxRDBMS::DefineTable()
gxRDBMS::DeleteKey()
gxRDBMS::DeleteRecord()
gxRDBMS::FKeyDef()
gxRDBMS::Find()
gxRDBMS::FindKey()
gxRDBMS::FindRecord()
gxRDBMS::Flush()
gxRDBMS::FormDef()
gxRDBMS::GenFileNames()
gxRDBMS::GetBtree()
gxRDBMS::GetDataFile()
gxRDBMS::GetDatabase()
gxRDBMS::HeaderSize()
gxRDBMS::IndexFileExt()
gxRDBMS::IndexFileNames()
gxRDBMS::IndexFileRev()
gxRDBMS::IsClosed()
gxRDBMS::IsEmpty()
gxRDBMS::IsOpen()
gxRDBMS::KeyDef()
gxRDBMS::Method()
gxRDBMS::Mode()
gxRDBMS::NoAlphaCompare()
gxRDBMS::NoCaseCompare()
gxRDBMS::NumKeys()
gxRDBMS::NumRecords()
gxRDBMS::NumSecKeys()
gxRDBMS::NumTrees()
gxRDBMS::Order()
gxRDBMS::OverWriteRecord()
gxRDBMS::PrimaryKey()
gxRDBMS::Read()
gxRDBMS::ReadAppSpace()
gxRDBMS::ReadBlockHeader()
gxRDBMS::ReadRecord()
gxRDBMS::ReadTableHeader()
gxRDBMS::RebuildDataFile()
gxRDBMS::RebuildIndex()
gxRDBMS::RecordDef()
gxRDBMS::Release()
gxRDBMS::Search()
gxRDBMS::SecKeyFields()
gxRDBMS::SetDataFileExt()
gxRDBMS::SetDataFileRev()
gxRDBMS::SetFKeyDef()
gxRDBMS::SetFormDef()
gxRDBMS::SetIndexFileExt()
gxRDBMS::SetIndexFileRev()
gxRDBMS::SetKeyDef()
gxRDBMS::SetMethod()
gxRDBMS::SetMode()
gxRDBMS::SetRecordDef()
gxRDBMS::SetTable()
gxRDBMS::SetTableDef()
gxRDBMS::SortOrderList()
gxRDBMS::Table()
gxRDBMS::TableDef()
gxRDBMS::TestDatabase()
gxRDBMS::UsingIndex()
gxRDBMS::VerifyDataFile()
gxRDBMS::VerifyIndex()
gxRDBMS::Write()
gxRDBMS::WriteAppSpace()
gxRDBMS::WriteTableHeader()
gxRDBMS::gxRDBMS()
gxRDBMS::~gxRDBMS()

int gxRDBMS::AddKey(DatabaseKeyB &key, DatabaseKeyB &compare_key, unsigned index_number = 0, int flushdb = 0)

Public member function used to insert a key into the B-tree with the given index number. Returns the result of the B-tree insert, true if successful or false if an error occurs. Returns false if the database is closed. Returns true without inserting anything if the database is not using an index. The index number is not checked against the number of B-trees.

gxDatabaseError gxRDBMS::AddKey(gxrdDatabaseRecord *r, FAU block_address, int flushdb = 0, int test_tree = 0)

Public member function used to build the primary key and all secondary keys for record "r" and insert them into the B-trees. Each key points to "block_address" in the data file. The primary key goes into B-tree 0 and secondary key "i" into B-tree "i+1". If a secondary key cannot be inserted, all keys for the record are deleted again and the error is returned. Returns gxDBASE_NO_ERROR if successful, gxDBASE_BAD_KEY if a key could not be made, or another error code.

int gxRDBMS::AddRecord(gxrdDatabaseRecord *r, int flushdb = 0, int test_tree = 0)

Public member function used to add a new record to the table. The function first calls FindKey(). If the primary key or any secondary key already exists, the record is not added and the data file error is set to gxDBASE_RECORD_EXISTS. This means secondary key values must also be unique unless duplicates are allowed. With duplicates allowed ("ATTRIB: ALLOWDUP") this check is skipped and the record is always written. Otherwise the record is written with Write(). NOTE: 10/24/2026: Before version 6.0 FindKey() could not find a record by key with ALLOWDUP, so the check always passed for indexed tables. If "flushdb" is true the file buffers are flushed after the write. If "test_tree" is true the B-tree header is tested before the search. Returns true if the record was added or false if not.

int gxRDBMS::AllowDup() const

Public member function that returns true if the key definition contained "ATTRIB: ALLOWDUP".

int gxRDBMS::AlphaCompare() const

Public member function that returns true if alphanumeric string compares are turned on ("ATTRIB: ANCOMPARE").

int gxRDBMS::CaseCompare() const

Public member function that returns true if string case is compared. This is the default. It is false after "ATTRIB: NOCASE".

int gxRDBMS::ChangeOrAdd(gxrdDatabaseRecord *from, gxrdDatabaseRecord *to, int flushdb = 0, int test_tree = 0)

Public member function used to change the record that matches "from" to the values in "to", or to add the "to" record if no match is found. Returns true if successful or false if an error occurs. NOTE: 10/14/2026: Fixed: when no match was found the old code wrote the "from" record; it now writes the "to" record.

int gxRDBMS::ChangeOrAdd(gxrdDatabaseRecord *from, gxrdDatabaseRecord *to, FAU_t &block_address, int flushdb = 0, int test_tree = 0)

Public member function that works like the version above. If "block_address" is zero the record is searched for. If it is gxCurrAddress the current data file position is used. Otherwise the record at "block_address" is changed. The block address is passed back. It may change if the record is moved to a new block, and it is set to the new block when the "to" record is added.

int gxRDBMS::ChangeRecord(gxrdDatabaseRecord *from, gxrdDatabaseRecord *to, int flushdb = 0, int test_tree = 0)

Public member function used to change an existing record. The "from" record is found with FindRecord(), which also loads it from disk. If "from" and "to" have the same size the block is overwritten in place, and if the primary key or any secondary key changed, the old keys are deleted and the new keys added. If the sizes differ, the old keys and block are deleted and "to" is written to a new block. Both records must have the table's record definition. Returns true if successful or false if the record is not found or an error occurs. NOTE: 10/14/2026: Fixed: secondary keys were not updated when the size and the primary key stayed the same.

int gxRDBMS::ChangeRecord(gxrdDatabaseRecord *from, gxrdDatabaseRecord *to, FAU_t &block_address, int flushdb = 0, int test_tree = 0)

Public member function that works like the version above but uses a known block address. A zero address means search for the record. gxCurrAddress means use the current data file position. The address is passed back and may change if the record is moved.

int gxRDBMS::ChangeRecordField(const void *data, __ULWORD__ bytes, __ULWORD__ col_number, FAU_t &block_address, int flushdb = 0, int test_tree = 0)

Public member function used to change one field of the record stored at "block_address". The column number is zero-based. If the record size changes, the record is deleted and written again and the new address is passed back. Otherwise only the field data is written in place, and the keys are deleted and added again if the primary key or any secondary key changed. Returns true if successful or false if an error occurs, including a zero block address. NOTE: 10/14/2026: Fixed: a zero block address did not stop the call, error codes were returned as the int result, only the primary key was updated, and a successful key update returned false.

gxDatabaseError gxRDBMS::CheckDataFile(int &rebuild_df, int &rebuild_ix, gxString *mesg = 0)

Public member function used to check the data file and its table header. If the data file does not exist it is created. Otherwise the file is opened with the database debug manager and the file header, the gxRDBMS file ID, the table header and the field types are tested against the current table definition. "rebuild_df" and "rebuild_ix" are set to true if the data file or the index files need to be rebuilt. A changed key or foreign key definition sets only "rebuild_ix". If "mesg" is not null, status messages are added to it. The table and key definitions must be set first, for example with GenFileNames(). Opens the database if it is not open. Returns gxDBASE_NO_ERROR if the file checks good or an error code.

gxDatabaseError gxRDBMS::CheckIndex(__ULWORD__ index_number, int &rebuild, gxString *mesg = 0)

Public member function used to check one index file. The index number must be less than NumTrees(). The file header and B-tree header are tested, then the number of keys is compared to the number of records in the data file. "rebuild" is set to true if the index should be rebuilt. If "mesg" is not null, status messages are added to it. Opens the database if it is not open. Returns gxDBASE_NO_ERROR if the index checks good or an error code.

gxDatabaseError gxRDBMS::Close()

Public member function used to close the data and index files. If they close without error the POD object is deleted, so IsOpen() returns false and GetDatabase() returns a null pointer until the table is created or opened again. Returns the POD close error or gxDBASE_NO_ERROR. NOTE: 10/14/2026: Fixed: the POD object was kept after Close(), so IsOpen() still returned true and later calls used closed files.

gxDatabaseError gxRDBMS::Create(const gxString &tdef)

Low-level public member function used to parse a table definition and create or open the table files. No key definition is parsed, so the current key settings are used (by default the primary key is made from all fields). Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::Create(const gxString &tdef, const gxString &dir)

Public member function that sets the database directory to "dir" and then calls Create(tdef).

gxDatabaseError gxRDBMS::CreateTable(const gxString &tdef, const gxString &kdef)

Public member function used to parse the table definition "tdef" and the key definition "kdef", build the file names, and create or open the data and index files. A new data file gets a new table header. An existing data file has its table header read, and written again if the field definitions changed. Returns gxDBASE_NO_ERROR if successful or an error code such as gxDBASE_BAD_TABLE_DEF, gxDBASE_BAD_KEY_DEF or a file error.

gxDatabaseError gxRDBMS::CreateTable(const gxString &tdef, const gxString &kdef, const gxString &dir)

Public member function that sets the database directory to "dir" and then calls CreateTable(tdef, kdef).

gxDatabaseError gxRDBMS::CreateTable(const gxString &tdef, const gxString &kdef, const gxString &fdef, const gxString &fkdef)

Public member function that stores the form definition "fdef" and foreign key definition "fkdef" and then calls CreateTable(tdef, kdef). The form and foreign key definitions are only stored in the table header. They are not parsed.

gxDatabaseError gxRDBMS::CreateTable(const gxString &tdef, const gxString &kdef, const gxString &fdef, const gxString &fkdef, const gxString &dir)

Public member function that stores the form and foreign key definitions, sets the database directory, and then calls CreateTable(tdef, kdef).

const gxString& gxRDBMS::DataFileExt() const

Public member function that returns the data file dot extension. The default is ".gxd".

const gxString& gxRDBMS::DataFileName() const

Public member function that returns the data file name built by the last create or GenFileNames() call.

__SBYTE__ gxRDBMS::DataFileRev() const

Public member function that returns the revision letter used when a new data file is created. The default is 'D'.

gxDatabaseError gxRDBMS::DefineKeys(const gxString &kdef)

Public member function used to parse a key definition. The table definition must already be set, because the number of fields is taken from the record definition. Sets the primary key, the secondary key fields, the compare options, the duplicate key option, the B-tree order and the reclaim method. Each call starts from the default primary key, compare and duplicate settings, so only the settings in "kdef" apply. The node order and reclaim method keep their current values unless "kdef" sets them. Returns gxDBASE_NO_ERROR if successful, or gxDBASE_BAD_KEY_DEF if the string has no "PRI", has more than one PRI word, has more secondary keys than fields, or contains a bad word. The secondary key field array is allocated with new[] and holds one entry per field. As of 10/14/2026 the old array is freed with delete[] (it was a scalar delete). NOTE: 10/14/2026: Fixed: the secondary key count was not reset, so a second call added to the old count and wrote past the end of the array. The bounds test also allowed one entry too many.

gxDatabaseError gxRDBMS::DefineTable(const gxString &tdef)

Public member function used to parse a table definition into the table object without opening any files. Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::DefineTable(const gxString &tdef, const gxString &kdef)

Public member function used to parse a table definition and then a key definition without opening any files. Returns gxDBASE_NO_ERROR if successful or an error code.

int gxRDBMS::DeleteKey(DatabaseKeyB &key, DatabaseKeyB &compare_key, unsigned index_number = 0, int flushdb = 0)

Public member function used to delete a key from the B-tree with the given index number. Returns the result of the B-tree delete, true if successful. Returns false if the database is closed or not using an index.

gxDatabaseError gxRDBMS::DeleteKey(gxrdDatabaseRecord *r, FAU &block_address, int flushdb = 0, int test_tree = 0)

Public member function used to build the primary and secondary keys for record "r", find them, and delete them from the B-trees. The block address found in the key is passed back in "block_address". With only one B-tree, returns gxDBASE_RECORD_NOT_FOUND if the primary key is not found. Returns gxDBASE_NO_ERROR if successful or an error code. Errors from secondary key deletes are not returned.

int gxRDBMS::DeleteRecord(gxrdDatabaseRecord *r, int flushdb = 0, int test_tree = 0)

Public member function used to delete the record that matches the keys in "r". The record must have the table's record definition. The record is found with FindKey(), which checks that the key fields really match, and then read from disk into "r" so that all its keys can be deleted. Without an index, the data file is searched. Returns true if the record was deleted or false if it was not found or an error occurred. NOTE: 10/14/2026: Fixed: with only one B-tree, the first key with the same CRC was deleted without checking the record.

const gxString& gxRDBMS::FKeyDef() const

Public member function that returns the foreign key definition string.

FAU_t gxRDBMS::Find(gxrdDatabaseRecord *r, __ULWORD__ field, int case_cmp, int alpha_cmp, int test_tree)

Low-level public member function used to find a record. "field" is a zero-based column number, or -1 for all fields. If the key definition gives this field a B-tree, a key is made from the field and that B-tree is searched. The record the key points to is then read and its key field is compared with "r". The block address is returned only if they match, and "r" is not changed. If the field has no B-tree, or no index is used, the data file is read block by block and each record is compared with "r". On a match for a single field, the record read from disk is copied into "r". Returns the block address, or zero if the record is not found or a key cannot be made. NOTE: 10/14/2026: Fixed: the field number itself was used as the B-tree index number, a key with the same CRC but a different value was reported as found, and the gxDBASE_BAD_KEY error code was returned as if it were an address. NOTE: 10/24/2026: Fixed in version 6.0: with duplicates allowed the block address is part of each key, so the search key, which has a block address of 0, never matched and every lookup by key failed. FindRecord(), DeleteRecord() and the change functions could not find any record. Find() now starts at the first key with the same CRC-32 value and reads each record with that value until one matches.

int gxRDBMS::FindKey(DatabaseKeyB &key, DatabaseKeyB &compare_key, unsigned index_number = 0, int test_tree = 0)

Public member function used to search the B-tree with the given index number for "key". If found, the stored key, including its block address, is copied into "key". Returns true if found or false if not found, the database is closed, or no index is used.

FAU_t gxRDBMS::FindKey(gxrdDatabaseRecord *r, int test_tree = 0)

Public member function used to look for record "r" by its primary key and then by each secondary key, using Find(). Returns the block address of the first match or zero if no key matches.

int gxRDBMS::FindRecord(gxrdDatabaseRecord *r, FAU_t &block_address, int load_record = 1, int test_tree = 0)

Public member function used to find a record by its keys. The block address is passed back in "block_address", or zero if not found. If "load_record" is true the record is read from disk into "r". Returns true if found or false if not. The data file error is set to gxDBASE_RECORD_NOT_FOUND when not found. The key fields of the record found are compared with "r", so a different value with the same CRC is not reported as found.

int gxRDBMS::FindRecord(gxrdDatabaseRecord *r, int load_record = 1, int test_tree = 0)

Public member function that works like the version above without passing back the block address.

void gxRDBMS::Flush()

Public member function used to flush the data and index file buffers. Does nothing if no POD object exists.

const gxString& gxRDBMS::FormDef() const

Public member function that returns the form definition string.

gxDatabaseError gxRDBMS::GenFileNames(const gxString &tdef, const gxString &kdef)

Public member function used to parse the table and key definitions and build the data and index file names without opening any files. This sets up the object for CheckDataFile() and CheckIndex(). Returns gxDBASE_NO_ERROR if successful or an error code. The index file name array is allocated with new[] and owned by this object.

gxDatabaseError gxRDBMS::GenFileNames(const gxString &tdef, const gxString &kdef, const gxString &dir)

Public member function that sets the database directory and then calls GenFileNames(tdef, kdef).

gxDatabaseError gxRDBMS::GenFileNames(const gxString &tdef, const gxString &kdef, const gxString &fdef, const gxString &fkdef)

Public member function that stores the form and foreign key definitions and then calls GenFileNames(tdef, kdef).

gxDatabaseError gxRDBMS::GenFileNames(const gxString &tdef, const gxString &kdef, const gxString &fdef, const gxString &fkdef, const gxString &dir)

Public member function that stores the form and foreign key definitions, sets the database directory, and then calls GenFileNames(tdef, kdef).

gxBtree *gxRDBMS::GetBtree(__ULWORD__ index_number = 0) const

Public member function that returns a pointer to the B-tree with the given index number. The pointer is owned by the POD object.

gxDatabase *gxRDBMS::GetDataFile() const

Public member function that returns a pointer to the open data file. The pointer is owned by the POD object.

POD *gxRDBMS::GetDatabase() const

Public member function that returns a pointer to the POD manager, or a null pointer if no table has been created or opened. The pointer is owned by this object.

FAU_t gxRDBMS::HeaderSize()

Public member function that returns the number of bytes needed for the gxRDBMS file ID and the current table header. This is the size of the static area of the data file.

const gxString& gxRDBMS::IndexFileExt() const

Public member function that returns the index file dot extension. The default is ".gix".

gxString *gxRDBMS::IndexFileNames() const

Public member function that returns the array of index file names, with NumTrees() entries, or a null pointer. The array is owned by this object and must not be deleted by the caller.

__SBYTE__ gxRDBMS::IndexFileRev() const

Public member function that returns the revision letter used when new index files are created. The default is 'E'.

int gxRDBMS::IsClosed() const

Public member function that returns true if no POD object exists.

int gxRDBMS::IsEmpty() const

Public member function that returns true if the data file has no records.

int gxRDBMS::IsOpen() const

Public member function that returns true if a POD object exists. A POD object exists after a successful create or open call and until Close() succeeds.

const gxString& gxRDBMS::KeyDef() const

Public member function that returns the key definition string.

gxDatabaseReclaimMethod gxRDBMS::Method() const

Public member function that returns the method used to reuse deleted data file blocks. The default is gxDBASE_RECLAIM_FIRSTFIT.

gxDatabaseAccessMode gxRDBMS::Mode() const

Public member function that returns the file access mode used when files are opened. The default is gxDBASE_READWRITE.

int gxRDBMS::NoAlphaCompare() const

Public member function that returns true if alphanumeric string compares are turned off.

int gxRDBMS::NoCaseCompare() const

Public member function that returns true if string case is ignored.

FAU_t gxRDBMS::NumKeys(__ULWORD__ index_number = 0)

Public member function that returns the number of keys in the B-tree with the given index number.

FAU_t gxRDBMS::NumRecords()

Public member function that returns the number of normal (not deleted) blocks in the data file, which is the number of records.

int gxRDBMS::NumSecKeys() const

Public member function that returns the number of secondary keys parsed from the key definition.

int gxRDBMS::NumTrees() const

Public member function that returns the number of B-tree indexes. This is 1, plus the number of secondary keys when a primary key column is set.

BtreeNodeOrder_t gxRDBMS::Order() const

Public member function that returns the B-tree node order. The default is gxrdDEFAULT_ORDER (64).

int gxRDBMS::OverWriteRecord(gxrdDatabaseRecord *r, FAU_t &block_address, int flushdb = 0, int test_tree = 0)

Public member function used to write record "r" over the record at "block_address". The function assumes the key fields have not changed. If "r" does not fit the existing block exactly, the old record and its keys are deleted and "r" is written to a new block, and the new address is passed back. Returns true if successful or false if an error occurs.

int gxRDBMS::PrimaryKey() const

Public member function that returns the one-based primary key column, or -1 if the primary key is made from all fields.

gxDatabaseError gxRDBMS::Read(gxrdDatabaseRecord *r, FAU_t block_address = gxCurrAddress)

Low-level public member function used to read the record stored at "block_address" into "r". The block header is read first to find the stored record length. If "r" does not have the table's record definition it is rebuilt from it. Returns gxDBASE_NO_ERROR if successful or an error code. gxDBASE_BAD_TABLE_ID means the block belongs to another table.

gxDatabaseError gxRDBMS::Read(gxrdDatabaseRecord *r, gxBlockHeader &blk, FAU_t block_address = gxCurrAddress)

Low-level public member function used to read a record when its block header "blk" has already been read. If "block_address" is not gxCurrAddress the file is first positioned just past the block header. Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::ReadAppSpace(void *buf, __ULWORD__ bytes, int test_db = 0)

Public member function used to read "bytes" bytes of the application space in the table header into "buf". "bytes" may not be more than tableAPPLICATION_SPACE. If "test_db" is true the file header is tested first. Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::ReadAppSpace(gxDatabase *f, gxrdTableHeader &table_header, void *buf, __ULWORD__ bytes, int test_db = 0)

Public member function used to read the application space from data file "f". "table_header" must have the same number of fields as this table. It is used to work out the file offset. Returns gxDBASE_NO_ERROR if successful, gxDBASE_BUFFER_OVERFLOW if "bytes" is too large, gxDBASE_BAD_TABLE_HEADER, or another error code.

gxDatabaseError gxRDBMS::ReadBlockHeader(gxBlockHeader &blk, FAU_t block_address = gxCurrAddress)

Low-level public member function used to read the data file block header at "block_address" into "blk". For revision C and D files the file is then positioned past the record lock header. Returns gxDBASE_NO_ERROR if successful or an error code.

int gxRDBMS::ReadRecord(gxrdDatabaseRecord *r, FAU_t block_address = gxCurrAddress)

Public member function used to read the record at "block_address" into "r". Returns true if successful or false if an error occurs.

gxDatabaseError gxRDBMS::ReadTableHeader(int test_db = 0)

Public member function used to read the table header from the open data file into this object's table header. Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::ReadTableHeader(gxrdTableHeader &table_header, gxRDBMSHeader &file_id, int test_db = 0)

Public member function used to read the file ID and table header from the open data file into the objects passed in.

gxDatabaseError gxRDBMS::ReadTableHeader(gxDatabase *f, gxrdTableHeader &table_header, gxRDBMSHeader &file_id, int test_db = 0)

Public member function used to read the file ID and table header from data file "f". Returns gxDBASE_BAD_TABLE_HEADER if the file ID is wrong or the stored number of fields is outside tableMIN_FIELDS to tableMAX_FIELDS. The field array in "table_header" is allocated by this call and owned by "table_header". Returns gxDBASE_NO_ERROR if successful or an error code.

int gxRDBMS::RebuildDataFile(__SBYTE__ rev, FAU_t static_area, int copy_static_data, FAU_t &records, const char *tempfile = 0)

Public member function used to rebuild a damaged data file. The good records are copied to a temporary file using revision letter "rev" and a static area of "static_area" bytes. If "copy_static_data" is true the old static area is copied too and its application space is kept. The old data file is removed, the temporary file is renamed to the data file name, and the table header is written again from the current definitions. If "tempfile" is null a name is made from the data file name plus "_rebuild_temp_file", the data file extension and ".00n". The number of records copied is passed back in "records". If the rebuild fails, the function tries to reconnect the files so later calls do not crash. Returns true if successful or false if an error occurs. NOTE: 10/14/2026: Fixed: "copy_static_data" was ignored and the application space was always cleared.

int gxRDBMS::RebuildDataFile(FAU_t &records, const char *tempfile = 0)

Public member function that rebuilds the data file using the current data file revision letter and HeaderSize() as the static area size.

int gxRDBMS::RebuildDataFile(int copy_static_data, FAU_t &records, const char *tempfile = 0)

Public member function that rebuilds the data file using the current data file revision letter and HeaderSize() as the static area size.

int gxRDBMS::RebuildIndex(__ULWORD__ index_number, FAU_t &records, FAU_t &keys)

Public member function used to rebuild one index file using the current node order, number of trees and index file revision letter. Returns true if successful or false if an error occurs.

int gxRDBMS::RebuildIndex(__ULWORD__ index_number, BtreeNodeOrder_t no, int ntrees, __SBYTE__ rev, FAU_t &records, FAU_t &keys)

Public member function used to rebuild one index file. The index is turned off, closed and created again with node order "no", "ntrees" trees and revision letter "rev". Every record in the data file is then read and a key is inserted for it. Index 0 gets primary keys and index "n" gets keys for secondary key "n" from the key definition. The number of records read and keys inserted are passed back. If the rebuild fails, the function tries to reconnect the files. Returns true if successful or false if an error occurs. NOTE: 10/14/2026: Fixed: the key field was the index number itself (index 1 used column 1 and so on), not the column from the key definition.

const gxString& gxRDBMS::RecordDef() const

Public member function that returns the record definition built from the table definition. Use it to construct records for this table.

void gxRDBMS::Release()

Public member function used when another object shares this object's POD object, secondary key array and index file name array. It sets those pointers to null without freeing them, so the destructor will not delete them. The caller becomes responsible for that memory.

gxDatabaseError gxRDBMS::Search(gxBStree<gxrdDatabaseRecord> &virtual_list, gxrdDatabaseRecord &compare_record, __ULWORD__ index_number, __ULWORD__ search_field, int case_cmp, int alpha_cmp, int find_all_matches, FAU_t list_limit)

Public member function used to search the table. The list is cleared, then the B-tree "index_number" is walked from the first key. Each record is read and its field "search_field" (one-based, or -1 for all) is compared with the same field in "compare_record". Matching records are inserted into "virtual_list", which is ordered by the primary key. If "find_all_matches" is true, a string field matches when it contains the search string, and other fields match on a byte pattern. "list_limit" is the number of records examined, not the number of matches, and it may not be more than the number of records. Returns gxDBASE_NO_ERROR if successful or an error code. NOTE: 10/14/2026: Fixed: a search field of -1 was rejected with gxDBASE_BUFFER_OVERFLOW. The compare settings of "compare_record" are changed by this call.

gxDatabaseError gxRDBMS::Search(gxBStree<gxrdDatabaseRecord> &virtual_list, gxString &search_string, int find_all_matches, FAU_t list_limit)

Public member function that calls the full string Search() with index number 0, search field PrimaryKey(), and the table compare settings. With "PRI: COL NONE" the call returns gxDBASE_BUFFER_OVERFLOW, because a string cannot be converted to all fields. NOTE: 10/14/2026: Fixed: the index number was PrimaryKey()-1.

gxDatabaseError gxRDBMS::Search(gxBStree<gxrdDatabaseRecord> &virtual_list, gxString &search_string, __ULWORD__ index_number, __ULWORD__ search_field, int case_cmp, int alpha_cmp, int find_all_matches, FAU_t list_limit)

Public member function used to search one field for a value given as a string. The string is converted to the field type and stored in a compare record, then the record version of Search() is called. BOOL fields accept Y, YES, TRUE, 1, CHECKED, N, NO, FALSE, 0 and UNCHECKED. CHAR strings are cut to the field length. "search_field" is one-based and may not be -1 (gxDBASE_BUFFER_OVERFLOW is returned). NOTE: 10/14/2026: Fixed: in the 32-bit engine an INT64 search value was stored as a 64-bit float, which never matched INT64 field data. It is now stored as low and high 32-bit words.

int *gxRDBMS::SecKeyFields() const

Public member function that returns the array of one-based secondary key columns, or a null pointer. The array is owned by this object. NumSecKeys() entries are used.

void gxRDBMS::SetDataFileExt(const UString &ext)

Public member function used to set the data file dot extension used by the next file name build.

void gxRDBMS::SetDataFileRev(__SBYTE__ rev)

Public member function used to set the revision letter for new data files.

void gxRDBMS::SetFKeyDef(const gxString &fkdef)

Public member function used to set the foreign key definition string.

void gxRDBMS::SetFormDef(const gxString &fdef)

Public member function used to set the form definition string.

void gxRDBMS::SetIndexFileExt(const UString &ext)

Public member function used to set the index file dot extension used by the next file name build.

void gxRDBMS::SetIndexFileRev(__SBYTE__ rev)

Public member function used to set the revision letter for new index files.

void gxRDBMS::SetKeyDef(const gxString &kdef)

Public member function used to set the stored key definition string. The string is not parsed. Use DefineKeys() to parse it.

void gxRDBMS::SetMethod(gxDatabaseReclaimMethod m)

Public member function used to set the deleted block reclaim method used by later writes.

void gxRDBMS::SetMode(gxDatabaseAccessMode m)

Public member function used to set the access mode used when files are next opened.

void gxRDBMS::SetRecordDef(const gxString &rdef)

Public member function used to set the record definition string directly. It is not checked.

void gxRDBMS::SetTable(const gxrdDatabaseTable &t)

Public member function used to copy a table object into this object.

void gxRDBMS::SetTableDef(const gxString &tdef)

Public member function used to set the table definition string directly. It is not parsed.

gxDatabaseError gxRDBMS::SortOrderList(gxBStree<gxrdDatabaseRecord> &virtual_list, FAU_t list_limit, FAU_t list_start, FAU_t list_end)

Public member function that calls the full SortOrderList() with index number 0, key number PrimaryKey(), and the table compare settings. NOTE: 10/14/2026: Fixed: the index number was PrimaryKey()-1, which failed with "PRI: COL NONE" or when the primary key column was greater than NumTrees().

gxDatabaseError gxRDBMS::SortOrderList(gxBStree<gxrdDatabaseRecord> &virtual_list, __ULWORD__ index_number, __ULWORD__ key_number, int case_cmp, int alpha_cmp, FAU_t list_limit, FAU_t list_start, FAU_t list_end)

Public member function used to build a sorted list of records. The list is cleared, then the B-tree "index_number" is walked in key order and records from position "list_start" to "list_end" are read and inserted into "virtual_list", up to "list_limit" records. The list is ordered by the primary key. "list_start" and "list_end" may not be more than the number of records and "list_end" may not be less than "list_start" (gxDBASE_BAD_RANGE_LIMIT). An empty table returns gxDBASE_NO_ERROR with an empty list. NOTE: "key_number" may be -1. NOTE: 10/14/2026: Fixed: -1 was rejected with gxDBASE_BUFFER_OVERFLOW. "key_number" is checked but does not change the list order, because each record is set to compare on the primary key before it is inserted.

const gxrdDatabaseTable& gxRDBMS::Table() const

Public member function that returns this object's table.

const gxString& gxRDBMS::TableDef() const

Public member function that returns the table definition string.

int gxRDBMS::TestDatabase() const

Public member function that calls POD::TestDatabase() to keep the in-memory buffers in step with the files. Returns the POD result.

int gxRDBMS::UsingIndex() const

Public member function that returns true if the POD object is using its index files.

int gxRDBMS::VerifyDataFile(FAU_t &records, int auto_fix, int &rebuild_df, int &rebuild_ix)

Public member function used to walk the data file and check every record against the record definition. The number of good records is passed back in "records". If "auto_fix" is true, bad records are deleted and "rebuild_ix" is set to true. If "auto_fix" is false, the first bad record stops the walk. If no database is open, CheckDataFile() is called first. If the data file does not exist a new one is created and the function returns true if that succeeds. An empty file sets gxDBASE_DATAFILE_EMPTY and returns true. Returns true if the data file is good or false if not. NOTE: 10/14/2026: Fixed: when the data file was missing, the gxDatabaseError result was returned as the int result, so a successful create returned false.

int gxRDBMS::VerifyDataFile(FAU_t &records)

Public member function that calls VerifyDataFile() with "auto_fix" set to true. Note that this means bad records are deleted.

int gxRDBMS::VerifyIndex(__ULWORD__ index_number, FAU_t &keys)

Public member function used to walk one B-tree and read the record each key points to. The number of keys is passed back in "keys". A record that does not match the record definition sets gxDBASE_BAD_DATAFILE but does not stop the walk. Returns true if the number of keys equals the number of records, or if both files are empty. Returns false otherwise.

gxDatabaseError gxRDBMS::Write(gxrdDatabaseRecord *r, FAU_t &block_address, int flushdb = 0, int test_tree = 0)

Low-level public member function used to write record "r" to a new data file block and add its keys. It does not check for an existing record. The record must have the table's record definition (gxDBASE_BAD_RECORD). The new block address is passed back. If the keys cannot be added, the data block is deleted. Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::Write(gxrdDatabaseRecord *r, int flushdb = 0, int test_tree = 0)

Low-level public member function that works like the version above without passing back the block address.

gxDatabaseError gxRDBMS::WriteAppSpace(const void *buf, __ULWORD__ bytes, int flushdb = 0)

Public member function used to write "bytes" bytes from "buf" to the application space of the table header. The data is also copied into this object's table header. Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::WriteAppSpace(gxDatabase *f, gxrdTableHeader &table_header, const void *buf, __ULWORD__ bytes, int flushdb = 0)

Public member function used to write the application space of data file "f" and copy the data into "table_header". "bytes" may not be more than tableAPPLICATION_SPACE (gxDBASE_BUFFER_OVERFLOW). "table_header" must have fields and the same number of fields as this table (gxDBASE_BAD_TABLE_HEADER).

gxDatabaseError gxRDBMS::WriteTableHeader(int init, int flushdb = 0)

Public member function used to write this object's table header to the open data file. If "init" is true the table header is first built again from the table, key, form and foreign key definitions. This clears the application space. Returns gxDBASE_NO_ERROR if successful or an error code.

gxDatabaseError gxRDBMS::WriteTableHeader(gxrdTableHeader &table_header, int flushdb = 0)

Public member function used to write "table_header" to the open data file.

gxDatabaseError gxRDBMS::WriteTableHeader(gxDatabase *f, gxrdTableHeader &table_header, int flushdb = 0)

Public member function used to write a new gxRDBMS file ID and "table_header" to the static area of data file "f". If "flushdb" is true the file is flushed. Returns gxDBASE_NO_ERROR if successful or an error code.

gxRDBMS::gxRDBMS()

Default class constructor. No files are opened. Sets these defaults: string case compared, no alphanumeric compare, primary key made from all fields, one B-tree, read/write access, node order 64, data file revision 'D', index file revision 'E', extensions ".gxd" and ".gix", first fit block reuse, and the key definition string "PRI: COL 1,ATTRIB: NOCASE, ATTRIB: ANCOMPARE" (stored but not parsed).

gxRDBMS::gxRDBMS(const gxRDBMS &ob)

Private copy constructor used to disallow copying. The assignment operator is also private.

virtual gxRDBMS::~gxRDBMS()

Class destructor. Deletes the POD object, which closes the files, and frees the index file name array and the secondary key field array. As of 10/14/2026 the secondary key field array is freed with delete[] (it was a scalar delete of an array).

gxRDBMSHeader Functions

The gxRDBMSHeader class holds the 8 byte file ID and the version number written at the start of the data file static area. A new object holds the ID "GXRDBMS", a revision letter of '\0' in the last byte, and version 1027.

gxRDBMSHeader::Clear()
gxRDBMSHeader::Copy()
gxRDBMSHeader::FileID()
gxRDBMSHeader::RevLetter()
gxRDBMSHeader::SizeOf()
gxRDBMSHeader::TestFileID()
gxRDBMSHeader::TestHeader()
gxRDBMSHeader::TestRevLetter()
gxRDBMSHeader::TestVersion()
gxRDBMSHeader::Version()
gxRDBMSHeader::operator=()
gxRDBMSHeader::gxRDBMSHeader()
gxRDBMSHeader::~gxRDBMSHeader()

void gxRDBMSHeader::Clear()

Public member function that sets the file ID bytes and the version to zero.

void gxRDBMSHeader::Copy(const gxRDBMSHeader &ob)

Public member function that copies the file ID and version from "ob".

const char *gxRDBMSHeader::FileID()

Public member function that returns a pointer to the 8 byte file ID. The bytes are owned by this object.

char gxRDBMSHeader::RevLetter()

Public member function that returns the last byte of the file ID, which is the revision letter.

__ULWORD__ gxRDBMSHeader::SizeOf()

Public member function that returns the number of bytes in the file ID plus the version.

int gxRDBMSHeader::TestFileID(const gxRDBMSHeader &ob)

Public member function that returns true if the first 7 bytes of the file ID match "ob".

int gxRDBMSHeader::TestHeader(const gxRDBMSHeader &ob)

Public member function that returns true if all 8 bytes of the file ID, including the revision letter, and the version match "ob".

int gxRDBMSHeader::TestRevLetter(const gxRDBMSHeader &ob)

Public member function that returns true if the revision letter matches "ob".

int gxRDBMSHeader::TestVersion(const gxRDBMSHeader &ob)

Public member function that returns true if the version matches "ob".

__ULWORD__ gxRDBMSHeader::Version()

Public member function that returns the version number.

void gxRDBMSHeader::operator=(const gxRDBMSHeader &ob)

Assignment operator. Calls Copy().

gxRDBMSHeader::gxRDBMSHeader()

Default class constructor. Sets the file ID to "GXRDBMS" with revision letter '\0' and the version to 1027.

gxRDBMSHeader::gxRDBMSHeader(const gxRDBMSHeader &ob)

Copy constructor. Calls Copy().

gxRDBMSHeader::~gxRDBMSHeader()

Class destructor. Does nothing.

gxrdRecordHeader Functions

The record header is written in front of every record in the data file. It is used to check that a record read from disk belongs to the table.

gxrdRecordHeader::Clear()
gxrdRecordHeader::Copy()
gxrdRecordHeader::GetCRC()
gxrdRecordHeader::SetTableID()
gxrdRecordHeader::SizeOf()
gxrdRecordHeader::TestTableID()
gxrdRecordHeader::operator=()
gxrdRecordHeader::gxrdRecordHeader()
gxrdRecordHeader::~gxrdRecordHeader()

void gxrdRecordHeader::Clear()

Public member function that sets the table ID and number of fields to zero.

void gxrdRecordHeader::Copy(const gxrdRecordHeader &ob)

Public member function that copies the table ID and number of fields from "ob".

gxUINT32 gxrdRecordHeader::GetCRC(const gxString &table_name)

Public member function that returns the CRC-32 of "table_name", or zero if the name is null.

void gxrdRecordHeader::SetTableID(const gxString &table_name)

Public member function that sets the table ID to the CRC-32 of "table_name", or to zero if the name is null. NOTE: 10/14/2026: Fixed: the null name test set zero and then fell through to compute the CRC.

__ULWORD__ gxrdRecordHeader::SizeOf()

Public member function that returns the number of bytes in the table ID plus the number of fields.

int gxrdRecordHeader::TestTableID(const gxString &table_name)

Public member function that returns true if the table ID equals the CRC-32 of "table_name".

void gxrdRecordHeader::operator=(const gxrdRecordHeader &ob)

Assignment operator. Calls Copy().

gxrdRecordHeader::gxrdRecordHeader()

Default class constructor. Clears the header.

gxrdRecordHeader::gxrdRecordHeader(const gxString &table_name, gxUINT32 nfields)

Class constructor that sets the table ID from "table_name" and the number of fields to "nfields".

gxrdRecordHeader::gxrdRecordHeader(const gxrdRecordHeader &ob)

Copy constructor.

gxrdRecordHeader::~gxrdRecordHeader()

Class destructor. Does nothing.

gxrdTableHeaderField Functions

One table header field describes one field of the table in the persistent table header.

gxrdTableHeaderField::Clear()
gxrdTableHeaderField::Copy()
gxrdTableHeaderField::SizeOf()
gxrdTableHeaderField::TestFieldType()
gxrdTableHeaderField::TestFieldVars()
gxrdTableHeaderField::VerifyFieldType()
gxrdTableHeaderField::operator=()
gxrdTableHeaderField::gxrdTableHeaderField()
gxrdTableHeaderField::~gxrdTableHeaderField()

void gxrdTableHeaderField::Clear()

Public member function that sets all members to zero.

void gxrdTableHeaderField::Copy(const gxrdTableHeaderField &ob)

Public member function that copies all members, including the full field name array, from "ob".

__ULWORD__ gxrdTableHeaderField::SizeOf()

Public member function that returns the sum of the sizes of the data members.

int gxrdTableHeaderField::TestFieldType(const gxrdTableHeaderField &ob, int strict_test = 0)

Public member function that returns true if the field type of "ob" can be used in place of this field type. If "strict_test" is true the types must be the same. Otherwise these casts are allowed: CHAR and VCHAR to each other; FLOAT and CURRENCY to each other; INT16 to INT32; INT16 and INT32 to INT64; any type except BLOB to BOOL. BLOB, BINARY, DATE and INT16 must match exactly.

int gxrdTableHeaderField::TestFieldVars(const gxrdTableHeaderField &ob)

Public member function that returns true if the format specifier, array length, column length and field name match "ob". The field type is not tested.

int gxrdTableHeaderField::VerifyFieldType()

Public member function that returns true if the field type ID is a known type other than gxrdINVALID_TYPE.

void gxrdTableHeaderField::operator=(const gxrdTableHeaderField &ob)

Assignment operator. Calls Copy().

gxrdTableHeaderField::gxrdTableHeaderField()

Default class constructor. Clears the field.

gxrdTableHeaderField::gxrdTableHeaderField(const gxrdTableHeaderField &ob)

Copy constructor.

gxrdTableHeaderField::~gxrdTableHeaderField()

Class destructor. Does nothing.

gxrdTableHeader Functions

The table header is the persistent description of the table stored in the data file static area. It owns its array of fields, which is allocated with new[] and freed by DestroyHeader() and the destructor.

gxrdTableHeader::AllocHeader()
gxrdTableHeader::Clear()
gxrdTableHeader::Copy()
gxrdTableHeader::DestroyHeader()
gxrdTableHeader::GetField()
gxrdTableHeader::SetFKeyDef()
gxrdTableHeader::SetField()
gxrdTableHeader::SetFormDef()
gxrdTableHeader::SetKeyDef()
gxrdTableHeader::SetTableName()
gxrdTableHeader::SizeOf()
gxrdTableHeader::TableDef()
gxrdTableHeader::TestFKeyDef()
gxrdTableHeader::TestFieldTypes()
gxrdTableHeader::TestFieldVars()
gxrdTableHeader::TestFormDef()
gxrdTableHeader::TestKeyDef()
gxrdTableHeader::TestTableName()
gxrdTableHeader::VerifyFieldTypes()
gxrdTableHeader::operator=()
gxrdTableHeader::gxrdTableHeader()
gxrdTableHeader::~gxrdTableHeader()

int gxrdTableHeader::AllocHeader(__ULWORD__ nfields)

Public member function that frees the current field array and allocates a new one with "nfields" fields. The count is forced into the range tableMIN_FIELDS to tableMAX_FIELDS. The application space is also set to zero. Returns true if successful or false if the allocation fails.

void gxrdTableHeader::Clear()

Public member function that sets the name and definition strings and the application space to zero and clears each field. The field array is kept.

void gxrdTableHeader::Copy(const gxrdTableHeader &ob)

Public member function that copies "ob" into this header, including the application space, and allocates a new field array. If "ob" has no fields, this header ends up with no field array. NOTE: 10/14/2026: Fixed: the application space was cleared by AllocHeader() after it was copied, and a header with no fields was copied through a null pointer.

void gxrdTableHeader::DestroyHeader()

Public member function that frees the field array and sets the number of fields to zero.

int gxrdTableHeader::GetField(gxrdTableHeaderField *fh, __ULWORD__ nfield)

Public member function that copies zero-based field "nfield" into "fh". The copied field name always ends with a null. Returns true if successful or false if there is no field array or "nfield" is out of range.

void gxrdTableHeader::SetFKeyDef(const char *s)

Public member function that copies "s" into the foreign key definition, cut to tableDEF_LEN-1 characters and ended with a null.

int gxrdTableHeader::SetField(char field_type_id, char format_specifier, char *field_name, gxUINT32 column_length, gxUINT32 array_length, __ULWORD__ nfield)

Public member function that clears zero-based field "nfield" and sets its members. As of 10/14/2026 the field name is copied with at most tableFIELD_NAME_LEN-1 characters so there is always room for the null terminator. Returns true if successful or false if there is no field array or "nfield" is out of range.

void gxrdTableHeader::SetFormDef(const char *s)

Public member function that copies "s" into the form definition, cut to tableDEF_LEN-1 characters and ended with a null.

void gxrdTableHeader::SetKeyDef(const char *s)

Public member function that copies "s" into the key definition, cut to tableDEF_LEN-1 characters and ended with a null.

void gxrdTableHeader::SetTableName(const char *s)

Public member function that copies "s" into the table name, cut to tableNAME_LEN-1 characters and ended with a null.

__ULWORD__ gxrdTableHeader::SizeOf()

Public member function that returns the number of bytes the header uses on disk: the name and definition arrays, the field count, the fields and the application space.

gxString gxrdTableHeader::TableDef() const

Public member function that builds a table definition string from the header, in the form "name,field{col}TYPE[n].fmt,...". A numeric format specifier is written as a number. Returns an empty string if the header has no fields.

int gxrdTableHeader::TestFKeyDef(const gxrdTableHeader &ob)

Public member function that returns true if the foreign key definition matches "ob".

int gxrdTableHeader::TestFieldTypes(const gxrdTableHeader &ob)

Public member function that returns true if both headers have the same number of fields and each field type of "ob" passes gxrdTableHeaderField::TestFieldType().

int gxrdTableHeader::TestFieldVars(const gxrdTableHeader &ob)

Public member function that returns true if both headers have the same number of fields and each field passes gxrdTableHeaderField::TestFieldVars().

int gxrdTableHeader::TestFormDef(const gxrdTableHeader &ob)

Public member function that returns true if the form definition matches "ob".

int gxrdTableHeader::TestKeyDef(const gxrdTableHeader &ob)

Public member function that returns true if the key definition matches "ob".

int gxrdTableHeader::TestTableName(const gxrdTableHeader &ob)

Public member function that returns true if the table name matches "ob".

int gxrdTableHeader::VerifyFieldTypes()

Public member function that returns true if the header has fields and every field type is valid.

void gxrdTableHeader::operator=(const gxrdTableHeader &ob)

Assignment operator. Calls Copy().

gxrdTableHeader::gxrdTableHeader()

Default class constructor. Creates an empty header with no field array.

gxrdTableHeader::gxrdTableHeader(__ULWORD__ nfields)

Class constructor that creates an empty header and allocates "nfields" fields.

gxrdTableHeader::gxrdTableHeader(const gxrdTableHeader &ob)

Copy constructor. Calls Copy().

gxrdTableHeader::~gxrdTableHeader()

Class destructor. Frees the field array.

gxrdExcludeFields Functions

An exclude list names zero-based fields whose data is not copied when a record is written to or loaded from disk. Excluded fields are stored with a length of zero. The list owns its array of field numbers.

gxrdExcludeFields::Clear()
gxrdExcludeFields::Copy()
gxrdExcludeFields::Exclude()
gxrdExcludeFields::SetNumFields()
gxrdExcludeFields::SizeOf()
gxrdExcludeFields::operator=()
gxrdExcludeFields::gxrdExcludeFields()
gxrdExcludeFields::~gxrdExcludeFields()

void gxrdExcludeFields::Clear()

Public member function that frees the field number array and sets the count to zero.

void gxrdExcludeFields::Copy(const gxrdExcludeFields &ob)

Public member function that copies the list from "ob". If "ob" is empty this list becomes empty. NOTE: 10/14/2026: Fixed: only "num_fields" bytes were copied instead of "num_fields" four byte entries, and copying an empty list left a freed pointer in place.

int gxrdExcludeFields::Exclude(gxUINT32 field)

Public member function that returns true if zero-based "field" is in the list.

void gxrdExcludeFields::SetNumFields(gxUINT32 nfields)

Public member function that allocates a new array of "nfields" entries, forced into the range tableMIN_FIELDS to tableMAX_FIELDS. Each entry is set to 0xffffffff, which matches no field. Set the entries directly through the "fields" member. As of 10/14/2026 the old array is freed with delete[] (it was a scalar delete).

__ULWORD__ gxrdExcludeFields::SizeOf()

Public member function that returns the size of the count plus the size of the entries.

void gxrdExcludeFields::operator=(const gxrdExcludeFields &ob)

Assignment operator. Calls Copy() unless "ob" is this object.

gxrdExcludeFields::gxrdExcludeFields()

Default class constructor. Creates an empty list.

gxrdExcludeFields::gxrdExcludeFields(gxUINT32 nfields)

Class constructor that calls SetNumFields(nfields).

gxrdExcludeFields::gxrdExcludeFields(const gxrdExcludeFields &ob)

Copy constructor. Calls Copy().

gxrdExcludeFields::~gxrdExcludeFields()

Class destructor. Calls Clear().

gxrdDatabaseRecord Functions

A database record holds one record in memory. It is built from a record definition and keeps one MemoryBuffer per field. The record owns this array. Pointers returned by GetField() and FieldData() point into the record's own buffers. They must not be freed, and they may become invalid after SetField() grows the field or the record is destroyed. Column numbers are zero-based. The compare field, case and alphanumeric settings control the overloaded comparison operators, which are used when records are kept in a gxBStree list.

gxrdDatabaseRecord::AlphaCompare()
gxrdDatabaseRecord::CaseCompare()
gxrdDatabaseRecord::Clear()
gxrdDatabaseRecord::Compare()
gxrdDatabaseRecord::CompareField()
gxrdDatabaseRecord::Copy()
gxrdDatabaseRecord::CreateDiskRecord()
gxrdDatabaseRecord::CreateKey()
gxrdDatabaseRecord::CreateRecord()
gxrdDatabaseRecord::FieldData()
gxrdDatabaseRecord::FieldDataDiskOffset()
gxrdDatabaseRecord::FieldDiskOffset()
gxrdDatabaseRecord::FieldHasNull()
gxrdDatabaseRecord::FieldLength()
gxrdDatabaseRecord::FieldType()
gxrdDatabaseRecord::GetField()
gxrdDatabaseRecord::GetRecord()
gxrdDatabaseRecord::GetRecordTypeSize()
gxrdDatabaseRecord::LoadDiskRecord()
gxrdDatabaseRecord::NoAlphaCompare()
gxrdDatabaseRecord::NoCaseCompare()
gxrdDatabaseRecord::NumFields()
gxrdDatabaseRecord::RecordDef()
gxrdDatabaseRecord::ResetAlphaCompare()
gxrdDatabaseRecord::ResetCaseCompare()
gxrdDatabaseRecord::ResetCompareField()
gxrdDatabaseRecord::SetAlphaCompare()
gxrdDatabaseRecord::SetCaseCompare()
gxrdDatabaseRecord::SetCompareField()
gxrdDatabaseRecord::SetField()
gxrdDatabaseRecord::SizeOf()
gxrdDatabaseRecord::SizeOfBuffer()
gxrdDatabaseRecord::SizeOfField()
gxrdDatabaseRecord::TableName()
gxrdDatabaseRecord::TestRecord()
gxrdDatabaseRecord::operator=()
operator==()
operator!=()
operator<()
operator>()
gxrdDatabaseRecord::gxrdDatabaseRecord()
gxrdDatabaseRecord::~gxrdDatabaseRecord()

int gxrdDatabaseRecord::AlphaCompare() const

Public member function that returns true if alphanumeric string compares are set.

int gxrdDatabaseRecord::CaseCompare() const

Public member function that returns true if string case is compared.

void gxrdDatabaseRecord::Clear()

Public member function that clears the table name and record definition and sets the compare settings back to all fields, case compared, no alphanumeric compare. The field array is kept so its memory can be reused.

int gxrdDatabaseRecord::Compare(const gxrdDatabaseRecord &ob, __ULWORD__ field, int case_cmp, int aplha_cmp, int find_match = 0) const

Public member function used to compare this record with "ob". "field" is a zero-based column, or -1 (or any value not less than the number of fields) to compare all fields. Returns -1 if the records have different tables, definitions or field counts. For one field it returns -1, 0 or 1 for less than, equal or greater than. When all fields are compared, the first field that is not equal decides the result, BLOB fields are skipped, and 0 means every field is equal. Strings are compared with StringCompare(), or StringANCompare() when "aplha_cmp" is true, and upper case is used when "case_cmp" is false. If "find_match" is true, a string field is equal when this field contains the "ob" string, and other non-BLOB fields are equal when the "ob" bytes are found in this field. A single BLOB field always returns -1. NOTE: 10/14/2026: Fixed: comparing all fields returned -1 even when every field was equal, and a field equal to the number of fields compared nothing and returned 0.

int gxrdDatabaseRecord::CompareField() const

Public member function that returns the zero-based compare field used by the comparison operators, or -1 for all fields.

void gxrdDatabaseRecord::Copy(const gxrdDatabaseRecord &ob)

Public member function that copies "ob" into this record: table name, record definition, field data, compare field, case and alphanumeric settings, and exclude list. The field array is reallocated when it is too small. NOTE: 10/14/2026: Fixed: the field count was set before the array size was tested, so copying into a record with a smaller array wrote past its end. The case compare setting was not copied.

gxDatabaseError gxrdDatabaseRecord::CreateDiskRecord(MemoryBuffer &disk_record)

Public member function that writes the record header and all fields into "disk_record" in the on-disk form. The buffer is resized if it is too small. Fields in the exclude list are written with a length of zero. Returns gxDBASE_NO_ERROR if successful or gxDBASE_NULL_PTR if the record has no fields.

gxrdKeyType_t gxrdDatabaseRecord::CreateKey(__ULWORD__ field, int case_cmp) const

Public member function that makes a B-tree key from zero-based "field", or from all fields if "field" is -1 or not less than the number of fields. The key is the CRC-32 of the field data. Strings stop at the first null and are converted to upper case when "case_cmp" is false. BLOB fields are skipped. Returns zero if a key cannot be made, for example when a field is too short for its type. A CRC that happens to be zero is also treated as an error by the callers. NOTE: 10/14/2026: Fixed: a field equal to the number of fields made a key from no data. NOTE: 10/24/2026: Fixed in version 6.0: when all fields were used, a BLOB field moved the write offset forward but did not add to the CRC length, so the fields after a BLOB were left out of the key. A BLOB is now skipped without leaving a gap. This changes the all-field keys of tables that have BLOB fields, so rebuild the index files made by version 5 for those tables with RebuildIndex.

gxDatabaseError gxrdDatabaseRecord::CreateRecord(const gxString &def, int clear_rec = 1)

Public member function that builds the record from record definition "def", such as "contacts,VCHAR[64],INT32". The first word is the table name and each other word is a type with an optional array length. Every field is set to zero. If "clear_rec" is true the record is cleared first and again on error. Returns gxDBASE_NO_ERROR if successful, gxDBASE_BAD_RECORD_DEF, gxDBASE_BAD_FIELD_TYPE or gxDBASE_MEM_ALLOC_ERROR. NOTE: 10/14/2026: Fixed: a record that already had a smaller field array kept it and the new fields were written past its end.

gxDatabaseError gxrdDatabaseRecord::CreateRecord(const gxString &def, __ULWORD__ cmp_field, int case_cmp, int alpha_cmp)

Public member function that clears the record, sets the compare field, case and alphanumeric settings, and then builds the record from "def".

void *gxrdDatabaseRecord::FieldData(__ULWORD__ col_number)

Public member function that returns a pointer to the data of field "col_number", or a null pointer if the column is out of range.

void *gxrdDatabaseRecord::FieldData(__ULWORD__ col_number, char &field_type_id, gxUINT32 &num_bytes)

Public member function that returns a pointer to the field data and passes back the field type ID and data length. Returns a null pointer if the column is out of range, and then the passed back values are not set.

gxDatabaseError gxrdDatabaseRecord::FieldDataDiskOffset(__ULWORD__ &offset, __ULWORD__ col_number)

Public member function that passes back the offset of the field's data from the end of the record header in the disk record. Returns gxDBASE_NO_ERROR or an error code.

gxDatabaseError gxrdDatabaseRecord::FieldDiskOffset(__ULWORD__ &offset, __ULWORD__ col_number)

Public member function that passes back the offset of the field's type ID from the end of the record header in the disk record. Returns gxDBASE_NO_ERROR, gxDBASE_NULL_PTR or gxDBASE_BUFFER_OVERFLOW.

int gxrdDatabaseRecord::FieldHasNull(__ULWORD__ col_number)

Public member function that returns true if the field data contains a null byte.

__ULWORD__ gxrdDatabaseRecord::FieldLength(__ULWORD__ col_number)

Public member function that returns the number of data bytes in the field. The column must be valid; for a bad column the returned value is not set.

int gxrdDatabaseRecord::FieldType(__ULWORD__ col_number)

Public member function that returns the field type ID, a gxrdFIELD_TYPES value. The column must be valid.

gxDatabaseError gxrdDatabaseRecord::GetField(void *data, __ULWORD__ bytes, __ULWORD__ col_number)

Public member function that copies "bytes" bytes of field data into "data". Returns gxDBASE_NO_ERROR, gxDBASE_NULL_PTR, gxDBASE_BUFFER_OVERFLOW for a bad column, or gxDBASE_BAD_FIELD_LENGTH if "bytes" is more than the field holds.

void *gxrdDatabaseRecord::GetField(__ULWORD__ col_number)

Public member function that returns a pointer to the field data, or a null pointer on error.

void *gxrdDatabaseRecord::GetField(__ULWORD__ col_number, __ULWORD__ &bytes)

Public member function that returns a pointer to the field data and passes back its length.

void *gxrdDatabaseRecord::GetField(__ULWORD__ col_number, __ULWORD__ &bytes, gxDatabaseError &err)

Public member function that returns a pointer to the field data and passes back its length. On error it returns a null pointer and sets "err". On success "err" is not changed.

MemoryBuffer *gxrdDatabaseRecord::GetRecord() const

Public member function that returns the record's field buffer array. The array is owned by the record.

void gxrdDatabaseRecord::GetRecordTypeSize(gxrdFIELD_TYPES type, __ULWORD__ &size, __ULWORD__ &overhead)

Public member function that passes back the data size of one element of "type" and the per-field overhead of 5 bytes. Unknown types get a size of 1.

gxDatabaseError gxrdDatabaseRecord::LoadDiskRecord(const MemoryBuffer &disk_record)

Public member function that loads the fields from a disk record made by CreateDiskRecord(). The table ID in the record header must match this record's table name (gxDBASE_BAD_TABLE_ID). Field buffers are grown if needed. Fields in the exclude list are loaded with a length of zero. Returns gxDBASE_BAD_RECORD if the stored lengths run past the end of the buffer. A disk record with more fields than this record is rejected with gxDBASE_BAD_RECORD. NOTE: 10/14/2026: Fixed: the field count from the disk record header was not checked, so a disk record with more fields wrote past the end of the field array.

int gxrdDatabaseRecord::NoAlphaCompare() const

Public member function that returns true if alphanumeric compares are not set.

int gxrdDatabaseRecord::NoCaseCompare() const

Public member function that returns true if string case is ignored.

__ULWORD__ gxrdDatabaseRecord::NumFields() const

Public member function that returns the number of fields.

const gxString& gxrdDatabaseRecord::RecordDef() const

Public member function that returns the record definition string.

void gxrdDatabaseRecord::ResetAlphaCompare()

Public member function that turns off alphanumeric compares.

void gxrdDatabaseRecord::ResetCaseCompare()

Public member function that makes compares ignore string case.

void gxrdDatabaseRecord::ResetCompareField()

Public member function that sets the compare field to -1 (all fields).

void gxrdDatabaseRecord::SetAlphaCompare()

Public member function that turns on alphanumeric compares.

void gxrdDatabaseRecord::SetCaseCompare()

Public member function that makes compares use string case.

void gxrdDatabaseRecord::SetCompareField(int cmp_field)

Public member function that sets the zero-based compare field used by the comparison operators.

gxDatabaseError gxrdDatabaseRecord::SetField(const void *data, __ULWORD__ bytes, __ULWORD__ col_number)

Public member function that copies "bytes" bytes from "data" into field "col_number" and sets the field length to "bytes". The field buffer grows if needed. A smaller value keeps the buffer but stores the smaller length. The type is not checked, and fixed length CHAR fields are not held to their defined length. Returns gxDBASE_NO_ERROR, gxDBASE_NULL_PTR or gxDBASE_BUFFER_OVERFLOW for a bad column.

__ULWORD__ gxrdDatabaseRecord::SizeOf() const

Public member function that returns the number of bytes needed to write the fields to disk, not counting the record header.

__ULWORD__ gxrdDatabaseRecord::SizeOfBuffer() const

Public member function that returns the number of bytes allocated for the field buffers, which may be larger than SizeOf().

__ULWORD__ gxrdDatabaseRecord::SizeOfField(__ULWORD__ col_number) const

Public member function that returns the on-disk size of one field, including its 5 byte overhead, or zero for a bad column.

const gxString& gxrdDatabaseRecord::TableName() const

Public member function that returns the table name from the record definition.

int gxrdDatabaseRecord::TestRecord(const gxrdDatabaseRecord &ob) const

Public member function that returns true if "ob" has the same record definition string.

void gxrdDatabaseRecord::operator=(const gxrdDatabaseRecord &ob)

Assignment operator. Calls Copy().

friend int operator==(const gxrdDatabaseRecord &a, const gxrdDatabaseRecord &b)

Returns true if Compare() returns 0, using the compare settings of "a".

friend int operator!=(const gxrdDatabaseRecord &a, const gxrdDatabaseRecord &b)

Returns true if Compare() does not return 0, using the compare settings of "a".

friend int operator<(const gxrdDatabaseRecord &a, const gxrdDatabaseRecord &b)

Returns true if Compare() returns a value less than 0, using the compare settings of "a".

friend int operator>(const gxrdDatabaseRecord &a, const gxrdDatabaseRecord &b)

Returns true if Compare() returns a value greater than 0, using the compare settings of "a".

gxrdDatabaseRecord::gxrdDatabaseRecord(__ULWORD__ cmp_field = (__ULWORD__)-1, int case_cmp = 1, int alpha_cmp = 0)

Default class constructor. Creates an empty record with the given compare settings. Call CreateRecord() before using it.

gxrdDatabaseRecord::gxrdDatabaseRecord(const gxString &def, __ULWORD__ cmp_field = (__ULWORD__)-1, int case_cmp = 1, int alpha_cmp = 0)

Class constructor that builds the record from record definition "def". Errors are not reported, so use it only with a known good definition, such as gxRDBMS::RecordDef().

gxrdDatabaseRecord::gxrdDatabaseRecord(const gxrdDatabaseRecord &ob)

Copy constructor. Calls Copy().

gxrdDatabaseRecord::~gxrdDatabaseRecord()

Class destructor. Frees the field buffer array.

gxrdDatabaseTable Functions

The database table holds the parsed form of a table definition: the table name, the record definition, the original table definition string and the persistent table header.

gxrdDatabaseTable::Clear()
gxrdDatabaseTable::Copy()
gxrdDatabaseTable::CreateTable()
gxrdDatabaseTable::SizeOf()
gxrdDatabaseTable::operator=()
gxrdDatabaseTable::gxrdDatabaseTable()
gxrdDatabaseTable::~gxrdDatabaseTable()

void gxrdDatabaseTable::Clear()

Public member function that clears the strings and the table header.

void gxrdDatabaseTable::Copy(const gxrdDatabaseTable &ob)

Public member function that copies "ob", including the table header and its application space.

gxDatabaseError gxrdDatabaseTable::CreateTable(const gxString &tdef)

Public member function that parses a table definition. It sets the table name, builds the record definition and fills in the table header. The table definition string is stored only after every field has been parsed. Returns gxDBASE_NO_ERROR if successful, gxDBASE_BAD_TABLE_DEF if the string has fewer than two words or no name, gxDBASE_ILLEGAL_CHAR if the name has a character that is not allowed in a file name, gxDBASE_BAD_COL_LENGTH if a field has no "{}", or gxDBASE_BAD_FIELD_TYPE. On error the name, record definition and header may already have been changed.

__ULWORD__ gxrdDatabaseTable::SizeOf()

Public member function that returns the lengths of the three strings plus the table header size.

void gxrdDatabaseTable::operator=(const gxrdDatabaseTable &ob)

Assignment operator. Calls Copy().

gxrdDatabaseTable::gxrdDatabaseTable()

Default class constructor. Creates an empty table.

gxrdDatabaseTable::gxrdDatabaseTable(const gxrdDatabaseTable &ob)

Copy constructor. Calls Copy().

gxrdDatabaseTable::~gxrdDatabaseTable()

Class destructor. Does nothing itself; the members free their own memory.

gxrdDatabaseKey_t Functions

The persistent key data stored in each B-tree entry.

gxrdDatabaseKey_t::Clear()
gxrdDatabaseKey_t::Copy()
gxrdDatabaseKey_t::SizeOf()
gxrdDatabaseKey_t::operator=()
gxrdDatabaseKey_t::gxrdDatabaseKey_t()
gxrdDatabaseKey_t::~gxrdDatabaseKey_t()

void gxrdDatabaseKey_t::Clear()

Public member function that sets the key, table ID and key ID to zero.

void gxrdDatabaseKey_t::Copy(const gxrdDatabaseKey_t &ob)

Public member function that copies the three members from "ob".

__ULWORD__ gxrdDatabaseKey_t::SizeOf()

Public member function that returns the sum of the sizes of the three members.

gxrdDatabaseKey_t& gxrdDatabaseKey_t::operator=(const gxrdDatabaseKey_t &ob)

Assignment operator. Calls Copy() and returns this object.

gxrdDatabaseKey_t::gxrdDatabaseKey_t()

Default class constructor. Clears the key.

gxrdDatabaseKey_t::gxrdDatabaseKey_t(const gxrdDatabaseKey_t &ob)

Copy constructor.

gxrdDatabaseKey_t::~gxrdDatabaseKey_t()

Class destructor. Does nothing.

gxrdDatabaseKey Functions

The key class used by every gxRDBMS B-tree. It is derived from DatabaseKeyB and wraps a gxrdDatabaseKey_t. When duplicates are not allowed, keys are compared by the key CRC only. When duplicates are allowed, the key ID (block address) is also compared.

gxrdDatabaseKey::AllowDuplicates()
gxrdDatabaseKey::Clear()
gxrdDatabaseKey::CompareKey()
gxrdDatabaseKey::Copy()
gxrdDatabaseKey::DisallowDuplicates()
gxrdDatabaseKey::Key()
gxrdDatabaseKey::KeyID()
gxrdDatabaseKey::KeySize()
gxrdDatabaseKey::SetKey()
gxrdDatabaseKey::SetKeyID()
gxrdDatabaseKey::SetTableID()
gxrdDatabaseKey::SizeOf()
gxrdDatabaseKey::TableID()
gxrdDatabaseKey::operator=()
gxrdDatabaseKey::operator==()
gxrdDatabaseKey::operator>()
gxrdDatabaseKey::gxrdDatabaseKey()

void gxrdDatabaseKey::AllowDuplicates()

Public member function that allows duplicate keys.

void gxrdDatabaseKey::Clear()

Public member function that clears the key data.

int gxrdDatabaseKey::CompareKey(const DatabaseKeyB& k) const

Public member function that returns -1, 0 or 1 when this key is less than, equal to or greater than "k". With duplicates allowed, equal key CRCs are ordered by key ID. Only used when the __USE_SINGLE_COMPARE__ directive is defined.

void gxrdDatabaseKey::Copy(const gxrdDatabaseKey &ob)

Public member function that copies the key data and the duplicate setting from "ob".

void gxrdDatabaseKey::DisallowDuplicates()

Public member function that does not allow duplicate keys.

gxrdKeyType &gxrdDatabaseKey::Key()

Public member function that returns a reference to the key CRC.

gxrdKeyID gxrdDatabaseKey::KeyID() const

Public member function that returns the key ID, which is the record's data file block address.

size_t gxrdDatabaseKey::KeySize()

Public member function that returns the size of the persistent key data.

void gxrdDatabaseKey::SetKey(const gxrdKeyType_t &k)

Public member function that sets the key CRC.

void gxrdDatabaseKey::SetKey(gxrdKeyType_t &k)

Public member function that sets the key CRC.

void gxrdDatabaseKey::SetKeyID(gxrdKeyID_t kid)

Public member function that sets the key ID.

void gxrdDatabaseKey::SetTableID(gxrdTableID_t tid)

Public member function that sets the table ID.

__ULWORD__ gxrdDatabaseKey::SizeOf()

Public member function that returns the size of the key data members.

gxrdTableID gxrdDatabaseKey::TableID() const

Public member function that returns the table ID.

gxrdDatabaseKey& gxrdDatabaseKey::operator=(const gxrdDatabaseKey &ob)

Assignment operator. Calls Copy() and returns this object.

int gxrdDatabaseKey::operator==(const DatabaseKeyB& k) const

Returns true if the key CRCs are equal. With duplicates allowed, the key IDs must also be equal.

int gxrdDatabaseKey::operator>(const DatabaseKeyB& k) const

Returns true if this key CRC is greater than the key CRC of "k". With duplicates allowed, keys with the same CRC are ordered by key ID, the same order CompareKey() uses. NOTE: 10/14/2026: Fixed: with duplicates allowed it returned true only if both the key CRC and the key ID were greater, which did not give the B-tree a consistent order.

gxrdDatabaseKey::gxrdDatabaseKey(int dup_names = 0)

Default class constructor. Sets the key ID and table ID to zero and sets the duplicate setting. The key CRC is not set.

gxrdDatabaseKey::gxrdDatabaseKey(gxrdKeyType_t &k, gxrdKeyID_t kid = (gxrdKeyID_t)0, gxrdTableID_t tid = (gxrdTableID_t)0, int dup_names = 0)

Class constructor that sets the key CRC, key ID, table ID and duplicate setting.

Standalone Functions

gxrdDefaultPIDName()
gxrdFieldTypeString()
gxrdHasPIDFile()
gxrdRemovePID()
gxrdWritePID()

void gxrdDefaultPIDName(gxString &fname)

Standalone function that sets "fname" to the default process ID file name, "gxRDBMS.pid".

const char *gxrdFieldTypeString(gxrdFIELD_TYPES t)

Standalone function that returns the type name for "t", such as "CHAR" or "INT32". A value past the last type returns "Invalid type". The returned string is static and must not be freed.

int gxrdHasPIDFile(const char *pid_file_name = 0)

Standalone function that returns true if the process ID file exists. The default name is used if "pid_file_name" is null.

int gxrdRemovePID(const char *pid_file_name = 0)

Standalone function that removes the process ID file if it exists. Returns true if the file is gone or false if it could not be removed.

int gxrdWritePID(const char *pid_file_name = 0)

Standalone function that creates the process ID file. Returns true if successful or false if the file could not be created. Note: the file is created empty; no process ID is written to it.

Definition File Functions

These functions are declared in "gxrdbdef.h". They read the definition file format. Each reader opens the file again and returns 1 for success or 0 if the file cannot be opened or read. On error, "error_message" holds messages formatted by gxrdFormatMessage().

gxrdFormatMessage()
gxrdReadDefFile()
gxrdReadFKeyDef()
gxrdReadFormDef()
gxrdReadGroupDef()
gxrdReadKeyDef()
gxrdReadTableDef()
gxrdReadUserDef()

void gxrdFormatMessage(gxString &mesg, const gxString &process_name)

Standalone function that puts the syslog style time and "process_name: " in front of "mesg".

int gxrdReadDefFile(const gxString &fname, const gxString &process_name, const char *TAG, gxString &def, gxString &error_message)

Standalone function that reads the block that starts with "TAG" from file "fname" and passes back its contents in "def". Note: a missing start or end tag only sets "error_message"; the function still returns 1, and "def" is then empty or holds the rest of the file. Check "error_message" as well as the return value. Lines are read with a 255 byte buffer.

int gxrdReadDefFile(const gxString &fname, const gxString &process_name, gxString &table_def, gxString &key_def, gxString &error_message)

Standalone function that reads the table and key definitions. Returns 0 at the first read that fails.

int gxrdReadDefFile(const gxString &fname, const gxString &process_name, gxString &table_def, gxString &key_def, gxString &form_def, gxString &fkey_def, gxString &error_message)

Standalone function that reads the table, key, form and foreign key definitions.

int gxrdReadDefFile(const gxString &fname, const gxString &process_name, gxString &table_def, gxString &key_def, gxString &form_def, gxString &fkey_def, gxString &user_def, gxString &group_def, gxString &error_message)

Standalone function that reads the table, key, form, foreign key, user access and group access definitions.

int gxrdReadFKeyDef(const gxString &fname, const gxString &process_name, gxString &fkey_def, gxString &error_message)

Standalone function that reads the "DEFINE FKEYS" block.

int gxrdReadFormDef(const gxString &fname, const gxString &process_name, gxString &form_def, gxString &error_message)

Standalone function that reads the "DEFINE FORM" block.

int gxrdReadGroupDef(const gxString &fname, const gxString &process_name, gxString &group_def, gxString &error_message)

Standalone function that reads the "DEFINE GROUP ACCESS" block.

int gxrdReadKeyDef(const gxString &fname, const gxString &process_name, gxString &key_def, gxString &error_message)

Standalone function that reads the "DEFINE KEYS" block.

int gxrdReadTableDef(const gxString &fname, const gxString &process_name, gxString &table_def, gxString &error_message)

Standalone function that reads the "DEFINE TABLE" block.

int gxrdReadUserDef(const gxString &fname, const gxString &process_name, gxString &user_def, gxString &error_message)

Standalone function that reads the "DEFINE USER ACCESS" block.

SQL Functions

The "gxrdbsql.h" header and "gxrdbsql.cpp" source are reserved as the future home of SQL functions for the relational database manager. They include "gxrdbhdr.h" and "gxrdbms.h" but declare and define nothing.