InstantTypes
Unit: InstantTypesCategory: Core
Overview
The InstantTypes unit defines all fundamental types, enumerations, and constants used throughout InstantObjects. These definitions provide type safety, consistency, and cross-platform compatibility across the framework.
Key Contents:
- Attribute Types - Types of object attributes (String, Integer, Reference, etc.)
- Data Types - Database field types
- Storage Kinds - How attributes are stored (Embedded, External, Virtual)
- Operation Types - CRUD operation identifiers
- Conflict Actions - Concurrency resolution strategies
- Load Modes - Query result loading strategies
- SQL Engines - Supported database engines
- Platform Types - 64-bit compatibility types
Type Definitions
Platform-Specific Types
{$IF DEFINED(WINLINUX64) OR DEFINED(USE_LARGEINT_FIELD_FOR_REF)}
IORefFieldType = ftLargeInt;
{$ELSE}
IORefFieldType = ftInteger;
{$IFEND}Platform-specific field type for object references. Uses ftLargeInt on 64-bit platforms for extended range.
TListSize = NativeInt; // Delphi 11+
TListSize = Integer; // Earlier versionsList index and count type, sized appropriately for platform.
TIORefValueType = {$IFDEF WINLINUX64}NativeInt{$ELSE}Integer{$ENDIF};Reference value type, matches platform pointer size.
Enumerations
TInstantAttributeType
Defines the type of an attribute in a business object.
type
TInstantAttributeType = (
atUnknown, // Not set or undefined
atInteger, // Integer value
atFloat, // Floating point value
atCurrency, // Currency value (fixed decimal)
atBoolean, // Boolean value
atString, // String value
atDateTime, // Date and time combined
atBlob, // Binary large object
atMemo, // Text memo (large text)
atGraphic, // Image or graphic
atPart, // Single owned object (composition)
atReference, // Single referenced object (association)
atParts, // Collection of owned objects
atReferences, // Collection of referenced objects
atDate, // Date only
atTime, // Time only
atEnum, // Enumeration value
atTimeStamp // Date and time with the highest precision of the database (4.4.0)
);New in 4.4.0: TimeStamp
atTimeStamp (class TInstantTimeStamp, data type dtTimeStamp) stores date and time with the highest precision supported by the database. In the IOMETADATA it is declared as Name: TimeStamp; and its property is a TDateTime. On the Delphi side the precision is the millisecond (TDateTime); the column type keeps the values written with a higher precision by the database itself.
Categories:
| Category | Types | Description |
|---|---|---|
| Simple | Integer, Float, Currency, Boolean, String, DateTime, Date, Time, TimeStamp, Enum | Value types |
| Complex | Blob, Memo, Graphic | Large object types |
| Container | Part, Parts, Reference, References | Relational types |
Usage:
var
Attr: TInstantAttributeMetadata;
begin
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Email';
Attr.AttributeType := atString; // Simple value type
Attr.Size := 100;
end;
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Category';
Attr.AttributeType := atReference; // Association
Attr.ObjectClassName := 'TCategory';
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Phones';
Attr.AttributeType := atParts; // Composition collection
Attr.ObjectClassName := 'TPhone';TInstantAttributeCategory
Categorizes attribute types into broad groups.
type
TInstantAttributeCategory = (
acUnknown, // Not categorized
acSimple, // Simple value types
acElement, // Complex types (Blob, Memo, Graphic)
acContainer // Relational types (Part, Parts, Reference, References)
);Mapping:
function GetAttributeCategory(AttrType: TInstantAttributeType): TInstantAttributeCategory;
begin
case AttrType of
atInteger, atFloat, atCurrency, atBoolean, atString,
atDateTime, atDate, atTime, atTimeStamp, atEnum:
Result := acSimple;
atBlob, atMemo, atGraphic:
Result := acElement;
atPart, atParts, atReference, atReferences:
Result := acContainer;
else
Result := acUnknown;
end;
end;TInstantDataType
Defines database field data types.
type
TInstantDataType = (
dtInteger, // Integer field
dtFloat, // Floating point field
dtCurrency, // Currency/decimal field
dtBoolean, // Boolean/bit field
dtString, // String/varchar field
dtMemo, // Memo/text field
dtDateTime, // DateTime field (milliseconds precision where available)
dtBlob, // Binary blob field
dtDate, // Date field
dtTime, // Time field
dtEnum, // Enumeration (stored as integer)
dtTimeStamp // Date and time with the highest precision of the database (4.4.0)
);
TInstantDataTypes = set of TInstantDataType;Mappings of the FireDAC broker (database-dependent):
| TInstantDataType | SQL Server | PostgreSQL | Firebird/InterBase | MySQL | Oracle | SQLite |
|---|---|---|---|---|---|---|
| dtInteger | INTEGER | INTEGER | INTEGER | INTEGER | NUMBER(10,0) | INTEGER |
| dtFloat | FLOAT | FLOAT8 | DOUBLE PRECISION | FLOAT | NUMBER(28,15) | FLOAT |
| dtCurrency | MONEY | DECIMAL(18,4) | DECIMAL(18,4) | DECIMAL(18,4) | NUMBER(18,4) | NUMERIC(18,4) |
| dtBoolean | BIT | BOOLEAN | SMALLINT | TINYINT(1) | NUMBER(1,0) | BOOLEAN |
| dtString | VARCHAR(n) | VARCHAR(n) | VARCHAR(n) | VARCHAR(n) | VARCHAR2(n) | VARCHAR(n) |
| dtMemo | TEXT | TEXT | BLOB SUB_TYPE 1 | TEXT | CLOB | TEXT |
| dtDateTime | DATETIME2(3) | TIMESTAMP | TIMESTAMP | DATETIME | DATE | TIMESTAMP |
| dtDate | DATETIME | TIMESTAMP | TIMESTAMP | DATE | DATE | TIMESTAMP |
| dtTime | DATETIME | TIMESTAMP | TIMESTAMP | TIME | DATE | TIMESTAMP |
| dtTimeStamp | DATETIME2(7) | TIMESTAMP(6) | TIMESTAMP | DATETIME(6) | TIMESTAMP(6) | TIMESTAMP |
| dtBlob | IMAGE | BYTEA | BLOB | BLOB | BLOB | BLOB |
| dtEnum | INTEGER | INTEGER | INTEGER | INTEGER | NUMBER(10,0) | INTEGER |
DATETIME2 only with FireDAC
DATETIME2(3) and DATETIME2(7) are used only by the FireDAC broker. The ADO and DBX brokers for MS SQL Server keep DATETIME for both DateTime and TimeStamp attributes, because legacy OLE DB providers (SQLOLEDB) read DATETIME2 columns as strings. The IBX broker uses TIMESTAMP for both.
Usage:
var
Field: TInstantFieldMetadata;
begin
Field := Table.FieldMetadatas.Add;
Field.Name := 'Name';
Field.DataType := dtString;
Field.Size := 100;
Field := Table.FieldMetadatas.Add;
Field.Name := 'BirthDate';
Field.DataType := dtDate; // No size needed
Field := Table.FieldMetadatas.Add;
Field.Name := 'Balance';
Field.DataType := dtCurrency; // Fixed decimal
end;TInstantStorageKind
Defines how an attribute is stored.
type
TInstantStorageKind = (
skEmbedded, // Stored in class table (default)
skExternal, // Stored in separate table
skVirtual, // Not stored (transient/calculated)
skForeignKeys // Stored using foreign keys (advanced)
);Details:
| Kind | Description | Use For | Example |
|---|---|---|---|
| skEmbedded | Field(s) in class table | Simple attributes, single references | Name, Email, CategoryId |
| skExternal | Separate link table | Parts/References collections | Contact.Phones → ContactPhones table |
| skVirtual | Not persisted | Calculated properties | FullName (FirstName + LastName) |
| skForeignKeys | Foreign key fields | Custom reference storage | Advanced scenarios |
Example:
// Embedded reference (default)
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Category';
Attr.AttributeType := atReference;
Attr.StorageKind := skEmbedded; // CategoryClass, CategoryId in Contact table
// External collection
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Phones';
Attr.AttributeType := atParts;
Attr.StorageKind := skExternal; // Separate ContactPhones table
Attr.ExternalStorageName := 'ContactPhones';
// Virtual attribute
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'FullName';
Attr.AttributeType := atString;
Attr.StorageKind := skVirtual; // Not stored, calculated at runtimeTInstantPersistence
Defines class persistence mode.
type
TInstantPersistence = (
peEmbedded, // Stored as blob in parent object
peStored // Stored in its own table (default)
);Details:
| Mode | Description | Use For | Storage |
|---|---|---|---|
| peStored | Normal persistence | Regular business classes | Separate table |
| peEmbedded | Embedded in parent | Small nested objects | Blob in parent |
Example:
// Normal class
ClassMeta := Model.ClassMetadatas.Add;
ClassMeta.Name := 'TContact';
ClassMeta.Persistence := peStored; // Own table: CONTACTS
ClassMeta.StorageName := 'CONTACTS';
// Embedded class
ClassMeta := Model.ClassMetadatas.Add;
ClassMeta.Name := 'TAddress';
ClassMeta.Persistence := peEmbedded; // No separate table
// Stored as blob in parent objectsTInstantFieldOptions
Field-level options for database schema.
type
TInstantFieldOption = (
foRequired, // NOT NULL constraint
foIndexed, // Create index on field
foUnique, // Unique constraint
foPrimaryKey, // Part of primary key
foMultiLanguage // Multi-language support
);
TInstantFieldOptions = set of TInstantFieldOption;Usage:
// Required field
Table.FieldMetadatas.AddFieldMetadata('Name', dtString, 100, [foRequired]);
// Unique index
Table.FieldMetadatas.AddFieldMetadata('Email', dtString, 100, [foRequired, foUnique, foIndexed]);
// Primary key
Table.FieldMetadatas.AddFieldMetadata('Id', dtString, 32, [foRequired, foPrimaryKey]);
// Index only
Table.FieldMetadatas.AddFieldMetadata('CategoryId', dtString, 32, [foIndexed]);TInstantOperationType
Type of persistence operation.
type
TInstantOperationType = (
otNone, // No operation
otCreate, // Creating new object
otStore, // Storing object
otRetrieve, // Retrieving object
otRefresh, // Refreshing object
otDispose // Disposing object
);Used in:
- Error handling events
- Logging and auditing
- Transaction management
- Operation-specific logic
Example:
procedure TMainForm.ConnectorError(Sender: TObject;
OperationType: TInstantOperationType; E: Exception;
var Action: TInstantErrorAction);
begin
case OperationType of
otStore:
begin
LogError('Store failed: ' + E.Message);
Action := eaRetry; // Retry store operations
end;
otRetrieve:
begin
ShowMessage('Object not found: ' + E.Message);
Action := eaIgnore; // Ignore retrieve errors
end;
else
Action := eaError; // Fail on other errors
end;
end;TInstantErrorAction
Action to take on persistence error.
type
TInstantErrorAction = (
eaRetry, // Retry the operation
eaIgnore, // Ignore the error and continue
eaError, // Raise exception (default)
eaRevert, // Revert changes
eaCancel // Cancel operation
);Used in: TInstantConnector.OnError event
TInstantConflictAction
Action on concurrency conflict.
type
TInstantConflictAction = (
caIgnore, // Overwrite (no concurrency check)
caFail // Fail on conflict (default)
);Usage:
// Default: Fail on conflict (optimistic locking)
Contact.Store; // or Contact.Store(caFail);
// Overwrite without checking
Contact.Store(caIgnore); // Dangerous! May overwrite changes
// Refresh on conflict
try
Contact.Store(caFail);
except
on E: EInstantConflict do
begin
Contact.Refresh; // Reload from database
// Re-apply changes or notify user
end;
end;TInstantContentChangeType
Type of change in a container (Parts/References collection).
type
TInstantContentChangeType = (
ctAdd, // Item added
ctAddRef, // Reference added (without ownership)
ctRemove, // Item removed
ctReplace, // Item replaced
ctClear // Container cleared
);Used in: TInstantObject.OnContentChange event
Example:
procedure TMainForm.ContactContentChange(Sender: TInstantObject;
Container: TInstantContainer; ChangeType: TInstantContentChangeType;
Index: Integer; AObject: TInstantObject);
begin
case ChangeType of
ctAdd:
LogChange('Added ' + AObject.ClassName + ' at ' + IntToStr(Index));
ctRemove:
LogChange('Removed from ' + IntToStr(Index));
ctClear:
LogChange('Cleared ' + Container.Name);
end;
end;TInstantLoadMode
Query result loading strategy for SQL brokers.
type
TInstantLoadMode = (
lmKeysFirst, // Load keys first, materialize on demand (default)
lmPartialBurst, // Load simple attributes first, rest on demand
lmFullBurst // Load everything upfront
);Details:
| Mode | First Query | Materialization | Database Hits | Memory | Use For |
|---|---|---|---|---|---|
| lmKeysFirst | SELECT Id, Class | On access, full object | 1 + N | Low | Large result sets |
| lmPartialBurst | SELECT Id, Class, simple attributes | On access, complex/container | 1 + partial N | Medium | Moderate result sets |
| lmFullBurst | SELECT everything | Immediate, all objects | 1 | High | Small result sets, eager loading |
Performance Comparison:
Query: SELECT * FROM TContact (1000 objects)
lmKeysFirst (default):
Initial: SELECT Class, Id FROM Contacts -- Fast, 1000 rows
Per object access: SELECT * FROM Contacts WHERE Id = ? -- 1000 queries
Total queries: 1 + 1000 = 1001
Memory: Low (only accessed objects loaded)
lmPartialBurst:
Initial: SELECT Class, Id, Name, Email, ... FROM Contacts -- Medium, 1000 rows
Per complex/container: SELECT * FROM ContactPhones WHERE ContactId = ?
Total queries: 1 + (containers accessed)
Memory: Medium (simple data pre-loaded)
lmFullBurst:
Initial: SELECT everything with JOINs -- Slow, large result set
Materialization: Immediate
Total queries: 1
Memory: High (all 1000 objects in memory)Usage:
var
Query: TInstantQuery;
begin
Query := TInstantQuery.Create(nil);
try
Query.Connector := FireDACConnector;
Query.Command := 'SELECT * FROM TContact';
// Default: Keys first (good for large result sets)
Query.RequestedLoadMode := lmKeysFirst;
Query.Open;
// Objects loaded on demand: for I := 0 to Query.ObjectCount - 1...
// Partial burst (good for displaying list with simple properties)
Query.RequestedLoadMode := lmPartialBurst;
Query.Open;
// Simple attributes pre-loaded, fast for grid display
// Full burst (good for small result sets, need everything)
Query.RequestedLoadMode := lmFullBurst;
Query.Open;
// All objects fully loaded immediately
finally
Query.Free;
end;
end;
// Check actual mode (may fall back)
if Query.ActualLoadMode <> Query.RequestedLoadMode then
ShowMessage('Load mode not supported, using: ' +
GetEnumName(TypeInfo(TInstantLoadMode), Ord(Query.ActualLoadMode)));Helper Function:
function IsBurstLoadMode(const ALoadMode: TInstantLoadMode): Boolean; inline;
begin
Result := ALoadMode in [lmPartialBurst, lmFullBurst];
end;TInstantSQLEngine
Identifies database engine for SQL dialect.
type
TInstantSQLEngine = (
seGenericSQL, // Generic SQL (ANSI standard)
seMSSQL, // Microsoft SQL Server
seOracle, // Oracle Database
seFirebird, // Firebird
seInterbase, // InterBase
seMySQL, // MySQL / MariaDB
sePostgres, // PostgreSQL
seSQLLite, // SQLite
seSybase // Sybase
);Used for:
- SQL dialect generation
- NOLOCK hints (SQL Server)
- Function translation
- Date/time formatting
- Reserved word handling
Example:
// Set SQL engine on connector
FireDACConnector.SQLEngine := seMSSQL; // SQL Server
// Get NOLOCK directive
function GetTableNoLockDirective(AEngine: TInstantSQLEngine): string;
begin
if AEngine = seMSSQL then
Result := ' WITH(NOLOCK)' // SQL Server
else
Result := ''; // Other databases
end;
// Usage in query
if FireDACConnector.ReadObjectListWithNoLock then
SQL := 'SELECT * FROM Contacts' + GetTableNoLockDirective(FireDACConnector.SQLEngine);
// SQL Server: "SELECT * FROM Contacts WITH(NOLOCK)"
// Others: "SELECT * FROM Contacts"TInstantGraphicFileFormat
Image file format enumeration.
type
TInstantGraphicFileFormat = (
gffUnknown, // Unknown or unsupported format
gffBmp, // Windows Bitmap
gffTiff, // Tagged Image File Format
gffJpeg, // JPEG
gffPng, // Portable Network Graphics
gffDcx, // Multi-page PCX
gffPcx, // PC Paintbrush
gffEmf, // Enhanced Metafile
gffGif, // Graphics Interchange Format
gffIco // Windows Icon
);Used in: TInstantGraphic attribute for image format detection and conversion.
TInstantCatalogFeature
Catalog capabilities for reading database metadata.
type
TInstantCatalogFeature = (
cfReadTableInfo, // Can read table names
cfReadColumnInfo, // Can read column definitions
cfReadIndexInfo // Can read index definitions
);
TInstantCatalogFeatures = set of TInstantCatalogFeature;Example:
var
Catalog: TInstantCatalog;
Features: TInstantCatalogFeatures;
begin
Catalog := FireDACConnector.Broker.CreateCatalog(Scheme);
Features := Catalog.Features;
if cfReadTableInfo in Features then
ShowMessage('Can read table names');
if cfReadColumnInfo in Features then
ShowMessage('Can read column definitions');
if cfReadIndexInfo in Features then
ShowMessage('Can read index definitions');
// Typical SQL broker: all features supported
// File-based broker (XML/JSON): features limited or none
end;TInstantDBBuildCommandType
Type of database build command.
type
TInstantDBBuildCommandType = (
ctAddTable, // CREATE TABLE
ctDropTable, // DROP TABLE
ctAddField, // ALTER TABLE ADD COLUMN
ctAlterField, // ALTER TABLE ALTER COLUMN
ctDropField, // ALTER TABLE DROP COLUMN
ctAddIndex, // CREATE INDEX
ctAlterIndex, // DROP INDEX + CREATE INDEX
ctDropIndex // DROP INDEX
);Used in: TInstantDBBuilder and TInstantDBEvolution for schema operations.
TInstantObjectNotification
Object lifecycle notification.
type
TInstantObjectNotification = (
onChanged, // Object modified
onCreated, // Object created
onDisposed, // Object disposed
onRefreshed, // Object refreshed from database
onRetrieved, // Object retrieved from database
onStored // Object stored to database
);Used in: Object notification events and observer pattern.
Example:
procedure TMainForm.ObjectNotification(Sender: TInstantObject;
Notification: TInstantObjectNotification);
begin
case Notification of
onCreated:
LogEvent('Created: ' + Sender.Id);
onStored:
LogEvent('Stored: ' + Sender.Id);
onDisposed:
LogEvent('Disposed: ' + Sender.Id);
onChanged:
UpdateUI(Sender);
end;
end;TInstantVerificationResult
Result of user verification/confirmation.
type
TInstantVerificationResult = (
vrOk, // Continue
vrCancel, // Cancel current operation
vrAbort, // Abort entire process
vrError // Error occurred
);Used in: Interactive database build/evolution for user confirmation.
TInstantCacheNodeColor
AVL tree node color (internal).
type
TInstantCacheNodeColor = (
ncRed, // Red node
ncBlack // Black node
);Used in: Internal object cache balanced tree implementation.
Event Types
TInstantWarningEvent
Non-fatal warning during operations.
type
TInstantWarningEvent = procedure(const Sender: TObject;
const AWarningText: string) of object;Used in:
TInstantScheme.OnWarningTInstantCatalog.OnWarning- Database build/evolution warnings
Example:
procedure TMainForm.SchemeWarning(const Sender: TObject;
const AWarningText: string);
begin
Memo1.Lines.Add('WARNING: ' + AWarningText);
end;
Scheme.OnWarning := SchemeWarning;Type Aliases
TInstantBytes
Byte array type.
type
TInstantBytes = TBytes;Standard dynamic byte array, used for binary data.
Helper Functions
IsBurstLoadMode
Checks if load mode is a burst mode.
function IsBurstLoadMode(const ALoadMode: TInstantLoadMode): Boolean; inline;
begin
Result := ALoadMode in [lmPartialBurst, lmFullBurst];
end;Usage:
if IsBurstLoadMode(Query.ActualLoadMode) then
ShowMessage('Using burst mode - data pre-loaded');GetTableNoLockDirective
Gets NOLOCK SQL hint for engine.
function GetTableNoLockDirective(AEngine: TInstantSQLEngine): string;
begin
if AEngine = seMSSQL then
Result := ' WITH(NOLOCK)'
else
Result := '';
end;Usage:
var
SQL: string;
begin
SQL := 'SELECT * FROM Contacts' +
GetTableNoLockDirective(Connector.SQLEngine);
// SQL Server: "SELECT * FROM Contacts WITH(NOLOCK)"
// Other DBs: "SELECT * FROM Contacts"
end;Common Usage Patterns
Type-Safe Attribute Definition
procedure DefineContactClass(Model: TInstantModel);
var
ClassMeta: TInstantClassMetadata;
Attr: TInstantAttributeMetadata;
begin
ClassMeta := Model.ClassMetadatas.Add;
ClassMeta.Name := 'TContact';
ClassMeta.Persistence := peStored;
ClassMeta.StorageName := 'CONTACTS';
// Simple attribute
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Name';
Attr.AttributeType := atString;
Attr.Size := 100;
Attr.StorageKind := skEmbedded;
// Date attribute
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'BirthDate';
Attr.AttributeType := atDate;
Attr.StorageKind := skEmbedded;
// Reference attribute
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Category';
Attr.AttributeType := atReference;
Attr.ObjectClassName := 'TCategory';
Attr.StorageKind := skEmbedded;
// Collection attribute
Attr := ClassMeta.AttributeMetadatas.Add;
Attr.Name := 'Phones';
Attr.AttributeType := atParts;
Attr.ObjectClassName := 'TPhone';
Attr.StorageKind := skExternal;
Attr.ExternalStorageName := 'ContactPhones';
end;Load Mode Selection
function SelectLoadMode(ObjectCount: Integer): TInstantLoadMode;
begin
if ObjectCount <= 100 then
Result := lmFullBurst // Small: load everything
else if ObjectCount <= 1000 then
Result := lmPartialBurst // Medium: load simple attributes
else
Result := lmKeysFirst; // Large: load keys only
end;
// Usage
Query.RequestedLoadMode := SelectLoadMode(EstimatedCount);Engine-Specific SQL
function BuildQueryForEngine(AEngine: TInstantSQLEngine): string;
begin
Result := 'SELECT * FROM Contacts';
// Add engine-specific hints
case AEngine of
seMSSQL:
Result := Result + ' WITH(NOLOCK)';
seOracle:
Result := Result + ' /*+ FIRST_ROWS */';
// Add other engine-specific optimizations
end;
end;Best Practices
Use Appropriate Data Types
dtStringfor varchardtMemofor large textdtCurrencyfor money (not dtFloat)dtDateordtTimewhen you don't need both
Choose Storage Kind Wisely
skEmbeddedfor simple attributes and single referencesskExternalfor Parts/References collectionsskVirtualfor calculated properties
Load Mode Selection
lmKeysFirstfor large result sets (default)lmPartialBurstfor grids showing simple datalmFullBurstfor small sets needing all data
Error Handling
- Use
TInstantErrorActionappropriately - Don't use
eaIgnorefor critical operations - Log errors with
TInstantOperationTypefor context
- Use
Concurrency
- Use
caFail(default) for optimistic locking - Only use
caIgnorewhen you're sure - Handle
EInstantConflictexceptions
- Use
SQL Engine
- Set correctly for optimal SQL generation
- Use engine-specific features when beneficial
- Test with target database
See Also
- InstantPersistence - Core persistence classes
- InstantMetadata - Metadata system using these types
- InstantBrokers - Broker implementation
- InstantCommand - Query command types
- 64-bit Platform Support - Platform-specific types
Version History
- Version 3.0 - Initial type system
- Version 3.5 - Added load modes
- Version 4.0 - Enhanced SQL engine support
- Version 4.2 - 64-bit types (IORefFieldType, TIORefValueType)
- Version 4.3 - Additional enum support
