(*****************************************************************************)
(* MODULE: BSEERRS*                                                          *)
(* AUTHOR: Peter Blair                                                       *)
(* RIGHTS: Reggatta Systems, Inc. - COPYRIGHT 1995 - 1999                    *)
(* DESCR.: This module contains the Database Error Routines.                 *)
(*                                                                           *)
(* NOTES :                                                                   *)
(*                                                                           *)
(*                                                                           *)
(*****************************************************************************)
Unit BseErrs;
{$I BSE.INC}
Interface
Uses
  SysUtils,
  Windows,
  DB,
  BDE,
  BseTypes;

Type
  ETitanEngineError =
  Class( EAbort )
    Protected
      FDbiErrorCode    : DBIResult;
      FDbiErrorMsg     : ShortString;
      FNativeErrorCode : Integer;
      Function GetNativeErrorMsg : ShortString; Virtual;
    Public
      Constructor Create( ErrorCode : DBIResult );
      Constructor CreateMsg( ErrorCode : DBIResult; Const ErrorMsg : ShortString );
      Function DBInterfaceErrorFormat : Shortstring; Virtual;
      Property DBIError : DBIResult
        Read FDBIErrorCode;
      Property DBIErrorMsg : ShortString
        Read FDbiErrorMsg;
      Property NativeError : Integer
        Read FNativeErrorCode;
      Property NativeErrorMsg : ShortString
        Read GetNativeErrorMsg;
  end;

  ETitanBoundryError = Class( ETitanEngineError );

  ETitanEOFError =
  Class( ETitanBoundryError )
    Public
      Constructor CreateEOF;
  end;

  ETitanBOFError =
  Class( ETitanBoundryError )
    Public
      Constructor CreateBOF;
  end;

Type
  pMapRec = ^MapRec;
  MapRec =
  Record
    NatError : SmallInt;
    BDEError : DBIResult;
  end;

  PMapRecArray = ^TMapRecArray;
  TMapRecArray = Array[ 0..0 ] of MapRec;

Procedure GetDBIErrorStr( Error : DBIResult; Var ErrStr : ShortString );
Procedure TestResult( ResultCode : DBIResult );
Procedure ThrowException( Error : DBIResult );
Procedure ThrowExceptionMsg( Error : DBIResult; Const ErrorMsg : ShortString );
Procedure ThrowEOFException;
Procedure ThrowBOFException;
Function  ValidatePointer( P : Pointer; Error : DBIResult ) : Pointer;
Function  ValidateValue( Expr : Boolean; Error : DBIResult ) : Boolean;
Function  ValidateParameter( P : Pointer ) : Pointer;
Function  ValidateHandle( P : Pointer ) : Pointer;
Procedure Not_Used( FuncConst : Integer );
Procedure Not_Supported( FuncConst : Integer );
Function  MapDBIToNative( pMapArray : PMapRecArray; Items, Error : SmallInt ) : DBIResult;
Function  MapNativeToDBI( pMapArray : PMapRecArray; Items, Error : SmallInt ) : DBIResult;

Const
  MAX_STACK_SIZE = 20;

Type
  TErrorStackEntry =
  Record
    NativeError   : LongInt;
    NativeMessage : DBIPATH;
    BasicInfo     : DBIErrInfo;
  end;

  TErrorStackArray = Array[ 1..MAX_STACK_SIZE ] of TErrorStackEntry;
  pErrorStackArray = ^TErrorStackArray;

  TErrorStack =
  Class( TObject )
    Private
      FStack      : pErrorStackArray;
      FMaxItems   : Word;
      FLastEntry  : Word;
    Public
      Constructor Create( MaxItems : Word );
      Destructor  Destroy; Override;

      Procedure   Clear;

      Property Entries : Word
        Read  FLastEntry;

      Function  PushError( Rec : TErrorStackEntry ) : Boolean;
      Function  PopError( Var Rec : TErrorStackEntry ) : Boolean;
      Function  WasError : Boolean;
      Function  GetError( Index : Word; Var Rec : TErrorStackEntry ) : Boolean;
      Procedure AddError( E : ETitanEngineError );
  end;

Implementation
Uses

  BseUtils,
  BseConst;

{$R *.RES}


Constructor ETitanEngineError.Create( ErrorCode : DBIResult );
begin
  Inherited Create( '' );
  FDBIErrorCode := ErrorCode;
