(*****************************************************************************)
(* MODULE: BSEDBASE^                                                         *)
(* RIGHTS: Reggatta Systems, Inc. - COPYRIGHT 1995 - 2000                    *)
(* DESCR.: This module contains the database classes.                        *)
(*                                                                           *)
(*                                                                           *)
(* NOTES :                                                                   *)
(*                                                                           *)
(* TBaseDatabase:      This is the base class for all database classes.      *)
(*                     All tables are associated with a database object      *)
(*                     at runtime.                                           *)
(*                                                                           *)
(*****************************************************************************)
Unit BseDbase;
{$I BSE.INC}
{$I BAPI.INC}
Interface
Uses
  Windows,
  Bde,

  BseBapi,
  BseColl;

Type
  TBaseDatabaseClass = Class of TBaseDatabase;

  TBaseDatabase =
  Class( TBapiListItem )
    Protected
      FexState    : eXState;       { xsActive, xsInactive }
      FeXIL       : eXILType;      { Xact isolation level }
    Public
      Tables      : TTitanCollection;
      LoggedIn    : Boolean;
      OpenMode    : DBIOpenMode;
      ShareMode   : DBIShareMode;
      Password    : DBINAME;
      InTrans     : Boolean;
      Description : DBDesc;
      FName       : DBINAME;

      Function GetObjType : PChar; Virtual;

      Property ObjType : PChar
        Read  GetObjType;

      Constructor Create( P : TObject; Container : TTitanCollection; Desc : pDbDesc;
                    OMode : DBIOpenMode; SMode : DBIShareMode; PPass : PChar;
                    iOptFlds : Word; pOptFldDesc : pFLDDesc; pOptParams : Pointer );
        Virtual;

      Destructor  Destroy; Override;

      Procedure   SetPermissions( OMode : DBIOpenMode; SMode : DBIShareMode ); Virtual;

      Function    IsSqlBased : Boolean; Virtual;

      Procedure   ProcessOptionalParam( Name, Value : PChar ); Virtual;
      Procedure   ReadOptionalParams( iOptFlds : Word; pOptFldDesc : pFLDDesc;
                    pOptParams : Pointer ); Virtual;

      Procedure   TableLoaded( pszTableName : PChar; Var T : TBapiListItem ); Virtual;

      Procedure   SetDirectory( pszDir : PChar ); Virtual;
      Procedure   GetDirectory( bDefault : Bool; pszDir : PChar ); Virtual;
      Procedure   SchemaCacheFlush(                         { Form Full Name }
                    pszTableName  : PChar                   { Table name }
                  ); Virtual;
      Procedure   FormFullName (                            { Form Full Name }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    pszFullName   : PChar                   { Returns full name }
                  ); Virtual;

      Procedure   OpenTable (                               { Open a table }
                    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 }
                  ); Virtual; Abstract;

      Procedure   OpenTableList (                           { Open a cursor on "Tables" }
                    bExtended     : Bool;                   { True for extended info }
                    bSystem       : Bool;                   { True to include system tables }
                    pszWild       : PChar;                  { Wild card name }
                    var   hCur    : hDBICur                 { Returned cursor }
                  ); Virtual; Abstract;

      Procedure   OpenFieldList (                           { Return "Fields" for a table }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    bPhyTypes     : Bool;                   { True, for physical types }
                    var   hCur    : hDBICur                 { Returned cursor on "Fields" }
                  ); Virtual; Abstract;

      Procedure   OpenFileList (
                    pszWild       : PChar;                  { Wild card name }
                    var   hCur    : hDBICur                 { Returned cursor }
                  ); Virtual;

      Procedure   OpenDriverList (                          { Open a cursor on Drivers }
                    var   hCur    : hDBICur                 { Returned cursor }
                  ); Virtual;

      Procedure   OpenIndexList (                           { Return "Indexes" for a table }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var   hCur    : hDBICur                 { Returned cursor on "Fields" }
                  ); Virtual;

      Procedure   OpenLockList (                            { Return "Checks" for a table }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver Type }
                    var hChkCur   : hDBICur                 { Returned cursor on "Checks" }
                  ); Virtual;

      Procedure   OpenVchkList (                            { Return "Checks" for a table }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver Type }
                    var hChkCur   : hDBICur                 { Returned cursor on "Checks" }
                  ); Virtual;

      Procedure   OpenRintList (                            { Return Integrity checks }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var hChkCur   : hDBICur                 { Returned cursor on "Ref Int". }
                  ); Virtual;

      Procedure   OpenSecurityList (                        { Return security descriptions }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var hSecCur   : hDBICur                 { Returned cursor on sec list }
                  ); Virtual;

      Procedure   OpenFamilyList (                          { Return family members }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type }
                    var hFmlCur   : hDBICur                 { Returned cursor on "Family" }
                  ); Virtual;

      Procedure   OpenSPList (                              { Open a cursor on "Stored Procedures" }
                    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 }
                  ); Virtual;

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

      Procedure   OpenFunctionList (                        { Open a cursor on "Functions" }
                    eoptBits      : DBIFUNCOpts;            { Options for function list }
                    phCur         : phDBICur                { Returned cursor on "Functions" }
                                                            { Record desc is of type DBIFUNCDesc }
                  ); Virtual;

      Procedure   OpenFunctionArgList (                     { Return "Arguments" for a function }
                    pszFuncName   : PChar;                  { Function name }
                    uOverload     : Word;                   { Overload number }
                    phCur         : phDBICur                { Returned cursor on "Arguments" }
                  ); Virtual;

      Procedure   TableExists(                              { NON BDE function to determine }
                    SearchName : PChar;                     { if a table exists             }
                    Var Found : Boolean
                  ); Virtual;

      Procedure   GetTableOpenCount (                       {  Get local cursor count }
                    pszTableName   : PChar;                 { Table name }
                    pszDriverType  : PChar;                 { Driver type }
                    var iOpenCount : Word                   { returned number of cursors }
                  ); Virtual;

      Procedure   GetCursorForTable (                       { Find cursor for a given table }
                    pszTableName   : PChar;                 { Table name }
                    pszDriverType  : PChar;                 { Driver type }
                    var   hCursor  : hDBICur                { Returned cursor }
                  ); Virtual;

      Procedure   EmptyTable (                              { Deletes all records }
                    hCursor       : hDBICur;                { Cursor (OR) }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar                   { Driver type /NULL }
                  ); Virtual;

      Procedure   PackTable (                               { Packs all records }
                    hCursor       : hDBICur;                { Cursor (OR) }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    bRegenIdxs    : Bool                    { Regenerate indexes }
                  ); Virtual;

      Procedure   RegenIndex (                              { Regenerate an index }
                    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 }
                  ); Virtual;

      Procedure   SortTable (                               { Sort table }
                    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 }
                  ); Virtual;

      Procedure   CreateTable (                             { Create a new table }
                    bOverWrite    : Bool;                   { True, to overwrite existing file. }
                    var crTblDsc  : CRTblDesc               { Table description }
                  ); Virtual;

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

      Procedure   CreateTempTable (                         { Create temporary table (Physical) }
                    var crTblDsc  : CRTblDesc;              { Table description }
                    var hCursor   : hDBICur                 { Returned cursor on table }
                  ); Virtual;

      Procedure   DoRestructure (                           { Restructure a table }
                    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 }
                  ); Virtual;

      Procedure   RenameTable (                             { Rename table & family }
                    pszOldName    : PChar;                  { Old name }
                    pszDriverType : PChar;                  { Driver type /NULL }
                    pszNewName    : PChar                   { New name }
                  ); Virtual;

      Procedure   DeleteTable (                             { Delete a table }
                    pszTableName  : PChar;                  { Name including any path }
                    pszDriverType : PChar                   { Driver type /NULL }
                  ); Virtual;

      Procedure   AddIndex (                                { Add a new index }
                    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) }
                  ); Virtual;

      Procedure   DeleteIndex (                             { Delete index }
                    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 }
                  ); Virtual;

      Procedure   BeginTran (                               { Begin a transaction }
                    eXIL          : eXILType;               { Transaction isolation level }
                    var hXact     : hDBIXact                { Returned Xact handle }
                  ); Virtual;

      Procedure   EndTran (                                 { End a transaction }
                    hXact         : hDBIXact;               { Xact handle }
                    eEnd          : eXEnd                   { Xact end type }
                  ); Virtual;

      Procedure   GetTranInfo (                             { Get transaction info }
                    hXact         : hDBIXact;               { Xact handle }
                    pxInfo        : pXInfo                  { Xact info }
                  ); Virtual;

      Procedure   CopyTable (                               { Copy one table to another }
                    bOverWrite    : Bool;                   { True, to overwrite existing file }
                    pszSrcTableName : PChar;                { Source table name }
                    pszSrcDriverType : PChar;               { Source driver type }
                    pszDestTableName : PChar                { Destination table name }
                  ); Virtual;

      Procedure   Login; Virtual;

      Procedure   LogOut; Virtual;

      Procedure   AcqPersistTableLock (                     { Get a persistent lock }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar                   { Driver type / NULL }
                  ); Virtual;

      Procedure   RelPersistTableLock (                     { Releases a persistent lock }
                    pszTableName  : PChar;                  { Table name }
                    pszDriverType : PChar                   { Driver type / NULL }
                  ); Virtual;

      Procedure   QExecDirect (                             { Execute query }
                    eQryLang      : DBIQryLang;             { Query language }
                    pszQuery      : PChar;                  { Query }
                    phCur         : phDBICur                { Returned cursor on result set }
                  ); Virtual;

      Procedure   QAlloc (                                  { Allocates a statement handle }
                    eQryLang      : DBIQryLang;             { Query language }
                    var hStmt     : hDBIStmt                { Returned statment handle }
                  ); Virtual;

      Procedure   QPrepare (                                { Prepare a query }
                    var hStmt     : hDBIStmt;               { Returned statment handle }
                    pszQuery      : PChar                   { Query }
                  ); Virtual;

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

      Procedure   QExecProcDirect (                         { Direct execution of stored procedure }
                    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 }
                  ); Virtual;

      Procedure   QPrepareProc (                            { Prepare a stored procedure }
                    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 }
                  ); Virtual;

      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   ValidateProp (                            { Validate a property }
                    iProp         : Longint;                { property to validate }
                    bSetting      : Bool                    { TRUE:setting, FALSE:getting }
                  ); Override;

      Procedure   GetLdNameFromDb( DbName: PChar; pldName: PChar); Virtual;

      Procedure   DatabaseFlush; Virtual;

  end;

