Skip to content

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 ​

pascal
{$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.

pascal
TListSize = NativeInt;  // Delphi 11+
TListSize = Integer;    // Earlier versions

List index and count type, sized appropriately for platform.

pascal
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.

pascal
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:

CategoryTypesDescription
SimpleInteger, Float, Currency, Boolean, String, DateTime, Date, Time, TimeStamp, EnumValue types
ComplexBlob, Memo, GraphicLarge object types
ContainerPart, Parts, Reference, ReferencesRelational types

Usage:

pascal
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.

pascal
type
  TInstantAttributeCategory = (
    acUnknown,     // Not categorized
    acSimple,      // Simple value types
    acElement,     // Complex types (Blob, Memo, Graphic)
    acContainer    // Relational types (Part, Parts, Reference, References)
  );

Mapping:

pascal
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.

pascal
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):

TInstantDataTypeSQL ServerPostgreSQLFirebird/InterBaseMySQLOracleSQLite
dtIntegerINTEGERINTEGERINTEGERINTEGERNUMBER(10,0)INTEGER
dtFloatFLOATFLOAT8DOUBLE PRECISIONFLOATNUMBER(28,15)FLOAT
dtCurrencyMONEYDECIMAL(18,4)DECIMAL(18,4)DECIMAL(18,4)NUMBER(18,4)NUMERIC(18,4)
dtBooleanBITBOOLEANSMALLINTTINYINT(1)NUMBER(1,0)BOOLEAN
dtStringVARCHAR(n)VARCHAR(n)VARCHAR(n)VARCHAR(n)VARCHAR2(n)VARCHAR(n)
dtMemoTEXTTEXTBLOB SUB_TYPE 1TEXTCLOBTEXT
dtDateTimeDATETIME2(3)TIMESTAMPTIMESTAMPDATETIMEDATETIMESTAMP
dtDateDATETIMETIMESTAMPTIMESTAMPDATEDATETIMESTAMP
dtTimeDATETIMETIMESTAMPTIMESTAMPTIMEDATETIMESTAMP
dtTimeStampDATETIME2(7)TIMESTAMP(6)TIMESTAMPDATETIME(6)TIMESTAMP(6)TIMESTAMP
dtBlobIMAGEBYTEABLOBBLOBBLOBBLOB
dtEnumINTEGERINTEGERINTEGERINTEGERNUMBER(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:

pascal
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.

pascal
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:

KindDescriptionUse ForExample
skEmbeddedField(s) in class tableSimple attributes, single referencesName, Email, CategoryId
skExternalSeparate link tableParts/References collectionsContact.Phones → ContactPhones table
skVirtualNot persistedCalculated propertiesFullName (FirstName + LastName)
skForeignKeysForeign key fieldsCustom reference storageAdvanced scenarios

Example:

pascal
// 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 runtime

TInstantPersistence ​

Defines class persistence mode.

pascal
type
  TInstantPersistence = (
    peEmbedded,    // Stored as blob in parent object
    peStored       // Stored in its own table (default)
  );

Details:

ModeDescriptionUse ForStorage
peStoredNormal persistenceRegular business classesSeparate table
peEmbeddedEmbedded in parentSmall nested objectsBlob in parent

Example:

pascal
// 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 objects

TInstantFieldOptions ​

Field-level options for database schema.

pascal
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:

pascal
// 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.

pascal
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:

pascal
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.

pascal
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.

pascal
type
  TInstantConflictAction = (
    caIgnore,      // Overwrite (no concurrency check)
    caFail         // Fail on conflict (default)
  );

Usage:

pascal
// 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).

pascal
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:

pascal
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.

pascal
type
  TInstantLoadMode = (
    lmKeysFirst,      // Load keys first, materialize on demand (default)
    lmPartialBurst,   // Load simple attributes first, rest on demand
    lmFullBurst       // Load everything upfront
  );

Details:

ModeFirst QueryMaterializationDatabase HitsMemoryUse For
lmKeysFirstSELECT Id, ClassOn access, full object1 + NLowLarge result sets
lmPartialBurstSELECT Id, Class, simple attributesOn access, complex/container1 + partial NMediumModerate result sets
lmFullBurstSELECT everythingImmediate, all objects1HighSmall 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:

pascal
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:

pascal
function IsBurstLoadMode(const ALoadMode: TInstantLoadMode): Boolean; inline;
begin
  Result := ALoadMode in [lmPartialBurst, lmFullBurst];
end;

TInstantSQLEngine ​

Identifies database engine for SQL dialect.

pascal
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:

pascal
// 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.

pascal
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.

pascal
type
  TInstantCatalogFeature = (
    cfReadTableInfo,   // Can read table names
    cfReadColumnInfo,  // Can read column definitions
    cfReadIndexInfo    // Can read index definitions
  );

  TInstantCatalogFeatures = set of TInstantCatalogFeature;

Example:

pascal
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.

pascal
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.

pascal
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:

pascal
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.

pascal
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).

pascal
type
  TInstantCacheNodeColor = (
    ncRed,         // Red node
    ncBlack        // Black node
  );

Used in: Internal object cache balanced tree implementation.

Event Types ​

TInstantWarningEvent ​

Non-fatal warning during operations.

pascal
type
  TInstantWarningEvent = procedure(const Sender: TObject;
    const AWarningText: string) of object;

Used in:

  • TInstantScheme.OnWarning
  • TInstantCatalog.OnWarning
  • Database build/evolution warnings

Example:

pascal
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.

pascal
type
  TInstantBytes = TBytes;

Standard dynamic byte array, used for binary data.

Helper Functions ​

IsBurstLoadMode ​

Checks if load mode is a burst mode.

pascal
function IsBurstLoadMode(const ALoadMode: TInstantLoadMode): Boolean; inline;
begin
  Result := ALoadMode in [lmPartialBurst, lmFullBurst];
end;

Usage:

pascal
if IsBurstLoadMode(Query.ActualLoadMode) then
  ShowMessage('Using burst mode - data pre-loaded');

GetTableNoLockDirective ​

Gets NOLOCK SQL hint for engine.

pascal
function GetTableNoLockDirective(AEngine: TInstantSQLEngine): string;
begin
  if AEngine = seMSSQL then
    Result := ' WITH(NOLOCK)'
  else
    Result := '';
end;

Usage:

pascal
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 ​

pascal
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 ​

pascal
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 ​

pascal
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 ​

  1. Use Appropriate Data Types

    • dtString for varchar
    • dtMemo for large text
    • dtCurrency for money (not dtFloat)
    • dtDate or dtTime when you don't need both
  2. Choose Storage Kind Wisely

    • skEmbedded for simple attributes and single references
    • skExternal for Parts/References collections
    • skVirtual for calculated properties
  3. Load Mode Selection

    • lmKeysFirst for large result sets (default)
    • lmPartialBurst for grids showing simple data
    • lmFullBurst for small sets needing all data
  4. Error Handling

    • Use TInstantErrorAction appropriately
    • Don't use eaIgnore for critical operations
    • Log errors with TInstantOperationType for context
  5. Concurrency

    • Use caFail (default) for optimistic locking
    • Only use caIgnore when you're sure
    • Handle EInstantConflict exceptions
  6. SQL Engine

    • Set correctly for optimal SQL generation
    • Use engine-specific features when beneficial
    • Test with target database

See Also ​

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

Released under Mozilla License, Version 2.0.