end;


Constructor ETitanEngineError.CreateMsg( ErrorCode : DBIResult; Const ErrorMsg : ShortString );
begin
  Create( ErrorCode );
  FDBIErrorMsg  := ErrorMsg;
end;


Function ETitanEngineError.DBInterfaceErrorFormat : Shortstring;
begin
  Result := BAPI_UNKNOWN_BDE_ERROR;
end;


Function ETitanEngineError.GetNativeErrorMsg : ShortString;
begin
  Result := '';
end;


Constructor ETitanEOFError.CreateEOF;
begin
  Create( DBIERR_EOF );
end;


Constructor ETitanBOFError.CreateBOF;
begin
  Create( DBIERR_BOF );
end;


Const
  MAX_BDE_ERRORS   = 470;
  BDE_ERROR_OFFSET = 14000;

Type
  BDEErrorTable    = Array[ 0..MAX_BDE_ERRORS ] of DBIResult;

Const
  BDEErrorMap : BDEErrorTable =
  (
     DBIERR_NONE,
     DBIERR_SYSFILEOPEN,
     DBIERR_SYSFILEIO,
     DBIERR_SYSCORRUPT,
     DBIERR_NOCONFIGFILE,
     DBIERR_CFGCANNOTWRITE,
     DBIERR_CFGMULTIFILE,
     DBIERR_REENTERED,
     DBIERR_CANTFINDODAPI,
     DBIERR_CANTLOADODAPI,
     DBIERR_CANTLOADLIBRARY,
     DBIERR_BOF,
     DBIERR_EOF,
     DBIERR_RECMOVED,
     DBIERR_RECDELETED,
     DBIERR_KEYORRECDELETED,
     DBIERR_NOCURRREC,
     DBIERR_RECNOTFOUND,
     DBIERR_ENDOFBLOB,
     DBIERR_OBJNOTFOUND,
     DBIERR_FMLMEMBERNOTFOUND,
     DBIERR_BLOBFILEMISSING,
     DBIERR_LDNOTFOUND,
     DBIERR_HEADERCORRUPT,
     DBIERR_FILECORRUPT,
     DBIERR_MEMOCORRUPT,
     DBIERR_BMPCORRUPT,
     DBIERR_INDEXCORRUPT,
     DBIERR_CORRUPTLOCKFILE,
     DBIERR_FAMFILEINVALID,
     DBIERR_VALFILECORRUPT,
     DBIERR_FOREIGNINDEX,
     DBIERR_READERR,
     DBIERR_WRITEERR,
     DBIERR_DIRNOACCESS,
     DBIERR_FILEDELETEFAIL,
     DBIERR_FILENOACCESS,
     DBIERR_ACCESSDISABLED,
     DBIERR_NOMEMORY,
     DBIERR_NOFILEHANDLES,
     DBIERR_NODISKSPACE,
     DBIERR_NOTEMPTBLSPACE,
     DBIERR_RECTOOBIG,
     DBIERR_CURSORLIMIT,
     DBIERR_TABLEFULL,
     DBIERR_WSSESLIMIT,
     DBIERR_SERNUMLIMIT,
     DBIERR_INTERNALLIMIT,
     DBIERR_OPENTBLLIMIT,
     DBIERR_TBLCURSORLIMIT,
     DBIERR_RECLOCKLIMIT,
     DBIERR_CLIENTSLIMIT,
     DBIERR_INDEXLIMIT,
     DBIERR_SESSIONSLIMIT,
     DBIERR_DBLIMIT,
     DBIERR_PASSWORDLIMIT,
     DBIERR_DRIVERLIMIT,
     DBIERR_FLDLIMIT,
     DBIERR_TBLLOCKLIMIT,
     DBIERR_OPENBLOBLIMIT,
     DBIERR_LOCKFILELIMIT,
     DBIERR_OPENQRYLIMIT,
     DBIERR_THREADLIMIT,
     DBIERR_BLOBLIMIT,
     DBIERR_KEYVIOL,
     DBIERR_MINVALERR,
     DBIERR_MAXVALERR,
     DBIERR_REQDERR,
     DBIERR_FORIEGNKEYERR,
     DBIERR_DETAILRECORDSEXIST,
     DBIERR_MASTERTBLLEVEL,
     DBIERR_LOOKUPTABLEERR,
     DBIERR_LOOKUPTBLOPENERR,
     DBIERR_DETAILTBLOPENERR,
     DBIERR_MASTERTBLOPENERR,
     DBIERR_FIELDISBLANK,
     DBIERR_MASTEREXISTS,
     DBIERR_MASTERTBLOPEN,
     DBIERR_DETAILTABLESEXIST,
     DBIERR_DETAILRECEXISTEMPTY,
     DBIERR_MASTERREFERENCEERR,
     DBIERR_DETAILTBLOPEN,
     DBIERR_DEPENDENTSMUSTBEEMPTY,
     DBIERR_RINTREQINDEX,
     DBIERR_LINKEDTBLPROTECTED,
     DBIERR_FIELDMULTILINKED,
     DBIERR_OUTOFRANGE,
     DBIERR_INVALIDPARAM,
     DBIERR_INVALIDFILENAME,
     DBIERR_NOSUCHFILE,
     DBIERR_INVALIDOPTION,
     DBIERR_INVALIDHNDL,
     DBIERR_UNKNOWNTBLTYPE,
     DBIERR_UNKNOWNFILE,
     DBIERR_PRIMARYKEYREDEFINE,
     DBIERR_INVALIDRINTDESCNUM,
     DBIERR_KEYFLDTYPEMISMATCH,
     DBIERR_INVALIDMODIFYREQUEST,
     DBIERR_NOSUCHINDEX,
     DBIERR_INVALIDBLOBOFFSET,
     DBIERR_INVALIDDESCNUM,
     DBIERR_INVALIDFLDTYPE,
     DBIERR_INVALIDFLDDESC,
     DBIERR_INVALIDFLDXFORM,
     DBIERR_INVALIDRECSTRUCT,
     DBIERR_INVALIDDESC,
     DBIERR_INVALIDINDEXSTRUCT,
     DBIERR_INVALIDVCHKSTRUCT,
     DBIERR_INVALIDRINTSTRUCT,
     DBIERR_INVALIDRESTRTBLORDER,
     DBIERR_NAMENOTUNIQUE,
     DBIERR_INDEXNAMEREQUIRED,
     DBIERR_INVALIDSESHANDLE,
     DBIERR_INVALIDRESTROP,
     DBIERR_UNKNOWNDRIVER,
     DBIERR_UNKNOWNDB,
     DBIERR_INVALIDPASSWORD,
     DBIERR_NOCALLBACK,
     DBIERR_INVALIDCALLBACKBUFLEN,
     DBIERR_INVALIDDIR,
     DBIERR_INVALIDXLATION,
     DBIERR_DIFFERENTTABLES,
     DBIERR_INVALIDBOOKMARK,
     DBIERR_INVALIDINDEXNAME,
     DBIERR_INVALIDIDXDESC,
     DBIERR_NOSUCHTABLE,
     DBIERR_USECOUNT,
     DBIERR_INVALIDKEY,
     DBIERR_INDEXEXISTS,
     DBIERR_INDEXOPEN,
     DBIERR_INVALIDBLOBLEN,
     DBIERR_INVALIDBLOBHANDLE,
     DBIERR_TABLEOPEN,
     DBIERR_NEEDRESTRUCTURE,
     DBIERR_INVALIDMODE,
     DBIERR_CANNOTCLOSE,
     DBIERR_ACTIVEINDEX,
     DBIERR_INVALIDUSRPASS,
     DBIERR_MULTILEVELCASCADE,
     DBIERR_INVALIDFIELDNAME,
     DBIERR_INVALIDTABLENAME,
     DBIERR_INVALIDLINKEXPR,
     DBIERR_NAMERESERVED,
     DBIERR_INVALIDFILEEXTN,
     DBIERR_INVALIDLANGDRV,
     DBIERR_ALIASNOTOPEN,
     DBIERR_INCOMPATRECSTRUCTS,
     DBIERR_RESERVEDOSNAME,
     DBIERR_DESTMUSTBEINDEXED,
     DBIERR_INVALIDINDEXTYPE,
     DBIERR_LANGDRVMISMATCH,
     DBIERR_NOSUCHFILTER,
     DBIERR_INVALIDFILTER,
     DBIERR_INVALIDTABLECREATE,
     DBIERR_INVALIDTABLEDELETE,
     DBIERR_INVALIDINDEXCREATE,
     DBIERR_INVALIDINDEXDELETE,
     DBIERR_INVALIDTABLE,
     DBIERR_MULTIRESULTS,
     DBIERR_INVALIDTIME,
     DBIERR_INVALIDDATE,
     DBIERR_INVALIDTIMESTAMP,
     DBIERR_DIFFERENTPATH,
     DBIERR_MISMATCHARGS,
     DBIERR_FUNCTIONNOTFOUND,
     DBIERR_MUSTUSEBASEORDER,
     DBIERR_INVALIDPROCEDURENAME,
     DBIERR_LOCKED,
     DBIERR_UNLOCKFAILED,
     DBIERR_FILEBUSY,
     DBIERR_DIRBUSY,
     DBIERR_FILELOCKED,
     DBIERR_DIRLOCKED,
     DBIERR_ALREADYLOCKED,
     DBIERR_NOTLOCKED,
     DBIERR_LOCKTIMEOUT,
     DBIERR_GROUPLOCKED,
     DBIERR_LOSTTBLLOCK,
     DBIERR_LOSTEXCLACCESS,
     DBIERR_NEEDEXCLACCESS,
     DBIERR_RECGROUPCONFLICT,
     DBIERR_DEADLOCK,
     DBIERR_ACTIVETRAN,
     DBIERR_NOACTIVETRAN,
     DBIERR_RECLOCKFAILED,
     DBIERR_OPTRECLOCKFAILED,
     DBIERR_OPTRECLOCKRECDEL,
     DBIERR_NOTSUFFFIELDRIGHTS,
     DBIERR_NOTSUFFTABLERIGHTS,
     DBIERR_NOTSUFFFAMILYRIGHTS,
     DBIERR_READONLYDIR,
     DBIERR_READONLYDB,
     DBIERR_READONLYFLD,
     DBIERR_TBLENCRYPTED,
     DBIERR_NOTSUFFSQLRIGHTS,
     DBIERR_NOTABLOB,
     DBIERR_BLOBOPENED,
     DBIERR_BLOBNOTOPENED,
     DBIERR_NA,
     DBIERR_NOTINDEXED,
     DBIERR_NOTINITIALIZED,
     DBIERR_MULTIPLEINIT,
     DBIERR_NOTSAMESESSION,
     DBIERR_PDXDRIVERNOTACTIVE,
     DBIERR_DRIVERNOTLOADED,
     DBIERR_TABLEREADONLY,
     DBIERR_NOASSOCINDEX,
     DBIERR_HASOPENCURSORS,
     DBIERR_NOTABLESUPPORT,
     DBIERR_INDEXREADONLY,
     DBIERR_NOUNIQUERECS,
     DBIERR_NOTCURSESSION,
     DBIERR_INVALIDKEYWORD,
     DBIERR_CONNECTINUSE,
     DBIERR_CONNECTNOTSHARED,
     DBIERR_OSEINVFNC,
     DBIERR_OSENOENT,
     DBIERR_OSENOPATH,
     DBIERR_OSEMFILE,
     DBIERR_OSEACCES,
     DBIERR_OSEBADF,
     DBIERR_OSECONTR,
     DBIERR_OSENOMEM,
     DBIERR_OSEINVMEM,
     DBIERR_OSEINVENV,
     DBIERR_OSEINVFMT,
     DBIERR_OSEINVACC,
     DBIERR_OSEINVDAT,
     DBIERR_OSENODEV,
     DBIERR_OSECURDIR,
     DBIERR_OSENOTSAM,
     DBIERR_OSENMFILE,
     DBIERR_OSEINVAL,
     DBIERR_OSE2BIG,
     DBIERR_OSENOEXEC,
     DBIERR_OSEXDEV,
     DBIERR_OSEDOM,
     DBIERR_OSERANGE,
     DBIERR_OSEEXIST,
     DBIERR_OSUNKNOWN,
     DBIERR_OSSHAREVIOL,
     DBIERR_OSLOCKVIOL,
     DBIERR_OSNETERR,
     DBIERR_OSINT24FAIL,
     DBIERR_OSDRIVENOTREADY,
     DBIERR_NOTEXACT,
     DBIERR_OSUNKNOWNSRVERR,
     DBIERR_SERVERNOMEMORY,
     DBIERR_OSALREADYLOCKED,
     DBIERR_OSNOTLOCKED,
     DBIERR_NOSERVERSW,
     DBIERR_NETINITERR,
     DBIERR_NETUSERLIMIT,
     DBIERR_NETFILEVERSION,
     DBIERR_NETFILELOCKED,
     DBIERR_DIRNOTPRIVATE,
     DBIERR_NETMULTIPLE,
     DBIERR_NETUNKNOWN,
     DBIERR_SHAREDFILE,
     DBIERR_SHARENOTLOADED,
     DBIERR_NOTONANETWORK,
     DBIERR_SQLCOMMLOST,
     DBIERR_SERVERCOMMLOST,
     DBIERR_WRONGDRVNAME,
     DBIERR_WRONGSYSVER,
     DBIERR_WRONGDRVVER,
     DBIERR_WRONGDRVTYPE,
     DBIERR_CANNOTLOADDRV,
     DBIERR_CANNOTLOADLDDRV,
     DBIERR_VENDINITFAIL,
     DBIERR_AMBJOASY,
     DBIERR_AMBJOSYM,
     DBIERR_AMBOUTEX,
     DBIERR_AMBOUTPR,
     DBIERR_AMBSYMAS,
     DBIERR_ASETOPER,
     DBIERR_AVENUMDA,
     DBIERR_BADEXPR1,
     DBIERR_BADFLDOR,
     DBIERR_BADVNAME,
     DBIERR_BITMAPER,
     DBIERR_CALCBADR,
     DBIERR_CALCTYPE,
     DBIERR_CHGTO1TI,
     DBIERR_CHGTOCHG,
     DBIERR_CHGTOEXP,
     DBIERR_CHGTOINS,
     DBIERR_CHGTONEW,
     DBIERR_CHGTOVAL,
     DBIERR_CHKMRKFI,
     DBIERR_CHNAMBIG,
     DBIERR_CHUNKERR,
     DBIERR_COLUM255,
     DBIERR_CONAFTAS,
     DBIERR_DEL1TIME,
     DBIERR_DELAMBIG,
     DBIERR_DELFRDEL,
     DBIERR_EGFLDTYP,
     DBIERR_EXAMINOR,
     DBIERR_EXPRTYPS,
     DBIERR_EXTRACOM,
     DBIERR_EXTRAORO,
     DBIERR_EXTRAQRO,
     DBIERR_FIND1ATT,
     DBIERR_FINDANST,
     DBIERR_GRPNOSET,
     DBIERR_GRPSTROW,
     DBIERR_IDFINLCO,
     DBIERR_IDFPERLI,
     DBIERR_INANEXPR,
     DBIERR_INS1TIME,
     DBIERR_INSAMBIG,
     DBIERR_INSDELCH,
     DBIERR_INSEXPRR,
     DBIERR_INSTOINS,
     DBIERR_ISARRAY,
     DBIERR_LABELERR,
     DBIERR_LINKCALC,
     DBIERR_LNGVNAME,
     DBIERR_LONGQURY,
     DBIERR_MEMVPROC,
     DBIERR_MISNGCOM,
     DBIERR_MISNGRPA,
     DBIERR_MISSRTQU,
     DBIERR_NAMTWICE,
     DBIERR_NOCHKMAR,
     DBIERR_NODEFOCC,
     DBIERR_NOGROUPS,
     DBIERR_NONSENSE,
     DBIERR_NOPATTER,
     DBIERR_NOSUCHDA,
     DBIERR_NOVALUE,
     DBIERR_ONLYCONS,
     DBIERR_ONLYSETR,
     DBIERR_OUTSENS1,
     DBIERR_OUTTWIC1,
     DBIERR_PAROWCNT,
     DBIERR_PERSEPAR,
     DBIERR_PROCPLSW,
     DBIERR_PWINSRTS,
     DBIERR_PWMODRTS,
     DBIERR_QBEFLDFOUND,
     DBIERR_QBENOFENCE,
     DBIERR_QBENOFENCET,
     DBIERR_QBENOHEADERT,
     DBIERR_QBENOTAB,
     DBIERR_QBENUMCOLS,
     DBIERR_QBEOPENTAB,
     DBIERR_QBETWICE,
     DBIERR_QRYNOANSWER,
     DBIERR_QRYNOTPREP,
     DBIERR_QUAINDEL,
     DBIERR_QUAININS,
     DBIERR_RAGININS,
     DBIERR_RAGINSET,
     DBIERR_ROWUSERR,
     DBIERR_SETEXPEC,
     DBIERR_SETVAMB1,
     DBIERR_SETVBAD1,
     DBIERR_SETVDEF1,
     DBIERR_SUMNUMBE,
     DBIERR_TBLISWP3,
     DBIERR_TOKENNOT,
     DBIERR_TWOOUTR1,
     DBIERR_TYPEMISM,
     DBIERR_UNRELQ1,
     DBIERR_UNUSEDST,
     DBIERR_USEINSDE,
     DBIERR_USEOFCHG,
     DBIERR_VARMUSTF,
     DBIERR_REGISTER,
     DBIERR_LONGEXPR,
     DBIERR_REFRESH,
     DBIERR_CANCEXCEPT,
     DBIERR_DBEXCEPT,
     DBIERR_MEMEXCEPT,
     DBIERR_FATALEXCEPT,
     DBIERR_QRYNIY,
     DBIERR_BADFORMAT,
     DBIERR_QRYEMPTY,
     DBIERR_NOQRYTOPREP,
     DBIERR_BUFFTOOSMALL,
     DBIERR_QRYNOTPARSE,
     DBIERR_NOTHANDLE,
     DBIERR_QRYSYNTERR,
     DBIERR_QXFLDCOUNT,
     DBIERR_QXFLDSYMNOTFOUND,
     DBIERR_QXTBLSYMNOTFOUND,
     DBIERR_BLOBTERM,
     DBIERR_BLOBERR,
     DBIERR_RESTARTQRY,
     DBIERR_UNKNOWNANSTYPE,
     DBIERR_SQLG_MDIST,
     DBIERR_SQLG_NOARI,
     DBIERR_SQLG_LIKEN,
     DBIERR_SQLG_ALPHO,
     DBIERR_SQLG_DATEO,
     DBIERR_SQLG_RELOP,
     DBIERR_SQLG_ONLYC,
     DBIERR_SQLG_CNTLN,
     DBIERR_SQLG_CHINI,
     DBIERR_SQLG_UNION,
     DBIERR_SQLG_SLFIN,
     DBIERR_SQLG_OTJVR,
     DBIERR_SQLG_STROW,
     DBIERR_SQLG_QUANT,
     DBIERR_SQLG_REGSO,
     DBIERR_SQLG_COUNT,
     DBIERR_SQLG_AVERA,
     DBIERR_SQLG_DATEA,
     DBIERR_SQLG_BADPT,
     DBIERR_SQLG_RELPA,
     DBIERR_SQLG_PATRN,
     DBIERR_SQLG_FNDSU,
     DBIERR_SQLG_IFDCS,
     DBIERR_SQLG_IDCCO,
     DBIERR_SQLG_ONLYI,
     DBIERR_SQLG_SQLDIALECT,
     DBIERR_SQLG_NOQUERY,
     DBIERR_BLOBGROUP,
     DBIERR_QRYNOPROP,
     DBIERR_ANSTYPNOTSUP,
     DBIERR_ANSALIASNOTSUP,
     DBIERR_INSBLOBREQ,
     DBIERR_CHGUNIQUENDXREQ,
     DBIERR_DELUNIQUENDXREQ,
     DBIERR_SQLNOFULLUPDATE,
     DBIERR_CANTEXECREMOTE,
     DBIERR_UNEXPECTEDEOC,
     DBIERR_SQLPARAMNOTSET,
     DBIERR_QUERYTOOLONG,
     DBIERR_INTERFACEVER,
     DBIERR_INDEXOUTOFDATE,
     DBIERR_OLDVERSION,
     DBIERR_VALFILEINVALID,
     DBIERR_BLOBVERSION,
     DBIERR_ENGQRYMISMATCH,
     DBIERR_SERVERVERSION,
     DBIERR_NOTSUPPORTED,
     DBIERR_NIY,
     DBIERR_TABLESQL,
     DBIERR_SEARCHCOLREQD,
     DBIERR_NOMULTCONNECT,
     DBIERR_INVALIDDBSPEC,
     DBIERR_UNKNOWNDBTYPE,
     DBIERR_INVALIDSYSDATA,
     DBIERR_UNKNOWNNETTYPE,
     DBIERR_NOTONTHATNET,
     DBIERR_INVALIDCFGPARAM,
     DBIERR_OBJIMPLICITLYDROPPED,
     DBIERR_OBJMAYBETRUNCATED,
     DBIERR_OBJIMPLICITLYMODIFIED,
     DBIERR_VALIDATEDATA,
     DBIERR_VALFIELDMODIFIED,
     DBIERR_TABLELEVELCHANGED,
     DBIERR_COPYLINKEDTABLES,
     DBIERR_OTHERSERVERLOADED,
     DBIERR_OBJIMPLICITLYTRUNCATED,
     DBIERR_VCHKMAYNOTBEENFORCED,
     DBIERR_MULTIPLEUNIQRECS,
     DBIERR_FIELDMUSTBETRIMMED,
     DBIERR_FILEEXISTS,
     DBIERR_BLOBMODIFIED,
     DBIERR_UNKNOWNSQL,
     DBIERR_TABLEEXISTS,
     DBIERR_PDX10TABLE,
     DBIERR_DIFFSORTORDER,
     DBIERR_DIRINUSEBYOLDVER,
     DBIERR_PDX35LDDRIVER,
     DBIERR_REQOPTPARAM,
     DBIERR_INVALIDOPTPARAM
 );


const
  BDEPREFIX = 'DBIERR_';

Procedure GetDBIErrorStr( Error : DBIResult; Var ErrStr : ShortString );
Var
  i : Integer;
begin
  For i := Low( BdeErrorMap ) to High( BdeErrorMap ) do
    if ( BdeErrorMap[ i ] = Error ) then
    begin
      ErrStr := BDEPREFIX + LoadStr( BDE_ERROR_OFFSET + i );
      Exit;
    end;
  ErrStr := Format( BAPI_UNKNOWN_BDE_ERROR, [ Error ] );
end;


Procedure TestResult( ResultCode : DBIResult );
begin
  If ( ResultCode <> DBIERR_NONE ) then
    ThrowException( ResultCode );
end;


Procedure ThrowException( Error : DBIResult );
begin
  Raise ETitanEngineError.Create( Error );
end;


Procedure ThrowExceptionMsg( Error : DBIResult; Const ErrorMsg : ShortString );
begin
  Raise ETitanEngineError.CreateMsg( Error, ErrorMsg );
end;


Procedure ThrowEOFException;
begin
  Raise ETitanEOFError.CreateEOF;
end;


Procedure ThrowBOFException;
begin
  Raise ETitanBOFError.CreateBOF;
end;


Function ValidateValue( Expr : Boolean; Error : DBIResult ) : Boolean;
begin
  If not Expr then
    ThrowException( Error );
  Result := TRUE;
end;


Procedure Not_Used( FuncConst : Integer );
begin
  Not_Supported( FuncConst );
end;


Procedure Not_Supported( FuncConst : Integer );
begin
  ThrowExceptionMsg( DBIERR_NOTSUPPORTED, LoadStr( FuncConst ) );
end;


Function ValidatePointer( P : Pointer; Error : DBIResult ) : Pointer;
begin
  If ( P = NIL ) then
    ThrowException( Error );
  Result := P;
end;


Function ValidateParameter( P : Pointer ) : Pointer;
begin
  Result := ValidatePointer( P, DBIERR_INVALIDPARAM );
end;


Function ValidateHandle( P : Pointer ) : Pointer;
begin
  Result := ValidatePointer( P, DBIERR_INVALIDHNDL );
end;

Constructor TErrorStack.Create( MaxItems : Word );
begin
  Inherited Create;
  FMaxItems := MaxItems;
  If ( FMaxItems > MAX_STACK_SIZE ) then
    FMaxItems := MAX_STACK_SIZE;
  Clear;
end;


Destructor TErrorStack.Destroy;
begin
  If ( FStack <> NIL ) then
    FreeMem( FStack, FMaxItems * SizeOf( TErrorStackEntry ) );
  FStack := NIL;
  Inherited Destroy;