Implementation
Uses
  SysUtils,

  BseUtils,
  BseCache,
  BseConst,
  BseErrs,
  BseTable,
  BseStmt;


Constructor TBaseDatabase.Create( P : TObject; Container : TTitanCollection; Desc : pDbDesc;
              OMode : DBIOpenMode; SMode : DBIShareMode; PPass : PChar;
              iOptFlds : Word; pOptFldDesc : pFLDDesc; pOptParams : Pointer
            );
begin
  Inherited Create( P, Container );

  ReadOptionalParams( iOptFlds, pOptFldDesc, pOptParams );

  Tables    := TTitanCollection.Create;
  LoggedIn  := FALSE;

  If Assigned( Desc ) then
    Move( Desc^, Description, Sizeof( Description ) );

  If Assigned( PPass ) then
    StrLCopy( @Password, PPass, SizeOf( Password ) - 1 );

  SetPermissions( OMode, SMode );

  FexState := xsInactive;
end;


Destructor TBaseDatabase.Destroy;
begin
  Tables.Free;
  LogOut;
  Inherited Destroy;
end;


Procedure TBaseDatabase.SetPermissions( OMode : DBIOpenMode; SMode : DBIShareMode );
begin
  OpenMode  := OMode;
  ShareMode := SMode;
end;


