ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/udr/client/IB.pas
(Generate patch)

Comparing ibx/trunk/fbintf/IB.pas (file contents):
Revision 117 by tony, Mon Jan 22 13:58:11 2018 UTC vs.
Revision 350 by tony, Wed Oct 20 14:58:56 2021 UTC

# Line 73 | Line 73 | unit IB;
73   {$IFEND}
74   {$ENDIF}
75  
76 + {$IFNDEF LEGACYFIREBIRDAPIONLY}
77   {$DEFINE USEFIREBIRD3API}
78 + {$ENDIF}
79 + {$IFNDEF FIREBIRD3APIONLY}
80   {$DEFINE USELEGACYFIREBIRDAPI}
81 + {$ENDIF}
82  
83   {
84    This unit defines the interfaces used to provide the Pascal Language
# Line 122 | Line 126 | unit IB;
126   interface
127  
128   uses
129 <  Classes, SysUtils, DB, FBMessages, IBExternals;
129 >  Classes,
130 >  {$IFDEF WINDOWS}Windows, {$ENDIF}
131 >  {$IFDEF FPC} Dynlibs, {$ENDIF}
132 >  SysUtils, DB, FBMessages, IBExternals, FmtBcd;
133  
134   const
135    {Interface version information}
136    FBIntf_Major = 1;
137 <  FBIntf_Minor = 0;
137 >  FBIntf_Minor = 3;
138    FBIntf_Release = 2;
139 <  FBIntf_Version = '1.0.2';
139 >  FBIntf_Version = '1.3.2';
140 >
141 > const
142 >  {DPB, TPB and SPB Parameter Block Name Prefixes}
143 >  DPBPrefix = 'isc_dpb_';
144 >  TPBPrefix = 'isc_tpb_';
145 >
146 > const
147 >  {Time Zone ID constraint}
148 >  MaxOffsetTimeZoneID = 2879; {lower values represent a time zone offset between
149 >                               -23:59 and 23:59. Higher values are keys to the
150 >                               Time Zone database.}
151 >
152 >  TimeZoneID_GMT = 23*minsPerHour + 59;
153 >  decimillisecondsPerSecond = 10000;
154 >  TimeZoneDisplacementDelta = 60*23 + 59; {23:59 in minutes}
155  
156   {These include files are converted from the 'C' originals in the Firebird API
157   and define the various constants used by the API}
158  
159   {$I 'include/consts_pub.inc'}
160 + {$I 'include/dyn_consts.inc'}
161   {$I 'include/inf_pub.inc'}
162   {$I 'include/configkeys.inc'}
163 + {$I 'include/blr.inc'}
164  
165   {The following constants define the values return by calls to the GetSQLType
166   methods provided by several of the interfaces defined below.}
# Line 158 | Line 182 | const
182    SQL_TYPE_TIME                  =        560;
183    SQL_TYPE_DATE                  =        570;
184    SQL_INT64                      =        580;
185 +  SQL_TIMESTAMP_TZ_EX            =        32748;
186 +  SQL_TIME_TZ_EX                 =        32750;
187 +  SQL_INT128                     =        32752;
188    SQL_BOOLEAN                    =        32764;
189 +  SQL_TIMESTAMP_TZ               =        32754;
190 +  SQL_TIME_TZ                    =        32756;
191 +  SQL_DEC_FIXED                  =        32758;    {FB4 Beta 1 only}
192 +  SQL_DEC16                      =        32760;
193 +  SQL_DEC34                      =        32762;
194 +  SQL_NULL                       =        32766;
195    SQL_DATE                       =        SQL_TIMESTAMP;
196  
197   type
# Line 173 | Line 206 | type
206     PISC_QUAD            = ^TISC_QUAD;
207  
208   {$IFNDEF FPC}
209 + {Delphi missing definitions}
210 + type
211 +  TLibHandle = THandle;
212 +
213 + const
214 +  NilHandle = 0;
215 +  DirectorySeparator = '\';
216 +
217   {Delphi only seems to define CP_UTF8 and CP_UTF16}
218   const
219    CP_ACP     = 0;     // default to ANSI code page
# Line 195 | Line 236 | type
236                    SQLGetSegment, SQLPutSegment,
237                    SQLExecProcedure, SQLStartTransaction,
238                    SQLCommit, SQLRollback,
239 <                  SQLSelectForUpdate, SQLSetGenerator);
239 >                  SQLSelectForUpdate, SQLSetGenerator,
240 >                  SQLSavePoint);
241  
242    TFBStatusCode = cardinal;
243    TByteArray = array of byte;
244 +  TFBTimeZoneID = ISC_USHORT;
245  
246 +  IFirebirdAPI = interface;
247    IAttachment = interface;
248    ITransaction = interface;
249 +  IStatement = interface;
250  
251    {The IParameterBlock interface provides the template for all parameter
252     block interfaces}
# Line 216 | Line 261 | type
261      property Items[index: integer]: _IItem read getItems; default;
262    end;
263  
264 +  IParameterBlockWithTypeNames<_IItem> = interface(IParameterBlock<_IItem>)
265 +    function AddByTypeName(ParamTypeName: AnsiString): _IItem;
266 +    function GetDPBParamTypeName(ParamType: byte): Ansistring; deprecated 'Use Get ParamTypeName';
267 +    function GetParamTypeName(ParamType: byte): Ansistring;
268 +  end;
269 +
270    {IParameterBlockItem is not used on its own but instead provides a base type for
271     different parameter block items }
272  
# Line 233 | Line 284 | type
284      property AsInteger: integer read getAsInteger write SetAsInteger;
285    end;
286  
287 +  IParameterBlockItemWithTypeName = interface(IParameterBlockItem)
288 +    function getParamTypeName: AnsiString;
289 +  end;
290  
291    {The IStatus interface provides access to error information, if any, returned
292     by the last API call. It can also be used to customise the error message
# Line 241 | Line 295 | type
295     This interface can be accessed from IFirebirdAPI.
296     }
297  
298 +   TIBDataBaseErrorMessage    = (ShowSQLCode,
299 +                                   ShowIBMessage,
300 +                                   ShowSQLMessage);
301 +
302 +   TIBDataBaseErrorMessages   = set of TIBDataBaseErrorMessage;
303 +
304 +   TStatusCode = long;
305 +
306    IStatus = interface
307      ['{34167722-af38-4831-b08a-93162d58ede3}']
308 <    function GetIBErrorCode: Long;
309 <    function Getsqlcode: Long;
308 >    function GetIBErrorCode: TStatusCode;
309 >    function Getsqlcode: TStatusCode;
310      function GetMessage: AnsiString;
311      function CheckStatusVector(ErrorCodes: array of TFBStatusCode): Boolean;
312      function GetIBDataBaseErrorMessages: TIBDataBaseErrorMessages;
# Line 267 | Line 329 | type
329      function GetSQLTypeName: AnsiString;
330      function GetScale: integer;
331      function GetSize: cardinal;
332 +    function GetCharSetWidth: integer;
333      function GetCharSetID: cardinal;
334      function GetTableName: AnsiString;
335      function GetColumnName: AnsiString;
# Line 305 | Line 368 | type
368      function GetAsBoolean(index: array of integer): boolean;
369      function GetAsCurrency(index: array of integer): Currency;
370      function GetAsInt64(index: array of integer): Int64;
371 <    function GetAsDateTime(index: array of integer): TDateTime;
371 >    function GetAsDateTime(index: array of integer): TDateTime; overload;
372 >    procedure GetAsDateTime(index: array of integer; var aDateTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload;
373 >    procedure GetAsDateTime(index: array of integer; var aDateTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload;
374 >    procedure GetAsTime(index: array of integer; var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID; OnDate: TDateTime); overload;
375 >    procedure GetAsTime(index: array of integer; var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString; OnDate: TDateTime); overload;
376 >    function GetAsUTCDateTime(index: array of integer): TDateTime;
377      function GetAsDouble(index: array of integer): Double;
378      function GetAsFloat(index: array of integer): Float;
379      function GetAsLong(index: array of integer): Long;
380      function GetAsShort(index: array of integer): Short;
381      function GetAsString(index: array of integer): AnsiString;
382      function GetAsVariant(index: array of integer): Variant;
383 +    function GetAsBCD(index: array of integer): tBCD;
384      procedure SetAsInteger(index: array of integer; AValue: integer);
385      procedure SetAsBoolean(index: array of integer; AValue: boolean);
386      procedure SetAsCurrency(index: array of integer; Value: Currency);
387      procedure SetAsInt64(index: array of integer; Value: Int64);
388      procedure SetAsDate(index: array of integer; Value: TDateTime);
389 +    procedure SetAsDateTime(index: array of integer; Value: TDateTime); overload;
390 +    procedure SetAsDateTime(index: array of integer; aValue: TDateTime; aTimeZoneID: TFBTimeZoneID); overload;
391 +    procedure SetAsDateTime(index: array of integer; aValue: TDateTime; aTimeZone: AnsiString); overload;
392 +    procedure SetAsTime(index: array of integer; Value: TDateTime); overload;
393 +    procedure SetAsTime(index: array of integer; aValue: TDateTime; OnDate: TDateTime; aTimeZoneID: TFBTimeZoneID); overload;
394 +    procedure SetAsTime(index: array of integer; aValue: TDateTime; OnDate: TDateTime; aTimeZone: AnsiString); overload;
395 +    procedure SetAsUTCDateTime(index: array of integer; aUTCTime: TDateTime);
396      procedure SetAsLong(index: array of integer; Value: Long);
321    procedure SetAsTime(index: array of integer; Value: TDateTime);
322    procedure SetAsDateTime(index: array of integer; Value: TDateTime);
397      procedure SetAsDouble(index: array of integer; Value: Double);
398      procedure SetAsFloat(index: array of integer; Value: Float);
399      procedure SetAsShort(index: array of integer; Value: Short);
400      procedure SetAsString(index: array of integer; Value: AnsiString);
401      procedure SetAsVariant(index: array of integer; Value: Variant);
402 +    procedure SetAsBcd(index: array of integer; aValue: tBCD);
403      procedure SetBounds(dim, UpperBound, LowerBound: integer);
404      function GetAttachment: IAttachment;
405      function GetTransaction: ITransaction;
# Line 395 | Line 470 | type
470      the output of an SQL Statement.
471    }
472  
473 +  TIBDateTimeFormats = (dfTimestamp, {SQL TIMESTAMP}
474 +                        dfDateTime,   {SQL DATETIME}
475 +                        dfTime,      {SQL TIME}
476 +                        dfTimestampTZ, {SQL_TIMESTAMP_TZ}
477 +                        dfTimeTZ);       {SQLTIME_TZ
478 +
479    { IColumnMetaData }
480  
481    IColumnMetaData = interface
# Line 411 | Line 492 | type
492      function getScale: integer;
493      function getCharSetID: cardinal;
494      function getCodePage: TSystemCodePage;
495 +    function GetCharSetWidth: integer;
496      function getIsNullable: boolean;
497      function GetSize: cardinal;
498      function GetArrayMetaData: IArrayMetaData; {Valid only for Array SQL Type}
499      function GetBlobMetaData: IBlobMetaData; {Valid only for Blob SQL Type}
500 +    function GetDateTimeStrLength(DateTimeFormat: TIBDateTimeFormats): integer;
501 +    function GetStatement: IStatement;
502 +    function GetTransaction: ITransaction;
503      property Name: AnsiString read GetName;
504      property Size: cardinal read GetSize;
505      property SQLType: cardinal read GetSQLType;
# Line 456 | Line 541 | type
541  
542    ISQLData = interface(IColumnMetaData)
543      ['{3f493e31-7e3f-4606-a07c-b210b9e3619d}']
544 +    function GetStrDataLength: short;
545      function GetAsBoolean: boolean;
546      function GetAsCurrency: Currency;
547      function GetAsInt64: Int64;
548 <    function GetAsDateTime: TDateTime;
548 >    function GetAsDateTime: TDateTime; overload;
549 >    procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload;
550 >    procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload;
551 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID; OnDate: TDateTime); overload;
552 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString; OnDate: TDateTime); overload;
553 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload;
554 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload;
555 >    function GetAsUTCDateTime: TDateTime;
556      function GetAsDouble: Double;
557      function GetAsFloat: Float;
558      function GetAsLong: Long;
# Line 472 | Line 565 | type
565      function GetAsBlob: IBlob; overload;
566      function GetAsBlob(BPB: IBPB): IBlob; overload;
567      function GetAsArray: IArray;
568 +    function GetAsBCD: tBCD;
569      property AsDate: TDateTime read GetAsDateTime;
570      property AsBoolean:boolean read GetAsBoolean;
571      property AsTime: TDateTime read GetAsDateTime;
# Line 489 | Line 583 | type
583      property AsVariant: Variant read GetAsVariant ;
584      property AsBlob: IBlob read GetAsBlob;
585      property AsArray: IArray read GetAsArray;
586 +    property AsBCD: tBCD read GetAsBCD;
587      property IsNull: Boolean read GetIsNull;
588      property Value: Variant read GetAsVariant;
589    end;
# Line 502 | Line 597 | type
597    IResults = interface
598      ['{e836b2bb-93d1-4bbf-a8eb-7ce535de3bb5}']
599     function getCount: integer;
600 +   function GetStatement: IStatement;
601     function GetTransaction: ITransaction;
602     function ByName(Idx: AnsiString): ISQLData;
603     function getSQLData(index: integer): ISQLData;
# Line 518 | Line 614 | type
614    }
615    IResultSet = interface(IResults)
616      ['{0ae4979b-7857-4e8c-8918-ec6f155b51a0}']
617 <    function FetchNext: boolean;
617 >    function FetchNext: boolean; {fetch next record}
618 >    function FetchPrior: boolean; {fetch previous record}
619 >    function FetchFirst:boolean; {fetch first record}
620 >    function FetchLast: boolean; {fetch last record}
621 >    function FetchAbsolute(position: Integer): boolean; {fetch record by its absolute position in result set}
622 >    function FetchRelative(offset: Integer): boolean; {fetch record by position relative to current}
623      function GetCursorName: AnsiString;
624 +    function IsBof: boolean;
625      function IsEof: boolean;
626      procedure Close;
627    end;
628  
629    {The ISQLParam interface is used to provide access to each parameter in a
630 <   parametised SQL Statement. It subclasses IColumnMetaData and this part of
529 <   the interface may be used to access information on the expected SQL Type, etc.
530 <
531 <   It also subclasses ISQLData and this part of the interface may be used to access
532 <   current values for each parameter.
533 <
534 <   Otherwise, the interface comprises the Setter Methods and properties used to
630 >   parametised SQL Statement. The interface comprises the Setter Methods and properties used to
631     set the value of each parameter.
632  
633     Automatic conversion is provided to and from strings. That is GetAsString and
634     SetAsString are safe to use for sql types other than boolean - provided automatic
635     conversion is possible.
636 +
637 +   ISQLParam is subclassed from the IParamMetaData interface. This interface provides
638 +   access to the parameter metadata. This metadata is mutable and can change after
639 +   a parameter is set to a given value. This is acceptable as long as the parameter
640 +   metadata is type compatible with the underlying column metadata and hence the
641 +   parameter value can be converted by Firebird into a value acceptable by the
642 +   underlying column. The column metadata, which is unmutable, can be obtained
643 +   by the ISQLParam.getColMetadata interface. When a statement is prepared, the
644 +   parameter metadata is always initialised to the column metadata.
645    }
646  
647 <  ISQLParam = interface
648 <    ['{b22b4578-6d41-4807-a9a9-d2ec8d1d5a14}']
544 <    function GetIndex: integer;
647 >  IParamMetaData = interface
648 >  ['{4e148c4e-2d48-4991-a263-f66eca05c6aa}']
649      function GetSQLType: cardinal;
650      function GetSQLTypeName: AnsiString;
651      function getSubtype: integer;
548    function getName: AnsiString;
652      function getScale: integer;
653      function getCharSetID: cardinal;
654      function getCodePage: TSystemCodePage;
655      function getIsNullable: boolean;
656      function GetSize: cardinal;
657 +    property SQLType: cardinal read GetSQLType;
658 +  end;
659 +
660 +  ISQLParam = interface(IParamMetaData)
661 +    ['{b22b4578-6d41-4807-a9a9-d2ec8d1d5a14}']
662 +    function getColMetadata: IParamMetaData;
663 +    function GetIndex: integer;
664 +    function getName: AnsiString;
665      function GetAsBoolean: boolean;
666      function GetAsCurrency: Currency;
667      function GetAsInt64: Int64;
668 <    function GetAsDateTime: TDateTime;
668 >    function GetAsDateTime: TDateTime; overload;
669 >    procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload;
670 >    procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload;
671 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID; OnDate: TDateTime); overload;
672 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString; OnDate: TDateTime); overload;
673 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload;
674 >    procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload;
675 >    function GetAsUTCDateTime: TDateTime;
676      function GetAsDouble: Double;
677      function GetAsFloat: Float;
678      function GetAsLong: Long;
# Line 566 | Line 684 | type
684      function GetAsVariant: Variant;
685      function GetAsBlob: IBlob;
686      function GetAsArray: IArray;
687 +    function GetAsBCD: tBCD;
688 +    function GetStatement: IStatement;
689 +    function GetTransaction: ITransaction;
690      procedure Clear;
691      function GetModified: boolean;
692      procedure SetAsBoolean(AValue: boolean);
# Line 573 | Line 694 | type
694      procedure SetAsInt64(aValue: Int64);
695      procedure SetAsDate(aValue: TDateTime);
696      procedure SetAsLong(aValue: Long);
697 <    procedure SetAsTime(aValue: TDateTime);
698 <    procedure SetAsDateTime(aValue: TDateTime);
697 >    procedure SetAsTime(aValue: TDateTime); overload;
698 >    procedure SetAsTime(aValue: TDateTime; OnDate: TDateTime; aTimeZoneID: TFBTimeZoneID); overload;
699 >    procedure SetAsTime(aValue: TDateTime; OnDate: TDateTime; aTimeZone: AnsiString); overload;
700 >    procedure SetAsTime(aValue: TDateTime; aTimeZoneID: TFBTimeZoneID); overload;
701 >    procedure SetAsTime(aValue: TDateTime; aTimeZone: AnsiString); overload;
702 >    procedure SetAsDateTime(aValue: TDateTime); overload;
703 >    procedure SetAsDateTime(aValue: TDateTime; aTimeZoneID: TFBTimeZoneID); overload;
704 >    procedure SetAsDateTime(aValue: TDateTime; aTimeZone: AnsiString); overload;
705 >    procedure SetAsUTCDateTime(aUTCTime: TDateTime);
706      procedure SetAsDouble(aValue: Double);
707      procedure SetAsFloat(aValue: Float);
708      procedure SetAsPointer(aValue: Pointer);
# Line 586 | Line 714 | type
714      procedure SetAsArray(anArray: IArray);
715      procedure SetAsQuad(aValue: TISC_QUAD);
716      procedure SetCharSetID(aValue: cardinal);
717 +    procedure SetAsBcd(aValue: tBCD);
718      property AsDate: TDateTime read GetAsDateTime write SetAsDate;
719      property AsBoolean:boolean read GetAsBoolean write SetAsBoolean;
720      property AsTime: TDateTime read GetAsDateTime write SetAsTime;
# Line 602 | Line 731 | type
731      property AsVariant: Variant read GetAsVariant write SetAsVariant;
732      property AsBlob: IBlob read GetAsBlob write SetAsBlob;
733      property AsArray: IArray read GetAsArray write SetAsArray;
734 +    property AsBCD: tBCD read GetAsBCD write SetAsBCD;
735      property AsQuad: TISC_QUAD read GetAsQuad write SetAsQuad;
736      property Value: Variant read GetAsVariant write SetAsVariant;
737      property IsNull: Boolean read GetIsNull write SetIsNull;
738      property IsNullable: Boolean read GetIsNullable;
739      property Modified: Boolean read getModified;
740      property Name: AnsiString read GetName;
611    property SQLType: cardinal read GetSQLType;
741    end;
742  
743     {
# Line 622 | Line 751 | type
751      function getSQLParam(index: integer): ISQLParam;
752      function ByName(Idx: AnsiString): ISQLParam ;
753      function GetModified: Boolean;
754 +    function GetHasCaseSensitiveParams: Boolean;
755      property Modified: Boolean read GetModified;
756      property Params[index: integer]: ISQLParam read getSQLParam; default;
757      property Count: integer read getCount;
# Line 632 | Line 762 | type
762                  psRealTime, psUserTime, psBuffers,
763                  psReads, psWrites, psFetches,psDeltaMemory);
764  
765 <  TPerfCounters = array[TPerfStats] of comp;
765 >  TPerfCounters = array[TPerfStats] of Int64;
766 >
767 >  {Batch Query Execution Support}
768 >
769 >  TBatchCompletionState = (bcExecuteFailed, bcSuccessNoInfo, bcNoMoreErrors);
770 >
771 >  IBatchCompletion = interface
772 >  ['{9bc3d49d-16d9-4606-94e5-ee987103ad92}']
773 >    function getTotalProcessed: cardinal;
774 >    function getState(updateNo: cardinal): TBatchCompletionState;
775 >    function getStatusMessage(updateNo: cardinal): AnsiString;
776 >    function getUpdated: integer;
777 >    function getErrorStatus(var RowNo: integer; var status: IStatus): boolean;
778 >    end;
779  
780    {The IStatement interface provides access to an SQL Statement once it has been
781     initially prepared. The interface is returned from the IAttachment interface.
# Line 645 | Line 788 | type
788      function GetPlan: AnsiString;
789      function GetRowsAffected(var SelectCount, InsertCount, UpdateCount, DeleteCount: integer): boolean;
790      function GetSQLStatementType: TIBSQLStatementTypes;
791 +    function GetSQLStatementTypeName: AnsiString;
792      function GetSQLText: AnsiString;
793 +    function GetProcessedSQLText: AnsiString;
794      function GetSQLDialect: integer;
795      function IsPrepared: boolean;
796 <    procedure Prepare(aTransaction: ITransaction=nil);
796 >    function HasBatchMode: boolean;
797 >    function IsInBatchMode: boolean;
798 >    procedure Prepare(aTransaction: ITransaction=nil); overload;
799 >    procedure Prepare(CursorName: AnsiString; aTransaction: ITransaction=nil); overload;
800      function Execute(aTransaction: ITransaction=nil): IResults;
801 <    function OpenCursor(aTransaction: ITransaction=nil): IResultSet;
801 >    function OpenCursor(aTransaction: ITransaction=nil): IResultSet; overload;
802 >    function OpenCursor(Scrollable: boolean; aTransaction: ITransaction=nil): IResultSet; overload;
803      function GetAttachment: IAttachment;
804      function GetTransaction: ITransaction;
805      procedure SetRetainInterfaces(aValue: boolean);
806      procedure EnableStatistics(aValue: boolean);
807      function GetPerfStatistics(var stats: TPerfCounters): boolean;
808 +    {IBatch interface support}
809 +    procedure AddToBatch;
810 +    function ExecuteBatch(aTransaction: ITransaction=nil): IBatchCompletion;
811 +    procedure CancelBatch;
812 +    function GetBatchCompletion: IBatchCompletion;
813 +    function GetBatchRowLimit: integer;
814 +    procedure SetBatchRowLimit(aLimit: integer);
815 +    {Stale Reference Check}
816 +    procedure SetStaleReferenceChecks(Enable:boolean); {default true}
817 +    function GetStaleReferenceChecks: boolean;
818 +
819      property MetaData: IMetaData read GetMetaData;
820      property SQLParams: ISQLParams read GetSQLParams;
821      property SQLStatementType: TIBSQLStatementTypes read GetSQLStatementType;
# Line 672 | Line 832 | type
832     found in the Interbase 6.0 API Guide.
833    }
834  
835 <  ITPBItem = interface(IParameterBlockItem)
835 >  ITPBItem = interface(IParameterBlockItemWithTypeName)
836      ['{544c1f2b-7c12-4a87-a4a5-face7ea72671}']
837 +    function getParamTypeName: AnsiString;
838    end;
839  
840 <  ITPB = interface(IParameterBlock<ITPBItem>)
840 >  ITPB = interface(IParameterBlockWithTypeNames<ITPBItem>)
841      ['{7369b0ff-defe-437b-81fe-19b211d42d25}']
842    end;
843  
# Line 742 | Line 903 | type
903      function GetAttachment: IAttachment;
904    end;
905  
906 +  TTZTextOptions = (tzOffset,      {Time Zone Rendered as an offset to GMT}
907 +                    tzGMT,         {No Time Zone. Time part is always rendered in GMT}
908 +                    tzOriginalID); {Time Zone shown as originally entered}
909 +
910 +  {The ITimeZoneServices interface provides access to the time zone database
911 +   used for the attachment. It may be used in support of TIMESTAMP WITH TIME ZONE
912 +   and TIME WITH TIME ZONE data types.}
913 +
914 +  ITimeZoneServices = interface
915 +    ['{163821f5-ebef-42b9-ac60-8ac4b5c09954}']
916 +    {utility functions}
917 +    function TimeZoneID2TimeZoneName(aTimeZoneID: TFBTimeZoneID): AnsiString;
918 +    function TimeZoneName2TimeZoneID(aTimeZone: AnsiString): TFBTimeZoneID;
919 +    function LocalTimeToGMT(aLocalTime: TDateTime; aTimeZone: AnsiString): TDateTime; overload;
920 +    function LocalTimeToGMT(aLocalTime: TDateTime; aTimeZoneID: TFBTimeZoneID): TDateTime; overload;
921 +    function GMTToLocalTime(aGMTTime: TDateTime; aTimeZone: AnsiString): TDateTime; overload;
922 +    function GMTToLocalTime(aGMTTime: TDateTime; aTimeZoneID: TFBTimeZoneID): TDateTime; overload;
923 +    function GetEffectiveOffsetMins(aLocalTime: TDateTime; aTimeZone: AnsiString): integer; overload;
924 +    function GetEffectiveOffsetMins(aLocalTime: TDateTime; aTimeZoneID: TFBTimeZoneID): integer; overload;
925 +
926 +    {Time Zone DB Information}
927 +    function UsingRemoteTZDB: boolean;
928 +    procedure SetUseLocalTZDB(useLocalTZDB: boolean);
929 +    function GetLocalTimeZoneName: AnsiString;
930 +    function GetLocalTimeZoneID: TFBTimeZoneID;
931 +    procedure GetTimeZoneInfo(aTimeZone: AnsiString; OnDate: TDateTime;
932 +                           var ZoneOffset, DSTOffset, EffectiveOffset: integer);
933 +    {Configurable Options}
934 +    function GetTimeTZDate: TDateTime;
935 +    procedure SetTimeTZDate(aDate: TDateTime);
936 +    function GetTZTextOption: TTZTextOptions;
937 +    procedure SetTZTextOption(aOptionValue: TTZTextOptions);
938 +  end;
939 +
940    {The IDBInformation Interface.
941  
942     An IDBInformation interface is returned by the  IAttachment GetDBInformation
# Line 770 | Line 965 | type
965      function getSize: integer;
966      procedure getRawBytes(var Buffer);
967      function getAsString: AnsiString;
968 <    function getAsInteger: integer;
968 >    function getAsInteger: int64;
969      procedure DecodeIDCluster(var ConnectionType: integer; var DBFileName, DBSiteName: AnsiString);
970      function getAsBytes: TByteArray;
971 +    function getAsDateTime: TDateTime;
972      procedure DecodeVersionString(var Version: byte; var VersionString: AnsiString);
973      function getOperationCounts: TDBOperationCounts;
974      procedure DecodeUserNames(UserNames: TStrings);
# Line 781 | Line 977 | type
977      function GetCount: integer;
978      function GetItem(index: integer): IDBInfoItem;
979      function Find(ItemType: byte): IDBInfoItem;
980 <    property AsInteger: integer read getAsInteger;
980 >    property AsInteger: int64 read getAsInteger;
981      property AsString: AnsiString read GetAsString;
982      property Count: integer read GetCount;
983      property Items[index: integer]: IDBInfoItem read getItem; default;
# Line 799 | Line 995 | type
995      property Items[index: integer]: IDBInfoItem read getItem; default;
996    end;
997  
998 +  {The Database Information Request Block is used to pass requests for
999 +   database information where at least one item requested has a parameter.
1000 +   At present, this is only fb_info_page_contents which has a single
1001 +   integer parameter.}
1002 +
1003 +  IDIRBItem = interface(IParameterBlockItem)
1004 +    ['{d34a7511-8435-4a24-81a7-5103d218d234}']
1005 +  end;
1006 +
1007 +  IDIRB = interface(IParameterBlock<IDIRBItem>)
1008 +    ['{1010e5ac-0a8f-403b-a302-91625e9d9579}']
1009 +  end;
1010 +
1011 +
1012    {The Database Parameter Block (DPB).
1013  
1014     The DPB provides the parameters used when connecting to a database. It is allocated
# Line 810 | Line 1020 | type
1020     found in the Interbase 6.0 API Guide.
1021     }
1022  
1023 <  IDPBItem = interface(IParameterBlockItem)
1023 >  IDPBItem = interface(IParameterBlockItemWithTypeName)
1024      ['{123d4ad0-087a-4cd1-a344-1b3d03b30673}']
1025    end;
1026  
1027 <  IDPB = interface(IParameterBlock<IDPBItem>)
1028 <    ['{e676067b-1cf4-4eba-9256-9724f57e0d16}']
1029 <  end;
1027 >   IDPB = interface(IParameterBlockWithTypeNames<IDPBItem>)
1028 >     ['{e676067b-1cf4-4eba-9256-9724f57e0d16}']
1029 >   end;
1030  
1031    {The IAttachment interface provides access to a Database Connection. It may be
1032     used to:
# Line 847 | Line 1057 | type
1057  
1058    IAttachment = interface
1059      ['{466e9b67-9def-4807-b3e7-e08a35e7185c}']
1060 +    function getFirebirdAPI: IFirebirdAPI;
1061      function getDPB: IDPB;
1062      function AllocateBPB: IBPB;
1063 +    function AllocateDIRB: IDIRB;
1064      procedure Connect;
1065      procedure Disconnect(Force: boolean=false);
1066      function IsConnected: boolean;
# Line 863 | Line 1075 | type
1075      function ExecuteSQL(transaction: ITransaction; sql: AnsiString; SQLDialect: integer; params: array of const): IResults; overload;
1076      function ExecuteSQL(TPB: array of byte; sql: AnsiString; params: array of const): IResults; overload;
1077      function ExecuteSQL(transaction: ITransaction; sql: AnsiString; params: array of const): IResults; overload;
866    function OpenCursor(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer): IResultSet; overload;
1078      function OpenCursor(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1079 +                             Scrollable: boolean=false): IResultSet; overload;
1080 +    function OpenCursor(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1081 +                             params: array of const): IResultSet; overload;
1082 +    function OpenCursor(transaction: ITransaction; sql: AnsiString; Scrollable: boolean=false): IResultSet; overload;
1083 +    function OpenCursor(transaction: ITransaction; sql: AnsiString; Scrollable: boolean;
1084                               params: array of const): IResultSet; overload;
869    function OpenCursor(transaction: ITransaction; sql: AnsiString): IResultSet; overload;
1085      function OpenCursor(transaction: ITransaction; sql: AnsiString;
1086                               params: array of const): IResultSet; overload;
1087 <    function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer): IResultSet; overload;
1087 >    function OpenCursor(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; Scrollable: boolean;
1088 >                             params: array of const): IResultSet; overload;
1089      function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1090 +                             Scrollable: boolean=false): IResultSet; overload;
1091 +    function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1092 +                             params: array of const): IResultSet; overload;
1093 +    function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; Scrollable: boolean;
1094                               params: array of const): IResultSet; overload;
1095 <    function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString): IResultSet; overload;
1095 >    function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString; Scrollable: boolean=false): IResultSet; overload;
1096      function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString;
1097                               params: array of const): IResultSet; overload;
1098 <    function OpenCursorAtStart(sql: AnsiString): IResultSet; overload;
1098 >    function OpenCursorAtStart(transaction: ITransaction; sql: AnsiString; Scrollable: boolean;
1099 >                             params: array of const): IResultSet; overload;
1100 >    function OpenCursorAtStart(sql: AnsiString; Scrollable: boolean=false): IResultSet; overload;
1101 >    function OpenCursorAtStart(sql: AnsiString; Scrollable: boolean;
1102 >                             params: array of const): IResultSet; overload;
1103      function OpenCursorAtStart(sql: AnsiString;
1104                               params: array of const): IResultSet; overload;
1105 <    function Prepare(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer): IStatement; overload;
1106 <    function Prepare(transaction: ITransaction; sql: AnsiString): IStatement; overload;
1105 >    function Prepare(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; CursorName: AnsiString=''): IStatement; overload;
1106 >    function Prepare(transaction: ITransaction; sql: AnsiString; CursorName: AnsiString=''): IStatement; overload;
1107      function PrepareWithNamedParameters(transaction: ITransaction; sql: AnsiString;
1108 <                       aSQLDialect: integer; GenerateParamNames: boolean=false): IStatement; overload;
1108 >                       aSQLDialect: integer; GenerateParamNames: boolean=false;
1109 >                       CaseSensitiveParams: boolean = false; CursorName: AnsiString=''): IStatement; overload;
1110      function PrepareWithNamedParameters(transaction: ITransaction; sql: AnsiString;
1111 <                       GenerateParamNames: boolean=false): IStatement; overload;
1111 >                       GenerateParamNames: boolean=false;
1112 >                       CaseSensitiveParams: boolean = false; CursorName: AnsiString=''): IStatement; overload;
1113  
1114      {Events}
1115      function GetEventHandler(Events: TStrings): IEvents; overload;
# Line 894 | Line 1120 | type
1120      function CreateBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BPB: IBPB=nil): IBlob; overload;
1121      function CreateBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BPB: IBPB=nil): IBlob; overload;
1122      function CreateBlob(transaction: ITransaction; SubType: integer; CharSetID: cardinal=0; BPB: IBPB=nil): IBlob; overload;
1123 <    function OpenBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob;
1123 >    function OpenBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob; overload;
1124 >    function OpenBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob;  overload;
1125 >    function GetInlineBlobLimit: integer;
1126 >    procedure SetInlineBlobLimit(limit: integer);
1127  
1128      {Array - may use to open existing arrays. However, ISQLData.AsArray is preferred}
1129  
1130 <    function OpenArray(transaction: ITransaction; RelationName, ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray;
1130 >    function OpenArray(transaction: ITransaction; RelationName, ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray; overload;
1131 >    function OpenArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData; ArrayID: TISC_QUAD): IArray; overload;
1132      function CreateArray(transaction: ITransaction; RelationName, ColumnName: AnsiString): IArray; overload;
1133      function CreateArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData): IArray; overload;
1134      function CreateArrayMetaData(SQLType: cardinal; tableName: AnsiString; columnName: AnsiString;
# Line 911 | Line 1141 | type
1141      function GetArrayMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IArrayMetaData;
1142      function GetDBInformation(Requests: array of byte): IDBInformation; overload;
1143      function GetDBInformation(Request: byte): IDBInformation; overload;
1144 +    function GetDBInformation(Requests: IDIRB): IDBInformation; overload;
1145      function GetConnectString: AnsiString;
1146      function GetRemoteProtocol: AnsiString;
1147 +    function GetAuthenticationMethod: AnsiString;
1148 +    function GetSecurityDatabase: AnsiString;
1149      function GetODSMajorVersion: integer;
1150      function GetODSMinorVersion: integer;
1151 +    procedure getFBVersion(version: TStrings);
1152      function HasActivity: boolean;
1153 +    function HasDecFloatSupport: boolean;
1154 +    function HasBatchMode: boolean;
1155  
1156      {Character Sets}
1157      function HasDefaultCharSet: boolean;
# Line 927 | Line 1163 | type
1163      function CharSetWidth(CharSetID: integer; var Width: integer): boolean;
1164      procedure RegisterCharSet(CharSetName: AnsiString; CodePage: TSystemCodePage;
1165        AllowReverseLookup:boolean; out CharSetID: integer);
930  end;
1166  
1167 <  TProtocol = (TCP, SPX, NamedPipe, Local);
1167 >    {Time Zone Database}
1168 >    function GetTimeZoneServices: ITimeZoneServices;
1169 >    function HasTimeZoneSupport: boolean;
1170 > end;
1171 >
1172 >  TProtocolAll = (TCP, SPX, NamedPipe, Local, inet, inet4, inet6, wnet, xnet, unknownProtocol);
1173 >  TProtocol = TCP..xnet;
1174  
1175    {Service Parameter Block (SPB).
1176  
# Line 943 | Line 1184 | type
1184  
1185    }
1186  
1187 <  ISPBItem = interface(IParameterBlockItem)
1187 >  ISPBItem = interface(IParameterBlockItemWithTypeName)
1188      ['{5d08ae2b-4519-41bd-8b40-97cd451c3f6a}']
1189    end;
1190  
1191 <  ISPB = interface(IParameterBlock<ISPBItem>)
1191 >  ISPB = interface(IParameterBlockWithTypeNames<ISPBItem>)
1192      ['{2c5836fd-41ed-4426-9b7d-5af580ec2659}']
1193    end;
1194  
# Line 1007 | Line 1248 | type
1248      function getSize: integer;
1249      procedure getRawBytes(var Buffer);
1250      function getAsString: AnsiString;
1251 <    function getAsInteger: integer;
1251 >    function getAsInteger: int64;
1252      function getAsByte: byte;
1253      function CopyTo(stream: TStream; count: integer): integer;
1254      property AsString: AnsiString read getAsString;
1255 <    property AsInteger: integer read getAsInteger;
1255 >    property AsInteger: int64 read getAsInteger;
1256      property AsByte: byte read getAsByte;
1257    end;
1258  
# Line 1034 | Line 1275 | type
1275      property Count: integer read getCount;
1276    end;
1277  
1278 +  IFirebirdLibrary = interface;
1279 +
1280    {The IServiceManager interface provides access to a service manager. It can
1281     used to Detach and re-attach to Service Manager, to start services and to
1282     query the service manager.
# Line 1045 | Line 1288 | type
1288  
1289    IServiceManager = interface
1290      ['{905b587d-1e1f-4e40-a3f8-a3519f852e48}']
1291 +    function getFirebirdAPI: IFirebirdAPI;
1292      function getSPB: ISPB;
1293      function getServerName: AnsiString;
1294 +    function getProtocol: TProtocol;
1295 +    function getPortNo: AnsiString;
1296      procedure Attach;
1297      procedure Detach(Force: boolean=false);
1298      function IsAttached: boolean;
1299      function AllocateSRB: ISRB;
1300      function AllocateSQPB: ISQPB;
1301 <    procedure Start(Request: ISRB);
1302 <    function Query(SQPB: ISQPB; Request: ISRB) :IServiceQueryResults; overload;
1303 <    function Query(Request: ISRB) :IServiceQueryResults; overload;
1301 >    function Start(Request: ISRB; RaiseExceptionOnError: boolean=true): boolean;
1302 >    function Query(SQPB: ISQPB; Request: ISRB; RaiseExceptionOnError: boolean=true) :IServiceQueryResults; overload;
1303 >    function Query(Request: ISRB; RaiseExceptionOnError: boolean=true) :IServiceQueryResults; overload;
1304 >  end;
1305 >
1306 >  {Tbe Firebird Library API used to get information about the Firebird library}
1307 >
1308 >
1309 >  IFirebirdLibrary = interface
1310 >    ['{3c04e0a1-12e0-428a-b2e1-bc6fcd97b79b}']
1311 >    function GetHandle: TLibHandle;
1312 >    function GetLibraryName: string;
1313 >    function GetLibraryFilePath: string;
1314 >    function GetFirebirdAPI: IFirebirdAPI;
1315    end;
1316  
1317    {The Firebird API.
# Line 1065 | Line 1322 | type
1322     The interface is returned by the FirebirdAPI function.
1323    }
1324  
1325 +  { IFirebirdAPI }
1326 +
1327    IFirebirdAPI = interface
1328      ['{edeee691-c8d3-4dcf-a780-cd7e432821d5}']
1329      {Database connections}
# Line 1083 | Line 1342 | type
1342      {Service Manager}
1343      function HasServiceAPI: boolean;
1344      function AllocateSPB: ISPB;
1345 <    function GetServiceManager(ServerName: AnsiString; Protocol: TProtocol; SPB: ISPB): IServiceManager;
1345 >    function GetServiceManager(ServerName: AnsiString; Protocol: TProtocol; SPB: ISPB): IServiceManager; overload;
1346 >    function GetServiceManager(ServerName: AnsiString; Port: AnsiString; Protocol: TProtocol; SPB: ISPB): IServiceManager; overload;
1347  
1348      {Information}
1349      function GetStatus: IStatus;
1090    function GetLibraryName: string;
1350      function HasRollbackRetaining: boolean;
1351      function IsEmbeddedServer: boolean;
1352      function GetImplementationVersion: AnsiString;
1353 +    function GetClientMajor: integer;
1354 +    function GetClientMinor: integer;
1355 +    function HasDecFloatSupport: boolean;
1356 +    function HasLocalTZDB: boolean;
1357 +    function HasTimeZoneSupport: boolean;
1358 +    function HasExtendedTZSupport: boolean;
1359 +    function HasScollableCursors: boolean;
1360  
1361      {Firebird 3 API}
1362      function HasMasterIntf: boolean;
1363 <    function GetIMaster: TObject;
1363 >    function GetIMaster: TObject;  deprecated 'Use FirebirdAPI.QueryInterface and FBClientLib.pas IFBIMasterProvider instead';
1364 >    function GetFBLibrary: IFirebirdLibrary;
1365   end;
1366  
1367   type
# Line 1129 | Line 1396 | type
1396     {IB Client Exceptions}
1397     EIBClientError = class(EIBError);
1398  
1399 < {IBError is used internally and by IBX to throw an EIBClientError}
1400 <
1134 < procedure IBError(ErrMess: TIBClientError; const Args: array of const);
1399 >   {Used to explicitly report a Batch Buffer overflow}
1400 >   EIBBatchBufferOverflow = class(EIBError);
1401  
1402   {The Firebird API function is used to access the IFirebirdAPI interface.
1403  
# Line 1142 | Line 1408 | procedure IBError(ErrMess: TIBClientErro
1408   function FirebirdAPI: IFirebirdAPI;
1409  
1410   {IBX support functions. Probably best ignored i.e. always used the FirebirdAPI
1411 < functino to load the library and check if it's loaded.}
1411 > function to load the library and check if it's loaded.}
1412  
1413   function TryIBLoad: Boolean;
1414   procedure CheckIBLoaded;
1415  
1416 + {If you want to explicitly load the Firebird library from a
1417 + non-default location then use this function and its GetFirebirdAPI function
1418 + to get the API.}
1419 +
1420 + function LoadFBLibrary(aLibPathName: string): IFirebirdLibrary;
1421 +
1422 +
1423   implementation
1424  
1425   uses FBClientAPI
1426    {$IFDEF USELEGACYFIREBIRDAPI}, FB25ClientAPI {$ENDIF}
1427    {$IFDEF USEFIREBIRD3API}, FB30ClientAPI {$ENDIF};
1428  
1429 < var FFirebirdAPI: IFirebirdAPI;
1429 > var FDefaultFBLibrary: IFirebirdLibrary;
1430 >
1431 > type
1432 >
1433 >  { TFBLibrary }
1434 >
1435 >  TFBLibraryImpl = class(TFBLibrary)
1436 >  protected
1437 >    function GetFirebird3API: IFirebirdAPI; override;
1438 >    function GetLegacyFirebirdAPI: IFirebirdAPI; override;
1439 >  end;
1440 >
1441 > function TFBLibraryImpl.GetFirebird3API: IFirebirdAPI;
1442 > begin
1443 > {$IFDEF USEFIREBIRD3API}
1444 > Result := TFB30ClientAPI.Create(self);
1445 > {$ELSE}
1446 > Result := nil;
1447 > {$ENDIF}
1448 > end;
1449 >
1450 > function TFBLibraryImpl.GetLegacyFirebirdAPI: IFirebirdAPI;
1451 > begin
1452 >  {$IFDEF USELEGACYFIREBIRDAPI}
1453 >  Result := TFB25ClientAPI.Create(self);
1454 >  {$ELSE}
1455 >  Result := nil;
1456 >  {$ENDIF}
1457 > end;
1458  
1459   function FirebirdAPI: IFirebirdAPI;
1460   begin
1461 <  if FFirebirdAPI = nil then
1461 >  if FDefaultFBLibrary = nil then
1462      CheckIBLoaded;
1463 <  Result := FFirebirdAPI;
1463 >  Result := FDefaultFBLibrary.GetFirebirdAPI;
1464   end;
1465  
1466   function TryIBLoad: Boolean;
1467 + var fblib: IFirebirdLibrary;
1468   begin
1469 < Result := FFirebirdAPI <> nil;
1469 > Result := FDefaultFBLibrary <> nil;
1470   try
1169  {$IFDEF USEFIREBIRD3API}
1170  if not Result then
1171  begin
1172    FFirebirdAPI := TFB30ClientAPI.Create;
1173    Result := FFirebirdAPI.HasMasterIntf;
1174  end;
1175  {$ENDIF}
1176  {$IFDEF USELEGACYFIREBIRDAPI}
1471    if not Result then
1472    begin
1473 <    FFirebirdAPI := nil;
1474 <    FFirebirdAPI := TFB25ClientAPI.Create;
1475 <    Result := true;
1476 <  end;
1183 <  {$ENDIF}
1184 <  if Result and not (FFirebirdAPI as TFBClientAPI).IsLibraryLoaded then
1185 <  begin
1186 <    Result := false;
1187 <    FFirebirdAPI := nil;
1473 >    fblib := TFBLibraryImpl.Create;
1474 >    if (fblib <> nil) and (fblib.GetFirebirdAPI <> nil) then
1475 >      FDefaultFBLibrary := fblib;
1476 >    Result := FDefaultFBLibrary <> nil;
1477    end;
1478   except
1479     SysUtils.showexception(ExceptObject,ExceptAddr);
# Line 1198 | Line 1487 | begin
1487      IBError(ibxeInterBaseMissing, [nil]);
1488   end;
1489  
1490 + function LoadFBLibrary(aLibPathName: string): IFirebirdLibrary;
1491 + var fblib: IFirebirdLibrary;
1492 + begin
1493 +  if trim(aLibPathName) = '' then
1494 +  begin
1495 +    CheckIBLoaded;
1496 +    Result := FDefaultFBLibrary;
1497 +  end
1498 +  else
1499 +  begin
1500 +    fblib := TFBLibraryImpl.GetFBLibrary(aLibPathName);
1501 +    if (fblib = nil) or (fblib.GetFirebirdAPI = nil) then
1502 +      IBError(ibxeInterBaseMissing, [nil]);
1503 +    Result := fblib;
1504 +  end;
1505 + end;
1506 +
1507   { EIBError }
1508  
1509   constructor EIBError.Create(ASQLCode: Long; Msg: AnsiString);
# Line 1221 | Line 1527 | begin
1527    FIBErrorCode := AIBErrorCode;
1528   end;
1529  
1224 procedure IBError(ErrMess: TIBClientError; const Args: array of const);
1225 begin
1226  raise EIBClientError.Create(Ord(ErrMess),
1227                              Format(GetErrorMessage(ErrMess), Args));
1228 end;
1530  
1531   initialization
1532 <  FFirebirdAPI := nil;
1532 >  FDefaultFBLibrary := nil;
1533  
1534 + finalization
1535 +  FDefaultFBLibrary := nil;
1536  
1537   end.
1538  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines