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
    atDate,         // Date only
    atTime,         // Time only
    atEnum,         // Enumeration value
    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
  );

Categories:

CategoryTypesDescription
SimpleInteger, Float, Currency, Boolean, String, DateTime, Date, Time, 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, 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/timestamp field
    dtDate,        // Date field
    dtTime,        // Time field
    dtBlob,        // Binary blob field
    dtEnum         // Enumeration (stored as integer or string)
  );

  TInstantDataTypes = set of TInstantDataType;

Typical Mappings (database-dependent):

TInstantDataTypeSQL ServerPostgreSQLFirebirdMySQL
dtIntegerINTINTEGERINTEGERINT
dtFloatFLOATDOUBLE PRECISIONDOUBLE PRECISIONDOUBLE
dtCurrencyDECIMAL(18,4)DECIMAL(18,4)DECIMAL(18,4)DECIMAL(18,4)
dtBooleanBITBOOLEANSMALLINTTINYINT
dtStringVARCHAR(n)VARCHAR(n)VARCHAR(n)VARCHAR(n)
dtMemoTEXTTEXTBLOB SUB_TYPE TEXTTEXT
dtDateTimeDATETIMETIMESTAMPTIMESTAMPDATETIME
dtDateDATEDATEDATEDATE
dtTimeTIMETIMETIMETIME
dtBlobVARBINARY(MAX)BYTEABLOBBLOB

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.