Function TBaseDatabase.IsSqlBased : Boolean;
begin
  Result := FALSE;
end;


Procedure TBaseDatabase.ProcessOptionalParam( Name, Value : PChar );
begin
  if ( StrIComp( Name, 'USER NAME' ) = 0 ) then
    StrLCopy( @FName, Value, Pred( Sizeof( FName ) ) );
end;


Procedure TBaseDatabase.ReadOptionalParams( iOptFlds : Word; pOptFldDesc : pFLDDesc;
                         pOptParams : Pointer );
var
  i : Word;
  F : pFLDDesc;
  O : PChar;
begin
  if ( iOptFlds > 0 ) then
  begin
    F := pOptFldDesc;
    For i := 0 to Pred( iOptFlds ) do
    begin
      O := PChar( pOptParams );
      Inc( O, F^.iOffset );
      ProcessOptionalParam( F^.szName, O );
      Inc( F );
    end;
  end;
end;


Function TBaseDatabase.GetObjType : PChar;
const
  T : PChar = 'STANDARD';
begin
  Result := T;
end;


Procedure TBaseDatabase.TableLoaded( pszTableName : PChar; Var T : TBapiListItem );
var
  UsePath : Boolean;
  i       : Integer;
  Found   : Boolean;
begin
  T := NIL;
  ValidateParameter( pszTableName );
  If ( Tables.Count > 0 ) then
  begin
    UsePath := HasPath( pszTableName, TRUE );
    For i := 0 to Pred( Tables.Count ) do
    begin
      T := Tables.Items[ i ];
      if UsePath then
        Found := ( StrIComp( pszTableName, TBaseTable( T ).FileName ) = 0 )
      else
        Found := ( StrIComp( pszTableName, TBaseTable( T ).TableName ) = 0 );
      If Found and ( StrLen( TBaseTable( T ).FileName ) > 0 ) then
        Exit;
    end;
  end;
  ThrowExceptionMsg( DBIERR_NOSUCHTABLE, StrPas( pszTableName ) );
