ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/fbintf/client/2.5/FB25ClientAPI.pas
Revision: 56
Committed: Mon Mar 6 10:20:02 2017 UTC (7 years, 8 months ago) by tony
Content type: text/x-pascal
File size: 25336 byte(s)
Log Message:
Committing updates for Trunk

File Contents

# User Rev Content
1 tony 45 (*
2     * Firebird Interface (fbintf). The fbintf components provide a set of
3     * Pascal language bindings for the Firebird API. Although predominantly
4     * a new development they include source code taken from IBX and may be
5     * considered a derived product. This software thus also includes the copyright
6     * notice and license conditions from IBX.
7     *
8     * Except for those parts dervied from IBX, contents of this file are subject
9     * to the Initial Developer's Public License Version 1.0 (the "License"); you
10     * may not use this file except in compliance with the License. You may obtain a
11     * copy of the License here:
12     *
13     * http://www.firebirdsql.org/index.php?op=doc&id=idpl
14     *
15     * Software distributed under the License is distributed on an "AS
16     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17     * implied. See the License for the specific language governing rights
18     * and limitations under the License.
19     *
20     * The Initial Developer of the Original Code is Tony Whyman.
21     *
22     * The Original Code is (C) 2016 Tony Whyman, MWA Software
23     * (http://www.mwasoftware.co.uk).
24     *
25     * All Rights Reserved.
26     *
27     * Contributor(s): ______________________________________.
28     *
29     *)
30     {************************************************************************}
31     { }
32     { Borland Delphi Visual Component Library }
33     { InterBase Express core components }
34     { }
35     { Copyright (c) 1998-2000 Inprise Corporation }
36     { }
37     { InterBase Express is based in part on the product }
38     { Free IB Components, written by Gregory H. Deatz for }
39     { Hoagland, Longo, Moran, Dunst & Doukas Company. }
40     { Free IB Components is used under license. }
41     { }
42     { The contents of this file are subject to the InterBase }
43     { Public License Version 1.0 (the "License"); you may not }
44     { use this file except in compliance with the License. You }
45     { may obtain a copy of the License at http://www.Inprise.com/IPL.html }
46     { Software distributed under the License is distributed on }
47     { an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either }
48     { express or implied. See the License for the specific language }
49     { governing rights and limitations under the License. }
50     { The Original Code was created by InterBase Software Corporation }
51     { and its successors. }
52     { Portions created by Inprise Corporation are Copyright (C) Inprise }
53     { Corporation. All Rights Reserved. }
54     { Contributor(s): Jeff Overcash }
55     { }
56     { IBX For Lazarus (Firebird Express) }
57     { Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
58     { Portions created by MWA Software are copyright McCallum Whyman }
59     { Associates Ltd 2011 - 2015 }
60     { }
61     {************************************************************************}
62     unit FB25ClientAPI;
63 tony 56 {$IFDEF MSWINDOWS}
64     {$DEFINE WINDOWS}
65     {$ENDIF}
66 tony 45
67     {$IFDEF FPC}
68     {$mode delphi}
69     {$interfaces COM}
70     {$ENDIF}
71    
72     interface
73    
74     uses
75     Classes, SysUtils, FBClientAPI, IBHeader, IBExternals, IB;
76    
77     const
78     FBClientInterfaceVersion = '2.5';
79    
80     type
81    
82     { TFB25Status }
83    
84     TFB25Status = class(TFBStatus,IStatus)
85     public
86     function StatusVector: PStatusVector; override;
87     end;
88    
89     { TFB25ClientAPI }
90    
91     TFB25ClientAPI = class(TFBClientAPI,IFirebirdAPI)
92     private
93     FIBServiceAPIPresent: boolean;
94     FStatus: TFB25Status;
95     FStatusIntf: IStatus; {Keep a reference to the interface - automatic destroy
96     when this class is freed and last reference to IStatus
97     goes out of scope.}
98     protected
99     {$IFDEF UNIX}
100     function GetFirebirdLibList: string; override;
101     {$ENDIF}
102     procedure LoadInterface; override;
103     public
104     constructor Create;
105     destructor Destroy; override;
106     function StatusVector: PISC_STATUS;
107     property IBServiceAPIPresent: boolean read FIBServiceAPIPresent;
108     property Status: TFB25Status read FStatus;
109    
110     public
111    
112     {fbclient API}
113     BLOB_get: TBLOB_get;
114     BLOB_put: TBLOB_put;
115     isc_wait_for_event: Tisc_wait_for_event;
116     isc_vax_integer: Tisc_vax_integer;
117     isc_portable_integer: Tisc_portable_integer;
118     isc_blob_info: Tisc_blob_info;
119     isc_blob_lookup_desc: Tisc_blob_lookup_desc;
120     isc_open_blob2: Tisc_open_blob2;
121     isc_close_blob: Tisc_close_blob;
122     isc_get_segment: Tisc_get_segment;
123     isc_put_segment: Tisc_put_segment;
124     isc_create_blob2: Tisc_create_blob2;
125     isc_cancel_blob: Tisc_cancel_blob;
126     isc_service_attach: Tisc_service_attach;
127     isc_service_detach: Tisc_service_detach;
128     isc_service_query: Tisc_service_query;
129     isc_service_start: Tisc_service_start;
130     isc_decode_date: Tisc_decode_date;
131     isc_decode_sql_date: Tisc_decode_sql_date;
132     isc_decode_sql_time: Tisc_decode_sql_time;
133     isc_decode_timestamp: Tisc_decode_timestamp;
134     isc_encode_date: Tisc_encode_date;
135     isc_encode_sql_date: Tisc_encode_sql_date;
136     isc_encode_sql_time: Tisc_encode_sql_time;
137     isc_encode_timestamp: Tisc_encode_timestamp;
138     isc_dsql_free_statement: Tisc_dsql_free_statement;
139     isc_dsql_execute2: Tisc_dsql_execute2;
140     isc_dsql_execute: Tisc_dsql_execute;
141     isc_dsql_set_cursor_name: Tisc_dsql_set_cursor_name;
142     isc_dsql_fetch: Tisc_dsql_fetch;
143     isc_dsql_sql_info: Tisc_dsql_sql_info;
144     isc_dsql_alloc_statement2: Tisc_dsql_alloc_statement2;
145     isc_dsql_prepare: Tisc_dsql_prepare;
146     isc_dsql_describe_bind: Tisc_dsql_describe_bind;
147     isc_dsql_describe: Tisc_dsql_describe;
148     isc_dsql_execute_immediate: Tisc_dsql_execute_immediate;
149     isc_drop_database: Tisc_drop_database;
150     isc_detach_database: Tisc_detach_database;
151     isc_attach_database: Tisc_attach_database;
152     isc_database_info: Tisc_database_info;
153     isc_start_transaction: Tisc_start_transaction;
154     isc_start_multiple: Tisc_start_multiple;
155     isc_commit_transaction: Tisc_commit_transaction;
156     isc_commit_retaining: Tisc_commit_retaining;
157     isc_rollback_transaction: Tisc_rollback_transaction;
158     isc_rollback_retaining: Tisc_rollback_retaining;
159     isc_cancel_events: Tisc_cancel_events;
160     isc_que_events: Tisc_que_events;
161     isc_add_user : Tisc_add_user;
162     isc_delete_user: Tisc_delete_user;
163     isc_modify_user: Tisc_modify_user;
164     isc_array_lookup_bounds: Tisc_array_lookup_bounds;
165     isc_array_get_slice: Tisc_array_get_slice;
166     isc_array_put_slice: Tisc_array_put_slice;
167     isc_prepare_transaction: Tisc_prepare_transaction;
168    
169     public
170     {Helper Functions}
171 tony 56 function DecodeInteger(bufptr: PByte; len: short): integer; override;
172     procedure SQLEncodeDate(aDate: TDateTime; bufptr: PByte); override;
173     function SQLDecodeDate(bufptr: PByte): TDateTime; override;
174     procedure SQLEncodeTime(aTime: TDateTime; bufptr: PByte); override;
175     function SQLDecodeTime(bufptr: PByte): TDateTime; override;
176     procedure SQLEncodeDateTime(aDateTime: TDateTime; bufptr: PByte); override;
177     function SQLDecodeDateTime(bufptr: PByte): TDateTime; override;
178 tony 45
179     public
180     {IFirebirdAPI}
181    
182     {Database connections}
183     function AllocateDPB: IDPB;
184 tony 56 function OpenDatabase(DatabaseName: AnsiString; DPB: IDPB; RaiseExceptionOnConnectError: boolean=true): IAttachment;
185     function CreateDatabase(DatabaseName: AnsiString; DPB: IDPB; RaiseExceptionOnError: boolean=true): IAttachment; overload;
186     function CreateDatabase(sql: AnsiString; aSQLDialect: integer; RaiseExceptionOnError: boolean=true): IAttachment; overload;
187 tony 45
188     {Start Transaction against multiple databases}
189     function AllocateTPB: ITPB;
190     function StartTransaction(Attachments: array of IAttachment;
191     TPB: array of byte; DefaultCompletion: TTransactionCompletion): ITransaction; overload;
192     function StartTransaction(Attachments: array of IAttachment;
193     TPB: ITPB; DefaultCompletion: TTransactionCompletion): ITransaction; overload;
194    
195     {Service Manager}
196     function AllocateSPB: ISPB;
197     function HasServiceAPI: boolean;
198 tony 56 function GetServiceManager(ServerName: AnsiString; Protocol: TProtocol; SPB: ISPB): IServiceManager;
199 tony 45
200     {Information}
201     function GetStatus: IStatus; override;
202     function HasRollbackRetaining: boolean;
203     function IsEmbeddedServer: boolean; override;
204 tony 56 function GetImplementationVersion: AnsiString;
205 tony 45
206     {Firebird 3 API}
207     function HasMasterIntf: boolean;
208     function GetIMaster: TObject;
209    
210     end;
211    
212 tony 56 var
213 tony 45 Firebird25ClientAPI: TFB25ClientAPI = nil;
214    
215     implementation
216    
217 tony 56 uses FBMessages,
218     {$IFDEF WINDOWS}Windows, {$ENDIF}
219     {$IFDEF FPC} Dynlibs, {$ENDIF}
220     FB25Attachment, FB25Transaction, FB25Services, FBParamBlock,
221 tony 45 IBUtils;
222    
223     { Stubs for 6.0 only functions }
224     function isc_rollback_retaining_stub(status_vector : PISC_STATUS;
225     tran_handle : PISC_TR_HANDLE):
226     ISC_STATUS; {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
227     begin
228     Result := 0;
229     IBError(ibxeIB60feature, ['isc_rollback_retaining']); {do not localize}
230     end;
231    
232     function isc_service_attach_stub(status_vector : PISC_STATUS;
233     isc_arg2 : UShort;
234 tony 56 isc_arg3 : PAnsiChar;
235 tony 45 service_handle : PISC_SVC_HANDLE;
236     isc_arg5 : UShort;
237 tony 56 isc_arg6 : PAnsiChar):
238 tony 45 ISC_STATUS; {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
239     begin
240     Result := 0;
241     IBError(ibxeIB60feature, ['isc_service_attach']); {do not localize}
242     end;
243    
244     function isc_service_detach_stub(status_vector : PISC_STATUS;
245     service_handle : PISC_SVC_HANDLE):
246     ISC_STATUS; {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
247     begin
248     Result := 0;
249     IBError(ibxeIB60feature, ['isc_service_detach']); {do not localize}
250     end;
251    
252     function isc_service_query_stub(status_vector : PISC_STATUS;
253     service_handle : PISC_SVC_HANDLE;
254     recv_handle : PISC_SVC_HANDLE;
255     isc_arg4 : UShort;
256 tony 56 isc_arg5 : PAnsiChar;
257 tony 45 isc_arg6 : UShort;
258 tony 56 isc_arg7 : PAnsiChar;
259 tony 45 isc_arg8 : UShort;
260 tony 56 isc_arg9 : PAnsiChar):
261 tony 45 ISC_STATUS; {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
262     begin
263     Result := 0;
264     IBError(ibxeIB60feature, ['isc_service_query']); {do not localize}
265     end;
266    
267     function isc_service_start_stub(status_vector : PISC_STATUS;
268     service_handle : PISC_SVC_HANDLE;
269     recv_handle : PISC_SVC_HANDLE;
270     isc_arg4 : UShort;
271 tony 56 isc_arg5 : PAnsiChar):
272 tony 45 ISC_STATUS; {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
273     begin
274     Result := 0;
275     IBError(ibxeIB60feature, ['isc_service_start']); {do not localize}
276     end;
277    
278     procedure isc_encode_sql_date_stub(tm_date : PCTimeStructure;
279     ib_date : PISC_DATE);
280     {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
281     begin
282     IBError(ibxeIB60feature, ['isc_encode_sql_date']); {do not localize}
283     end;
284    
285     procedure isc_encode_sql_time_stub(tm_date : PCTimeStructure;
286     ib_time : PISC_TIME);
287     {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
288     begin
289     IBError(ibxeIB60feature, ['isc_encode_sql_time']); {do not localize}
290     end;
291    
292     procedure isc_encode_timestamp_stub(tm_date : PCTimeStructure;
293     ib_timestamp : PISC_TIMESTAMP);
294     {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
295     begin
296     IBError(ibxeIB60feature, ['isc_encode_sql_timestamp']); {do not localize}
297     end;
298    
299     procedure isc_decode_sql_date_stub(ib_date : PISC_DATE;
300     tm_date : PCTimeStructure);
301     {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
302     begin
303     IBError(ibxeIB60feature, ['isc_decode_sql_date']); {do not localize}
304     end;
305    
306     procedure isc_decode_sql_time_stub(ib_time : PISC_TIME;
307     tm_date : PCTimeStructure);
308     {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
309     begin
310     IBError(ibxeIB60feature, ['isc_decode_sql_time']); {do not localize}
311     end;
312    
313     procedure isc_decode_timestamp_stub(ib_timestamp : PISC_TIMESTAMP;
314     tm_date : PCTimeStructure);
315     {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
316     begin
317     IBError(ibxeIB60feature, ['isc_decode_timestamp']); {do not localize}
318     end;
319    
320     { TFB25Status }
321    
322     threadvar
323     FStatusVector: TStatusVector;
324    
325     function TFB25Status.StatusVector: PStatusVector;
326     begin
327     Result := @FStatusVector;
328     end;
329    
330    
331     { TFB25ClientAPI }
332    
333     {$IFDEF UNIX}
334     function TFB25ClientAPI.GetFirebirdLibList: string;
335     begin
336     Result := 'libfbembed.so:libfbembed.so.2.5:libfbembed.so.2.1:libfbclient.so:libfbclient.so.2';
337     end;
338     {$ENDIF}
339    
340     procedure TFB25ClientAPI.LoadInterface;
341     begin
342     inherited LoadInterface;
343     BLOB_get := GetProcAddr('BLOB_get'); {do not localize}
344     BLOB_put := GetProcAddr('BLOB_put'); {do not localize}
345     isc_wait_for_event := GetProcAddr('isc_wait_for_event'); {do not localize}
346     isc_vax_integer := GetProcAddr('isc_vax_integer'); {do not localize}
347     isc_portable_integer := GetProcAddr('isc_portable_integer'); {do not localize}
348     isc_blob_info := GetProcAddr('isc_blob_info'); {do not localize}
349     isc_blob_lookup_desc := GetProcAddr('isc_blob_lookup_desc'); {do not localize}
350     isc_open_blob2 := GetProcAddr('isc_open_blob2'); {do not localize}
351     isc_close_blob := GetProcAddr('isc_close_blob'); {do not localize}
352     isc_get_segment := GetProcAddr('isc_get_segment'); {do not localize}
353     isc_put_segment := GetProcAddr('isc_put_segment'); {do not localize}
354     isc_create_blob2 := GetProcAddr('isc_create_blob2'); {do not localize}
355     isc_cancel_blob := GetProcAddr('isc_cancel_blob'); {do not localize}
356     isc_decode_date := GetProcAddr('isc_decode_date'); {do not localize}
357     isc_encode_date := GetProcAddr('isc_encode_date'); {do not localize}
358     isc_dsql_free_statement := GetProcAddr('isc_dsql_free_statement'); {do not localize}
359     isc_dsql_execute2 := GetProcAddr('isc_dsql_execute2'); {do not localize}
360     isc_dsql_execute := GetProcAddr('isc_dsql_execute'); {do not localize}
361     isc_dsql_set_cursor_name := GetProcAddr('isc_dsql_set_cursor_name'); {do not localize}
362     isc_dsql_fetch := GetProcAddr('isc_dsql_fetch'); {do not localize}
363     isc_dsql_sql_info := GetProcAddr('isc_dsql_sql_info'); {do not localize}
364     isc_dsql_alloc_statement2 := GetProcAddr('isc_dsql_alloc_statement2'); {do not localize}
365     isc_dsql_prepare := GetProcAddr('isc_dsql_prepare'); {do not localize}
366     isc_dsql_describe_bind := GetProcAddr('isc_dsql_describe_bind'); {do not localize}
367     isc_dsql_describe := GetProcAddr('isc_dsql_describe'); {do not localize}
368     isc_dsql_execute_immediate := GetProcAddr('isc_dsql_execute_immediate'); {do not localize}
369     isc_drop_database := GetProcAddr('isc_drop_database'); {do not localize}
370     isc_detach_database := GetProcAddr('isc_detach_database'); {do not localize}
371     isc_attach_database := GetProcAddr('isc_attach_database'); {do not localize}
372     isc_database_info := GetProcAddr('isc_database_info'); {do not localize}
373     isc_start_transaction := GetProcAddr('isc_start_transaction'); {do not localize}
374     isc_start_multiple := GetProcAddr('isc_start_multiple'); {do not localize}
375     isc_commit_transaction := GetProcAddr('isc_commit_transaction'); {do not localize}
376     isc_commit_retaining := GetProcAddr('isc_commit_retaining'); {do not localize}
377     isc_rollback_transaction := GetProcAddr('isc_rollback_transaction'); {do not localize}
378     isc_cancel_events := GetProcAddr('isc_cancel_events'); {do not localize}
379     isc_que_events := GetProcAddr('isc_que_events'); {do not localize}
380     isc_add_user := GetProcAddr('isc_add_user'); {do not localize}
381     isc_delete_user := GetProcAddr('isc_delete_user'); {do not localize}
382     isc_modify_user := GetProcAddr('isc_modify_user'); {do not localize}
383     isc_array_lookup_bounds := GetProcAddr('isc_array_lookup_bounds'); {do not localize}
384     isc_array_get_slice := GetProcAddr('isc_array_get_slice'); {do not localize}
385     isc_array_put_slice := GetProcAddr('isc_array_put_slice'); {do not localize}
386     isc_prepare_transaction := GetProcAddr('isc_prepare_transaction'); {do not localize}
387    
388     FIBServiceAPIPresent := true;
389     isc_rollback_retaining := GetProcAddress(IBLibrary, 'isc_rollback_retaining'); {do not localize}
390     if Assigned(isc_rollback_retaining) then
391     begin
392     isc_service_attach := GetProcAddr('isc_service_attach'); {do not localize}
393     isc_service_detach := GetProcAddr('isc_service_detach'); {do not localize}
394     isc_service_query := GetProcAddr('isc_service_query'); {do not localize}
395     isc_service_start := GetProcAddr('isc_service_start'); {do not localize}
396     isc_decode_sql_date := GetProcAddr('isc_decode_sql_date'); {do not localize}
397     isc_decode_sql_time := GetProcAddr('isc_decode_sql_time'); {do not localize}
398     isc_decode_timestamp := GetProcAddr('isc_decode_timestamp'); {do not localize}
399     isc_encode_sql_date := GetProcAddr('isc_encode_sql_date'); {do not localize}
400     isc_encode_sql_time := GetProcAddr('isc_encode_sql_time'); {do not localize}
401     isc_encode_timestamp := GetProcAddr('isc_encode_timestamp'); {do not localize}
402     end else
403     begin
404     FIBServiceAPIPresent := false;
405     isc_rollback_retaining := @isc_rollback_retaining_stub;
406     isc_service_attach := @isc_service_attach_stub;
407     isc_service_detach := @isc_service_detach_stub;
408     isc_service_query := @isc_service_query_stub;
409     isc_service_start := @isc_service_start_stub;
410     isc_decode_sql_date := @isc_decode_sql_date_stub;
411     isc_decode_sql_time := @isc_decode_sql_time_stub;
412     isc_decode_timestamp := @isc_decode_timestamp_stub;
413     isc_encode_sql_date := @isc_encode_sql_date_stub;
414     isc_encode_sql_time := @isc_encode_sql_time_stub;
415     isc_encode_timestamp := @isc_encode_timestamp_stub;
416     end;
417     end;
418    
419     constructor TFB25ClientAPI.Create;
420     begin
421     inherited;
422     FStatus := TFB25Status.Create(self);
423     FStatusIntf := FStatus;
424     Firebird25ClientAPI := self;
425     end;
426    
427     destructor TFB25ClientAPI.Destroy;
428     begin
429     FStatusIntf := nil;
430     Firebird25ClientAPI := nil;
431     inherited Destroy;
432     end;
433    
434    
435     function TFB25ClientAPI.StatusVector: PISC_STATUS;
436     begin
437     Result := PISC_STATUS(FStatus.StatusVector);
438     end;
439    
440     function TFB25ClientAPI.GetStatus: IStatus;
441     begin
442     Result := FStatus;
443     end;
444    
445     function TFB25ClientAPI.AllocateDPB: IDPB;
446     begin
447     Result := TDPB.Create;
448     end;
449    
450 tony 56 function TFB25ClientAPI.OpenDatabase(DatabaseName: AnsiString; DPB: IDPB;
451 tony 45 RaiseExceptionOnConnectError: boolean): IAttachment;
452     begin
453     Result := TFB25Attachment.Create(DatabaseName,DPB,RaiseExceptionOnConnectError);
454     if not Result.IsConnected then
455     Result := nil;
456     end;
457    
458 tony 56 function TFB25ClientAPI.CreateDatabase(DatabaseName: AnsiString; DPB: IDPB;
459 tony 45 RaiseExceptionOnError: boolean): IAttachment;
460     begin
461     Result := TFB25Attachment.CreateDatabase(DatabaseName, DPB, RaiseExceptionOnError );
462     if (Result <> nil) and not Result.IsConnected then
463     Result := nil;
464     end;
465    
466 tony 56 function TFB25ClientAPI.CreateDatabase(sql: AnsiString; aSQLDialect: integer;
467 tony 47 RaiseExceptionOnError: boolean): IAttachment;
468     begin
469     Result := TFB25Attachment.CreateDatabase(sql,aSQLDialect, RaiseExceptionOnError );
470     if (Result <> nil) and not Result.IsConnected then
471     Result := nil;
472     end;
473    
474 tony 45 function TFB25ClientAPI.AllocateSPB: ISPB;
475     begin
476     Result := TSPB.Create;
477     end;
478    
479     function TFB25ClientAPI.AllocateTPB: ITPB;
480     begin
481     Result := TTPB.Create;
482     end;
483    
484 tony 56 function TFB25ClientAPI.GetServiceManager(ServerName: AnsiString;
485 tony 45 Protocol: TProtocol; SPB: ISPB): IServiceManager;
486     begin
487     if HasServiceAPI then
488     Result := TFB25ServiceManager.Create(ServerName,Protocol,SPB)
489     else
490     Result := nil;
491     end;
492    
493     function TFB25ClientAPI.StartTransaction(Attachments: array of IAttachment;
494     TPB: array of byte; DefaultCompletion: TTransactionCompletion): ITransaction;
495     begin
496     Result := TFB25Transaction.Create(Attachments,TPB,DefaultCompletion);
497     end;
498    
499     function TFB25ClientAPI.StartTransaction(Attachments: array of IAttachment;
500     TPB: ITPB; DefaultCompletion: TTransactionCompletion): ITransaction;
501     begin
502     Result := TFB25Transaction.Create(Attachments,TPB,DefaultCompletion);
503     end;
504    
505     function TFB25ClientAPI.HasServiceAPI: boolean;
506     begin
507     Result := IBServiceAPIPresent;
508     end;
509    
510     function TFB25ClientAPI.HasRollbackRetaining: boolean;
511     begin
512     Result := assigned(isc_rollback_retaining);
513     end;
514    
515     function TFB25ClientAPI.IsEmbeddedServer: boolean;
516     begin
517     Result := false;
518     {$IFDEF UNIX}
519     Result := Pos('libfbembed',FFBLibraryName) = 1;
520     {$ENDIF}
521     {$IFDEF WINDOWS}
522     Result := CompareText(FFBLibraryName,FIREBIRD_EMBEDDED) = 0;
523     {$ENDIF}
524     end;
525    
526     function TFB25ClientAPI.HasMasterIntf: boolean;
527     begin
528     Result := false;
529     end;
530    
531     function TFB25ClientAPI.GetIMaster: TObject;
532     begin
533     Result := nil;
534     end;
535    
536 tony 56 function TFB25ClientAPI.GetImplementationVersion: AnsiString;
537 tony 45 begin
538     Result := FBClientInterfaceVersion;
539     end;
540    
541 tony 56 function TFB25ClientAPI.DecodeInteger(bufptr: PByte; len: short): integer;
542 tony 45 begin
543     Result := isc_portable_integer(bufptr,len);
544     end;
545    
546 tony 56 procedure TFB25ClientAPI.SQLEncodeDate(aDate: TDateTime; bufptr: PByte);
547 tony 45 var
548     tm_date: TCTimeStructure;
549     Yr, Mn, Dy: Word;
550     begin
551     DecodeDate(aDate, Yr, Mn, Dy);
552     with tm_date do begin
553     tm_sec := 0;
554     tm_min := 0;
555     tm_hour := 0;
556     tm_mday := Dy;
557     tm_mon := Mn - 1;
558     tm_year := Yr - 1900;
559     end;
560     isc_encode_sql_date(@tm_date, PISC_DATE(bufptr));
561     end;
562    
563 tony 56 function TFB25ClientAPI.SQLDecodeDate(bufptr: PByte): TDateTime;
564 tony 45 var
565     tm_date: TCTimeStructure;
566     begin
567     isc_decode_sql_date(PISC_DATE(bufptr), @tm_date);
568     try
569     result := EncodeDate(Word(tm_date.tm_year + 1900), Word(tm_date.tm_mon + 1),
570     Word(tm_date.tm_mday));
571     except
572     on E: EConvertError do begin
573     IBError(ibxeInvalidDataConversion, [nil]);
574     end;
575     end;
576     end;
577    
578 tony 56 procedure TFB25ClientAPI.SQLEncodeTime(aTime: TDateTime; bufptr: PByte);
579 tony 45 var
580     tm_date: TCTimeStructure;
581     Hr, Mt, S, Ms: Word;
582     begin
583     DecodeTime(aTime, Hr, Mt, S, Ms);
584     with tm_date do begin
585     tm_sec := S;
586     tm_min := Mt;
587     tm_hour := Hr;
588     tm_mday := 0;
589     tm_mon := 0;
590     tm_year := 0;
591     end;
592     with Firebird25ClientAPI do
593     isc_encode_sql_time(@tm_date, PISC_TIME(bufptr));
594     if Ms > 0 then
595     Inc(PISC_TIME(bufptr)^,Ms*10);
596     end;
597    
598 tony 56 function TFB25ClientAPI.SQLDecodeTime(bufptr: PByte): TDateTime;
599 tony 45 var
600     tm_date: TCTimeStructure;
601     msecs: Word;
602     begin
603     isc_decode_sql_time(PISC_TIME(bufptr), @tm_date);
604     try
605     msecs := (PISC_TIME(bufptr)^ mod 10000) div 10;
606     result := EncodeTime(Word(tm_date.tm_hour), Word(tm_date.tm_min),
607     Word(tm_date.tm_sec), msecs)
608     except
609     on E: EConvertError do begin
610     IBError(ibxeInvalidDataConversion, [nil]);
611     end;
612     end;
613     end;
614    
615 tony 56 procedure TFB25ClientAPI.SQLEncodeDateTime(aDateTime: TDateTime; bufptr: PByte);
616 tony 45 var
617     tm_date: TCTimeStructure;
618     Yr, Mn, Dy, Hr, Mt, S, Ms: Word;
619     begin
620     DecodeDate(aDateTime, Yr, Mn, Dy);
621     DecodeTime(aDateTime, Hr, Mt, S, Ms);
622     with tm_date do begin
623     tm_sec := S;
624     tm_min := Mt;
625     tm_hour := Hr;
626     tm_mday := Dy;
627     tm_mon := Mn - 1;
628     tm_year := Yr - 1900;
629     end;
630     isc_encode_date(@tm_date, PISC_QUAD(bufptr));
631     if Ms > 0 then
632     Inc(PISC_TIMESTAMP(bufptr)^.timestamp_time,Ms*10);
633     end;
634    
635 tony 56 function TFB25ClientAPI.SQLDecodeDateTime(bufptr: PByte): TDateTime;
636 tony 45 var
637     tm_date: TCTimeStructure;
638     msecs: Word;
639     begin
640     isc_decode_date(PISC_QUAD(bufptr), @tm_date);
641     try
642     result := EncodeDate(Word(tm_date.tm_year + 1900), Word(tm_date.tm_mon + 1),
643     Word(tm_date.tm_mday));
644     msecs := (PISC_TIMESTAMP(bufptr)^.timestamp_time mod 10000) div 10;
645     if result >= 0 then
646     result := result + EncodeTime(Word(tm_date.tm_hour), Word(tm_date.tm_min),
647     Word(tm_date.tm_sec), msecs)
648     else
649     result := result - EncodeTime(Word(tm_date.tm_hour), Word(tm_date.tm_min),
650     Word(tm_date.tm_sec), msecs)
651     except
652     on E: EConvertError do begin
653     IBError(ibxeInvalidDataConversion, [nil]);
654     end;
655     end;
656     end;
657    
658     end.
659    
660 tony 56