end;


Procedure TErrorStack.Clear;
begin
  FLastEntry := 0;
end;


Function TErrorStack.PushError( Rec : TErrorStackEntry ) : Boolean;
var
  BytesToMove : Word;
  Dest        : PChar;
begin
  If ( FStack = NIL ) then
    GetMem( FStack, FMaxItems * SizeOf( TErrorStackEntry ) );
  If WasError then
  begin
    If ( FLastEntry < FMaxItems ) then
      BytesToMove := FLastEntry * SizeOf( TErrorStackEntry )
    else
      BytesToMove := Pred( FMaxItems ) * SizeOf( TErrorStackEntry );
    Dest := PChar( FStack );
    Inc( Dest, SizeOf( TErrorStackEntry ) );
    Move( FStack^, Dest^, BytesToMove );
  end;
  FStack^[ 1 ] := Rec;
  Inc( FLastEntry );
  Result := TRUE;
end;


Function TErrorStack.PopError( Var Rec : TErrorStackEntry ) : Boolean;
var
  BytesToMove : Word;
  Dest        : PChar;
begin
  If WasError then
  begin
    Rec    := FStack^[ 1 ];
    Result := TRUE;
    If ( FLastEntry < FMaxItems ) then
      BytesToMove := Pred( FLastEntry ) * SizeOf( TErrorStackEntry )
    else
      BytesToMove := Pred( FMaxItems ) * SizeOf( TErrorStackEntry );
    Dest := PChar( FStack );
    Inc( Dest, SizeOf( TErrorStackEntry ) );
    Move( Dest^, FStack^, BytesToMove );
    Dec( FLastEntry );
  end
  else
  begin
    MoveZero( Rec, SizeOf( Rec ) );
    Result     := FALSE;
  end;