end;



Procedure TBaseDatabase.SetDirectory( pszDir : PChar );
begin
  StrLCopy( @Description.szPhyName, pszDir, SizeOf( Description.szPhyName ) - 1 );
end;


Procedure TBaseDatabase.GetDirectory( bDefault : Bool; pszDir : PChar );
begin
  StrCopy( pszDir, @Description.szPhyName );
end;


Procedure TBaseDatabase.SchemaCacheFlush(                   { Form Full Name }
           pszTableName  : PChar                            { Table name }
          );
begin
end;


Procedure TBaseDatabase.FormFullName (                      { Form Full Name }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type /NULL }
           pszFullName   : PChar                            { Returns full name }
         );
begin
  Not_Used( fnFORMFULLNAME );
end;


Procedure TBaseDatabase.OpenFileList (
           pszWild       : PChar;                           { Wild card name }
           var   hCur    : hDBICur                          { Returned cursor }
         );
begin
  OpenTableList( FALSE, FALSE, pszWild, hCur );
end;


Procedure TBaseDatabase.OpenDriverList (                    { Open a cursor on Drivers }
           var   hCur    : hDBICur                          { Returned cursor }
         );
begin
  Not_Supported( fnOPENDRIVERLIST );
end;


Procedure TBaseDatabase.OpenIndexList (                     { Return "Indexes" for a table }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var   hCur    : hDBICur                          { Returned cursor on "Fields" }
         );
var
  P     : TBaseTable;
  Ind   : TIndexListTable;

  Procedure ProcessTable;
  var
    Props : CURProps;
    Items : Word;
    Descs : Pointer;
  begin
    P.GetCursorProps( Props );
    Items := Props.iIndexes;
    if ( Items > 0 ) then
    begin
      Descs := AllocMem( Items * Sizeof( idxDesc ) );
      Try
        P.GetIndexDescs( PIDXDesc( Descs ) );
        Ind  := TIndexListTable.Create( Self, Tables, Descs, Items );
        hCur := hDBICur( Ind );
      Finally
        FreeMem( Descs, Items * Sizeof( idxDesc ) );
      end
    end
    else
      ThrowException( DBIERR_NOTINDEXED );
  end;

  Procedure OpenAndProcessTable;
  begin
    OpenTable( pszTableName, NIL, NIL, NIL, 0, dbiREADONLY, dbiOPENSHARED,
        xltNONE, FALSE, NIL, hDBICur( P ) );
    Try
      ProcessTable;
      P.CloseTable;
    Finally
      P.Free;
    end;
  end;

