--- ibx/trunk/fbintf/IB.pas 2021/02/25 11:27:14 314 +++ ibx/trunk/fbintf/IB.pas 2021/02/25 11:56:36 315 @@ -129,21 +129,38 @@ uses Classes, {$IFDEF WINDOWS}Windows, {$ENDIF} {$IFDEF FPC} Dynlibs, {$ENDIF} - SysUtils, DB, FBMessages, IBExternals; + SysUtils, DB, FBMessages, IBExternals, FmtBcd; const {Interface version information} FBIntf_Major = 1; - FBIntf_Minor = 1; - FBIntf_Release = 6; - FBIntf_Version = '1.1.6'; + FBIntf_Minor = 2; + FBIntf_Release = 0; + FBIntf_Version = '1.2.0'; + +const + {DPB, TPB and SPB Parameter Block Name Prefixes} + DPBPrefix = 'isc_dpb_'; + TPBPrefix = 'isc_tpb_'; + +const + {Time Zone ID constraint} + MaxOffsetTimeZoneID = 2879; {lower values represent a time zone offset between + -23:59 and 23:59. Higher values are keys to the + Time Zone database.} + + TimeZoneID_GMT = 23*minsPerHour + 59; + decimillisecondsPerSecond = 10000; + TimeZoneDisplacementDelta = 60*23 + 59; {23:59 in minutes} {These include files are converted from the 'C' originals in the Firebird API and define the various constants used by the API} {$I 'include/consts_pub.inc'} +{$I 'include/dyn_consts.inc'} {$I 'include/inf_pub.inc'} {$I 'include/configkeys.inc'} +{$I 'include/blr.inc'} {The following constants define the values return by calls to the GetSQLType methods provided by several of the interfaces defined below.} @@ -165,7 +182,16 @@ const SQL_TYPE_TIME = 560; SQL_TYPE_DATE = 570; SQL_INT64 = 580; + SQL_TIMESTAMP_TZ_EX = 32748; + SQL_TIME_TZ_EX = 32750; + SQL_INT128 = 32752; SQL_BOOLEAN = 32764; + SQL_TIMESTAMP_TZ = 32754; + SQL_TIME_TZ = 32756; + SQL_DEC_FIXED = 32758; {FB4 Beta 1 only} + SQL_DEC16 = 32760; + SQL_DEC34 = 32762; + SQL_NULL = 32766; SQL_DATE = SQL_TIMESTAMP; type @@ -215,6 +241,7 @@ type TFBStatusCode = cardinal; TByteArray = array of byte; + TFBTimeZoneID = ISC_USHORT; IFirebirdAPI = interface; IAttachment = interface; @@ -234,6 +261,11 @@ type property Items[index: integer]: _IItem read getItems; default; end; + IParameterBlockWithTypeNames<_IItem> = interface(IParameterBlock<_IItem>) + function AddByTypeName(ParamTypeName: AnsiString): _IItem; + function GetDPBParamTypeName(ParamType: byte): Ansistring; + end; + {IParameterBlockItem is not used on its own but instead provides a base type for different parameter block items } @@ -251,6 +283,9 @@ type property AsInteger: integer read getAsInteger write SetAsInteger; end; + IParameterBlockItemWithTypeName = interface(IParameterBlockItem) + function getParamTypeName: AnsiString; + end; {The IStatus interface provides access to error information, if any, returned by the last API call. It can also be used to customise the error message @@ -330,26 +365,38 @@ type function GetAsBoolean(index: array of integer): boolean; function GetAsCurrency(index: array of integer): Currency; function GetAsInt64(index: array of integer): Int64; - function GetAsDateTime(index: array of integer): TDateTime; + function GetAsDateTime(index: array of integer): TDateTime; overload; + procedure GetAsDateTime(index: array of integer; var aDateTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload; + procedure GetAsDateTime(index: array of integer; var aDateTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload; + procedure GetAsTime(index: array of integer; var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID; OnDate: TDateTime); overload; + procedure GetAsTime(index: array of integer; var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString; OnDate: TDateTime); overload; + function GetAsUTCDateTime(index: array of integer): TDateTime; function GetAsDouble(index: array of integer): Double; function GetAsFloat(index: array of integer): Float; function GetAsLong(index: array of integer): Long; function GetAsShort(index: array of integer): Short; function GetAsString(index: array of integer): AnsiString; function GetAsVariant(index: array of integer): Variant; + function GetAsBCD(index: array of integer): tBCD; procedure SetAsInteger(index: array of integer; AValue: integer); procedure SetAsBoolean(index: array of integer; AValue: boolean); procedure SetAsCurrency(index: array of integer; Value: Currency); procedure SetAsInt64(index: array of integer; Value: Int64); procedure SetAsDate(index: array of integer; Value: TDateTime); + procedure SetAsDateTime(index: array of integer; Value: TDateTime); overload; + procedure SetAsDateTime(index: array of integer; aValue: TDateTime; aTimeZoneID: TFBTimeZoneID); overload; + procedure SetAsDateTime(index: array of integer; aValue: TDateTime; aTimeZone: AnsiString); overload; + procedure SetAsTime(index: array of integer; Value: TDateTime); overload; + procedure SetAsTime(index: array of integer; aValue: TDateTime; OnDate: TDateTime; aTimeZoneID: TFBTimeZoneID); overload; + procedure SetAsTime(index: array of integer; aValue: TDateTime; OnDate: TDateTime; aTimeZone: AnsiString); overload; + procedure SetAsUTCDateTime(index: array of integer; aUTCTime: TDateTime); procedure SetAsLong(index: array of integer; Value: Long); - procedure SetAsTime(index: array of integer; Value: TDateTime); - procedure SetAsDateTime(index: array of integer; Value: TDateTime); procedure SetAsDouble(index: array of integer; Value: Double); procedure SetAsFloat(index: array of integer; Value: Float); procedure SetAsShort(index: array of integer; Value: Short); procedure SetAsString(index: array of integer; Value: AnsiString); procedure SetAsVariant(index: array of integer; Value: Variant); + procedure SetAsBcd(index: array of integer; aValue: tBCD); procedure SetBounds(dim, UpperBound, LowerBound: integer); function GetAttachment: IAttachment; function GetTransaction: ITransaction; @@ -422,7 +469,9 @@ type TIBDateTimeFormats = (dfTimestamp, {SQL TIMESTAMP} dfDateTime, {SQL DATETIME} - dfTime); {SQL TIME} + dfTime, {SQL TIME} + dfTimestampTZ, {SQL_TIMESTAMP_TZ} + dfTimeTZ); {SQLTIME_TZ { IColumnMetaData } @@ -493,7 +542,14 @@ type function GetAsBoolean: boolean; function GetAsCurrency: Currency; function GetAsInt64: Int64; - function GetAsDateTime: TDateTime; + function GetAsDateTime: TDateTime; overload; + procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload; + procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID; OnDate: TDateTime); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString; OnDate: TDateTime); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload; + function GetAsUTCDateTime: TDateTime; function GetAsDouble: Double; function GetAsFloat: Float; function GetAsLong: Long; @@ -506,6 +562,7 @@ type function GetAsBlob: IBlob; overload; function GetAsBlob(BPB: IBPB): IBlob; overload; function GetAsArray: IArray; + function GetAsBCD: tBCD; property AsDate: TDateTime read GetAsDateTime; property AsBoolean:boolean read GetAsBoolean; property AsTime: TDateTime read GetAsDateTime; @@ -523,6 +580,7 @@ type property AsVariant: Variant read GetAsVariant ; property AsBlob: IBlob read GetAsBlob; property AsArray: IArray read GetAsArray; + property AsBCD: tBCD read GetAsBCD; property IsNull: Boolean read GetIsNull; property Value: Variant read GetAsVariant; end; @@ -589,7 +647,14 @@ type function GetAsBoolean: boolean; function GetAsCurrency: Currency; function GetAsInt64: Int64; - function GetAsDateTime: TDateTime; + function GetAsDateTime: TDateTime; overload; + procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload; + procedure GetAsDateTime(var aDateTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID; OnDate: TDateTime); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString; OnDate: TDateTime); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezoneID: TFBTimeZoneID); overload; + procedure GetAsTime(var aTime: TDateTime; var dstOffset: smallint; var aTimezone: AnsiString); overload; + function GetAsUTCDateTime: TDateTime; function GetAsDouble: Double; function GetAsFloat: Float; function GetAsLong: Long; @@ -601,6 +666,9 @@ type function GetAsVariant: Variant; function GetAsBlob: IBlob; function GetAsArray: IArray; + function GetAsBCD: tBCD; + function GetStatement: IStatement; + function GetTransaction: ITransaction; procedure Clear; function GetModified: boolean; procedure SetAsBoolean(AValue: boolean); @@ -608,8 +676,15 @@ type procedure SetAsInt64(aValue: Int64); procedure SetAsDate(aValue: TDateTime); procedure SetAsLong(aValue: Long); - procedure SetAsTime(aValue: TDateTime); - procedure SetAsDateTime(aValue: TDateTime); + procedure SetAsTime(aValue: TDateTime); overload; + procedure SetAsTime(aValue: TDateTime; OnDate: TDateTime; aTimeZoneID: TFBTimeZoneID); overload; + procedure SetAsTime(aValue: TDateTime; OnDate: TDateTime; aTimeZone: AnsiString); overload; + procedure SetAsTime(aValue: TDateTime; aTimeZoneID: TFBTimeZoneID); overload; + procedure SetAsTime(aValue: TDateTime; aTimeZone: AnsiString); overload; + procedure SetAsDateTime(aValue: TDateTime); overload; + procedure SetAsDateTime(aValue: TDateTime; aTimeZoneID: TFBTimeZoneID); overload; + procedure SetAsDateTime(aValue: TDateTime; aTimeZone: AnsiString); overload; + procedure SetAsUTCDateTime(aUTCTime: TDateTime); procedure SetAsDouble(aValue: Double); procedure SetAsFloat(aValue: Float); procedure SetAsPointer(aValue: Pointer); @@ -621,6 +696,7 @@ type procedure SetAsArray(anArray: IArray); procedure SetAsQuad(aValue: TISC_QUAD); procedure SetCharSetID(aValue: cardinal); + procedure SetAsBcd(aValue: tBCD); property AsDate: TDateTime read GetAsDateTime write SetAsDate; property AsBoolean:boolean read GetAsBoolean write SetAsBoolean; property AsTime: TDateTime read GetAsDateTime write SetAsTime; @@ -637,6 +713,7 @@ type property AsVariant: Variant read GetAsVariant write SetAsVariant; property AsBlob: IBlob read GetAsBlob write SetAsBlob; property AsArray: IArray read GetAsArray write SetAsArray; + property AsBCD: tBCD read GetAsBCD write SetAsBCD; property AsQuad: TISC_QUAD read GetAsQuad write SetAsQuad; property Value: Variant read GetAsVariant write SetAsVariant; property IsNull: Boolean read GetIsNull write SetIsNull; @@ -709,11 +786,12 @@ type found in the Interbase 6.0 API Guide. } - ITPBItem = interface(IParameterBlockItem) + ITPBItem = interface(IParameterBlockItemWithTypeName) ['{544c1f2b-7c12-4a87-a4a5-face7ea72671}'] + function getParamTypeName: AnsiString; end; - ITPB = interface(IParameterBlock) + ITPB = interface(IParameterBlockWithTypeNames) ['{7369b0ff-defe-437b-81fe-19b211d42d25}'] end; @@ -779,6 +857,40 @@ type function GetAttachment: IAttachment; end; + TTZTextOptions = (tzOffset, {Time Zone Rendered as an offset to GMT} + tzGMT, {No Time Zone. Time part is always rendered in GMT} + tzOriginalID); {Time Zone shown as originally entered} + + {The ITimeZoneServices interface provides access to the time zone database + used for the attachment. It may be used in support of TIMESTAMP WITH TIME ZONE + and TIME WITH TIME ZONE data types.} + + ITimeZoneServices = interface + ['{163821f5-ebef-42b9-ac60-8ac4b5c09954}'] + {utility functions} + function TimeZoneID2TimeZoneName(aTimeZoneID: TFBTimeZoneID): AnsiString; + function TimeZoneName2TimeZoneID(aTimeZone: AnsiString): TFBTimeZoneID; + function LocalTimeToGMT(aLocalTime: TDateTime; aTimeZone: AnsiString): TDateTime; overload; + function LocalTimeToGMT(aLocalTime: TDateTime; aTimeZoneID: TFBTimeZoneID): TDateTime; overload; + function GMTToLocalTime(aGMTTime: TDateTime; aTimeZone: AnsiString): TDateTime; overload; + function GMTToLocalTime(aGMTTime: TDateTime; aTimeZoneID: TFBTimeZoneID): TDateTime; overload; + function GetEffectiveOffsetMins(aLocalTime: TDateTime; aTimeZone: AnsiString): integer; overload; + function GetEffectiveOffsetMins(aLocalTime: TDateTime; aTimeZoneID: TFBTimeZoneID): integer; overload; + + {Time Zone DB Information} + function UsingRemoteTZDB: boolean; + procedure SetUseLocalTZDB(useLocalTZDB: boolean); + function GetLocalTimeZoneName: AnsiString; + function GetLocalTimeZoneID: TFBTimeZoneID; + procedure GetTimeZoneInfo(aTimeZone: AnsiString; OnDate: TDateTime; + var ZoneOffset, DSTOffset, EffectiveOffset: integer); + {Configurable Options} + function GetTimeTZDate: TDateTime; + procedure SetTimeTZDate(aDate: TDateTime); + function GetTZTextOption: TTZTextOptions; + procedure SetTZTextOption(aOptionValue: TTZTextOptions); + end; + {The IDBInformation Interface. An IDBInformation interface is returned by the IAttachment GetDBInformation @@ -862,13 +974,13 @@ type found in the Interbase 6.0 API Guide. } - IDPBItem = interface(IParameterBlockItem) + IDPBItem = interface(IParameterBlockItemWithTypeName) ['{123d4ad0-087a-4cd1-a344-1b3d03b30673}'] end; - IDPB = interface(IParameterBlock) - ['{e676067b-1cf4-4eba-9256-9724f57e0d16}'] - end; + IDPB = interface(IParameterBlockWithTypeNames) + ['{e676067b-1cf4-4eba-9256-9724f57e0d16}'] + end; {The IAttachment interface provides access to a Database Connection. It may be used to: @@ -978,6 +1090,7 @@ type function GetODSMinorVersion: integer; procedure getFBVersion(version: TStrings); function HasActivity: boolean; + function HasDecFloatSupport: boolean; {Character Sets} function HasDefaultCharSet: boolean; @@ -989,7 +1102,11 @@ type function CharSetWidth(CharSetID: integer; var Width: integer): boolean; procedure RegisterCharSet(CharSetName: AnsiString; CodePage: TSystemCodePage; AllowReverseLookup:boolean; out CharSetID: integer); - end; + + {Time Zone Database} + function GetTimeZoneServices: ITimeZoneServices; + function HasTimeZoneSupport: boolean; + end; TProtocolAll = (TCP, SPX, NamedPipe, Local, inet, inet4, inet6, wnet, xnet, unknownProtocol); TProtocol = TCP..xnet; @@ -1006,11 +1123,11 @@ type } - ISPBItem = interface(IParameterBlockItem) + ISPBItem = interface(IParameterBlockItemWithTypeName) ['{5d08ae2b-4519-41bd-8b40-97cd451c3f6a}'] end; - ISPB = interface(IParameterBlock) + ISPB = interface(IParameterBlockWithTypeNames) ['{2c5836fd-41ed-4426-9b7d-5af580ec2659}'] end; @@ -1144,6 +1261,8 @@ type The interface is returned by the FirebirdAPI function. } + { IFirebirdAPI } + IFirebirdAPI = interface ['{edeee691-c8d3-4dcf-a780-cd7e432821d5}'] {Database connections} @@ -1172,10 +1291,14 @@ type function GetImplementationVersion: AnsiString; function GetClientMajor: integer; function GetClientMinor: integer; + function HasDecFloatSupport: boolean; + function HasLocalTZDB: boolean; + function HasTimeZoneSupport: boolean; + function HasExtendedTZSupport: boolean; {Firebird 3 API} function HasMasterIntf: boolean; - function GetIMaster: TObject; + function GetIMaster: TObject; deprecated 'Use FirebirdAPI.QueryInterface and FBClientLib.pas IFBIMasterProvider instead'; function GetFBLibrary: IFirebirdLibrary; end; @@ -1220,7 +1343,7 @@ type function FirebirdAPI: IFirebirdAPI; {IBX support functions. Probably best ignored i.e. always used the FirebirdAPI - functino to load the library and check if it's loaded.} + function to load the library and check if it's loaded.} function TryIBLoad: Boolean; procedure CheckIBLoaded; @@ -1231,6 +1354,7 @@ procedure CheckIBLoaded; function LoadFBLibrary(aLibPathName: string): IFirebirdLibrary; + implementation uses FBClientAPI