end;


Procedure TErrorStack.AddError( E : ETitanEngineError );
Var
  ErrorEntry : TErrorStackEntry;
  tmp        : ShortString;
begin
  MoveZero( ErrorEntry, SizeOf( ErrorEntry ) );
  With ErrorEntry Do
  begin
    BasicInfo.iError := E.DbiError;
    GetDBIErrorStr( BasicInfo.iError, tmp );
    If ( Pos( BDEPREFIX, tmp ) = 0 ) then
      { We don't have a DBIERR_ type error }
      tmp := Format( E.DBInterfaceErrorFormat, [ E.NativeError ] );
    StrPCopy( @BasicInfo.szErrCode, tmp );
    NativeError      := E.NativeError;
    If ( Length( E.NativeErrorMsg ) > 0 ) then
      StrPCopy( @NativeMessage, E.NativeErrorMsg );
    If ( Length( E.DBIErrorMsg ) > 0 ) then
      StrPCopy( @BasicInfo.szContext[ 1 ], E.DBIErrorMsg );
(*
    StrCopy( @BasicInfo.szContext[ 2 ], PChar( E.NativeErrorMsg ) );
*)
  end;
  PushError( ErrorEntry );
end;


Function TErrorStack.GetError( Index : Word; Var Rec : TErrorStackEntry ) : Boolean;
begin
  Result := ( Index <= FLastEntry );
  If Result then
    Rec := FStack^[ Index ];
end;


Function TErrorStack.WasError : Boolean;
begin
  Result := ( FLastEntry > 0 );
end;


{ Move these functions into BSEERRS with a parameter }
Function MapDBIToNative( pMapArray : PMapRecArray; Items, Error : SmallInt ) : DBIResult;
Var
  i : Integer;
  P : pMapRec;
begin
  if ( Error = DBIERR_NONE ) then
  begin
    Result := 0;
    Exit;
  end;
  P := pMapRec( pMapArray );
  For i := 1 to Items do
  begin
    if ( P^.BDEError = Error ) then
    begin
      Result := P^.NatError;
      Exit;
    end;
    Inc( P );
  end;
  Result := Error;
end;


Function MapNativeToDBI( pMapArray : PMapRecArray; Items, Error : SmallInt ) : DBIResult;
Var
  i : Integer;
  P : pMapRec;
begin
  if ( Error <> 0 ) then
  begin
    P := pMapRec( pMapArray );
    For i := 1 to Items do
    begin
      if ( P^.NatError = Error ) then
      begin
        Result := P^.BDEError;
        Exit;
      end;
      Inc( P );
    end;
  end;
  Result := DBIResult( Error );
end;


end.