begin
  hCur := NIL;
  Try
    GetCursorForTable( pszTableName, pszDriverType, hDBICur( P ) );
    if ( P.State <> TblClosed ) then
      ProcessTable
    else
      OpenAndProcessTable;
  Except
    On E:ETitanEngineError do
      OpenAndProcessTable;
  end;
end;


Procedure TBaseDatabase.OpenLockList (                      { Return "Checks" for a table }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver Type }
           var hChkCur   : hDBICur                          { Returned cursor on "Checks" }
         );
begin
  Not_Used( fnOPENLOCKLIST );
end;


Procedure TBaseDatabase.OpenVchkList (                      { Return "Validity" for a table }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var hChkCur   : hDBICur                          { Returned cursor on "Checks" }
         );
begin
  Not_Used( fnOPENVCHKLIST );
end;


Procedure TBaseDatabase.OpenRintList (                      { Return Integrity checks }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var hChkCur   : hDBICur                          { Returned cursor on "Ref Int". }
         );
begin
  Not_Used( fnOPENRINTLIST );
end;


Procedure TBaseDatabase.OpenSecurityList (                  { Return security descriptions }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var hSecCur   : hDBICur                          { Returned cursor on sec list }
         );
begin
  Not_Used( fnOPENSECURITYLIST );
end;


Procedure TBaseDatabase.OpenFamilyList (                    { Return family members }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type }
           var hFmlCur   : hDBICur                          { Returned cursor on "Family" }
         );
begin
  Not_Used( fnOPENFAMILYLIST );
end;


Procedure TBaseDatabase.OpenFunctionList (                  { Open a cursor on "Functions" }
           eoptBits      : DBIFUNCOpts;                     { Options for function list }
           phCur         : phDBICur                         { Returned cursor on "Functions" }
                                                            { Record desc is of type DBIFUNCDesc }
         );
begin
  Not_Supported( fnOPENFUNCTIONLIST );
end;


Procedure TBaseDatabase.OpenFunctionArgList (               { Return "Arguments" for a function }
           pszFuncName   : PChar;                           { Function name }
           uOverload     : Word;                            { Overload number }
           phCur         : phDBICur                         { Returned cursor on "Arguments" }
         );
begin
  Not_Supported( fnOPENFUNCTIONARGLIST );
end;


Procedure TBaseDatabase.TableExists( SearchName : PChar; Var Found : Boolean );
var
  P    : TBaseTable;
  Desc : TBLBaseDesc;
  S    : ShortString;
begin
  If HasPath( SearchName, TRUE ) then
  begin
    S := BuildPath( StrPas( SearchName ), StrPas( @Description.szPhyName ) );
    if FileExists( S ) then
      Found := TRUE
  end
  else
  begin
    Found  := FALSE;
    OpenTableList( FALSE, TRUE, NIL, hDBICur( P ) );
    Try
      SearchName := StrUpper( SearchName );
      Try
        Repeat
          P.GetNextRecord( dbiNOLOCK, @Desc, NIL );
          Found := ( StrIComp( @Desc.szName, SearchName ) = 0  )
        until Found;
      Except
        On E:ETitanBoundryError do
          ;
      end;
    Finally
      P.Free;
    end;
  end;  
end;


Procedure TBaseDatabase.GetTableOpenCount (                 {  Get local cursor count }
           pszTableName   : PChar;                          { Table name }
           pszDriverType  : PChar;                          { Driver type }
           var iOpenCount : Word                            { returned number of cursors }
         );
Var
  i : Integer;
  P : TBaseTable;
begin
  iOpenCount := 0;
  For i := 0 to Pred( Tables.Count ) do
  begin
    P := Tables.Items[ i ];
    If ( StrLIComp( P.TableName, pszTableName, Pred( Sizeof( DBINAME ) ) ) = 0 ) then
      Inc( iOpenCount );
  end;
  if ( iOpenCount = 0 ) then
    ThrowExceptionMsg( DBIERR_NOSUCHTABLE, StrPas( pszTableName ) );
