(*****************************************************************************)
(* MODULE: BSEENG*                                                           *)
(* RIGHTS: Reggatta Systems - COPYRIGHT 1995 - 2000                          *)
(* DESCR.: This module contains the Database Engine classes.                 *)
(*****************************************************************************)
Unit BseEng;
{$I BSE.INC}
Interface
Uses
  Classes,
  SysUtils,
  Windows,
  BDE,

  BseTypes,
  BseBapi,
  BseColl,
  BseErrs,
  BseSess;

Type
  Time    = Longint;


Type
  TVirtEng =
  Class( TBapiListItem )
    Private
      FSessionClass     : TBaseSessionClass;
      FErrorStack       : TErrorStack;
      FSessions         : TTitanCollection;
      FDateFormat       : FMTDate;
      FTimeFormat       : FMTTime;
      FSession          : hDBISes;
      FCursor           : hDBICur;
      FDatabase         : hDBIDb;
      FStatus           : DBIResult;
      FStartFlags       : LongInt;
      FStatement        : hDBIStmt;


      Function  GetDateFormat : FMTDate;
      Procedure SetDateFormat( D : FMTDate );

      Function  GetTimeFormat : FMTTime;
      Procedure SetTimeFormat( D : FMTTime );

      Function  GetCursor : hDBICur;
      Procedure SetCursor( H : hDBICur );

      Function  GetSession : hDBISes;
      Procedure SetSession( H : hDBISes );

      Function  GetDatabase : hDBIDb;
      Procedure SetDatabase( H : hDBIDb );

      Function  GetStatement : hDBIStmt;
      Procedure SetStatement( H : hDBIStmt );

    Public
      Constructor Create( SessionClass : TBaseSessionClass; P : TObject;
         Container : TTitanCollection; iVer : Word; pEnv : pDBIEnv );
      Destructor  Destroy; Override;

      Property Status : DBIResult
        Read  FStatus;
      Property Session    : hDBISes
        Read  GetSession
        Write SetSession;
      Property Sessions   : TTitanCollection
        Read  FSessions;
      Property Database   : hDBIDb
        Read  GetDatabase
        Write SetDatabase;
      Property Cursor     : hDBICur
        Read  GetCursor
        Write SetCursor;
      Property DateFormat : FMTDate
        Read  GetDateFormat
        Write SetDateFormat;
      Property TimeFormat : FMTTime
        Read  GetTimeFormat
        Write SetTimeFormat;
      Property Statement  : hDBIStmt
        Read  GetStatement
        Write SetStatement;

      Function    CleanupException : DBIResult;

      Function    IsSqlBased( hDb : hDBIDB ) : Boolean;

      Function    StartSession( pszName : PChar; var hSes : hDBISes; pszNetDir : PChar ) : DBIResult;
      Function    CloseSession( hSes : hDBISes ) : DBIResult;
      Function    SetCurrSession( hSes : hDBISes ) : DBIResult;
      Function    GetCurrSession( var hSes : hDBISes ) : DBIResult;

      Function    SetPrivateDir( pszDir : PChar ) : DBIResult;

      Function    GetDatabaseDesc (                         { Get a description of a logical db }
                    pszName       : PChar;                  { Name of logical database }
                    pdbDesc       : pDBDesc                 { Database description }
                  ): DBIResult;

      Function    OpenTableTypesList (                      { Get a list of table types }
                    pszDriverType : PChar;                  { Driver type }
                    var hCur      : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    GetTableTypeDesc (                        { Get Table capabilities }
                    pszDriverType : PChar;                  { Driver type }
                    pszTableType  : PChar;                  { Table type }
                    var tblType   : TBLType                 { Table Capabilities }
                  ): DBIResult;

      Function    OpenFieldTypesList (                      { Get a list of field types }
                    pszDriverType : PChar;                  { Driver type }
                    pszTblType    : PChar;                  { Table type (Optional) }
                    var hCur      : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    GetFieldTypeDesc (                        { Get Table capabilities }
                    pszDriverType : PChar;                  { Driver type }
                    pszTableType  : PChar;                  { Table type }
                    pszFieldType  : PChar;                  { Field type }
                    var fldType   : FLDType                 { Field Capabilities }
                  ): DBIResult;

      Function    OpenIndexTypesList (                      { Get a list of index types }
                    pszDriverType : PChar;                  { Driver type }
                    var hCur      : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    GetIndexTypeDesc (                        { Get Table capabilities }
                    pszDriverType : PChar;                  { Driver type }
                    pszIndexType  : PChar;                  { Index type }
                    var idxType   : idxType                 { Index Capabilities }
                  ): DBIResult;

      Function    OpenLdList (                              { Get a list of Lang Drivers }
                    var hCur : hDBICur                      { Returned cursor }
                  ): DBIResult;

      Procedure   SetSessionfromDB(                         { Determine Session to use }
                    pszDbName     : PChar;                  { Database name }
                    pszDbType     : PChar;                  { Database type (NULL: Universal) }
                    iOptFlds      : Word;                   { Number of optional Params }
                    pOptFldDesc   : pFLDDesc;               { Optional Field Descriptors }
                    pOptParams    : Pointer;                { Optional Params }
                    NewDBName     : PChar;                  { returned DB Name without Tag }
                    Var WasDesc   : Boolean                 { A Session description was found }
                  );

      Function    OpenDatabase (                            { Open a database }
                    pszDbName     : PChar;                  { Database name }
                    pszDbType     : PChar;                  { Database type (NULL: Universal) }
                    eOpenMode     : DBIOpenMode;            { Open type }
                    eShareMode    : DBIShareMode;           { Share type }
                    pszPassword   : PChar;                  { Password }
                    iOptFlds      : Word;                   { Number of optional Params }
                    pOptFldDesc   : pFLDDesc;               { Optional Field Descriptors }
                    pOptParams    : Pointer;                { Optional Params }
                    var   hDb     : hDBIDb                  { Returned database handle }
                  ): DBIResult;

      Function    OpenVchkList (                            { Return "Checks" for a table }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver Type }
                    var hChkCur   : hDBICur                 { Returned cursor on "Checks" }
                  ): DBIResult;

      Function    OpenRintList (                            { Return Integrity checks }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var hChkCur   : hDBICur                 { Returned cursor on "Ref Int". }
                  ): DBIResult;

      Function    OpenSecurityList (                        { Return security descriptions }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var hSecCur   : hDBICur                 { Returned cursor on sec list }
                  ): DBIResult;

      Function    OpenFamilyList (                          { Return family members }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var hFmlCur   : hDBICur                 { Returned cursor on "Family" }
                  ): DBIResult;

      Function    OpenSPList (                              { Open a cursor on "Stored Procedures" }
                    hDb           : hDBIDb;                 { Universal database handle }
                    bExtended     : Bool;                   { True for extended info (N/A) }
                    bSystem       : Bool;                   { True to include system procedures }
                    pszQual       : PChar;                  { Qualifier (N/A) }
                    var hCur      : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    OpenSPParamList (                         { Return "Parameters" for a stored procedure }
                    hDb           : hDBIDb;                 { Database handle }
                    pszSPName     : PChar;                  { Stored procedure name }
                    bPhyTypes     : Bool;                   { True, for physical types }
                    uOverload     : Word;                   { Overload number }
                    var hCur      : hDBICur                 { Returned cursor on "Parameters" }
                  ): DBIResult;

      Function    OpenFunctionList (                        { Open a cursor on "Functions" }
                    hDb           : hDBIDb;                 { Universal database handle }
                    eoptBits      : DBIFUNCOpts;            { Options for function list }
                    phCur         : phDBICur                { Returned cursor on "Functions" }
                                                            { Record desc is of type DBIFUNCDesc }
                  ): DBIResult;

      Function    OpenFunctionArgList (                     { Return "Arguments" for a function }
                    hDb           : hDBIDb;                 { Database handle }
                    pszFuncName   : PChar;                  { Function name }
                    uOverload     : Word;                   { Overload number }
                    phCur         : phDBICur                { Returned cursor on "Arguments" }
                  ): DBIResult;

      Function    CloseDatabase( var hDb : hDBIDb ) : DBIResult;

      Function    GetTableOpenCount (                       {  Get local cursor count }
                    hDb           : hDBIDb;                 { Database }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    var iOpenCount : Word                   { returned number of cursors }
                  ): DBIResult;

      Function    UseIdleTime : DBIResult;                  { Use Idle Processor Time }

      Function    GetLdObj (                                { Get language driver }
                    hCursor       : hDBICur;                { Cursor handle }
                    var   pLdObj  : Pointer                 { Returned language driver object }
                  ): DBIResult;

      Function    GetLdName (                               { Get language driver name from table }
                    pszDriver     : PChar;                  { Driver name }
                    pObjName      : PChar;                  { Name of object, i.e. table name }
                    pLdName       : PChar                   { Returned language driver name }
                  ): DBIResult;
      Function    SchemaCacheFlush(                         { Form Full Name }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar                   { Table name }
                  ): DBIResult;

      Function    FormFullName (                            { Form Full Name }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    pszFullName   : PChar                   { Returns full name }
                  ): DBIResult;

      Function    OpenTable (                               { Open a table }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name or file name }
                    pszDriverType : PChar;                  { Driver type                 /NULL }
                    pszIndexName  : PChar;                  { Index to be used for access /NULL }
                    pszIndexTagName : PChar;                { Index tag name              /NULL }
                    iIndexId      : Word;                   { Index number                /0 }
                    eOpenMode     : DBIOpenMode;            { Read or RW }
                    eShareMode    : DBIShareMode;           { Excl or Share }
                    exltMode      : XLTMode;                { Xlate mode }
                    bUniDirectional : Bool;                 { Uni or Bi directional }
                    pOptParams    : Pointer;                { Optional params /NULL }
                    var hCursor   : hDBICur                 { Returns Cursor handle }
                  ): DBIResult;

      Function    OpenNestedTable(                          { Get nested table }
                    hCursor       : hDBICur;                { Master cursor }
                    iFieldNo      : Word;                   { FieldID of nested table field }
                    bReadOnly     : Bool;                   { if TRUE, read only mode }
                    bUniDirectional: Bool;                  { if TRUE, unidirectional }
                    var hCursorNested : hDBICur             { Returns Cursor handle for nested table }
                  ): DBIResult;

      Function    OpenRef(
                    hCursor       : hDBICur;               { Master cursor }
                    iFieldNo      : Word;                  { FieldID }
                    bReadOnly     : Bool;                  { if TRUE, read only mode }
                    bUniDirectional: Bool;                 { If TRUE, Uni directional }
                    var hRefCursor : hDBICur               { Returns Cursor handle for REF }
                  ): DBIResult;

      Function    DatabaseFlush(
                    hDb           : hDBIDb                 { database handle }
                 ): DBIResult;

      Function    OpenTableList (                           { Open a cursor on "Tables" }
                    hDb           : hDBIDb;                 { Database handle }
                    bExtended     : Bool;                   { True for extended info }
                    bSystem       : Bool;                   { True to include system tables }
                    pszWild       : PChar;                  { Wild card name }
                    var   hCur    : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    OpenFieldList (                           { Return "Fields" for a table }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    bPhyTypes     : Bool;                   { True, for physical types }
                    var   hCur    : hDBICur                 { Returned cursor on "Fields" }
                  ): DBIResult;

      Function    OpenFileList (                            { Open a cursor on "Tables" }
                    hDb           : hDBIDb;                 { Database handle }
                    pszWild       : PChar;                  { Wild card name }
                    var   hCur    : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    GetDriverDesc (                           { Get description for a given type }
                    pszDriverType : PChar;                  { Symbolic name for driver type }
                    var  drvType  : DRVType                 { Driver type description }
                  ): DBIResult;

      Function    OpenDriverList (                          { Get a list of driver names }
                    var   hCur          : hDBICur           { Returned cursor }
                  ): DBIResult;

      Function    OpenDatabaseList (                        { Get a list of database names }
                    var   hCur          : hDBICur           { Returned cursor }
                  ): DBIResult;

      Function    OpenIndexList (                           { Return "Indexes" for a table }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var   hCur    : hDBICur                 { Returned cursor on "Indexes" }
                  ): DBIResult;

      Function    GetCursorForTable (                       { Find cursor for a given table }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var   hCursor : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    CloseCursor( hCursor : hDBICur ) : DBIResult;

      Function    OpenIndex (                               { Open an index }
                    hCursor       : hDBICur;                { Cursor handle }
                    pszIndexName  : PChar;                  { Index Name }
                    iIndexId      : Word              
                  ): DBIResult;

      Function    CloseIndex (                              { Close an index }
                    hCursor       : hDBICur;                { Cursor handle }
                    pszIndexName  : PChar;                  { Index Name }
                    iIndexId      : Word                    { Index number (if applicable) }
                  ): DBIResult;

      Function    CloneCursor(                              { Return a duplicate cursor }
                    hCurSrc         : hDBICur;              { Source cursor }
                    bReadOnly       : Bool;                 { If TRUE, read only mode }
                    bUniDirectional : Bool;                 { If TRUE, Uni directional }
                    var   hCurNew   : hDBICur               { Destination cursor address }
                  ): DBIResult;

      Function    SetToBegin( hCursor : hDBICur ) : DBIResult;
      Function    SetToEnd( hCursor : hDBICur ) : DBIResult;
      Function    SetToCursor( hDest, hSrc : hDBICur ) : DBIResult;
      Function    GetBookMark( hCur : hDBICur; pBookMark : Pointer ) : DBIResult;
      Function    SetToBookMark( hCur : hDBICur; pBookMark : Pointer ) : DBIResult;

      Function    CompareBookMarks ( hCur : hDBICur; pBookMark1, pBookMark2 : Pointer;
                    var CmpBkmkResult : CmpBkmkRslt ): DBIResult;
      Function    GetNextRecord (                           { Find/Get the next record }
                    hCursor       : hDBICur;                { Cursor handle }
                    eLock         : DBILockType;            { Optional lock request }
                    pRecBuff      : Pointer;                { Record buffer(client) }
                    pRecProps     : pRECProps               { Optional record properties }
                  ): DBIResult;

      Function    GetPriorRecord (                          { Find/Get the prior record }
                    hCursor       : hDBICur;                { Cursor handle }
                    eLock         : DBILockType;            { Optional lock request }
                    pRecBuff      : Pointer;                { Record buffer(client) }
                    pRecProps     : pRECProps               { Optional record properties }
                  ): DBIResult;

      Function    GetRecord (                               { Gets the current record }
                    hCursor       : hDBICur;                { Cursor handle }
                    eLock         : DBILockType;            { Optional lock request }
                    pRecBuff      : Pointer;                { Record buffer(client) }
                    pRecProps     : pRECProps               { Optional record properties }
                  ): DBIResult;

      Function    GetRelativeRecord (                       { Find/Get a record by record number }
                    hCursor       : hDBICur;                { Cursor handle }
                    iPosOffset    : Longint;                { offset from current position }
                    eLock         : DBILockType;            { Optional lock request }
                    pRecBuff      : Pointer;                { Record buffer(client) }
                    pRecProps     : pRECProps               { Optional record properties }
                  ): DBIResult;

      Function    GetRecordForKey (                         { Find a record matching key }
                    hCursor       : hDBICur;                { Cursor handle }
                    bDirectKey    : Bool;                   { Key is supplied directly }
                    iFields       : Word;                   { No of full fields to match }
                    iLen          : Word;                   { Partial key len of last field }
                    pKey          : Pointer;                { Either Record buffer or Key itself }
                    pRecBuff      : Pointer                 { (Optional) Record buffer }
                  ): DBIResult;

      Function    GetVchkDesc (                             { Get valcheck descriptor }
                    hCursor       : hDBICur;                { Cursor handle }
                    iValSeqNo     : Word;                   { Valcheck sequence number }
                    pvalDesc      : pVCHKDesc               { Returned valcheck description }
                  ): DBIResult;

      Function    GetRintDesc (                             { Get referential integrity descriptor }
                    hCursor       : hDBICur;                { Cursor handle }
                    iRintSeqNo    : Word;                   { Rint sequence number }
                    printDesc     : pRINTDesc               { Returned rint description }
                  ): DBIResult;

      Function    AcqPersistTableLock (                     { Get a persistent lock }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar                   { Driver type / NULL }
                  ): DBIResult;

      Function    RelPersistTableLock (                     { Releases a persistent lock }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar                   { Driver type / NULL }
                  ): DBIResult;

      Function    AcqTableLock (                            { Lock a table }
                    hCursor       : hDBICur;                { Cursor handle }
                    eLockType     : DBILockType             { Lock type }
                  ): DBIResult;

      Function    RelTableLock (                            { Unlocks Table level locks }
                    hCursor       : hDBICur;                { Cursor handle }
                    bAll          : Bool;                   { True for all table level locks }
                    eLockType     : DBILockType             { Specific lock type }
                  ): DBIResult;

      Function    RelRecordLock (                           { Releases record level locks }
                    hCursor       : hDBICur;                { Cursor handle }
                    bAll          : Bool                    { True for all. Default Current. }
                  ): DBIResult;

      Function    IsRecordLocked (                          { Check if current record is locked }
                    hCursor       : hDBICur;                { Cursor handle }
                    var bLocked   : Bool                    { Rec lock status }
                  ): DBIResult;

      Function    IsTableLocked (                           { Verify if Table is locked }
                    hCursor       : hDBICur;                { Cursor handle }
                    epdxLock      : DBILockType;            { Lock type to verify }
                    var iLocks    : Word                    { Nbr of locks of the given type }
                  ): DBIResult;

      Function    IsTableShared (                           { Verify if this is a shared table }
                    hCursor       : hDBICur;                { Cursor handle }
                    var bShared   : Bool                    { Shared status }
                  ): DBIResult;

      Function    InitRecord ( hCursor : hDBICur; pRecBuff : Pointer ): DBIResult;
      Function    InsertRecord ( hCursor : hDBICur; eLock : DBILockType; pRecBuff : Pointer ): DBIResult;
      Function    AppendRecord ( hCursor : hDBICur; pRecBuff : Pointer ): DBIResult;
      Function    ModifyRecord ( hCursor : hDBICur; pRecBuff : Pointer; bFreeLock : Bool ): DBIResult;
      Function    DeleteRecord ( hCursor : hDBICur; pRecBuff : Pointer ): DBIResult;
      Function    UnDeleteRecord ( hCursor : hDBICur ): DBIResult;
      Function    ReadBlock ( hCursor : hDBICur; var iRecords : Longint; pBuf : Pointer ): DBIResult;
      Function    WriteBlock ( hCursor : hDBICur; var iRecords : Longint; pBuf : Pointer ): DBIResult;

      Function    GetSeqNo (                                { Get logical record number }
                    hCursor       : hDBICur;                { Cursor handle }
                    var iSeqNo    : Longint                 { Pointer to sequence number }
                  ): DBIResult;

      Function    SettoSeqNo (                              { Set logical record number }
                    hCursor       : hDBICur;                { Cursor handle }
                    iSeqNo        : Longint                 { Pointer to sequence number }
                  ): DBIResult;

      Function    GetField (                                { Get Field value }
                    hCursor       : hDBICur;                { Cursor }
                    iField        : Word;                   { Field # (1..n) }
                    pRecBuff      : Pointer;                { Record buffer }
                    pDest         : Pointer;                { Destination field buffer }
                    var bBlank    : Bool                    { Returned : is field blank }
                  ): DBIResult;

      Function    PutField (                                { Put a value in the record buffer }
                    hCursor       : hDBICur;                { Cursor }
                    iField        : Word;                   { Field # (1..n) }
                    pRecBuff      : Pointer;                { Record buffer }
                    pSrc          : Pointer                 { Source field buffer }
                  ): DBIResult;

      Function    VerifyField (                             { Verifies the field value }
                    hCursor       : hDBICur;                { Cursor }
                    iField        : Word;                   { Field # (1..n) }
                    pSrc          : Pointer;                { Field Value }
                    var bBlank    : Bool                    { Field is Blank (Returned) }
                  ): DBIResult;

      Function    OpenBlob (                                { Open a blob for access }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuf       : Pointer;                { Record Buffer }
                    iField        : Word;                   { Field number (1..n) }
                    eOpenMode     : DBIOpenMode             { Open for Read or RW }
                  ): DBIResult;

      Function    GetBlobSize (                             { Get Blob Size }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuf       : Pointer;                { Record Buffer }
                    iField        : Word;                   { Field number (1..n) }
                    var iSize     : Longint                 { returned size }
                  ): DBIResult;

       Function   GetBlob (                                 { Read bytes from blob }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuf       : Pointer;                { Record Buffer }
                    iField        : Word;                   { Field number of blob (1..n) }
                    iOffSet       : Longint;                { Starting position   }
                    iLen          : Longint;                { No of bytes to be read   }
                    pDest         : Pointer;                { Destination }
                    var iRead     : Longint                 { Actual no of bytes read }
                   ): DBIResult;

      Function    PutBlob (                                 { Write bytes to blob }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuf       : Pointer;                { Record Buffer }
                    iField        : Word;                   { Field number of blob (1..n) }
                    iOffSet       : Longint;                { Starting position   }
                    iLen          : Longint;                { No of bytes to put   }
                    pSrc          : Pointer                 { pntr to Source }
                  ): DBIResult;

      Function    TruncateBlob (                            { Reduces the blob size }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuf       : Pointer;                { Record Buffer }
                    iField        : Word;                   { Field number of blob (1..n) }
                    iLen          : Longint                 { New blob length }
                  ): DBIResult;

      Function    FreeBlob (                                { Free the blob }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuf       : Pointer;                { Record Buffer }
                    iField        : Word                    { Field number of blob (1..n) }
                  ): DBIResult;

      Function    GetBlobHeading (                          { Get Blob Heading }
                    hCursor       : hDBICur;                { Cursor handle }
                    iField        : Word;                   { Field number of blob (1..n) }
                    pRecBuf       : Pointer;                { Record buffer of owner record }
                    pDest         : Pointer                 { Destination buffer }
                  ): DBIResult;

      Function    SetFieldMap (                             { Set a fieldmap }
                    hCur          : hDBICur;                { Cursor handle }
                    iFields       : Word;                   { Number of fields }
                    pFldDesc      : pFLDDesc                { Array of field descriptions }
                  ): DBIResult;

      Function    BeginTran (                               { Begin a transaction }
                    hDb           : hDBIDb;                 { Database handle }
                    eXIL          : eXILType;               { Transaction isolation level }
                    var hXact     : hDBIXact                { Returned Xact handle }
                  ): DBIResult;

      Function    EndTran (                                 { End a transaction }
                    hDb           : hDBIDb;                 { Database handle }
                    hXact         : hDBIXact;               { Xact handle }
                    eEnd          : eXEnd                   { Xact end type }
                  ): DBIResult;

      Function    GetTranInfo (                             { Get transaction info }
                    hDb           : hDBIDb;                 { Database handle }
                    hXact         : hDBIXact;               { Xact handle }
                    pxInfo        : pXInfo                  { Xact info }
                  ): DBIResult;

      Procedure   GetProp (                                 { Get property }
                    iProp         : Longint;                { Property to retrieve }
                    PropValue     : Pointer;                { == NULL, validate iProp for getting }
                    iMaxLen       : Word;                   { Length of buffer pPropValue }
                    var   iLen    : Word                    { Returns required length }
                  ); Override;

      Procedure   SetProp (                                 { Get property }
                    iProp         : Longint;                { Property to retrieve }
                    PropValue     : Longint                 { == NULL, validate iProp for getting }
                  ); Override;

      Function    GetEngProp (                              { Get property }
                    hObj          : hDBIObj;                { Object handle }
                    iProp         : Longint;                { Property to retrieve }
                    PropValue     : Pointer;                { == NULL, validate iProp for getting }
                    iMaxLen       : Word;                   { Length of buffer pPropValue }
                    var   iLen    : Word                    { Returns required length }
                  ): DBIResult;

      Function    SetEngProp (                              { Get property }
                    hObj          : hDBIObj;
                    iProp         : Longint;                { Property to retrieve }
                    PropValue     : Longint                 { == NULL, validate iProp for getting }
                  ): DBIResult;

      Function    ValidateEngProp (                         { Validate a property }
                    hObj          : hDBIObj;                { Object handle }
                    iProp         : Longint;                { property to validate }
                    bSetting      : Bool                    { TRUE:setting, FALSE:getting }
                  ): DBIResult;

      Function    GetCursorProps ( hCursor : hDBICur; var curProps : CURProps ): DBIResult;
      Function    GetObjFromObj( Source : hDBIObj; eObjType : DBIOBJType; var hObj : hDBIObj ) : DBIResult;
      Function    GetObjFromName (                          { Get object from name }
                    eObjType      : DBIOBJType;             { Object handle }
                    pszObjName    : PChar;                  { Name of object /NULL }
                    var hObj      : hDBIObj                 { Returned object handle }
                  ): DBIResult;

      Function    GetFieldDescs( hCursor : hDBICur; pfldDesc : pFLDDesc ) : DBIResult;
      Function    GetRecordCount( hCursor : hDBICur; Var iRecCount : Longint ) : DBIResult;
      Function    GetExactRecordCount( hCursor : hDBICur; Var iRecCount : Longint ) : DBIResult;

      Function    SetToRecordNo (                           { Position to Physical Rec# }
                    hCursor       : hDBICur;                { Cursor handle }
                    iRecNo        : Longint                 { Physical record number }
                  ): DBIResult;

      Function    SaveChanges (                             { flush all buffered changes }
                    hCursor       : hDBICur                 { Cursor handle }
                  ): DBIResult;

      Function    ForceReread (                             { reread buffered record }
                    hCursor       : hDBICur                 { Cursor handle }
                  ): DBIResult;
      Function    ForceRecordReread (                       { Force Reread of current record from Server }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuff      : Pointer                 { Returned : record buffer }
                  ): DBIResult;
      Function    CheckRefresh : DBIResult;                 { Check to see if changes made }

      Function    SetLockRetry (                            { Set Lock wait time }
                    iWait         : SmallInt                { Time in seconds }
                  ): DBIResult;

      Function    BatchMove (                               { Copy records to destination table }
                    pSrcTblDesc          : pBATTblDesc;     { Source table identification, }
                    hSrcCur              : hDBICur;         {  OR source cursor  ( one must be NULL ) }
                    pDstTblDesc          : pBATTblDesc;     { Destination table identification, }
                    hDstCur              : hDBICur;         {  OR destination cursor ( one must be NULL ) }
                    ebatMode             : eBATMode;        { Batch mode }
                    iFldCount            : Word;            { size of field maps }
                    pSrcFldMap           : PWord;           { Array of source field numbers }
                    pszIndexName         : PChar;           { If update mode, used to match records }
                    pszIndexTagName      : PChar;           { Index tag name }
                    iIndexId             : Word;            { Index  id }
                    pszKeyviolName       : PChar;           { Keyviol table name  (optional) }
                    pszProblemsName      : PChar;           { Problems table name (optional) }
                    pszChangedName       : PChar;           { Changed table name (optional) }
                    lProbRecs            : PLongint;        { Number of records to read from source }
                    lKeyvRecs            : PLongint;        { Number of records to read from source }
                    lChangedRecs         : PLongint;        { Number of records to read from source }
                    bAbortOnFirstProb    : Bool;            { If TRUE, abort on first problem rec }
                    bAbortOnFirstKeyviol : Bool;            { If TRUE, abort on first keyviol rec }
                    var lRecsToMove      : Longint;         { Number of records to read from source }
                    bTransliterate       : Bool             { If TRUE, transliterate character data }
                  ): DBIResult;

      Function    CopyTable (                               { Copy one table to another }
                    hDb           : hDBIDb;                 { Database handle }
                    bOverWrite    : Bool;                   { True, to overwrite existing file }
                    pszSrcTableName : PChar;                { Source table name }
                    pszSrcDriverType : PChar;               { Source driver type }
                    pszDestTableName : PChar                { Destination table name }
                  ): DBIResult;

      Function    OpenLockList (                            { Get a list of locks }
                    hCursor       : hDBICur;                { Cursor handle }
                    bAllUsers     : Bool;                   { True, for all Users locks }
                    bAllLockTypes : Bool;                   { True, for all lock types }
                    var hLocks    : hDBICur                 { Returned cursor on Lock list }
                  ): DBIResult;

      Function    OpenUserList (                            { Get a list of users loggedin }
                    var hUsers : hDBICur                    { Returned cursor on user list }
                  ): DBIResult;

      Function    MakePermanent (                           { Make temporary table permanent }
                    hCursor       : hDBICur;                { Cursor handle }
                    pszName       : PChar;                  { Rename temporary table }
                    bOverWrite    : Bool                    { Overwrite existing file }
                  ): DBIResult;

      Function    SetRange (                                { Set cursor to a range }
                    hCursor       : hDBICur;                { Cursor }
                    bKeyItself    : Bool;                   { Whether Key or Record buffer }
                    iFields1      : Word;                   { Key fields to be mathced in full }
                    iLen1         : Word;                   { Key length to compare }
                    pKey1         : Pointer;                { Top/Left key in Range }
                    bKey1Incl     : Bool;                   { If Inclusive of Key1 }
                    iFields2      : Word;                   { Key fields to be mathced in full }
                    iLen2         : Word;                   { Key length to compare }
                    pKey2         : Pointer;                { Bottom/Right key in Range }
                    bKey2Incl     : Bool                    { If Inclusive of Key2 }
                  ): DBIResult;

      Function    ResetRange(
                    hCursor       : hDBICur                 { Cursor }
                  ) : DBIResult;

      Function    CompareKeys (                             { Compare two keys }
                    hCursor       : hDBICur;                { Cursor handle }
                    pKey1         : Pointer;                { Key buffer 1 to compare }
                    pKey2         : Pointer;                { Key buffer 2 (Or NULL) }
                    iFields       : Word;                   { Fields to compare in full }
                    iLen          : Word;                   { Partial key to compare }
                    var iResult   : SmallInt                { Compare result }
                  ): DBIResult;

      Function    SwitchToIndex( hCursor : hDBICur; pszIndexName, pszTagName : PChar;
                    iIndexId : Word; bCurrRec : Bool
                  ) : DBIResult;
  
      Function    SetToKey (                                { Set key condition }
                    hCursor       : hDBICur;                { Cursor handle }
                    eSearchCond   : DBISearchCond;          { Search condition (default is =) }
                    bDirectKey    : Bool;                   { Key is supplied directly }
                    iFields       : Word;                   { No of full fields to match }
                    iLen          : Word;                   { Partial key len of last field }
                    pBuff         : Pointer                 { Either Record buffer or Key itself }
                  ): DBIResult;
  
      Function    ExtractKey (                              { Get the key value of current record }
                    hCursor       : hDBICur;                { Cursor handle }
                    pRecBuf       : Pointer;                { Record buffer (optional) }
                    pKeyBuf       : Pointer                 { Returned. Key bytes. }
                  ): DBIResult;
  
      Function    GetIndexDesc (                            { Get index properties }
                    hCursor       : hDBICur;                { Cursor handle }
                    iIndexSeqNo   : Word;                   { Index number }
                    var   idxDesc : IDXDesc                 { Returned index description }
                  ): DBIResult;

      Function    GetIndexDescs(                            { Get index properties }
                    hCursor       : hDBICur;                { Cursor handle }
                    idxDesc       : PIDXDesc                { Returned index description }
                  ): DBIResult;

      Function    GetIndexForField(                         { Get index properties }
                    hCursor       : hDBICur;                { Cursor handle }
                    iFld          : Word;                   { Field Number (1..N) }
                    bProdTagOnly  : Bool;                   { If TRUE, only xBASE prod tags will be returned }
                    var   idxDesc : IDXDesc                 { Returned index description }
                  ): DBIResult;
  
      Function    GetIndexSeqNo (                           { Get index sequence number }
                    hCursor       : hDBICur;                { Cursor handle }
                    pszIndexName  : PChar;                  { Index name }
                    pszTagName    : PChar;                  { Tag name (if applicable) }
                    iIndexId      : Word;                   { Index number }
                    var iIndexSeqNo  : Word                 { Index number }
                  ): DBIResult;
  
      Function    EmptyTable (                              { Deletes all records }
                    hDb           : hDBIDb;                 { Database handle }
                    hCursor       : hDBICur;                { Cursor (OR) }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar                   { Driver type /NULL }
                  ): DBIResult;

      Function    PackTable (                               { Packs all records }
                    hDb           : hDBIDb;                 { Database handle }
                    hCursor       : hDBICur;                { Cursor (OR) }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    bRegenIdxs    : Bool                    { Regenerate indexes }
                  ): DBIResult;

      Function    RegenIndex (                              { Regenerate an index }
                    hDb           : hDBIDb;                 { Database handle }
                    hCursor       : hDBICur;                { Cursor (OR) }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    pszIndexName  : PChar;                  { Index name }
                    pszIndexTagName : PChar;                { Index tagname (xbase MDX) }
                    iIndexId      : Word                    { Index number }
                  ): DBIResult;

      Function    RegenIndexes (                            { Regenerate all indexes }
                    hCursor       : hDBICur                 { Cursor }
                  ): DBIResult;

      Function    SortTable (                               { Sort table }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Table name of source }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    hSrcCur       : hDBICur;                { OR cursor of table to sort }
                    pszSortedName : PChar;                  { Destination table (NULL if sort to self) }
                    phSortedCur   : phDBICur;               { If non-null, return cursor on destination }
                    hDstCur       : hDBICur;                { OR cursor of destination }
                    iSortFields   : Word;                   { Number of sort fields }
                    piFieldNum    : PWord;                  { Array of field numbers }
                    pbCaseInsensitive : PBool;              { Which fields should sort c-i (Opt) }
                    pSortOrder    : pSORTOrder;             { Array of Sort orders (Opt) }
                    ppfSortFn     : ppfSORTCompFn;          { Array of compare fn pntrs (Opt) }
                    bRemoveDups   : Bool;                   { TRUE : Remove duplicates }
                    hDuplicatesCur : hDBICur;               { Cursor to duplicates table (Opt) }
                    var lRecsSort  : Longint                { in/out param. - sort this number }
                  ): DBIResult;

      Function    CreateTable (                             { Create a new table }
                    hDb           : hDBIDb;                 { Database handle }
                    bOverWrite    : Bool;                   { True, to overwrite existing file. }
                    var crTblDsc  : CRTblDesc               { Table description }
                  ): DBIResult;

      Function    CreateInMemTable (                        { Create a temporary table (Logical) }
                    hDb           : hDBIDb;                 { Database handle }
                    pszName       : PChar;                  { Logical Name }
                    iFields       : Word;                   { No of fields }
                    pfldDesc      : pFLDDesc;               { Array of field descriptors }
                    var hCursor   : hDBICur                 { Returned cursor handle }
                  ): DBIResult;

      Function    CreateTempTable (                         { Create temporary table (Physical) }
                    hDb           : hDBIDb;                 { Database handle }
                    var crTblDsc  : CRTblDesc;              { Table description }
                    var hCursor   : hDBICur                 { Returned cursor on table }
                  ): DBIResult;

      Function    DoRestructure (                           { Restructure a table }
                    hDb           : hDBIDb;                 { Database handle }
                    iTblDescCount : Word;                   { Number of table descriptors (1) }
                    pTblDesc      : pCRTblDesc;             { Array of table descs }
                    pszSaveAs     : PChar;                  { Restructure to this table }
                    pszKeyviolName : PChar;                 { Keyviol table name  (optional) }
                    pszProblemsName : PChar;                { Problems table name (optional) }
                    bAnalyzeOnly  : Bool                    { Analyze restructure }
                  ): DBIResult;

      Function    RenameTable (                             { Rename table & family }
                    hDb           : hDBIDb;                 { Database handle }
                    pszOldName    : PChar;                  { Old name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    pszNewName    : PChar                   { New name }
                  ): DBIResult;

      Function    DeleteTable (                             { Delete a table }
                    hDb           : hDBIDb;                 { Database handle }
                    pszTableName  : PChar;                  { Name including any path }
                    pszDriverType : PChar                   { Driver type /NULL }
                  ): DBIResult;

      Function    AddIndex (                                { Add a new index }
                    hDb           : hDBIDb;                 { Database handle }
                    hCursor       : hDBICur;                { Cursor (OR) }
                    pszTableName  : PChar;                  { Table name including any path }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    var IdxDesc   : IDXDesc;                { Description of the index }
                    pszKeyviolName : PChar                  { Keyviol table name (optional) }
                  ): DBIResult;
  
      Function    DeleteIndex (                             { Delete index }
                    hDb           : hDBIDb;                 { Database handle }
                    hCursor       : hDBICur;                { Cursor (OR) }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    pszIndexName  : PChar;                  { Index name }
                    pszIndexTagName : PChar;                { Index tagname (xbase MDX) }
                    iIndexId      : Word                    { Index number }
                  ): DBIResult;

      Function    SetDirectory( hDb : hDBIDb; pszDir : PChar ): DBIResult;
      Function    GetDirectory( hDb : hDBIDb; bDefault : Bool; pszDir : PChar ): DBIResult;
      Function    GetSysVersion( var s : SysVersion ) : DBIResult;
      Function    GetSysConfig( var s : SysConfig ) : DBIResult;
      Function    GetClientInfo( var s : clientInfo ) : DBIResult;

      Function    LoadDriver (                              { Load a given driver }
                    pszDriverType : PChar                   { Driver name }
                  ): DBIResult;

      Function    GetSysInfo( var s : SysInfo ) : DBIResult;
      Function    GetSesInfo( var s : SesInfo ) : DBIResult;

      Function    AddPassword (                             { Add a password to current session }
                    pszPassword   : PChar                   { Password }
                  ): DBIResult;

      Function    DropPassword (                            { Drop a password to current session }
                    pszPassword   : PChar                   { Password }
                  ): DBIResult;

      Function    GetNetUserName (                          { Get network username }
                    pszNetUserName : PChar                  { Returns username }
                  ): DBIResult;

      Function    AddAlias (                                { Add a new alias }
                    hCfg          : hDBICfg;                { NULL }
                    pszAliasName  : PChar;                  { Alias name }
                    pszDriverType : PChar;                  { Driver type for alias }
                    pszParams     : PChar;                  { Optional parameters }
                    bPersist      : Bool                    { Persistent or session relative }
                  ): DBIResult;

      Function    DeleteAlias (                             { Add a new alias }
                    hCfg          : hDBICfg;                { NULL }
                    pszAliasName  : PChar                   { Alias name }
                  ): DBIResult;

      Function    AddTitanAlias (                           { Add a new alias }
                    pszAliasName  : PChar;                  { Alias name }
                    pszParams     : PChar                   { Optional parameters }
                  ): DBIResult;

      Function    DeleteTitanAlias (                        { Add a new alias }
                    pszAliasName  : PChar                   { Alias name }
                  ): DBIResult;

      Function    OpenCfgInfoList (                         { Open a cursor on "Config" }
                    hCfg          : hDBICfg;                { NULL }
                    eOpenMode     : DBIOpenMode;            { ReadWrite or readonly }
                    eConfigMode   : CFGMode;                { Config mode }
                    pszCfgPath    : PChar;                  { Path }
                    var   hCur    : hDBICur                 { Returned cursor }
                  ): DBIResult;

      Function    ImportODBC(                               { Import current ODBC drivers and data sources }
                    hCfg          : hDBICfg;                { NULL }
                    bPersist      : Bool                    { Persistent or session relative }
                  ): DBIResult;

      Function    AddDriver(                                { Add a new driver }
                    hCfg          : hDBICfg;                { NULL }
                    pszDriverName : PChar;                  { Driver name }
                    pszParams     : PChar;                  { Optional parameters }
                    bPersist      : Bool                    { Persistent or session relative }
                  ): DBIResult;

      Function    DeleteDriver(                             { Delete a driver }
                    hCfg          : hDBICfg;                { NULL }
                    pszDriverName : PChar;                  { Driver name }
                    bSave         : Bool                    { Save config file }
                  ): DBIResult;

     Function    TranslateRecordStructure (                 { Translate a record }
                    pszSrcDriverType : PChar;               { Source driver type }
                    iFlds         : Word;                   { Number of fields }
                    pfldsSrc      : pFLDDesc;               { Array of source fields: logical or physical types }
                    pszDstDriverType : PChar;               { Destination driver type }
                    pszLangDriver : PChar;                  { Language driver for destination }
                    pfldsDst      : pFLDDesc                { Array of dest. fields returned }
                    ;
                    bCreatable    : Bool                    { TRUE -> map to creatable fields only. }
                  ): DBIResult;

      Function    OpenFieldXlt (                            { Open translation object }
                    pszSrcTblType : PChar;                  { NULL for Logical }
                    pszSrcLangDrv : PChar;                  { NULL if no tranliteration }
                    pfldSrc       : pFLDDesc;               { source field descriptor }
                    pszDestTblType : PChar;                 { NULL for Logical }
                    pszDstLangDrv : PChar;                  { NULL if no tranliteration }
                    pfldDest      : pFLDDesc;               { Source field descriptor }
                    var bDataLoss : Bool;                   { Set to TRUE, for data loss }
                    var hXlt      : hDBIXlt                 { Returned translate handle }
                  ): DBIResult;

      Function    TranslateField (                          { Translate a field }
                    hXlt          : hDBIXlt;                { Translation handle }
                    pSrc          : Pointer;
                    pDest         : Pointer                 { Destination field }
                  ): DBIResult;

      Function    CloseFieldXlt (                           { Close translation object }
                    hXlt          : hDBIXlt                 { Translation handle }
                  ): DBIResult;
                  
      Function    BeginDelayedUpdates (                     { put cursor in delayed update mode }
                    var hCursor   : hDBICur                 { In/Out : returns new Cursor }
                  ): DBIResult;

      Function    EndDelayedUpdates (                       { Convert cursor back to normal cursor }
                    var hCursor   : hDBICur                 { In/Out : returns original Cursor }
                  ): DBIResult;

      Function    ApplyDelayedUpdates (                     { Perform the specified operation. }
                    hCursor       : hDBICur;                { Delayed update cursor handle }
                    eUpdCmd       : DBIDelayedUpdCmd        { Op Type: Commit or Rollback. }
                  ): DBIResult;

      Function    GetDelayedUpdates (
                    hCursor       : hDBICur;                { Delayed update cursor handle }
                    var hCache    : hDBICur                 { In/Out: returns cursor on cache }
                  ): DBIResult;

      Function    NativeToAnsi (                            { Convert from native to Ansi }
                    LdObj         : Pointer;                { Language driver }
                    pAnsiStr      : PChar;                  { Destination buffer (opt) }
                    pNativeStr    : PChar;                  { Source buffer }
                    iLen          : LongInt;                { Length of buffer (opt) }
                    var bDataLoss : Bool                    { Returns TRUE if conversion will loose data (opt) }
                  ): DBIResult;

      Function    AnsiToNative (                            { Convert from Ansi to native }
                    LdObj         : Pointer;                { Language driver }
                    pNativeStr    : PChar;                  { Destination buffer (opt) }
                    pAnsiStr      : PChar;                  { Source buffer }
                    iLen          : LongInt;                { Length of buffer (opt) }
                    var bDataLoss : Bool                    { Returns TRUE if conversion will loose data (opt) }
                  ): DBIResult;

      Function    AddFilter (                               { Add a filter to the cursor }
                    hCursor       : hDBICur;                { Cursor handle }
                    iClientData   : Longint;                { Client supplied data      (opt) }
                    iPriority     : Word;                   { 1..N with 1 being highest (opt) }
                    bCanAbort     : Bool;                   { TRUE if pfFiltercan return ABORT (opt) }
                    pcanExpr      : pCANExpr;               { Expression tree        (opt) }
                    pfFilter      : pfGENFilter;            { ptr to filter function (opt) }
                    var hFilter   : hDBIFilter              { Returns filter handle }
                  ): DBIResult;

      Function    DropFilter (                              { Drop a filter }
                    hCursor       : hDBICur;                { Cursor handle }
                    hFilter       : hDBIFilter              { Filter handle }
                  ): DBIResult;

      Function    ActivateFilter (                          { Activate a Filter }
                    hCursor       : hDBICur;                { Cursor handle }
                    hFilter       : hDBIFilter              { Filter handle }
                  ): DBIResult;

      Function    DeactivateFilter (                        { Deactivate Filter }
                    hCursor       : hDBICur;                { Cursor handle }
                    hFilter       : hDBIFilter              { Filter handle }
                  ): DBIResult;

      Function    GetFilterInfo (                           { Get filter information }
                    hCur          : hDBICur;                { Cursor handle }
                    hFilter       : hDBIFilter;             { Filter handle          /NULL }
                    iFilterId     : Word;                   { Filter id              /0 }
                    iFilterSeqNo  : Word;                   { Filter sequence number /0 }
                    var Filterinfo : FilterInfo             { Returns filter info }
                  ): DBIResult;

      Function    BeginLinkMode (                           { Convert cursor to a link cursor }
                    var hCursor   : hDBICur                 { In/Out : returns new cursor }
                  ): DBIResult;

      Function    EndLinkMode (                             { Convert cursor back to normal cursor }
                    var hCursor   : hDBICur                 { In/Out : returns original cursor }
                  ): DBIResult;

      Function    LinkDetail (                              { Link detail to master }
                    hMstrCursor   : hDBICur;                { Master cursor }
                    hDetlCursor   : hDBICur;                { Detail cursor }
                    iLnkFields    : Word;                   { Number of link fields }
                    piMstrFields  : PWord;                  { Array of fields in master }
                    piDetlFields  : PWord                   { Array of fields in detail }
                  ): DBIResult;

      Function    LinkDetailToExp (                         { Link detail to a master using exp }
                    hCursorMstr   : hDBICur;                { Master cursor }
                    hCursorDetl   : hDBICur;                { Detail cursor }
                    iKeyLen       : Word;                   { Key length to match }
                    pszMstrExp    : PChar                   { Expression string }
                  ): DBIResult;

      Function    UnlinkDetail (                            { Unlink detail from master }
                    hDetlCursor   : hDBICur                 { Detail cursor to unlink }
                  ): DBIResult;

      Function    GetLinkStatus (                           { Query linkage info for table }
                    hCursor       : hDBICur;                { Cursor handle }
                    var hCursorMstr : hDBICur;              { Returns master cursor, if any   (opt) }
                    var hCursorDet : hDBICur;               { Returns first detail cursor, if any (opt) }
                    var hCursorSib : hDBICur                { Returns next sibling detail cursor, if any (opt) }
                  ): DBIResult;

      Procedure   SetDefaultDateAndTimeFormat;

      Function    DateEncode( iMon, iDay : Word; iYear : SmallInt; var dateD : DBIDate ): DBIResult;
      Function    DateDecode( dateD : DBIDate; var iMon, iDay : Word;
                                 var iYear : SmallInt ): DBIResult;
      Function    TimeEncode( iHour, iMin, iMilSec : Word; var timeT : Time ): DBIResult;
      Function    TimeDecode( timeT : Time; var iHour, iMin, iMilSec : Word ): DBIResult;

      Function    TimeStampEncode (                         { Encode Date & TIme into Date+Time }
                    dateD         : DBIDate;                { Encoded Date }
                    timeT         : Time;                   { Encoded Time }
                    var tsTS      : TimeStamp               { Encoded Date+Time }
                  ): DBIResult;

      Function    TimeStampDecode (                         { Decode Date & Time from Date+Time }
                    tsTS          : TIMESTAMP;              { Encoded Date+Time }
                    var dateD     : DBIDate;                { Encoded Date }
                    var timeT     : Time                    { Encoded Time }
                  ): DBIResult;

      Function    BcdFromFloat (                            { Converts FLOAT number into FMTBcd format }
                    var iVal      : Double;                 { Float to convert }
                    iPrecision    : Word;                   { Precision of BCD }
                    iPlaces       : Word;                   { Number of decimals }
                    var Bcd       : FMTBcd                  { returns Bcd number (length = iPrecision +2) }
                  ): DBIResult;

      Function    BcdToFloat (                              { Converts FMTBcd number to FLOAT }
                    var Bcd       : FMTBcd;                 { Bcd number to convert }
                    var iVal      : Double                  { Returns converted float }
                  ): DBIResult;

      Function    RegisterCallBack (                        { Register a call back fn }
                    hCursor       : hDBICur;                { Cursor (Optional) }
                    ecbType       : CBType;                 { Type of call back }
                    iClientData   : Longint;                { Pass-thru client data }
                    iCbBufLen     : Word;                   { Callback buffer len }
                    CbBuf         : Pointer;                { Pointer to callback buffer }
                    pfCb          : pfDBICallBack           { Call back fn being registered }
                  ): DBIResult;

      Function    GetCallBack (                             { Register a call back fn }
                    hCursor       : hDBICur;                { Cursor (Optional) }
                    ecbType       : CBType;                 { Type of call back }
                    piClientData  : PLongint;               { Pass-thru client data }
                    piCbBufLen    : PWord;                  { Callback buffer len }
                    ppCbBuf       : Pointer;                { Pointer to callback buffer }
                    var pfCb      : pfDBICallBack           { Call back fn being registered }
                  ): DBIResult;

      Function    GetNumberFormat (                         { Get current number format }
                    var   fmtNumber     : FMTNumber
                  ): DBIResult;

      Function    SetNumberFormat (                         { Set current number format }
                    var   fmtNumber     : FMTNumber
                  ): DBIResult;

      Function    GetErrorEntry (                           { Get error entry }
                    uEntry        : Word;                   { Error stack entry }
                    var ulNativeError : Longint;            { Returned. Native error code, if any }
                    pszError      : PChar                   { Returned. Error string, if any }
                  ): DBIResult;

      Function    GetErrorString (                          { Get message for error code }
                    rslt          : DBIResult;              { Engine error code }
                    pszError      : PChar                   { Error string for the error }
                  ): DBIResult;

      Function    GetErrorContext (                         { Get specific Context if available }
                    eContext      : SmallInt;               { Context type }
                    pszContext    : PChar                   { Context string (MAXMSGLEN +1) }
                  ): DBIResult;

      Function    GetErrorInfo (                            { Return info on last error }
                    bFull         : Bool;                   { If Full details }
                    var   ErrInfo : DBIErrInfo              { Error Info }
                  ): DBIResult;

      Function    DebugLayerOptions (                       { Get SDK debug layer options }
                    iOption       : Word;                   { Option }
                    pDebugFile    : PChar
                  ): DBIResult;

      Function    OpenConfigFile (                          { Open/Create configuration }
                    pszDirPath    : PChar;                  { Directory }
                    bCreate       : Bool;                   { TRUE to create/overwrite }
                    var hCfg      : hDBICfg                 { Handle to config }
                  ): DBIResult;

      Function    CloseConfigFile (                         { Close the config file }
                    var hCfg      : hDBICfg;                { Handle }
                    bSave         : Bool;                   { To save the changes }
                    bDefault      : Bool                    { To make this file the default }
					;
                    bSaveAs16     : Bool                    { To save as a 16-bit config file }
                  ): DBIResult;

      Function    CfgSave (                                 { Save current configuration }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszNewFile    : PChar                   { (Optional): Save as this file }
					;
                    bSaveAs16     : Bool                    { To save as a 16-bit config file }
                  ): DBIResult;

      Function    CfgBuildPath (                            { Build a path for accessing config. }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszCategory   : PChar;                  { NULL for root }
                    pszGroup      : PChar;                  { NULL for no group }
                    pszSection    : PChar;                  { NULL fro no section }
                    pszCfgPath    : PChar                   { Returned path }
                  ): DBIResult;

      Function    CfgPosition (                             { Position the config path }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszCfgPath    : PChar                   { Path }
                  ): DBIResult;

      Function    CfgGetNextNode (                          { Get next defined node }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszNodeName   : PChar                   { Node name (Returned) }
                  ): DBIResult;

      Function    CfgGetRecord (                            { Get a record }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszCfgPath    : PChar;                  { Path }
                    var iFields   : Word;                   { Returned nbr of fields }
                    pfldDesc      : pFLDDesc;               { Field descriptors }
                    pRec          : Pointer                 { Field values }
                  ): DBIResult;

      Function    CfgAddRecord (                            { Add a record }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszCfgPath    : PChar;                  { Path }
                    iFields       : Word;                   { No of fields }
                    pfldDesc      : pFLDDesc;               { Field descriptors }
                    pRec          : Pointer                 { Data values }
                  ): DBIResult;

      Function    CfgModifyRecord (                         { Modify a record }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszCfgPath    : PChar;                  { Path }
                    iFields       : Word;                   { Nbr of fields }
                    pfldDesc      : pFLDDesc;               { Field descriptors }
                    pRec          : Pointer                 { Data values }
                  ): DBIResult;

      Function    CfgDropRecord (                           { Delete a record }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszCfgPath    : PChar                   { Path }
                  ): DBIResult;

      Function    CfgTranslate (                            { Translate configuration string }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszConfigPath : PChar;                  { configuration path }
                    pszTrans      : PChar;                  { translated path }
                    iFields       : Word;                   { number of fields, 0 if path only }
                    pfldDesc      : pFLDDesc;               { field descriptors, NULL if path only }
                    pRec          : Pointer                 { record buffer, NULL if path only }
                  ): DBIResult;

      Function    CfgGetHelp (                              { Get help message }
                    hCfg          : hDBICfg;                { Config Handle/NULL }
                    pszConfigPath : PChar;                  { configuration path }
                    pszFldName    : PChar;                  { field name  ( optional ) }
                    pszHelpString : PChar                   { help string ( returned ) }
                  ): DBIResult;

      Function    CfgMerge (                                { Merge config files }
                    hCfgDest      : hDBICfg;                { Destination Cfg handle/ NULL }
                    hCfgSrc       : hDBICfg;                { Source Cfg handle/ NULL }
                    pszSrcPath    : PChar                   { Source Path / NULL }
                  ): DBIResult;

      Function    QExecDirect (                             { Execute query }
                    hDb           : hDBIDb;                 { Database handle }
                    eQryLang      : DBIQryLang;             { Query language }
                    pszQuery      : PChar;                  { Query }
                    phCur         : phDBICur                { Returned cursor on result set }
                  ): DBIResult;
      Function    QAlloc (                                  { Allocates a statement handle }
                    hDb           : hDBIDb;                 { Database handle }
                    eQryLang      : DBIQryLang;             { Query language }
                    var hStmt     : hDBIStmt                { Returned statment handle }
                  ): DBIResult;

      Function    QPrepare (                                { Prepare a query }
                    hStmt         : hDBIStmt;               { Returned statment handle }
                    pszQuery      : PChar                   { Query }
                  ): DBIResult;
      Function    QExec (                                   { Execute prepared query }
                    hStmt         : hDBIStmt;               { Statement handle }
                    phCur         : phDBICur                { Returned handle on result set }
                  ): DBIResult;

      Function    QPrepareExt (                             { Prepare a query }
                    hDb           : hDBIDb;                 { Database handle }
                    eQryLang      : DBIQryLang;             { Query language }
                    pszQuery      : PChar;                  { Query }
                    propBits      : Word;                   { properties for Prepare, e.g. qprepFORUPDATE }
                    var hStmt     : hDBIStmt                { Returned statment handle }
                  ): DBIResult;

      Function    QFree (                                   { Free statement handle }
                    var hStmt : hDBIStmt                    { Statement handle }
                  ): DBIResult;

      Function    QSetParams (                              { Set query options }
                    hStmt         : hDBIStmt;               { Statement handle }
                    uFldDescs     : Word;                   { Number of parameter field descriptors }
                    paFldDescs    : pFLDDesc;               { Array of parameter field descriptors }
                    pRecBuff      : Pointer                 { Record buffer }
                  ): DBIResult;

      Function    QInstantiateAnswer (                      { Create answer table }
                    hStmt         : hDBIStmt;               { Statement Handle }
                    hCur          : hDBICur;                { Cursor Handle }
                    pszAnswerName : PChar;                  { Answer Table Name/NULL }
                    pszAnswerType : PChar;                  { Answer Table Type/NULL }
                    bOverWrite    : Bool;                   { Overwrite Flag }
                    phCur         : phDBICur                { cursor to instantiated table (output)(optional) }
                  ): DBIResult;

      Function    QExecProcDirect (                         { Direct execution of stored procedure }
                    hDb           : hDBIDb;                 { Database handle }
                    pszProc       : PChar;                  { Stored procedure name }
                    uParamDescs   : Word;                   { Number of parameter descriptors }
                    paParamDescs  : pSPParamDesc;           { Array of parameter descriptors }
                    pRecBuff      : Pointer;                { Record buffer }
                    var hCur      : hDBICur                 { Returned handle on result set }
                  ): DBIResult;

      Function    QPrepareProc (                            { Prepare a stored procedure }
                    hDb           : hDBIDb;                 { Database handle }
                    pszProc       : PChar;                  { Stored procedure name }
                    uParamDescs   : Word;                   { Number of parameter descriptors }
                    paParamDescs  : pSPParamDesc;           { Array of parameter descriptors }
                    pRecBuff      : Pointer;                { Record buffer }
                    var hStmt     : hDBIStmt                { Returned statment handle }
                  ): DBIResult;

      Function    QSetProcParams (                          { Set procedure params }
                    hStmt         : hDBIStmt;               { Statement handle }
                    uParamDescs   : Word;                   { Number of parameter descriptors }
                    paParamDescs  : pSPParamDesc;           { Array of parameter descriptors }
                    pRecBuff      : Pointer                 { Record buffer }
                  ): DBIResult;

      Function    BeginConstraintLayer(
                    hDb          : hDBIDb;
                    var  hCur         : hDBICur;
                    pDsCb        : pfDataSourcesCallback;
                    lUserVal     : Integer
                  ): DBIResult;

      Function    EndConstraintLayer( var hCur : hDBICur ): DBIResult;

      Function    SQLTextToCanEx(
                    hStmt         :  hDBIStmt;
                    pExprText     :  PChar;
                    iFields       :  Word;
                    pFlds         :  pFLDDesc;
                    exType        :  EXPType;
                    pszFldName    :  PChar;
                    pszSourceDb   :  PChar;
                    var  piCanSize     :  Word;
                    pCanEx        :  PByte
                  ): DBIResult;

      Function    CheckSQLExpression(
                    hCur          :  hDBICur;
                    pszExpr       :  PChar;
                    pszFldName    :  PChar;
                    expType       :  EXPType;
                    pDsCB         :  pfDataSourcesCallback;
                    iClientData   :  Integer
                  ): DBIResult;

      Function    DsProviderGetDataPacket(
                    hCur             : hDBICur;             { Result cursor handle }
                    eProvOptions     : Integer;             { Options for provider }
                    pDsCB            : Pointer;             { Callback for field origin }
                    iClientData      : Integer;             { Client Data for callback }
                    piMaxRecords     : PInteger;            { In: Max recs, Out: Actual Recs }
                    var Packet           : PVarArray;
                    var pbEndOfData      : Bool             { End of file was reached }
                  ): DBIResult;

      Function    DsResolver(
                    iNoOfDataSources  : Integer;            { Number of data sources. }
                    Packets           : PPacketList;        { Packet Buffer }
                    hDb               : hDBIDb;             { Database handle. }
                    szDbName          : PChar;              { Database name }
                    szDbType          : PChar;              { Database type }
                    szDbPassword      : PChar;              { Password }
                    pszSqlStr         : PNameList;          { SQL str used to generate Packet. }
                    ppTableName       : PNameList;          { If open table, name of table }
                    piClientData      : PInteger;           { Client Data for Resolver callback }
                    ppfReconcile      : PCBList;            { Reconcile Callback-fn }
                    ppDsCB            : PCBList;            { PpfDataSourcesCallback; }
                    ClientData        : Integer;            { Client Data for DSCallback }
                    piMaxErrorRecords : PInteger;           { In: MaxErrors, Out: ErrorCount }
                    pppErrPacket      : PPacketList         { Packet Buffer for error set }
                  ): DBIResult;

      Function    OsLdInit( pDefDir: PChar; pDefLangDr: PChar): DBIResult;
      Function    OsLdExit: DBIResult;
      Function    OsLdGetDefaultObj(var pLdObj: PLocale): DBIResult;
      Function    OsLdGetSymbName( pLdObj: PLocale; pSymbName: PByte): DBIResult;
      Function    OsLdGetDriverId( pLocaleObj :PLocale; var DriverId: Word): DBIResult;
      Function    OsLdGetDescName( pLocaleObj : PLocale; pDescName: PByte): DBIResult;
      Function    OsLdGetSortsig( pLocaleObj : PLocale; var SortSig: SmallInt): DBIResult;
      Function    OsLdGetCodePage( pLocaleObj : PLocale; var CodePage: SmallInt): DBIResult;
      Function    OsLdGetFName( pLocaleObj : PLocale; PName: PChar): DBIResult;
      Function    OsLdGetProductID( pLdObj : Pointer; piProdID : PWord ) : DBIResult;
      Function    OsLdSearchInit( var SHandle : Pointer ) : DBIResult;
      Function    OsLdSearchNext( SHandle : Pointer; var ppLdObj : Pointer ) : DBIResult;
      Function    OsLdSearchEnd( SHandle : Pointer ): DBIResult;
      Function    OsLdLoadByCID( _lcid : Integer; var pLdObj: Pointer ): DBIResult;
      Function    OsLdGetMinMax( pLdObj : Pointer; pcMin : PChar; pcMax : PChar ): DBIResult;
      Function    OsLdSetConvChars( o2a : Shortint; a2o : Shortint ): DBIResult;
      Function    OsLdGetFuncAddrLdStrnColli_( var ppf : Pointer ): DBIResult;
      Function    OsLdGetFuncAddrLdStrnColl_( var ppf : Pointer ) : DBIResult;
      Function    OsLdGetFuncAddrLdStrnCmpi_( var ppf : Pointer ) : DBIResult;
      Function    OsLdStrnColl( pLdObj : Pointer; Str1 : PByte; Str2 : PByte; Maxlen : Word ): Shortint;
      Function    OsLdStrnColli( pBlObj : Pointer; str1 : PChar; str2 : PChar; iLen : Word ): Shortint;
      Function    OsLdExStrCmp( pLdObj : Pointer; Right : PByte; RightLen : Shortint;
                    Left : PByte; LeftLen : Shortint; Exact: Bool ): Shortint;
      Function    OsLdLoadBySortSig( SortSig: Word; CodePage: Word; var pLocaleObj : PLocale): DBIResult;
      Function    OsLdLoadByFName( pFName: PChar; var PLocaleObj :PLocale): DBIResult;
      Function    OsLdLoadBySymbName( pSymbName: PChar; var pLocaleObj : PLocale): DBIResult;
      Function    OsLdLoadByDriverId( iDriverId: Word; var pLocaleObj : PLocale): DBIResult;
      Function    OsLdUnloadObj( var pLocaleObj : PLocale): DBIResult;
      Function    OsLdStrnCmp( pLocaleObj : PLocale; Str1: PChar; Str2: PChar; Len: Word): DBIResult;
      Function    OsLdStrCmp( pLocaleObj : PLocale; Str1: PChar; Str2: PChar): DBIResult;
      Function    OsLdStrToUpper( pLocaleObj : PLocale; Str: PByte): DBIResult;
      Function    OsLdStrnToUpper( pLocaleObj : PLocale; Str: PByte; Len: Word): DBIResult;
      Function    OsLdStrToLower( pLocaleObj : PLocale; Str: PByte): DBIResult;
      Function    OsLdStrnToLower( pLocaleObj : PLocale; Str: PByte; Len: Word): DBIResult;
      Function    OsLdStrCmpi( pLdObj: PLocale; str1:pCHAR; str2: PChar): SmallInt;
      Function    OsLdStrnCmpi( pLocaleObj : PLocale; Str1: PChar; Str2: PChar; Len: Word): SmallInt;
      Function    OsLdOemToAnsi( pLocaleObj : PLocale; AnsiStr: PChar; OemStr: PChar;
                     Len: Word; var DataLoss: BOOL): DBIResult;
      Function    OsLdAnsiToOem( pLocaleObj : PLocale; OemStr: PChar; AnsiStr: PChar;
                     Len: Word; var DataLoss: BOOL): DBIResult;
      Function    OsLdIsAnsiCharInOemCp( PLocaleObj :PLocale; AnsiCh: Char): Bool;
      Function    OsLdIsOemCharInAnsiCp( PLocaleObj :PLocale; OemCh: Char): Bool;
      Function    OsLdAnsiCharToOem( pLocaleObj : PLocale; ch: Byte): Byte;
      Function    OsLdOemCharToAnsi( pLocaleObj : PLocale; ch: Byte): Byte;
      Function    OsLdCharToUpper( pLocaleObj : PLocale; ch: Byte): Byte;
      Function    OsLdCharToLower( pLocaleObj : PLocale; ch: Byte): Byte;
      Function    OsLdIsAlpha( pLocaleObj : PLocale; ch: Byte): Bool;
      Function    OsLdIsDigit( pLocaleObj : PLocale; ch: Byte): Bool;
      Function    OsLdBuildCharSetXform( pCharMap: PChar; pLdObjSrc: PLocale; pLdObjDest: PLocale; var DataLoss: Bool): Bool;
      Function    GetLdNameFromDb(hDb: hDbiDb; DbName: PChar; pldName: PChar): DbiResult;
    end;


Implementation
Uses
  BseRgtry,

  BseConst,

  BseUtils,
  BseTable,
  BseStmt,
  BseDbase

  ;

Const
  ENG_VERSION        = 2;                                   { Engine version }
  CLI_LEVEL          = 0;                                   { Client Interface level }




Constructor TVirtEng.Create( SessionClass : TBaseSessionClass;
              P : TObject; Container : TTitanCollection; iVer : Word; pEnv : pDBIEnv );
begin
  Inherited Create( P, Container );
  FSessions     := TTitanCollection.Create;
  FSessionClass := SessionClass;
  FErrorStack   := TErrorStack.Create( 10 );
  SetDefaultDateAndTimeFormat;
  FStatus := StartSession( NIL, FSession, NIL );
  FDatabase := hDBIDb( Self );
end;


Destructor TVirtEng.Destroy;
begin
  FSessions.Free;
  FErrorStack.Free;
  Inherited Destroy;
end;




Function TVirtEng.GetCursor : hDBICur;
begin
  Result := FCursor;
end;


Procedure TVirtEng.SetCursor( H : hDBICur );
begin
  FCursor := ValidateHandle( h );
end;


Function TVirtEng.GetSession : hDBISes;
begin
  Result := FSession;
end;


Procedure TVirtEng.SetSession( H : hDBISes );
begin
  FSession := ValidateHandle( h );
end;


Function TVirtEng.GetDatabase : hDBIDb;
begin
  Result := FDatabase;
end;


Procedure TVirtEng.SetDatabase( H : hDBIDb );
begin
  FDatabase := ValidateHandle( h );
end;


Function TVirtEng.GetStatement : hDBIStmt;
begin
  Result := FStatement;
end;


Procedure TVirtEng.SetStatement( H : hDBIStmt );
begin
  ValidateHandle( h );
  FStatement := H;
end;


Procedure TVirtEng.SetDefaultDateAndTimeFormat;
Const
  TOPIC      : PChar = 'INTL';
  DATE_YEAR  = 'yyyy';
  DATE_MONTH = 'mm';
  DATE_DAY   = 'dd';
  DATE_TYPE  : PChar = 'iDATE';   DATE_TYPE_DEF : Word    = 0;
  TIME_TYPE  : PChar = 'iTIME';   TIME_TYPE_DEF : Integer = 0;
  TIME_POST  = ' AMPM';
var
  tmpDate : FMTDate;
  tmpTime : FMTTime;
begin
  MoveZero( tmpDate, SizeOf( tmpDate ) );
  With tmpDate do
  begin
    szDateSeparator[ 0 ] := DateSeparator; {From SysUtils}
    iDateMode            := GetProfileInt( TOPIC, DATE_TYPE, DATE_TYPE_DEF );
    bFourDigitYear       := ( Pos( ShortDateFormat, DATE_YEAR  ) <> 0 );
    bMonthLeadingZero    := ( Pos( ShortDateFormat, DATE_MONTH ) <> 0 );
    bDayLeadingZero      := ( Pos( ShortDateFormat, DATE_DAY   ) <> 0 );
    bYearBiased          := TRUE;
  end;
  DateFormat := tmpDate;

  MoveZero( tmpTime, SizeOf( tmpTime ) );
  With tmpTime do
  begin
    cTimeSeparator := TimeSeparator;
    bTwelveHour    := ( Pos( ShortTimeFormat, TIME_POST ) <> 0 );
    If bTwelveHour then
    begin
      StrPLCopy( @szAmString, TimeAMString, SizeOf( szAMString ) - 1 );
      StrPLCopy( @szPmString, TimePMString, SizeOf( szPMString ) - 1 );
    end;
    bSeconds := TRUE;
  end;
  TimeFormat := tmpTime;
end;


Function TVirtEng.GetDateFormat : FMTDate;
begin
  Result  := FDateFormat;
end;


Procedure TVirtEng.SetDateFormat( D : FMTDate );
begin
  Move( D, FDateFormat, SizeOf( FDateFormat ) );
end;


Function TVirtEng.GetTimeFormat : FMTTime;
begin
  Result := FTimeFormat;
end;


Procedure TVirtEng.SetTimeFormat( D : FMTTime );
begin
  Move( D, FTimeFormat, SizeOf( FTimeFormat ) );
end;


Function TVirtEng.TranslateRecordStructure (                { Translate a record }
           pszSrcDriverType : PChar;                        { Source driver type }
           iFlds         : Word;                            { Number of fields }
           pfldsSrc      : pFLDDesc;                        { Array of source fields: logical or physical types }
           pszDstDriverType : PChar;                        { Destination driver type }
           pszLangDriver : PChar;                           { Language driver for destination }
           pfldsDst      : pFLDDesc                         { Array of dest. fields returned }
           ;
           bCreatable    : Bool                             { TRUE -> map to creatable fields only. }

         ): DBIResult;
begin
  begin
    Try
      TBaseSession( Session ).TranslateRecordStructure(
                pszSrcDriverType,
                iFlds,
                pfldsSrc,
                pszDstDriverType,
                pszLangDriver,
                pfldsDst
                ,bCreatable
       );
      Result := DBIERR_NONE;
    Except
      Result := CleanupException;
    end;
  end;
end;


Function TVirtEng.OpenFieldXlt (                            { Open translation object }
           pszSrcTblType : PChar;                           { NULL for Logical }
           pszSrcLangDrv : PChar;                           { NULL if no tranliteration }
           pfldSrc       : pFLDDesc;                        { source field descriptor }
           pszDestTblType : PChar;                          { NULL for Logical }
           pszDstLangDrv : PChar;                           { NULL if no tranliteration }
           pfldDest      : pFLDDesc;                        { Source field descriptor }
           var bDataLoss : Bool;                            { Set to TRUE, for data loss }
           var hXlt      : hDBIXlt                          { Returned translate handle }
         ): DBIResult;
begin
  Try
    TBaseSession( Session ).OpenFieldXlt(
       pszSrcTblType,
       pszSrcLangDrv,
       pfldSrc,
       pszDestTblType,
       pszDstLangDrv,
       pfldDest,
       bDataLoss,
       hXlt
     );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.TranslateField (                          { Translate a field }
           hXlt          : hDBIXlt;                         { Translation handle }
           pSrc          : Pointer;                         { Source field }
           pDest         : Pointer                          { Destination field }
         ): DBIResult;
begin
  Try
    TBaseSession( Session ).TranslateField( hXlt, pSrc, pDest );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CloseFieldXlt (                           { Close translation object }
           hXlt          : hDBIXlt                          { Translation handle }
         ): DBIResult;
begin
  Try
    TBaseSession( Session ).CloseFieldXlt( hXlt );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.BeginDelayedUpdates (                     { put cursor in delayed update mode }
           var hCursor   : hDBICur                          { In/Out : returns new Cursor }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).BeginDelayedUpdates( hCursor );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.EndDelayedUpdates (                       { Convert cursor back to normal cursor }
           var hCursor   : hDBICur                          { In/Out : returns original Cursor }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).EndDelayedUpdates( hCursor );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.ApplyDelayedUpdates (                     { Perform the specified operation. }
           hCursor       : hDBICur;                         { Delayed update cursor handle }
           eUpdCmd       : DBIDelayedUpdCmd                 { Op Type: Commit or Rollback. }
          ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).ApplyDelayedUpdates( eUpdCmd );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.GetDelayedUpdates (
           hCursor       : hDBICur;                { Delayed update cursor handle }
           var hCache    : hDBICur                 { In/Out: returns cursor on cache }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetDelayedUpdates( hCache );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.NativeToAnsi (                            { Convert from native to Ansi }
           LdObj         : Pointer;                         { Language driver }
           pAnsiStr      : PChar;                           { Destination buffer (opt) }
           pNativeStr    : PChar;                           { Source buffer }
           iLen          : LongInt;                         { Length of buffer (opt) }
           var bDataLoss : Bool                             { Returns TRUE if conversion will loose data (opt) }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).NativeToAnsi( LdObj, pAnsiStr, pNativeStr, iLen, bDataLoss );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AnsiToNative (                            { Convert from Ansi to native }
           LdObj         : Pointer;                         { Language driver }
           pNativeStr    : PChar;                           { Destination buffer (opt) }
           pAnsiStr      : PChar;                           { Source buffer }
           iLen          : LongInt;                         { Length of buffer (opt) }
           var bDataLoss : Bool                             { Returns TRUE if conversion will loose data (opt) }
   ): DBIResult;
begin
  Try
    TBaseSession( FSession ).AnsiToNative( LdObj, pNativeStr, pAnsiStr, iLen, bDataLoss );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AddFilter (                               { Add a filter to the cursor }
           hCursor       : hDBICur;                         { Cursor handle }
           iClientData   : Longint;                         { Client supplied data      (opt) }
           iPriority     : Word;                            { 1..N with 1 being highest (opt) }
           bCanAbort     : Bool;                            { TRUE if pfFiltercan return ABORT (opt) }
           pcanExpr      : pCANExpr;                        { Expression tree        (opt) }
           pfFilter      : pfGENFilter;                     { ptr to filter function (opt) }
           var hFilter   : hDBIFilter                       { Returns filter handle }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).AddFilter( iClientData, iPriority, bCanAbort,
      pcanExpr, pfFilter, hFilter );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DropFilter (                              { Drop a filter }
           hCursor       : hDBICur;                         { Cursor handle }
           hFilter       : hDBIFilter                       { Filter handle }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).DropFilter( hFilter );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ActivateFilter (                          { Activate a Filter }
           hCursor       : hDBICur;                         { Cursor handle }
           hFilter       : hDBIFilter                       { Filter handle }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).ActivateFilter( hFilter );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DeactivateFilter (                        { Deactivate Filter }
           hCursor       : hDBICur;                         { Cursor handle }
           hFilter       : hDBIFilter                       { Filter handle }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).DeactivateFilter( hFilter );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetFilterInfo (                           { Get filter information }
           hCur          : hDBICur;                         { Cursor handle }
           hFilter       : hDBIFilter;                      { Filter handle          /NULL }
           iFilterId     : Word;                            { Filter id              /0 }
           iFilterSeqNo  : Word;                            { Filter sequence number /0 }
           var Filterinfo : FilterInfo                      { Returns filter info }
         ): DBIResult;
begin
  Try
    TBaseTable( hCur ).GetFilterInfo( hFilter, iFilterId, iFilterSeqNo, FilterInfo );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.BeginLinkMode (                           { Convert cursor to a link cursor }
           var hCursor   : hDBICur                          { In/Out : returns new cursor }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).BeginLinkMode;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.EndLinkMode (                             { Convert cursor back to normal cursor }
           var hCursor   : hDBICur                          { In/Out : returns original cursor }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).EndLinkMode;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.LinkDetail (                              { Link detail to master }
           hMstrCursor   : hDBICur;                         { Master cursor }
           hDetlCursor   : hDBICur;                         { Detail cursor }
           iLnkFields    : Word;                            { Number of link fields }
           piMstrFields  : PWord;                           { Array of fields in master }
           piDetlFields  : PWord                            { Array of fields in detail }
         ): DBIResult;
begin
  Try
    TBaseTable( hMstrCursor ).LinkDetail( hDetlCursor, iLnkFields, piMstrFields, piDetlFields );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.LinkDetailToExp (                         { Link detail to a master using exp }
           hCursorMstr   : hDBICur;                         { Master cursor }
           hCursorDetl   : hDBICur;                         { Detail cursor }
           iKeyLen       : Word;                            { Key length to match }
           pszMstrExp    : PChar                            { Expression string }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursorMstr ).LinkDetailToExp( hCursorDetl, iKeyLen, pszMstrExp );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.UnlinkDetail (                            { Unlink detail from master }
           hDetlCursor   : hDBICur                          { Detail cursor to unlink }
         ): DBIResult;
begin
  Try
    TBaseTable( hDetlCursor ).UnLinkDetail;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetLinkStatus (                           { Query linkage info for table }
           hCursor       : hDBICur;                         { Cursor handle }
           var hCursorMstr : hDBICur;                       { Returns master cursor, if any   (opt) }
           var hCursorDet : hDBICur;                        { Returns first detail cursor, if any (opt) }
           var hCursorSib : hDBICur                         { Returns next sibling detail cursor, if any (opt) }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetLinkStatus( hCursorMstr, hCursorDet, hCursorSib );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DateEncode( iMon, iDay : Word; iYear : SmallInt; var dateD : DBIDate ) : DBIResult;
begin
  dateD  := Trunc( EncodeDate( iYear, iMon, iDay ) );
  Result := DBIERR_NONE;
end;


Function TVirtEng.DateDecode( dateD : DBIDate; var iMon, iDay : Word;
                               var iYear : SmallInt ): DBIResult;
begin
  Decodedate( dateD, Word( iYear ), iMon, iDay );
  Result := DBIERR_NONE;
end;


Function TVirtEng.TimeEncode( iHour, iMin, iMilSec : Word; var timeT : Time ): DBIResult;
var
  iSec : Word;
begin
  iSec    := Word( iMilSec div 1000 );
  iMilSec := iMilSec - ( iSec * 1000 );
  timeT   := Trunc( EncodeTime( iHour, iMin, iSec, iMilSec ) );
  Result  := DBIERR_NONE;
end;


Function TVirtEng.TimeDecode( timeT : Time; var iHour, iMin, iMilSec : Word ): DBIResult;
var
  iSec : Word;
begin
  DecodeTime( timeT, iHour, iMin, iSec, iMilSec );
  iMilSec := iMilSec + ( iSec * 1000 );
  Result  := DBIERR_NONE;
end;


Function TVirtEng.TimeStampEncode (                         { Encode Date & TIme into Date+Time }
           dateD         : DBIDate;                         { Encoded Date }
           timeT         : Time;                            { Encoded Time }
           var tsTS      : TimeStamp                        { Encoded Date+Time }
         ): DBIResult;
begin
  Not_Supported( fnTIMESTAMPENCODE );
  Result := DBIERR_NOTSUPPORTED;
end;


Function TVirtEng.TimeStampDecode (                         { Decode Date & Time from Date+Time }
           tsTS          : TIMESTAMP;                       { Encoded Date+Time }
           var dateD     : DBIDate;                         { Encoded Date }
           var timeT     : Time                             { Encoded Time }
         ): DBIResult;
begin
  Not_Supported( fnTIMESTAMPDECODE );
  Result := DBIERR_NOTSUPPORTED;
end;


Function TVirtEng.BcdFromFloat (                            { Converts FLOAT number into FMTBcd format }
           var iVal      : Double;                          { Float to convert }
           iPrecision    : Word;                            { Precision of BCD }
           iPlaces       : Word;                            { Number of decimals }
           var Bcd       : FMTBcd                           { returns Bcd number (length = iPrecision +2) }
         ): DBIResult;
begin
  Result := BdeBcdFromFloat( iVal, iPrecision, iPlaces, Bcd );
end;


Function TVirtEng.BcdToFloat (                              { Converts FMTBcd number to FLOAT }
           var Bcd       : FMTBcd;                          { Bcd number to convert }
           var iVal      : Double                           { Returns converted float }
         ): DBIResult;
begin
  Result := BdeBcdToFloat( Bcd, iVal );
end;

Function TVirtEng.RegisterCallBack (                        { Register a call back fn }
           hCursor       : hDBICur;                         { Cursor (Optional) }
           ecbType       : CBType;                          { Type of call back }
           iClientData   : Longint;                         { Pass-thru client data }
           iCbBufLen     : Word;                            { Callback buffer len }
           CbBuf         : Pointer;                         { Pointer to callback buffer }
           pfCb          : pfDBICallBack                    { Call back fn being registered }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).RegisterCallBack( hCursor, ecbType, iClientData, iCbBufLen, CbBuf, pfCb );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;

Function TVirtEng.GetCallBack (                             { Register a call back fn }
                    hCursor       : hDBICur;                { Cursor (Optional) }
                    ecbType       : CBType;                 { Type of call back }
                    piClientData  : PLongint;               { Pass-thru client data }
                    piCbBufLen    : PWord;                  { Callback buffer len }
                    ppCbBuf       : Pointer;                { Pointer to callback buffer }
                    var pfCb      : pfDBICallBack           { Call back fn being registered }
                  ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetCallBack( hCursor, ecbType, piClientData, piCbBufLen, ppCbBuf, pfCb );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetNumberFormat (                         { Get current number format }
           var   fmtNumber     : FMTNumber
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetNumberFormat( fmtNumber );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetNumberFormat (                         { Set current number format }
           var   fmtNumber     : FMTNumber
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).SetNumberFormat( fmtNumber );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CleanupException : DBIResult;
{ ExceptObject is defined in SysUtils }
begin
  If ExceptObject is ETitanEngineError then
  begin
    FErrorStack.Clear;
    FErrorStack.AddError( ETitanEngineError( ExceptObject ) );
    Result := ETitanEngineError( ExceptObject ).DBIError;
  end
  else
    Raise ExceptObject;
end;


Function TVirtEng.IsSqlBased( hDb : hDBIDB ) : Boolean;
begin
  Try
    Database := hDb;
    Result   := TBaseDatabase( hDb ).IsSqlBased;
  Except
    On E:ETitanEngineError do
      result := FALSE;
  end;
end;


Function TVirtEng.StartSession(
           pszName   : PChar;
           var hSes  : hDBISes;
           pszNetDir : PChar
         ) : DBIResult;
begin
    Try
      ValidateParameter( FSessionClass );
      Session := HDBISes( FSessionClass.CreateAsSes( Self, FSessions, pszName, pszNetDir ) );
      hSes    := Session;
      Result  := DBIERR_NONE;
    Except
      hSes   := NIL;
      Result := CleanupException;
    end;
end;


Function TVirtEng.CloseSession(
           hSes : hDBISes
         ) : DBIResult;
begin
  Try
    Session := hSes;
    TBaseSession( hSes ).Free;
    Session := FSessions.At( 0 );
    Result  := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetCurrSession( hSes : hDBISes ) : DBIResult;
begin
  Try
    Session := hSes;
    Result  := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetCurrSession( var hSes : hDBISes ) : DBIResult;
begin
  hSes   := FSession;
  Result := DBIERR_NONE;
end;


Function TVirtEng.OpenTableTypesList (                      { Get a list of table types }
           pszDriverType : PChar;                           { Driver type }
           var hCur      : hDBICur                          { Returned cursor }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenTableTypesList( pszDriverType, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenFieldTypesList (                      { Get a list of field types }
           pszDriverType : PChar;                           { Driver type }
           pszTblType    : PChar;                           { Table type (Optional) }
           var hCur      : hDBICur                          { Returned cursor }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenFieldTypesList( pszDriverType, pszTblType, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenIndexTypesList (                      { Get a list of Index types }
           pszDriverType : PChar;                           { Driver type }
           var hCur      : hDBICur                          { Returned cursor }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenIndexTypesList( pszDriverType, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetIndexTypeDesc (                        { Get list of Index types }
           pszDriverType : PChar;                           { Driver type }
           pszIndexType  : PChar;                           { Index type }
           var idxType   : idxType                          { Index type description }
   ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetIndexTypeDesc( pszDriverType, pszIndexType, idxType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetFieldTypeDesc (                        { Get list of field types }
           pszDriverType : PChar;                           { Driver type }
           pszTableType  : PChar;                           { Table type }
           pszFieldType  : PChar;                           { Field type  (Physical only) }
           var fldType   : FLDType                          { Field type description }
   ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetFieldTypeDesc(
      pszDriverType,
      pszTableType,
      pszFieldType,
      fldType
    );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetTableTypeDesc (                        { Get Table capabilities }
           pszDriverType : PChar;                           { Driver type }
           pszTableType  : PChar;                           { Table type }
           var tblType   : TBLType                          { Table Capabilities }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetTableTypeDesc( pszDriverType, pszTableType, tblType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetDatabaseDesc (                         { Get a description of a logical db }
           pszName       : PChar;                           { Name of logical database }
           pdbDesc       : pDBDesc                          { Database description }
         ): DBIResult;
Var
  NewDBName   : DBIPATH;
  WasSessDesc : Boolean;
begin
  Try
    SetSessionFromDB( pszName, NIL, 0, NIL, NIL, @NewDbName, WasSessDesc );
    TBaseSession( FSession ).GetDatabaseDesc( @NewDBName, pdbDesc );
    Result := DBIERR_NONE;
  Except
    On E:ETitanEngineError do
        Result := CleanupException;
  end;
end;



Function TVirtEng.OpenLdList (                              { Get a list of Lang Drivers }
           var hCur : hDBICur                               { Returned cursor }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenLdList( hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;  
end;


Procedure TVirtEng.SetSessionfromDB(                { Determine Session to use }
            pszDbName     : PChar;                  { Database name }
            pszDbType     : PChar;                  { Database type (NULL: Universal) }
            iOptFlds      : Word;                   { Number of optional Params }
            pOptFldDesc   : pFLDDesc;               { Optional Field Descriptors }
            pOptParams    : Pointer;                { Optional Params }
            NewDBName     : PChar;                  { returned DB Name without Tag }
            Var WasDesc   : Boolean                 { A Session description was found }
          );
Var
  i         : Word;
  FieldDesc : pFLDDesc;
  SessDesc  : DBINAME;
  P         : Pointer;

  Procedure RemoveSessionDescription( Source, Modified, Description : PChar );
  var
    S : PChar;
    T : PChar;
    P : PChar;
  begin
    Modified^    := #0;
    Description^ := #0;
    If ( Source <> NIL ) then
    begin
      StrCopy( Modified, Source );
      S := StrPos( Modified, DBNAME_PREFIX );
      if ( S <> NIL ) then
      begin
        P := DBNAME_SUFFIX;
        T := S;
        While ( S^ <> P^ ) and ( S^ <> #0 ) do
        begin
          Inc( S );
        end;
        If ( S^ = P^ ) then
        begin
          Inc( S, Length( DBNAME_SUFFIX ) ); { Skip the suffix & trailing space }
          StrCopy( T, S );
        end;
      end;
    end;
  end;


begin
  WasDesc := FALSE;
  If ( pszDBName = NIL ) and ( pszDBType = NIL ) then
  begin
    if ( iOptFlds > 0 ) then
    begin
      FieldDesc := pFLDDesc( pOptFldDesc );
      For i := 1 to iOptFlds do
      begin
        if ( StrIComp( @FieldDesc^.szName, 'PATH' ) = 0 ) then
        begin
          P := pOptParams;
          Inc( PChar( P ), FieldDesc^.iOffset );
          RemoveSessionDescription( P, NewDbName, @SessDesc );
          StrCopy( P, NewDbName );
          Exit;
        end;
      end;
    end;
  end
  else
  begin
    RemoveSessionDescription( pszDbName, NewDbName, @SessDesc );
  end;
end;


Function TVirtEng.OpenDatabase (                            { Open a database }
           pszDbName     : PChar;                           { Database name }
           pszDbType     : PChar;                           { Database type (NULL: Universal) }
           eOpenMode     : DBIOpenMode;                     { Open type }
           eShareMode    : DBIShareMode;                    { Share type }
           pszPassword   : PChar;                           { Password }
           iOptFlds      : Word;                            { Number of optional Params }
           pOptFldDesc   : pFLDDesc;                        { Optional Field Descriptors }
           pOptParams    : Pointer;                         { Optional Params }
           var   hDb     : hDBIDb                           { Returned database handle }
         ): DBIResult;
Var
  NewDbName   : DBIPATH;
  WasSessDesc : Boolean;
begin
  Try
    SetSessionFromDB( pszDbName, pszDbType, iOptFlds, pOptFldDesc, pOptParams, @NewDbName, WasSessDesc );
    TBaseSession( FSession ).OpenDatabase(
      @NewDbName,
      pszDbType,
      eOpenMode,
      eShareMode,
      pszPassword,
      iOptFlds,
      pOptFldDesc,
      pOptParams,
      hDb
    );
    Database := hDb;
    Result := DBIERR_NONE;
  Except
    On E:ETitanEngineError do
        Result := CleanupException;
  end;
end;


Function TVirtEng.OpenVchkList (                            { Return "Checks" for a table }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver Type }
           var hChkCur   : hDBICur                          { Returned cursor on "Checks" }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenVchkList( pszTableName, pszDriverType, hChkCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenRintList (                            { Return Integrity checks }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var hChkCur   : hDBICur                          { Returned cursor on "Ref Int". }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenRIntList( pszTableName, pszDriverType, hChkCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenSecurityList (                        { Return security descriptions }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var hSecCur   : hDBICur                          { Returned cursor on sec list }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenSecurityList( pszTableName, pszDriverType, hSecCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenFamilyList (                          { Return family members }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var hFmlCur   : hDBICur                          { Returned cursor on "Family" }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenFamilyList( pszTableName, pszDriverType, hFmlCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenSPList (                              { Open a cursor on "Stored Procedures" }
           hDb           : hDBIDb;                          { Universal database handle }
           bExtended     : Bool;                            { True for extended info (N/A) }
           bSystem       : Bool;                            { True to include system procedures }
           pszQual       : PChar;                           { Qualifier (N/A) }
           var hCur      : hDBICur                          { Returned cursor }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenSPList( bExtended, bSystem, pszQual, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenSPParamList (                         { Return "Parameters" for a stored procedure }
           hDb           : hDBIDb;                          { Database handle }
           pszSPName     : PChar;                           { Stored procedure name }
           bPhyTypes     : Bool;                            { True, for physical types }
           uOverload     : Word;                            { Overload number }
           var hCur      : hDBICur                          { Returned cursor on "Parameters" }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenSPParamList( pszSPName, bPhyTypes, uOverload, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenFunctionList (                        { Open a cursor on "Functions" }
           hDb           : hDBIDb;                          { Universal database handle }
           eoptBits      : DBIFUNCOpts;                     { Options for function list }
           phCur         : phDBICur                         { Returned cursor on "Functions" }
                                                            { Record desc is of type DBIFUNCDesc }
         ): DBIResult;
begin
  Try
    Database := hDB;
    TBaseDatabase( Database ).OpenFunctionList( eOptBits, phCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenFunctionArgList (                     { Return "Arguments" for a function }
           hDb           : hDBIDb;                          { Database handle }
           pszFuncName   : PChar;                           { Function name }
           uOverload     : Word;                            { Overload number }
           phCur         : phDBICur                         { Returned cursor on "Arguments" }
         ): DBIResult;
begin
  Try
    Database := hDB;
    TBaseDatabase( Database ).OpenFunctionArgList( pszFuncName, uOverload, phCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CloseDatabase( var hDb : hDBIDb ) : DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).Free;
    hDb    := NIL;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetTableOpenCount (                       {  Get local cursor count }
           hDb            : hDBIDb;                         { Database }
           pszTableName   : PChar;                          { Table name }
           pszDriverType  : PChar;                          { Driver type /NULL }
           var iOpenCount : Word                            { returned number of cursors }
         ): DBIResult;
Var
  i     : Integer;
  P     : TBaseSession;
  Total : Word;
begin
  Try
    iOpenCount := 0;
    ValidateParameter( pszTableName );
    Total := 0;
    For i := 0 to Pred( FSessions.Count ) Do
    begin
      P := FSessions.Items[ i ];
      IOpenCount := 0;
      P.GetTableOpenCount( hDb, pszTableName, pszDriverType, iOpenCount );
      Inc( Total, IOpenCount );
    end;
    iOpenCount := Total;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.UseIdleTime: DBIResult;                   { Use Idle time }
begin
  Try
    TBaseSession( FSession ).UseIdleTime;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetLdObj (                                { Get language driver }
           hCursor       : hDBICur;                         { Cursor handle }
           var   pLdObj  : Pointer                          { Returned language driver object }
         ): DBIResult;
begin
  Try
    If ( hCursor <> NIL ) then
      TBaseTable( hCursor ).GetLdObj( pLdObj )
    else
      TBaseSession( FSession ).GetLdObj( NIL, pLdObj );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetLdName (                               { Get language driver name from table }
           pszDriver     : PChar;                           { Driver name }
           pObjName      : PChar;                           { Name of object, i.e. table name }
           pLdName       : PChar                            { Returned language driver name }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetLdName( pszDriver, pObjName, pLdName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SchemaCacheFlush(                         { Form Full Name }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar                            { Table name }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).SchemaCacheFlush( pszTableName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.FormFullName (                            { Form Full Name }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type /NULL }
           pszFullName   : PChar                            { Returns full name }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).FormFullName( pszTableName, pszDriverType, pszFullName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenTable (                               { Open a table }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name or file name }
           pszDriverType : PChar;                           { Driver type                 /NULL }
           pszIndexName  : PChar;                           { Index to be used for access /NULL }
           pszIndexTagName : PChar;                         { Index tag name              /NULL }
           iIndexId      : Word;                            { Index number                /0 }
           eOpenMode     : DBIOpenMode;                     { Read or RW }
           eShareMode    : DBIShareMode;                    { Excl or Share }
           exltMode      : XLTMode;                         { Xlate mode }
           bUniDirectional : Bool;                          { Uni or Bi directional }
           pOptParams    : Pointer;                         { Optional params /NULL }
           var hCursor   : hDBICur                          { Returns Cursor handle }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenTable(
      pszTableName,
      pszDriverType,
      pszIndexName,
      pszIndexTagName,
      iIndexId,
      eOpenMode,
      eShareMode,
      exltMode,
      bUnidirectional,
      pOptParams,
      hCursor
    );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenNestedTable(                          { Get nested table }
           hCursor       : hDBICur;                         { Master cursor }
           iFieldNo      : Word;                            { FieldID of nested table field }
           bReadOnly     : Bool;                            { if TRUE, read only mode }
           bUniDirectional: Bool;                           { if TRUE, unidirectional }
           var hCursorNested : hDBICur                      { Returns Cursor handle for nested table }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).OpenNestedTable( iFieldNo, bReadOnly, bUniDirectional, hCursorNested );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;

Function TVirtEng.OpenRef(
           hCursor       : hDBICur;                         { Master cursor }
           iFieldNo      : Word;                            { FieldID }
           bReadOnly     : Bool;                            { if TRUE, read only mode }
           bUniDirectional: Bool;                           { If TRUE, Uni directional }
           var hRefCursor : hDBICur                         { Returns Cursor handle for REF }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).OpenRef( iFieldNo, bReadOnly, bUniDirectional, hRefCursor );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;

Function  TVirtEng.DatabaseFlush( hDb : hDBIDb ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).DatabaseFlush;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;

Function TVirtEng.OpenTableList (                           { Open a cursor on "Tables" }
           hDb           : hDBIDb;                          { Database handle }
           bExtended     : Bool;                            { True for extended info }
           bSystem       : Bool;                            { True to include system tables }
           pszWild       : PChar;                           { Wild card name }
           var   hCur    : hDBICur                          { Returned cursor }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenTableList( bExtended, bSystem, pszWild, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenFieldList (                           { Return "Fields" for a table }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           bPhyTypes     : Bool;                            { True, for physical types }
           var   hCur    : hDBICur                          { Returned cursor on "Fields" }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenFieldList( pszTableName, pszDriverType, bPhyTypes, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenFileList (                            { Open a cursor on "Tables" }
           hDb           : hDBIDb;                          { Database handle }
           pszWild       : PChar;                           { Wild card name }
           var   hCur    : hDBICur                          { Returned cursor }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenFileList( pszWild, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function  TVirtEng.GetDriverDesc (                          { Get description for a given type }
            pszDriverType : PChar;                          { Symbolic name for driver type }
            var  drvType  : DRVType                         { Driver type description }
          ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetDriverDesc( pszDriverType, drvType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function  TVirtEng.OpenDriverList (                         { Get a list of driver names }
            var   hCur          : hDBICur                   { Returned cursor }
          ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenDriverList( hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.OpenDatabaseList (                        { Get a list of driver names }
            var   hCur          : hDBICur                   { Returned cursor }
          ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenDatabaseList( hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenIndexList (                           { Return "Indexes" for a table }
      hDb           : hDBIDb;                               { Database handle }
      pszTableName  : PChar;                                { Table name }
      pszDriverType : PChar;                                { Driver type }
var   hCur          : hDBICur                               { Returned cursor on "Indexes" }
   ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).OpenIndexList( pszTableName, pszDriverType, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CloseCursor(
           hCursor : hDBICur
         ) : DBIResult;
begin
  Try
    ValidateHandle( hCursor );
    TBaseTable( hCursor ).CloseTable;
    TBaseTable( hCursor ).Free;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenIndex (                               { Open an index }
           hCursor       : hDBICur;                         { Cursor handle }
           pszIndexName  : PChar;                           { Index Name }
           iIndexId      : Word                             { Index number (if applicable) }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).OpenIndex( pszIndexName, iIndexId );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CloseIndex (                              { Close an index }
           hCursor       : hDBICur;                         { Cursor handle }
           pszIndexName  : PChar;                           { Index Name }
           iIndexId      : Word                             { Index number (if applicable) }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).CloseIndex( pszIndexName, iIndexId );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetCursorForTable(
           hDb           : hDBIDb;
           pszTableName  : PChar;
           pszDriverType : PChar;            { Driver type }
           var hCursor   : hDBICur
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).GetCursorForTable( pszTableName, pszDriverType, hCursor );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CloneCursor(
           hCurSrc : hDBICur;
           bReadOnly : Bool;                                { If TRUE, read only mode }
           bUniDirectional : Bool;
           var hCurNew : hDBICur                            { Destination cursor address }
         ): DBIResult;
begin
  Try
    Cursor := hCurSrc;
    TBaseTable( hCurSrc ).Clone( bReadonly, bUniDirectional, hCurNew );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetToBegin(
           hCursor : hDBICur
         ) : DBIResult;
begin
  TBaseTable( hCursor ).SetToBegin;
  Result := DBIERR_NONE;
end;


Function TVirtEng.SetToEnd( hCursor : hDBICur ) : DBIResult;
begin
  TBaseTable( hCursor ).SetToEnd;
  Result := DBIERR_NONE;
end;


Function TVirtEng.SetToCursor(
           hDest,
           hSrc : hDBICur
         ) : DBIResult;
begin
  Try
    Cursor := hSrc;
    TBaseTable( hSrc ).SetToCursor( hDest );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetBookMark(
           hCur      : hDBICur;
           pBookMark : Pointer
         ) : DBIResult;
begin
  Try
    Cursor := hCur;
    TBaseTable( hCur ).GetBookMark( pBookMark );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetToBookMark(
           hCur      : hDBICur;
           pBookMark : Pointer
         ) : DBIResult;
begin
  Try
    Cursor := hCur;
    TBaseTable( hCur ).SetToBookMark( pBookMark );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CompareBookMarks (
           hCur : hDBICur;
           pBookMark1,
           pBookMark2 : Pointer;
           Var CmpBkmkResult : CmpBkmkRslt
         ): DBIResult;
begin
  Try
    TBaseTable( hCur ).CompareBookMarks( pBookMark1, pBookMark2, CmpBkmkResult );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetRecord (
           hCursor  : hDBICur;
           eLock    : DBILockType;
           pRecBuff : Pointer;
           pRecProps: pRECProps
         ): DBIResult;

begin
  Try
    TBaseTable( hCursor ).GetRecord( eLock, pRecBuff, pRecProps );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetRelativeRecord(
           hCursor    : hDBICur;
           iPosOffset : Longint;
           eLock      : DBILockType;
           pRecBuff   : Pointer;
           pRecProps: pRECProps
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetRelativeRecord( iPosOffset, eLock, pRecBuff, pRecProps );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetNextRecord (
           hCursor  : hDBICur;
           eLock    : DBILockType;
           pRecBuff : Pointer;
           pRecProps: pRECProps
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetNextRecord( eLock, pRecBuff, pRecProps );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetPriorRecord (
           hCursor  : hDBICur;
           eLock    : DBILockType;
           pRecBuff : Pointer;
           pRecProps: pRECProps
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetPriorRecord( eLock, pRecBuff, pRecProps );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
    If ( Result = DBIERR_EOF ) then
      Result := DBIERR_BOF;
  end;
end;


Function TVirtEng.GetRecordForKey (                         { Find a record matching key }
           hCursor       : hDBICur;                         { Cursor handle }
           bDirectKey    : Bool;                            { Key is supplied directly }
           iFields       : Word;                            { No of full fields to match }
           iLen          : Word;                            { Partial key len of last field }
           pKey          : Pointer;                         { Either Record buffer or Key itself }
           pRecBuff      : Pointer                          { (Optional) Record buffer }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetRecordForKey( bDirectKey, iFields, iLen, pKey, pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetVchkDesc (                             { Get valcheck descriptor }
           hCursor       : hDBICur;                         { Cursor handle }
           iValSeqNo     : Word;                            { Valcheck sequence number }
           pvalDesc      : pVCHKDesc                        { Returned valcheck description }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetVchkDesc( iValSeqNo, pvalDesc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetRintDesc (                             { Get referential integrity descriptor }
           hCursor       : hDBICur;                         { Cursor handle }
           iRintSeqNo    : Word;                            { Rint sequence number }
           printDesc     : pRINTDesc                        { Returned rint description }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetRintDesc( iRintSeqNo, printDesc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AcqPersistTableLock (                     { Get a persistent lock }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar                            { Driver type / NULL }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).AcqPersistTableLock( pszTableName, pszDriverType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.RelPersistTableLock (                     { Releases a persistent lock }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar                            { Driver type / NULL }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).RelPersistTableLock( pszTableName, pszDriverType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AcqTableLock (                            { Lock a table }
           hCursor       : hDBICur;                         { Cursor handle }
           eLockType     : DBILockType                      { Lock type }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).AcqTableLock( eLockType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.RelTableLock (                            { Unlocks Table level locks }
           hCursor       : hDBICur;                         { Cursor handle }
           bAll          : Bool;                            { True for all table level locks }
           eLockType     : DBILockType                      { Specific lock type }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).RelTableLock( bAll, eLockType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.RelRecordLock (                           { Releases record level locks }
           hCursor       : hDBICur;                         { Cursor handle }
           bAll          : Bool                             { True for all. Default Current. }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).RelRecordLock( bAll );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.IsRecordLocked (                          { Check if current record is locked }
           hCursor       : hDBICur;                         { Cursor handle }
           var bLocked   : Bool                             { Rec lock status }
   ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).IsRecordLocked( bLocked );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.IsTableLocked (                           { Verify if Table is locked }
           hCursor       : hDBICur;                         { Cursor handle }
           epdxLock      : DBILockType;                     { Lock type to verify }
           var iLocks    : Word                             { Nbr of locks of the given type }
   ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).IsTableLocked( epdxLock, iLocks );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.IsTableShared (                           { Verify if this is a shared table }
           hCursor       : hDBICur;                         { Cursor handle }
           var bShared   : Bool                             { Shared status }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).IsTableShared( bShared );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.InitRecord (
           hCursor  : hDBICur;
           pRecBuff : Pointer
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).InitRecord( pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.InsertRecord (
           hCursor  : hDBICur;
           eLock    : DBILockType;
           pRecBuff : Pointer
         ) : DBIResult;
begin
  Try
    TBaseTable( hCursor ).InsertRecord( eLock, pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AppendRecord (
           hCursor : hDBICur;
           pRecBuff : Pointer
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).AppendRecord( pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ModifyRecord (
           hCursor   : hDBICur;
           pRecBuff  : Pointer;
           bFreeLock : Bool
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).ModifyRecord( pRecBuff, bFreeLock );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DeleteRecord (
           hCursor  : hDBICur;
           pRecBuff : Pointer
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).DeleteRecord( pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.UnDeleteRecord ( hCursor : hDBICur ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).UnDeleteRecord;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ReadBlock (
           hCursor : hDBICur;
           var iRecords : Longint;
           pBuf : Pointer
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).ReadBlock( iRecords, pBuf );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.WriteBlock (
           hCursor : hDBICur;
           var iRecords : Longint;
           pBuf : Pointer
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).WriteBlock( iRecords, pBuf );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetSeqNo (                                { Get logical record number }
           hCursor       : hDBICur;                         { Cursor handle }
           var iSeqNo    : Longint                          { Pointer to sequence number }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetSeqNo( iSeqNo );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetToSeqNo (                              { Position to a logical record number }
           hCursor       : hDBICur;                         { Cursor handle }
           iSeqNo        : Longint                          { Sequence number }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).SettoSeqNo( iSeqNo );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetField(                                 { Get Field value }
           hCursor       : hDBICur;                         { Cursor }
           iField        : Word;                            { Field # (1..n) }
           pRecBuff      : Pointer;                         { Record buffer }
           pDest         : Pointer;                         { Destination field buffer }
           var bBlank    : Bool                             { Returned : is field blank }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetField( iField, pRecBuff, PDest, bBlank );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.PutField (                                { Put a value in the record buffer }
           hCursor       : hDBICur;                         { Cursor }
           iField        : Word;                            { Field # (1..n) }
           pRecBuff      : Pointer;                         { Record buffer }
           pSrc          : Pointer                          { Source field buffer }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).PutField( iField, pRecBuff, PSrc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.VerifyField (                             { Verifies the field value }
           hCursor       : hDBICur;                         { Cursor }
           iField        : Word;                            { Field # (1..n) }
           pSrc          : Pointer;                         { Field Value }
           var bBlank    : Bool                             { Field is Blank (Returned) }
   ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).VerifyField( iField, pSrc, bBlank );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenBlob (                                { Open a blob for access }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuf       : Pointer;                         { Record Buffer }
           iField        : Word;                            { Field number (1..n) }
           eOpenMode     : DBIOpenMode                      { Open for Read or RW }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).OpenBlob( pRecBuf, iField, eOpenMode );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetBlobSize (                             { Get Blob Size }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuf       : Pointer;                         { Record Buffer }
           iField        : Word;                            { Field number (1..n) }
           var iSize     : Longint                          { returned size }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetBlobSize( pRecBuf, iField, iSize );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetBlob (                                 { Read bytes from blob }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuf       : Pointer;                         { Record Buffer }
           iField        : Word;                            { Field number of blob (1..n) }
           iOffSet       : Longint;                         { Starting position   }
           iLen          : Longint;                         { No of bytes to be read   }
           pDest         : Pointer;                         { Destination }
           var iRead     : Longint                          { Actual no of bytes read }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetBlob( precBuf, iField, iOffset, iLen, pDest, iRead );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.PutBlob (                                 { Write bytes to blob }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuf       : Pointer;                         { Record Buffer }
           iField        : Word;                            { Field number of blob (1..n) }
           iOffSet       : Longint;                         { Starting position   }
           iLen          : Longint;                         { No of bytes to put   }
           pSrc          : Pointer                          { pntr to Source }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).PutBlob( pRecBuf, iField, iOffset, iLen, pSrc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.TruncateBlob (                            { Reduces the blob size }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuf       : Pointer;                         { Record Buffer }
           iField        : Word;                            { Field number of blob (1..n) }
           iLen          : Longint                          { New blob length }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).TruncateBlob( pRecBuf, iField, iLen );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.FreeBlob (                                { Free the Blob }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuf       : Pointer;                         { Record Buffer }
           iField        : Word                             { Field number of blob (1..n) }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).FreeBlob( pRecBuf, iField );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetBlobHeading (                          { Get Blob Heading }
           hCursor       : hDBICur;                         { Cursor handle }
           iField        : Word;                            { Field number of blob (1..n) }
           pRecBuf       : Pointer;                         { Record buffer of owner record }
           pDest         : Pointer                          { Destination buffer }
          ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetBlobHeading( iField, pRecBuf, pDest );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetFieldMap (                             { Set a fieldmap }
           hCur          : hDBICur;                         { Cursor handle }
           iFields       : Word;                            { Number of fields }
           pFldDesc      : pFLDDesc                         { Array of field descriptions }
         ): DBIResult;
begin
  Try
    TBaseTable( hCur ).SetFieldMap( iFields, pFldDesc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.BeginTran (                               { Begin a transaction }
           hDb           : hDBIDb;                          { Database handle }
           eXIL          : eXILType;                        { Transaction isolation level }
           var hXact     : hDBIXact                         { Returned Xact handle }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).BeginTran( eXIL, hXact );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.EndTran (                                 { End a transaction }
           hDb           : hDBIDb;                          { Database handle }
           hXact         : hDBIXact;                        { Xact handle }
           eEnd          : eXEnd                            { Xact end type }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).EndTran( hXact, eEnd );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetTranInfo (                             { Get transaction info }
           hDb           : hDBIDb;                          { Database handle }
           hXact         : hDBIXact;                        { Xact handle }
           pxInfo        : pXInfo                           { Xact info }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).GetTranInfo( hXact, pxInfo );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetEngProp (                              { Get property }
           hObj          : hDBIObj;                         { Object handle }
           iProp         : Longint;                         { Property to retrieve }
           PropValue     : Pointer;                         { == NULL, validate iProp for getting }
           iMaxLen       : Word;                            { Length of buffer pPropValue }
           var   iLen    : Word                             { Returns required length }
         ): DBIResult;
begin
  iLen := 0;
  Try
    if Assigned( hObj ) then
    begin
      TBapiListItem( hObj ).GetProp( iProp, PropValue, iMaxLen, iLen );
      Result := DBIERR_NONE;
    end
    else
      Result := DBIERR_INVALIDPARAM;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetEngProp (                              { Set property }
           hObj          : hDBIObj;                         { Object handle }
           iProp         : Longint;                         { Property to retrieve }
           PropValue     : Longint                          { == NULL, validate iProp for getting }
         ): DBIResult;
begin
  Try
    if Assigned( hObj ) then
    begin
      TBapiListItem( hObj ).SetProp( iProp, PropValue );
      Result := DBIERR_NONE;
    end
    else
      Result := DBIERR_INVALIDPARAM;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ValidateEngProp (                         { Validate a property }
           hObj          : hDBIObj;                         { Object handle }
           iProp         : Longint;                         { property to validate }
           bSetting      : Bool                             { TRUE:setting, FALSE:getting }
         ): DBIResult;
begin
  Try
    If Assigned( hObj ) then
    begin
      TBapiListItem( hObj ).ValidateProp( iProp, bSetting );
      Result := DBIERR_NONE;
    end
    else
      Result := DBIERR_INVALIDHNDL;
  Except
    Result := CleanupException;
  end;
end;


Procedure TVirtEng.GetProp (                                { Get property }
           iProp         : Longint;                         { Property to retrieve }
           PropValue     : Pointer;                         { == NULL, validate iProp for getting }
           iMaxLen       : Word;                            { Length of buffer pPropValue }
           var   iLen    : Word                             { Returns required length }
         );
begin
    Case iProp of
      clSQLRESTRICT:
      begin
        iLen      := SizeOf( FStartFlags );
        Move( PropValue^,  FStartFlags, iLen );
      end;
    else
      Inherited GetProp( iProp, PropValue, iMaxLen, iLen );
    end;
end;


Procedure TVirtEng.SetProp (                                { Set property }
           iProp         : Longint;                         { Property to retrieve }
           PropValue     : Longint                          { == NULL, validate iProp for getting }
         );
begin
  Case iProp of
    clSQLRESTRICT:
      FStartFlags := PropValue;
  else
    Inherited SetProp( iProp, PropValue );
  end;
end;


Function TVirtEng.GetObjFromObj( Source : hDBIObj; eObjType : DBIOBJType; var hObj : hDBIObj ) : DBIResult;
begin
  If ( eObjType = objSESSION ) then
  begin
    hObj   := hDBIObj( TBaseDatabase( Source ).Parent );
    Result := DBIERR_NONE;
  end
  else
  begin
    hObj   := NIL;
    Result := DBIERR_INVALIDPARAM;
  end;
end;


Function TVirtEng.GetObjFromName (                          { Get object from name }
           eObjType      : DBIOBJType;                      { Object handle }
           pszObjName    : PChar;                           { Name of object /NULL }
           var hObj      : hDBIObj                          { Returned object handle }
         ): DBIResult;
begin
{ PGB - This may need work }
  If ( eObjType = objCLIENT ) and ( pszObjName = NIL ) then
  begin
    hObj   := hDBIObj( Self );
    Result := DBIERR_NONE;
  end
  else
  begin
    hObj   := NIL;
    Not_Supported( fnGETOBJFROMNAME );
    Result := DBIERR_NOTSUPPORTED;
  end;
end;


Function TVirtEng.GetCursorProps (
           hCursor      : hDBICur;
           var curProps : CURProps
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetCursorProps( curProps );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetFieldDescs(
           hCursor  : hDBICur;
           pfldDesc : pFLDDesc
         ) : DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetFieldDescs( pFldDesc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetRecordCount(
           hCursor : hDBICur;
           Var iRecCount : Longint
         ) : DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetRecordCount( iRecCount );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetExactRecordCount(
           hCursor : hDBICur;
           Var iRecCount : Longint
         ) : DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetExactRecordCount( iRecCount );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetToRecordNo (                           { Position to Physical Rec# }
           hCursor       : hDBICur;                         { Cursor handle }
           iRecNo        : Longint                          { Physical record number }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).SetToRecordNo( iRecNo );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SaveChanges (                             { flush all buffered changes }
           hCursor       : hDBICur                          { Cursor handle }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).SaveChanges;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ForceReread (                             { reread buffered data }
           hCursor       : hDBICur                          { Cursor handle }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).ForceReread;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.ForceRecordReread (                       { reread buffered data }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuff      : Pointer
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).ForceRecordReread( pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CheckRefresh : DBIResult;
begin
  Try
    TBaseSession( FSession ).CheckRefresh;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenLockList (                            { Get a list of locks }
           hCursor       : hDBICur;                         { Cursor handle }
           bAllUsers     : Bool;                            { True, for all Users locks }
           bAllLockTypes : Bool;                            { True, for all lock types }
           var hLocks    : hDBICur                          { Returned cursor on Lock list }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).OpenLockList( bAllUsers, bAllLockTypes, hLocks );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.OpenUserList (                            { Get a list of users loggedin }
           var hUsers : hDBICur                             { Returned cursor on user list }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenUserList( hUsers );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetLockRetry (                            { Set Lock wait time }
           iWait         : SmallInt                         { Time in seconds }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).LockRetry := iWait;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.BatchMove (                               { Copy records to destination table }
           pSrcTblDesc          : pBATTblDesc;              { Source table identification, }
           hSrcCur              : hDBICur;                  {  OR source cursor  ( one must be NULL ) }
           pDstTblDesc          : pBATTblDesc;              { Destination table identification, }
           hDstCur              : hDBICur;                  {  OR destination cursor ( one must be NULL ) }
           ebatMode             : eBATMode;                 { Batch mode }
           iFldCount            : Word;                     { size of field maps }
           pSrcFldMap           : PWord;                    { Array of source field numbers }
           pszIndexName         : PChar;                    { If update mode, used to match records }
           pszIndexTagName      : PChar;                    { Index tag name }
           iIndexId             : Word;                     { Index  id }
           pszKeyviolName       : PChar;                    { Keyviol table name  (optional) }
           pszProblemsName      : PChar;                    { Problems table name (optional) }
           pszChangedName       : PChar;                    { Changed table name (optional) }
           lProbRecs            : PLongint;                 { Number of records to read from source }
           lKeyvRecs            : PLongint;                 { Number of records to read from source }
           lChangedRecs         : PLongint;                 { Number of records to read from source }
           bAbortOnFirstProb    : Bool;                     { If TRUE, abort on first problem rec }
           bAbortOnFirstKeyviol : Bool;                     { If TRUE, abort on first keyviol rec }
           var lRecsToMove      : Longint;                  { Number of records to read from source }
           bTransliterate       : Bool                      { If TRUE, transliterate character data }
         ): DBIResult;
begin
  Not_Supported( fnBATCHMOVE );
  Result := DBIERR_NOTSUPPORTED;
end;


Function TVirtEng.CopyTable (                               { Copy one table to another }
           hDb           : hDBIDb;                          { Database handle }
           bOverWrite    : Bool;                            { True, to overwrite existing file }
           pszSrcTableName : PChar;                         { Source table name }
           pszSrcDriverType : PChar;                        { Source driver type }
           pszDestTableName : PChar                         { Destination table name }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDB ).CopyTable( bOverWrite, pszSrcTableName, pszSrcDriverType, pszDestTableName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.MakePermanent (                           { Make temporary table permanent }
           hCursor       : hDBICur;                         { Cursor handle }
           pszName       : PChar;                           { Rename temporary table }
           bOverWrite    : Bool                             { Overwrite existing file }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).MakePermanent( pszName, bOverWrite );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetRange (                                { Set cursor to a range }
           hCursor       : hDBICur;                         { Cursor }
           bKeyItself    : Bool;                            { Whether Key or Record buffer }
           iFields1      : Word;                            { Key fields to be mathced in full }
           iLen1         : Word;                            { Key length to compare }
           pKey1         : Pointer;                         { Top/Left key in Range }
           bKey1Incl     : Bool;                            { If Inclusive of Key1 }
           iFields2      : Word;                            { Key fields to be mathced in full }
           iLen2         : Word;                            { Key length to compare }
           pKey2         : Pointer;                         { Bottom/Right key in Range }
           bKey2Incl     : Bool                             { If Inclusive of Key2 }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).SetRange( bKeyItself, iFields1, iLen1, pKey1, bKey1Incl,
      iFields2, iLen2, pKey2, bKey2Incl );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ResetRange(
           hCursor : hDBICur
         ) : DBIResult;
begin
  Try
    TBaseTable( hCursor ).ResetRange;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CompareKeys (                             { Compare two keys }
           hCursor       : hDBICur;                         { Cursor handle }
           pKey1         : Pointer;                         { Key buffer 1 to compare }
           pKey2         : Pointer;                         { Key buffer 2 (Or NULL) }
           iFields       : Word;                            { Fields to compare in full }
           iLen          : Word;                            { Partial key to compare }
           var iResult   : SmallInt                         { Compare result }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).CompareKeys( Pointer( pKey1 ), Pointer( pKey2 ), Word( iFields),
      Word( iLen ), SmallInt( iResult ) );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SwitchToIndex (
           hCursor : hDBICur;
           pszIndexName,
           pszTagName : PChar;
           iIndexId : Word;
           bCurrRec : Bool
         ) : DBIResult;
begin
  Try
    TBaseTable( hCursor ).SwitchToIndex( pszIndexName, pszTagName, iIndexId, bCurrRec );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetToKey (                                { Set key condition }
           hCursor       : hDBICur;                         { Cursor handle }
           eSearchCond   : DBISearchCond;                   { Search condition (default is =) }
           bDirectKey    : Bool;                            { Key is supplied directly }
           iFields       : Word;                            { No of full fields to match }
           iLen          : Word;                            { Partial key len of last field }
           pBuff         : Pointer                          { Either Record buffer or Key itself }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).SetToKey( eSearchCond, bDirectKey, iFields, iLen, pBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ExtractKey (                              { Get the key value of current record }
           hCursor       : hDBICur;                         { Cursor handle }
           pRecBuf       : Pointer;                         { Record buffer (optional) }
           pKeyBuf       : Pointer                          { Returned. Key bytes. }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).ExtractKey( pRecBuf, pKeyBuf );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetIndexDesc (                            { Get index properties }
           hCursor       : hDBICur;                         { Cursor handle }
           iIndexSeqNo   : Word;                            { Index number }
           var idxDesc   : IDXDesc                          { Returned index description }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetIndexDesc( iIndexSeqNo, idxDesc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.GetIndexDescs (                           { Get index properties }
           hCursor       : hDBICur;                         { Cursor handle }
           idxDesc       : PIDXDesc                         { Returned index description }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetIndexDescs( idxDesc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetIndexForField (                        { Get index properties }
           hCursor       : hDBICur;                         { Cursor handle }
           iFld          : Word;                            { Field Number (1..N) }
           bProdTagOnly  : Bool;                            { If TRUE, only xBASE prod tags will be returned }
           var idxDesc   : IDXDesc                          { Returned index description }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetIndexForField( iFld, bProdTagOnly, idxDesc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetIndexSeqNo (                           { Get index sequence number }
           hCursor       : hDBICur;                         { Cursor handle }
           pszIndexName  : PChar;                           { Index name }
           pszTagName    : PChar;                           { Tag name (if applicable) }
           iIndexId      : Word;                            { Index number }
           var iIndexSeqNo  : Word                          { Index number }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).GetIndexSeqNo( pszIndexName, pszTagName, iIndexId, iIndexSeqNo );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DeleteTable (                             { Delete a table }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Name including any path }
           pszDriverType : PChar                            { Driver type /NULL }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDB ).DeleteTable( pszTableName, pszDriverType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.EmptyTable (                              { Deletes all records }
           hDb           : hDBIDb;                          { Database handle }
           hCursor       : hDBICur;                         { Cursor (OR) }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar                            { Driver type /NULL }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).EmptyTable( hCursor, pszTableName, pszDriverType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.PackTable (                               { Deletes all records }
           hDb           : hDBIDb;                          { Database handle }
           hCursor       : hDBICur;                         { Cursor (OR) }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type /NULL }
           bRegenIdxs    : Bool                             { Regenerate Indexes }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).PackTable( hCursor, pszTableName, pszDriverType, bRegenIdxs );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.RegenIndex (                              { Regenerate an index }
           hDb           : hDBIDb;                          { Database handle }
           hCursor       : hDBICur;                         { Cursor (OR) }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type /NULL }
           pszIndexName  : PChar;                           { Index name }
           pszIndexTagName : PChar;                         { Index tagname (xbase MDX) }
           iIndexId      : Word                             { Index number }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).RegenIndex( hCursor, pszTableName, pszDriverType, pszIndexName,
      pszIndexTagName, iIndexId );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.RegenIndexes (                            { Regenerate all indexes }
           hCursor       : hDBICur                          { Cursor }
         ): DBIResult;
begin
  Try
    TBaseTable( hCursor ).RegenIndexes;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SortTable (                               { Sort table }
           hDb           : hDBIDb;                          { Database handle }
           pszTableName  : PChar;                           { Table name of source }
           pszDriverType : PChar;                           { Driver type /NULL }
           hSrcCur       : hDBICur;                         { OR cursor of table to sort }
           pszSortedName : PChar;                           { Destination table (NULL if sort to self) }
           phSortedCur   : phDBICur;                        { If non-null, return cursor on destination }
           hDstCur       : hDBICur;                         { OR cursor of destination }
           iSortFields   : Word;                            { Number of sort fields }
           piFieldNum    : PWord;                           { Array of field numbers }
           pbCaseInsensitive : PBool;                       { Which fields should sort c-i (Opt) }
           pSortOrder    : pSORTOrder;                      { Array of Sort orders (Opt) }
           ppfSortFn     : ppfSORTCompFn;                   { Array of compare fn pntrs (Opt) }
           bRemoveDups   : Bool;                            { TRUE : Remove duplicates }
           hDuplicatesCur : hDBICur;                        { Cursor to duplicates table (Opt) }
           var lRecsSort : Longint                          { in/out param. - sort this number }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).SortTable(
      pszTableName,                               { Table name of source }
      pszDriverType,                              { Driver type /NULL }
      hSrcCur,                                    { OR cursor of table to sort }
      pszSortedName,                              { Destination table (NULL if sort to self) }
      phSortedCur,                                { If non-null, return cursor on destination }
      hDstCur,                                    { OR cursor of destination }
      iSortFields,                                { Number of sort fields }
      piFieldNum,                                 { Array of field numbers }
      pbCaseInsensitive,                          { Which fields should sort c-i (Opt) }
      pSortOrder,                                 { Array of Sort orders (Opt) }
      ppfSortFn,                                  { Array of compare fn pntrs (Opt) }
      bRemoveDups,                                { TRUE : Remove duplicates }
      hDuplicatesCur,                             { Cursor to duplicates table (Opt) }
      lRecsSort                                   { in/out param. - sort this number }
    );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CreateTable (                             { Create a new table }
           hDb           : hDBIDb;                          { Database handle }
           bOverWrite    : Bool;                            { True, to overwrite existing file. }
           var crTblDsc  : CRTblDesc                        { Table description }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).CreateTable( bOverwrite, crTblDsc );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CreateInMemTable (                        { Create a temporary table (Logical) }
           hDb           : hDBIDb;                          { Database handle }
           pszName       : PChar;                           { Logical Name }
           iFields       : Word;                            { No of fields }
           pfldDesc      : pFLDDesc;                        { Array of field descriptors }
           var hCursor   : hDBICur                          { Returned cursor handle }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).CreateInMemTable( pszName, iFields, pFldDesc, hCursor );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CreateTempTable (                         { Create temporary table (Physical) }
           hDb           : hDBIDb;                          { Database handle }
           var crTblDsc  : CRTblDesc;                       { Table description }
           var hCursor   : hDBICur                          { Returned cursor on table }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).CreateTempTable( crTblDsc, hCursor );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DoRestructure (                           { Restructure a table }
           hDb           : hDBIDb;                          { Database handle }
           iTblDescCount : Word;                            { Number of table descriptors (1) }
           pTblDesc      : pCRTblDesc;                      { Array of table descs }
           pszSaveAs     : PChar;                           { Restructure to this table }
           pszKeyviolName : PChar;                          { Keyviol table name  (optional) }
           pszProblemsName : PChar;                         { Problems table name (optional) }
           bAnalyzeOnly  : Bool                             { Analyze restructure }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).DoRestructure( iTblDescCount, pTblDesc, pszSaveAs,
      pszKeyviolName, pszProblemsName, bAnalyzeOnly );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.RenameTable (                             { Rename table & family }
           hDb           : hDBIDb;                          { Database handle }
           pszOldName    : PChar;                           { Old name }
           pszDriverType : PChar;                           { Driver type /NULL }
           pszNewName    : PChar                            { New name }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).RenameTable( pszOldName, pszDriverType, pszNewName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AddIndex (                                { Add a new index }
           hDb           : hDBIDb;                          { Database handle }
           hCursor       : hDBICur;                         { Cursor (OR) }
           pszTableName  : PChar;                           { Table name including any path }
           pszDriverType : PChar;                           { Driver type /NULL }
           var   IdxDesc : IDXDesc;                         { Description of the index }
           pszKeyviolName : PChar                           { Keyviol table name (optional) }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDB ).AddIndex( hCursor, pszTableName, pszDriverType, idxDesc, pszKeyViolName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DeleteIndex (                             { Delete index }
           hDb           : hDBIDb;                          { Database handle }
           hCursor       : hDBICur;                         { Cursor (OR) }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type /NULL }
           pszIndexName  : PChar;                           { Index name }
           pszIndexTagName : PChar;                         { Index tagname (xbase MDX) }
           iIndexId      : Word                             { Index number }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDB ).DeleteIndex( hCursor, pszTableName, pszDriverType, pszIndexName, pszIndexTagName, iIndexId );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.SetDirectory(
           hDb    : hDBIDb;
           pszDir : PChar
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).SetDirectory( pszDir );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetDirectory(
           hDb      : hDBIDb;
           bDefault : Bool;
           pszDir   : PChar
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hDb ).GetDirectory( bDefault, pszDir );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetSysVersion(
           var s : SysVersion
         ) : DBIResult;
begin
  MoveZero( s, SizeOf( s ) );
  With s do
  begin
    iVersion    := ENG_VERSION;                             { Engine version }
    iIntfLevel  := CLI_LEVEL;                               { Client Interface level }
  end;
  Result := DBIERR_NONE;
end;


Function TVirtEng.GetSysConfig(
           var s : SysConfig
         ) : DBIResult;
begin
  Try
    TBaseSession( FSession ).GetSysConfig( s );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetClientInfo(
           var s : clientInfo
         ) : DBIResult;
begin
  Try
    TBaseSession( FSession ).GetClientInfo( s );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.LoadDriver (                              { Load a given driver }
           pszDriverType : PChar                            { Driver name }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).LoadDriver( pszDriverType );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetSysInfo( var s : SysInfo ) : DBIResult;
begin
  Try
    TBaseSession( FSession ).GetSysInfo( s );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetSesInfo(
           var s : SesInfo
         ) : DBIResult;
begin
  Try
    TBaseSession( FSession ).GetSesInfo( s );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AddPassword (                             { Add a password to current session }
           pszPassword   : PChar                            { Password }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).AddPassword( pszPassword );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DropPassword (                            { Add a password to current session }
           pszPassword   : PChar                            { Password }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).DropPassword( pszPassword );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetNetUserName (                          { Get network username }
           pszNetUserName : PChar                           { Returns username }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).GetNetUserName( pszNetUserName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.AddAlias (                                { Add a new alias }
           hCfg          : hDBICfg;                         { NULL }
           pszAliasName  : PChar;                           { Alias name }
           pszDriverType : PChar;                           { Driver type for alias }
           pszParams     : PChar;                           { Optional parameters }
           bPersist      : Bool                             { Persistent or session relative }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).AddAlias( hCfg, pszAliasName, pszDriverType, pszParams, bPersist );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DeleteAlias (                             { Add a new alias }
           hCfg          : hDBICfg;                         { NULL }
           pszAliasName  : PChar                            { Alias name }
          ): DBIResult;
begin
  Try
    TBaseSession( FSession ).DeleteAlias( hCfg, pszAliasName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;

Function TVirtEng.AddTitanAlias (                           { Add a new alias }
           pszAliasName  : PChar;                           { Alias name }
           pszParams     : PChar                            { Optional parameters }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).AddTitanAlias( pszAliasName, pszParams );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DeleteTitanAlias (                        { Add a new alias }
           pszAliasName  : PChar                            { Alias name }
          ): DBIResult;
begin
  Try
    TBaseSession( FSession ).DeleteTitanAlias( pszAliasName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;

Function TVirtEng.OpenCfgInfoList (                         { Open a cursor on "Config" }
           hCfg          : hDBICfg;                         { NULL }
           eOpenMode     : DBIOpenMode;                     { ReadWrite or readonly }
           eConfigMode   : CFGMode;                         { Config mode }
           pszCfgPath    : PChar;                           { Path }
           var   hCur    : hDBICur                          { Returned cursor }
         ): DBIResult;
Var
  NewDbCfgPath : DBIPATH;
  Dummy        : Boolean;
begin
  Try
    SetSessionFromDB( pszCfgPath, NIL, 0, NIL, NIL, @NewDbCfgPath, Dummy );
    TBaseSession( FSession ).OpenCfgInfoList( hCfg, eOpenMode, eConfigMode,
      @NewDbCfgPath, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.ImportODBC(                               { Import current ODBC drivers and data sources }
           hCfg          : hDBICfg;                         { NULL }
           bPersist      : Bool                             { Persistent or session relative }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).ImportODBC( hCfg, bPersist );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;

Function TVirtEng.AddDriver(                                { Add a new driver }
           hCfg          : hDBICfg;                         { NULL }
           pszDriverName : PChar;                           { Driver name }
           pszParams     : PChar;                           { Optional parameters }
           bPersist      : Bool                             { Persistent or session relative }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).AddDriver( hCfg, pszDriverName, pszParams, bPersist );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.DeleteDriver(                             { Delete a driver }
           hCfg          : hDBICfg;                         { NULL }
           pszDriverName : PChar;                           { Driver name }
           bSave         : Bool                             { Save config file }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).DeleteDriver( hCfg, pszDriverName, bSave );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.SetPrivateDir(
           pszDir : PChar
         ) : DBIResult;
begin
  Try
    if ( FSession <> NIL ) then
      TBaseSession( FSession ).SetPrivateDir( pszDir );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.GetErrorEntry (                           { Get error entry }
           uEntry        : Word;                            { Error stack entry }
           var ulNativeError : Longint;                     { Returned. Native error code, if any }
           pszError      : PChar                            { Returned. Error string, if any }
         ): DBIResult;
Var
  ErrorEntry : TErrorStackEntry;
  i          : Integer;
  tmp        : String;
  Buffer     : DBIMSG;

  Procedure AddMessage( P : pChar );
  begin
    If ( StrLen( P ) > 0 ) then
      If ( Tmp <> '' ) then
        Tmp := Tmp + #13#10 + StrPas( P )
      else
        Tmp := StrPas( P );
  end;

begin
  If ( FErrorStack.GetError( uEntry, ErrorEntry ) ) then
  begin
    tmp := '';
    With ErrorEntry do
    begin
      Result        := BasicInfo.iError;
      ulNativeError := NativeError;
      If ( NativeError <> 0 ) then
        AddMessage( @ErrorEntry.NativeMessage );
      If ( BasicInfo.iError <> 0 )then
      begin
        If ( Abs( NativeError ) = BasicInfo.iError ) then
          StrCopy( @Buffer, 'DBI Error Code = ' )
        else
          MoveZero( Buffer, SizeOf( Buffer ) );
        StrCat( @Buffer, @BasicInfo.szErrCode );
        AddMessage( @Buffer );
      end;
      For i := Low( BasicInfo.szContext ) to High( BasicInfo.szContext ) do
        AddMessage( @BasicInfo.szContext[ i ] );
    end;
    StrLCopy( pszError, pChar( tmp ), SizeOf( DBIPATH ) - 1  );
  end
  else
    Result := DBIERR_NONE;
end;


Function TVirtEng.GetErrorString (                          { Get message for error code }
           rslt          : DBIResult;                       { Engine error code }
           pszError      : PChar                            { Error string for the error }
         ): DBIResult;
Var
  Count  : Word;
  Native : LongInt;
begin
  Count := 1;
  Repeat
    Result := GetErrorEntry( Count, Native, pszError );
    If ( Result = rslt ) then
    begin
      Result := DBIERR_NONE;
      Exit;
    end
    else
      pszError^ := #0;
    Inc( Count );
  until ( Count > MAX_STACK_SIZE );
  if ( pszError <> NIL ) then
    pszError^ := #0;
  Result := rslt;
end;


Function TVirtEng.GetErrorContext (                         { Get specific Context if available }
           eContext      : SmallInt;                        { Context type }
           pszContext    : PChar                            { Context string (MAXMSGLEN +1) }
         ): DBIResult;
begin
  Result := DBIERR_NOTSUPPORTED;
end;


Function TVirtEng.GetErrorInfo (                            { Return info on last error }
           bFull         : Bool;                            { If Full details }
           var   ErrInfo : DBIErrInfo                       { Error Info }
          ): DBIResult;
Var
  ErrorEntry : TErrorStackEntry;
begin
  MoveZero( ErrInfo, Sizeof( ErrInfo ) );
  if ( FErrorStack.GetError( 1, ErrorEntry ) ) then
  begin
    With ErrInfo do
    begin
      iError := ErrorEntry.BasicInfo.iError;
      StrLCopy( @szErrCode, @ErrorEntry.NativeMessage, SizeOf( szErrCode ) - 1 );
    end;
  end;
  Result := DBIERR_NONE;
end;


Function TVirtEng.DebugLayerOptions (                       { Get SDK debug layer options }
           iOption       : Word;                            { Option }
           pDebugFile    : PChar
         ): DBIResult;
begin
  Result := DBIERR_NOTSUPPORTED;
end;


Function TVirtEng.OpenConfigFile (                          { Open/Create configuration }
           pszDirPath    : PChar;                           { Directory }
           bCreate       : Bool;                            { TRUE to create/overwrite }
           var hCfg      : hDBICfg                          { Handle to config }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).OpenConfigFile( pszDirPath, bCreate, hCfg );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CloseConfigFile (                         { Close the config file }
           var hCfg      : hDBICfg;                         { Handle }
           bSave         : Bool;                            { To save the changes }
           bDefault      : Bool                             { To make this file the default }
           ;
           bSaveAs16     : Bool                             { To save as a 16-bit config file }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CloseConfigFile( hCfg, bSave, bDefault, bSaveAs16 );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgSave (                                 { Save current configuration }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszNewFile    : PChar                            { (Optional): Save as this file }
           ;
           bSaveAs16     : Bool                             { To save as a 16-bit config file }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgSave( hCfg, pszNewFile, bSaveAs16 );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgBuildPath (                            { Build a path for accessing config. }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszCategory   : PChar;                           { NULL for root }
           pszGroup      : PChar;                           { NULL for no group }
           pszSection    : PChar;                           { NULL fro no section }
           pszCfgPath    : PChar                            { Returned path }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgBuildPath( hCfg, pszCategory, pszGroup, pszSection, pszCfgPath );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgPosition (                             { Position the config path }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszCfgPath    : PChar                            { Path }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgPosition( hCfg, pszCfgPath );
    Result := DBIERR_NONE;
  Except
    On E:ETitanEngineError do
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgGetNextNode (                          { Get next defined node }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszNodeName   : PChar                            { Node name (Returned) }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgGetNextNode( hCfg, pszNodeName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgGetRecord (                            { Get a record }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszCfgPath    : PChar;                           { Path }
           var iFields   : Word;                            { Returned nbr of fields }
           pfldDesc      : pFLDDesc;                        { Field descriptors }
           pRec          : Pointer                          { Field values }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgGetRecord( hCfg, pszCfgPath, iFields, pFldDesc, pRec );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgAddRecord (                            { Add a record }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszCfgPath    : PChar;                           { Path }
           iFields       : Word;                            { No of fields }
           pfldDesc      : pFLDDesc;                        { Field descriptors }
           pRec          : Pointer                          { Data values }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgAddRecord( hCfg, pszCfgPath, iFields, pFldDesc, pRec );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgModifyRecord (                         { Modify a record }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszCfgPath    : PChar;                           { Path }
           iFields       : Word;                            { Nbr of fields }
           pfldDesc      : pFLDDesc;                        { Field descriptors }
           pRec          : Pointer                          { Data values }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgModifyRecord( hCfg, pszCfgPath, iFields, pFldDesc, pRec );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgDropRecord (                           { Delete a record }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszCfgPath    : PChar                            { Path }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgDropRecord( hCfg, pszCfgPath );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgTranslate (                            { Translate configuration string }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszConfigPath : PChar;                           { configuration path }
           pszTrans      : PChar;                           { translated path }
           iFields       : Word;                            { number of fields, 0 if path only }
           pfldDesc      : pFLDDesc;                        { field descriptors, NULL if path only }
           pRec          : Pointer                          { record buffer, NULL if path only }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgTranslate( hCfg, pszConfigPath, pszTrans, iFields, pFldDesc, pRec );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgGetHelp (                              { Get help message }
           hCfg          : hDBICfg;                         { Config Handle/NULL }
           pszConfigPath : PChar;                           { configuration path }
           pszFldName    : PChar;                           { field name  ( optional ) }
           pszHelpString : PChar                            { help string ( returned ) }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgGetHelp( hCfg, pszConfigPath, pszFldName, pszHelpString );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.CfgMerge (                                { Merge config files }
           hCfgDest      : hDBICfg;                         { Destination Cfg handle/ NULL }
           hCfgSrc       : hDBICfg;                         { Source Cfg handle/ NULL }
           pszSrcPath    : PChar                            { Source Path / NULL }
         ): DBIResult;
begin
  Try
    TBaseSession( FSession ).CfgMerge( hCfgDest, hCfgSrc, pszSrcPath );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.QExecDirect (                             { Execute query  }
           hDb           : hDBIDb;                          { Database handle }
           eQryLang      : DBIQryLang;                      { Query language }
           pszQuery      : PChar;                           { Query }
           phCur         : phDBICur                         { Returned cursor on result set }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hdb ).QExecDirect( eQryLang, pszQuery, phCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QAlloc(                                   { Allocates a statement handle  }
           hDb           : hDBIDb;                          { Database handle }
           eQryLang      : DBIQryLang;                      { Query language }
           var hStmt     : hDBIStmt                         { Returned statment handle }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hdb ).QAlloc( eQryLang, hStmt );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QPrepare (                                { Prepare a query }
           hStmt         : hDBIStmt;                        { Returned statment handle }
           pszQuery      : PChar                            { Query }
         ): DBIResult;
begin
  Try
    Database := hDBIDB( TBapiListItem( hStmt ).Parent );
    TBaseDatabase( Database ).QPrepare( hStmt, pszQuery );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.QExec (                                   { Execute prepared query }
           hStmt         : hDBIStmt;                        { Statement handle }
           phCur         : phDBICur                         { Returned handle on result set }
         ): DBIResult;
begin
  Try
    Statement := hStmt;
    TSqlStmt( hStmt ).QExec( phCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QPrepareExt (                             { Prepare a query }
           hDb           : hDBIDb;                          { Database handle }
           eQryLang      : DBIQryLang;                      { Query language }
           pszQuery      : PChar;                           { Query }
           propBits      : Word;                            { properties for Prepare, e.g. qprepFORUPDATE }
           var hStmt     : hDBIStmt                         { Returned statment handle }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hdb ).QPrepareExt( eQryLang, pszQuery, propBits, hStmt );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QFree (                                   { Free statement handle }
           var hStmt : hDBIStmt                             { Statement handle }
         ): DBIResult;
begin
  Try
    Statement := hStmt;
    TSqlStmt( hStmt ).Free;
    hStmt  := NIL;
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QSetParams (                              { Set query options }
           hStmt         : hDBIStmt;                        { Statement handle }
           uFldDescs     : Word;                            { Number of parameter field descriptors }
           paFldDescs    : pFLDDesc;                        { Array of parameter field descriptors }
           pRecBuff      : Pointer                          { Record buffer }
         ): DBIResult;
begin
  Try
    Statement := hStmt;
    TSqlStmt( hStmt ).QSetParams( uFldDescs, paFldDescs, pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QInstantiateAnswer (                      { Create answer table }
           hStmt         : hDBIStmt;                        { Statement Handle }
           hCur          : hDBICur;                         { Cursor Handle }
           pszAnswerName : PChar;                           { Answer Table Name/NULL }
           pszAnswerType : PChar;                           { Answer Table Type/NULL }
           bOverWrite    : Bool;                            { Overwrite Flag }
           phCur         : phDBICur                         { cursor to instantiated table (output)(optional) }
   ): DBIResult;
begin
  Try
    Result := DBIERR_NA;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QExecProcDirect (                         { Direct execution of stored procedure }
           hDb           : hDBIDb;                          { Database handle }
           pszProc       : PChar;                           { Stored procedure name }
           uParamDescs   : Word;                            { Number of parameter descriptors }
           paParamDescs  : pSPParamDesc;                    { Array of parameter descriptors }
           pRecBuff      : Pointer;                         { Record buffer }
           var hCur      : hDBICur                          { Returned handle on result set }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hdb ).QExecProcDirect( pszProc, uParamDescs, paParamDescs, pRecBuff, hCur );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QPrepareProc (                            { Prepare a stored procedure }
           hDb           : hDBIDb;                          { Database handle }
           pszProc       : PChar;                           { Stored procedure name }
           uParamDescs   : Word;                            { Number of parameter descriptors }
           paParamDescs  : pSPParamDesc;                    { Array of parameter descriptors }
           pRecBuff      : Pointer;                         { Record buffer }
           var hStmt     : hDBIStmt                         { Returned statment handle }
         ): DBIResult;
begin
  Try
    Database := hDb;
    TBaseDatabase( hdb ).QPrepareProc( pszProc, uParamDescs, paParamDescs, pRecBuff, hStmt );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


Function TVirtEng.QSetProcParams (                          { Set procedure params }
           hStmt         : hDBIStmt;                        { Statement handle }
           uParamDescs   : Word;                            { Number of parameter descriptors }
           paParamDescs  : pSPParamDesc;                    { Array of parameter descriptors }
           pRecBuff      : Pointer                          { Record buffer }
         ): DBIResult;
begin
  Try
    Statement := hStmt;
    TSqlStmt( hStmt ).QSetProcParams( uParamDescs, paParamDescs, pRecBuff );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;



Function TVirtEng.BeginConstraintLayer(
     hDb          : hDBIDb;
var  hCur         : hDBICur;
     pDsCb        : pfDataSourcesCallback;
     lUserVal     : Integer
  ): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.EndConstraintLayer(
var  hCur         : hDBICur
  ): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.SQLTextToCanEx(
     hStmt         :  hDBIStmt;
     pExprText     :  PChar;
     iFields       :  Word;
     pFlds         :  pFLDDesc;
     exType        :  EXPType;
     pszFldName    :  PChar;
     pszSourceDb   :  PChar;
var  piCanSize     :  Word;
     pCanEx        :  PByte
   ): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.CheckSQLExpression(
     hCur          :  hDBICur;
     pszExpr       :  PChar;
     pszFldName    :  PChar;
     expType       :  EXPType;
     pDsCB         :  pfDataSourcesCallback;
     iClientData   :  Integer
   ): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.DsProviderGetDataPacket(
    hCur             : hDBICur;         { Result cursor handle }
    eProvOptions     : Integer;         { Options for provider }
    pDsCB            : Pointer;         { Callback for field origin }
    iClientData      : Integer;         { Client Data for callback }
    piMaxRecords     : PInteger;        { In: Max recs, Out: Actual Recs }
var Packet           : PVarArray;
var pbEndOfData      : Bool             { End of file was reached }
): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.DsResolver(
    iNoOfDataSources  : Integer;               { Number of data sources. }
    Packets           : PPacketList;           { Packet Buffer }
    hDb               : hDBIDb;                { Database handle. }
    szDbName          : PChar;                 { Database name }
    szDbType          : PChar;                 { Database type }
    szDbPassword      : PChar;                 { Password }
    pszSqlStr         : PNameList;             { SQL str used to generate Packet. }
    ppTableName       : PNameList;             { If open table, name of table }
    piClientData      : PInteger;              { Client Data for Resolver callback }
    ppfReconcile      : PCBList;               { Reconcile Callback-fn }
    ppDsCB            : PCBList;               { PpfDataSourcesCallback; }
    ClientData        : Integer;               { Client Data for DSCallback }
    piMaxErrorRecords : PInteger;              { In: MaxErrors, Out: ErrorCount }
    pppErrPacket      : PPacketList            { Packet Buffer for error set }
): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.OsLdInit(pDefDir: PChar; pDefLangDr: PChar): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdExit: DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdGetDefaultObj(var pLdObj: PLocale): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdGetSymbName(pLdObj: PLocale; pSymbName: PByte): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdGetDriverId( pLocaleObj :PLocale; var DriverId: Word): DBIResult;
begin
    Result   := DBIERR_NA;
end;


Function TVirtEng.OsLdGetDescName( pLocaleObj : PLocale; pDescName: PByte): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdGetSortsig( pLocaleObj : PLocale; var SortSig: SmallInt ): DBIResult;
begin
    Result  := DBIERR_NA;
end;

Function TVirtEng.OsLdGetProductID( pLdObj : Pointer; piProdID : PWord ): DBIResult;
begin
  Result  := DBIERR_NA;
end;

Function TVirtEng.OsLdGetCodePage( pLocaleObj : PLocale; var CodePage: SmallInt): DBIResult;
begin
    Result  := DBIERR_NA;
end;


Function TVirtEng.OsLdGetFName( pLocaleObj : PLocale; PName: PChar): DBIResult;
begin
    Result := DBIERR_NA;
end;

Function TVirtEng.OsLdSearchInit( var SHandle : Pointer ) : DBIResult;
begin
  Result := DBIERR_NA;
end;

Function TVirtEng.OsLdSearchNext( SHandle: Pointer; var ppLdObj: Pointer): DBIResult;
begin
  Result := DBIERR_NA;
end;

Function TVirtEng.OsLdSearchEnd( SHandle : Pointer ) : DBIResult;
begin
  Result := DBIERR_NA;
end;



Function TVirtEng.OsLdLoadBySortSig(SortSig: Word; CodePage: Word; var pLocaleObj : PLocale): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdLoadByFName(pFName: PChar; var PLocaleObj :PLocale): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdLoadBySymbName(pSymbName: PChar; var pLocaleObj : PLocale): DBIResult;
begin
(*
{  $IFDEF DUAL_MODE}
  If TBaseSession( Session ).IsBDE then
    Result := BdeProcs.OsLdLoadBySymbName( pSymbName, pLocaleObj )
  else
{  $ELSE}
*)
    Result := DBIERR_NA;
{...$ENDIF DUAL_MODE}
end;


Function TVirtEng.OsLdLoadByDriverId(iDriverId: Word; var pLocaleObj : PLocale): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdLoadByCID ( _lcid : Integer; var pLdObj: Pointer ): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.OsLdUnloadObj(var pLocaleObj : PLocale): DBIResult;
begin
    Result := DBIERR_NA;
end;

Function TVirtEng.OsLdGetMinMax (
           pLdObj        : Pointer;
           pcMin         : PChar;
           pcMax         : PChar
         ): DBIResult;
begin
  Result := DBIERR_NA;
end;


Function TVirtEng.OsLdSetConvChars (
      o2a           : Shortint;
      a2o           : Shortint
   ): DBIResult;
begin
  Result := DBIERR_NA;
end;

function TVirtEng.OsLdGetFuncAddrLdStrnColli_ (
var   ppf           : Pointer
   ): DBIResult;
begin
  Result := DBIERR_NA;
end;


function TVirtEng.OsLdGetFuncAddrLdStrnColl_ (
var   ppf           : Pointer
   ): DBIResult;
begin
  Result := DBIERR_NA;
end;


function TVirtEng.OsLdGetFuncAddrLdStrnCmpi_ (
var   ppf           : Pointer
   ): DBIResult;
begin
  Result := DBIERR_NA;
end;


function TVirtEng.OsLdStrnColl (
      pLdObj        : Pointer;
      Str1          : PByte;
      Str2          : PByte;
      Maxlen        : Word
   ): Shortint;
begin
  Result := 0;
end;


function TVirtEng.OsLdStrnColli (
      pBlObj        : Pointer;
      str1          : PChar;
      str2          : PChar;
      iLen          : Word
   ): Shortint;
begin
  Result := 0;
end;


function TVirtEng.OsLdExStrCmp (
      pLdObj        : Pointer;
      Right         : PByte;
      RightLen      : Shortint;
      Left          : PByte;
      LeftLen       : Shortint;
      Exact: Bool
   ): Shortint;
begin
  Result := 0;
end;


Function TVirtEng.OsLdStrnCmp( pLocaleObj : PLocale; Str1: PChar; Str2: PChar; Len: Word): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdStrCmp( pLocaleObj : PLocale; Str1: PChar; Str2: PChar): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdStrToUpper( pLocaleObj : PLocale; Str: PByte): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdStrnToUpper( pLocaleObj : PLocale; Str: PByte; Len: Word): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdStrToLower( pLocaleObj : PLocale; Str: PByte): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdStrnToLower( pLocaleObj : PLocale; Str: PByte; Len: Word): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdStrCmpi(pLdObj: PLocale; str1:pCHAR; str2: PChar): SmallInt;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdStrnCmpi( pLocaleObj : PLocale; Str1: PChar; Str2: PChar; Len: Word): SmallInt;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdOemToAnsi( pLocaleObj : PLocale; AnsiStr: PChar; OemStr: PChar;
           Len: Word; var DataLoss: BOOL): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdAnsiToOem( pLocaleObj : PLocale; OemStr: PChar; AnsiStr: PChar;
           Len: Word; var DataLoss: BOOL): DBIResult;
begin
    Result := DBIERR_NA;
end;


Function TVirtEng.OsLdIsAnsiCharInOemCp( pLocaleObj :PLocale; AnsiCh: Char): Bool;
begin
    Result := FALSE;
end;


Function TVirtEng.OsLdIsOemCharInAnsiCp( pLocaleObj :PLocale; OemCh: Char): Bool;
begin
    Result := FALSE;
end;


Function TVirtEng.OsLdAnsiCharToOem( pLocaleObj : PLocale; ch: Byte): Byte;
begin
    Result := 0;
end;


Function TVirtEng.OsLdOemCharToAnsi( pLocaleObj : PLocale; ch: Byte): Byte;
begin
    Result := 0;
end;


Function TVirtEng.OsLdCharToUpper( pLocaleObj : PLocale; ch: Byte): Byte;
begin
    Result := 0;
end;


Function TVirtEng.OsLdCharToLower( pLocaleObj : PLocale; ch: Byte): Byte;
begin
    Result := 0;
end;


Function TVirtEng.OsLdIsAlpha( pLocaleObj : PLocale; ch: Byte): Bool;
begin
    Result := FALSE;
end;


Function TVirtEng.OsLdIsDigit( pLocaleObj : PLocale; ch: Byte): Bool;
begin
    Result := FALSE;
end;


Function TVirtEng.OsLdBuildCharSetXform(pCharMap: PChar; pLdObjSrc: PLocale;
           pLdObjDest: PLocale; var DataLoss: Bool): Bool;
begin
    Result := FALSE;
end;


Function TVirtEng.GetLdNameFromDb(hDb: hDbiDb; DbName: PChar; pldName: PChar): DbiResult;
begin
  Try
    TBaseDatabase( hDb ).GetLdNameFromDb( DbName, pldName );
    Result := DBIERR_NONE;
  Except
    Result := CleanupException;
  end;
end;


end.