end;


Procedure TBaseDatabase.GetCursorForTable(
           pszTableName   : PChar;
           pszDriverType  : PChar;                          { Driver type }
           var hCursor    : hDBICur
         );
var
  SearchTmp : DBIPATH;
begin
  StrLCopy( @SearchTmp, pszTableName, SizeOf( SearchTmp ) - 1 );
  CutString( @SearchTmp, BAPI_FIELD_DELIM );
  TableLoaded( @SearchTmp, TBapiListItem( hCursor ) );
end;


Procedure TBaseDatabase.BeginTran (                         { Begin a transaction }
           eXIL          : eXILType;                        { Transaction isolation level }
           var hXact     : hDBIXact                         { Returned Xact handle }
         );
begin
  Not_Supported( fnBEGINTRAN );
end;


Procedure TBaseDatabase.EndTran (                           { End a transaction }
           hXact         : hDBIXact;                        { Xact handle }
           eEnd          : eXEnd                            { Xact end type }
         );
begin
  Not_Supported( fnENDTRAN );
end;


Procedure TBaseDatabase.GetTranInfo (                       { Get transaction info }
            hXact         : hDBIXact;                       { Xact handle }
            pxInfo        : pXInfo                          { Xact info }
          );
begin
  MoveZero( pxInfo^, Sizeof( pxInfo^ ) );
  pxInfo^.eXState := FexState;
  pxInfo^.eXIL    := FeXIL;
end;


Procedure TBaseDatabase.CopyTable (                         { Copy one table to another }
           bOverWrite    : Bool;                            { True, to overwrite existing file }
           pszSrcTableName : PChar;                         { Source table name }
           pszSrcDriverType : PChar;                        { Source driver type }
           pszDestTableName : PChar                         { Destination table name }
         );
begin
  Not_Supported( fnCOPYTABLE );
end;


Procedure TBaseDatabase.EmptyTable (                        { Deletes all records }
           hCursor       : hDBICur;                         { Cursor (OR) }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar                            { Driver type /NULL }
         );
var
  NeedOpen : Boolean;
begin
  NeedOpen := Not Assigned( hCursor );
  If NeedOpen then
    OpenTable( pszTableName, NIL, NIL, NIL, 0, dbiREADWRITE, dbiOPENEXCL, XLTNONE, TRUE, NIL, hCursor );
  Try
    TBaseTable( hCursor ).EmptyTable;
  Finally
    If NeedOpen then
      TBaseTable( hCursor ).Free;
  end;
end;


Procedure TBaseDatabase.PackTable (                         { Packs all records }
           hCursor       : hDBICur;                         { Cursor (OR) }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar;                           { Driver type /NULL }
           bRegenIdxs    : Bool                             { Regenerate Indexes }
         );
begin
  Not_Supported( fnPACKTABLE );
end;


Procedure TBaseDatabase.RegenIndex (                        { Regenerate an index }
           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 }
         );
begin
  Not_Supported( fnREGENINDEX );
end;


Procedure TBaseDatabase.SortTable (                         { Sort table }
           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 }
         );
begin
  Not_Supported( fnSORTTABLE );
end;


Procedure TBaseDatabase.CreateTable (                       { Create a new table }
           bOverWrite    : Bool;                            { True, to overwrite existing file. }
           var crTblDsc  : CRTblDesc                        { Table description }
         );
Var
  H     : hDBICur;
  Found : Boolean;
  TName : ShortString;
begin
  If Not bOverwrite then
  begin
    TableExists( crTblDsc.szTblName, Found );
    If Found then
      ThrowException( DBIERR_FILEEXISTS );
  end;
  CreateTempTable( crTblDsc, H );
  ValidateHandle( H );
  Try
    TName := ExtractFileName( StrPas( crTblDsc.szTblName ) );
    TName := ChangeFileExt( TName, '' ) + #0;
    TBaseTable( H ).MakePermanent( @TName[ 1 ], bOverwrite );
  Finally
    TBaseTable( H ).Free;
  end;
end;


Procedure TBaseDatabase.CreateInMemTable (                  { Create a temporary table (Logical) }
           pszName       : PChar;                           { Logical Name }
           iFields       : Word;                            { No of fields }
           pfldDesc      : pFLDDesc;                        { Array of field descriptors }
           var hCursor   : hDBICur                          { Returned cursor handle }
         );
var
  P : TMemTable;
begin
  If ( pFldDesc <> NIL ) and ( iFields > 0 ) then
  begin
    hCursor := NIL;
    P := TMemTable.Create( Self, Tables, pszName, iFields, 0, pFldDesc, NIL );
    If ( P <> NIL ) then
      hCursor := hDBICur( P )
    else
      ThrowExceptionMsg( DBIERR_INVALIDTABLECREATE, StrPas( pszName ) );
  end
  else
    ThrowExceptionMsg( DBIERR_INVALIDPARAM, StrPas( pszName ) );
end;


Procedure TBaseDatabase.CreateTempTable (                   { Create temporary table (Physical) }
           var crTblDsc  : CRTblDesc;                       { Table description }
           var hCursor   : hDBICur                          { Returned cursor on table }
         );
begin
  Not_Supported( fnCREATETEMPTABLE );
end;


Procedure TBaseDatabase.DoRestructure (                     { Restructure a table }
           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 }
         );
begin
  Not_Supported( fnDORESTRUCTURE );
end;


Procedure TBaseDatabase.RenameTable (                       { Rename table & family }
           pszOldName    : PChar;                           { Old name }
           pszDriverType : PChar;                           { Driver type /NULL }
           pszNewName    : PChar                            { New name }
         );
begin
  Not_Supported( fnRENAMETABLE );
end;


Procedure TBaseDatabase.DeleteTable (                       { Delete a table }
           pszTableName  : PChar;                           { Name including any path }
           pszDriverType : PChar                            { Driver type /NULL }
         );
begin
  Not_Supported( fnDELETETABLE );
end;


Procedure TBaseDatabase.AddIndex (                          { Add a new index }
           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) }
         );
var
  P : TBaseTable;
begin
  If Assigned( hCursor ) then
    P := TBaseTable( hCursor )
  else
    OpenTable( pszTableName, NIL, NIL, NIL, IdxDesc.iIndexId,
                dbiREADWRITE, dbiOPENEXCL, XLTNONE, TRUE, NIL, hDBICur( P ) );
  Try
    P.AddIndex( idxDesc, pszKeyViolName );
  Finally
    If Not Assigned( hCursor ) then
      P.Free;
  end;
end;


Procedure TBaseDatabase.DeleteIndex (                       { Delete index }
           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 }
         );
var
  P : TBaseTable;
begin
  If Assigned( hCursor ) then
    P := TBaseTable( hCursor )
  else
    OpenTable( pszTableName, NIL, pszIndexName, NIL, iIndexId,
      dbiREADWRITE, dbiOPENEXCL, XLTNONE, TRUE, NIL, hDBICur( P ) );
  Try
    P.DeleteIndex( pszIndexName, pszIndexTagName, iIndexID );
  Finally
    If Not Assigned( hCursor ) then
      P.Free;
  end;
end;


Procedure TBaseDatabase.Login;
begin
  LoggedIn := FALSE;
  Not_Used( fnLOGIN );
end;


Procedure TBaseDatabase.LogOut;
begin
  LoggedIn := FALSE;
end;


Procedure TBaseDatabase.AcqPersistTableLock (               { Get a persistent lock }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar                            { Driver type / NULL }
         );
begin
  Not_Supported( fnACQPERSISTTABLELOCK );
end;


Procedure TBaseDatabase.RelPersistTableLock (               { Releases a persistent lock }
           pszTableName  : PChar;                           { Table name }
           pszDriverType : PChar                            { Driver type / NULL }
         );
begin
  Not_Supported( fnRELPERSISTTABLELOCK );
end;


Procedure TBaseDatabase.QExecDirect (                       { Execute query }
           eQryLang      : DBIQryLang;                      { Query language }
           pszQuery      : PChar;                           { Query }
           phCur         : phDBICur                         { Returned cursor on result set }
         );
var
  hStmt : hDBIStmt;
begin
  hStmt := NIL;
  QAlloc( eQryLang, hStmt );
  QPrepare( hStmt, pszQuery );
  If ( hStmt <> NIL ) then
  begin
    Try
      TSQLStmt( hStmt ).QExec( phCur );
    Finally
      TSqlStmt( hStmt ).Free;
    end;
  end;
end;


Procedure TBaseDatabase.QAlloc(                             { Allocates a statement handle  }
           eQryLang      : DBIQryLang;                      { Query language }
           var hStmt     : hDBIStmt                         { Returned statment handle }
         );
begin
  Not_Supported( fnQALLOC );
end;


Procedure TBaseDatabase.QPrepare (                          { Prepare a query }
           var hStmt     : hDBIStmt;                        { Returned statment handle }
           pszQuery      : PChar                            { Query }
         );
begin
  QPrepareExt( qrylangSQL, pszQuery, qprepNONE, hStmt );
end;



Procedure TBaseDatabase.QPrepareExt (                       { Prepare a query }
           eQryLang      : DBIQryLang;                      { Query language }
           pszQuery      : PChar;                           { Query }
           propBits      : Word;                            { properties for Prepare, e.g. qprepFORUPDATE }
           var hStmt     : hDBIStmt                         { Returned statment handle }
         );
begin
  Not_Supported( fnQPREPAREEXT );
end;


Procedure TBaseDatabase.QExecProcDirect (                   { Direct execution of stored procedure }
           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 }
         );
begin
  Not_Supported( fnQEXECPROCDIRECT );
end;


Procedure TBaseDatabase.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
  iLen := 0;
  Case TPropertyRec( iProp ).Prop of
    Word( dbMAXPROPS ):                                     { ro UINT16   , Number of defined properties }
      begin
        iLen := Sizeof( Word );
        Word( PropValue^ ) := maxDbProps;
      end;
    Word( dbDATABASETYPE ):                                 { ro pDBINAME , Database type }
      begin
        StrLCopy( PropValue, ObjType, iMaxLen );
        iLen := Succ( StrLen( PropValue ) );
      end;
    else
      Inherited GetProp( iProp, PropValue, iMaxLen, iLen );
  end;
end;


Procedure TBaseDatabase.ValidateProp (                      { Validate a property }
           iProp         : Longint;                         { property to validate }
           bSetting      : Bool                             { TRUE:setting, FALSE:getting }
         );
begin
  Case TPropertyRec( iProp ).Prop of
    Word( dbMAXPROPS ),                                     { ro UINT16   , Number of defined properties }
    Word( dbDATABASETYPE ):                                 { ro pDBINAME , Database type }
      ValidateValue( Not bSetting, DBIERR_NOTSUPPORTED );
  else
    Inherited ValidateProp( iProp, bSetting );
  end;
end;


Procedure TBaseDatabase.QPrepareProc (                      { Prepare a stored procedure }
           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 }
         );
begin
  Not_Supported( fnQPREPAREPROC );
end;


Procedure TBaseDatabase.OpenSPList (                        { Open a cursor on "Stored Procedures" }
           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 }
         );
begin
  Not_Supported( fnOPENSPLIST );
end;


Procedure TBaseDatabase.OpenSPParamList (                   { Return "Parameters" for a stored procedure }
           pszSPName     : PChar;                           { Stored procedure name }
           bPhyTypes     : Bool;                            { True, for physical types }
           uOverload     : Word;                            { Overload number }
           var hCur      : hDBICur                          { Returned cursor on "Parameters" }
         );
begin
  Not_Supported( fnOPENSPPARAMLIST );
end;


Procedure TBaseDatabase.GetLdNameFromDb( DbName: PChar; pldName : PChar );
begin
  ThrowException( DBIERR_NA );
end;


Procedure TBaseDatabase.DatabaseFlush;
begin
end;


end.
