ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/fbintf/IB.pas
Revision: 45
Committed: Tue Dec 6 10:33:46 2016 UTC (7 years, 11 months ago) by tony
Content type: text/x-pascal
File size: 45466 byte(s)
Log Message:
Committing updates for Release R2-0-0

File Contents

# Content
1 (*
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 IB;
63
64 {$IFDEF FPC}
65 {$mode objfpc}{$H+}
66 {$codepage UTF8}
67 {$interfaces COM}
68 {$IF FPC_FULLVERSION < 30000 }
69 {$ERROR FPC Version 3.0.0 or later is required}
70 {$ENDIF}
71 {$ENDIF}
72
73 {$DEFINE USEFIREBIRD3API}
74 {$DEFINE USELEGACYFIREBIRDAPI}
75
76 {
77 This unit defines the interfaces used to provide the Pascal Language
78 bindings for the Firebird API. These are COM style references counted interfaces
79 and are automatically freed when they go out of scope.
80
81 The interface definition is independent of the Firebird API version and two
82 implementations are provided. One is for the legacy API (2.5 and earlier) and the
83 other is for the new object orientated API (3.0 and later). By default, both are
84 available with the 3.0 API used if it is available. Otherwise the 2.5 API is used.
85 The above two defines can be used to force only one implementation by undefining
86 the symbol for the unwanted API.
87
88 Note that the FirebirdAPI function defined below is used for initial access to
89 the language bindings.
90
91 The goals of these Pascal Langauge bindings are to provide:
92
93 1. A set of reference counted interfaces providing complete access to the Firebird API.
94
95 2. Application Independence from the Firebird API version.
96
97 3. All data access through strongly typed variables and functions with no need for
98 the end user to manipulate untyped data in buffers such as the legacy API SQLDA
99 or the Firebird 3.0 message buffer.
100
101 4. A stable platform for LCL Packages (e.g. IBX) that implement the TDataSet model
102 with independence from the Firebird API version.
103
104 5. Straightforward progammatic access to the Firebird API from Pascal programs.
105
106 String Types
107 ============
108
109 From FPC 3.0 onwards, ANSISTRINGs include the codepage in their definition. All
110 strings used by the interface are sensitive to the codepage in that the codepage
111 for all strings returned by an interface is consistent with the SQL Character set
112 used for the database connection. Input strings will be transliterated, where possible
113 and if necessary, to the codepage consistent with the character set used for
114 the database connection.
115 }
116
117 interface
118
119 uses
120 Classes, SysUtils, DB, FBMessages, IBExternals;
121
122 {These include files are converted from the 'C' originals in the Firebird API
123 and define the various constants used by the API}
124
125 {$I consts_pub.inc}
126 {$I inf_pub.inc}
127 {$I configkeys.inc}
128
129 {The following constants define the values return by calls to the GetSQLType
130 methods provided by several of the interfaces defined below.}
131
132 (*********************)
133 (** SQL definitions **)
134 (*********************)
135 SQL_VARYING = 448;
136 SQL_TEXT = 452;
137 SQL_DOUBLE = 480;
138 SQL_FLOAT = 482;
139 SQL_LONG = 496;
140 SQL_SHORT = 500;
141 SQL_TIMESTAMP = 510;
142 SQL_BLOB = 520;
143 SQL_D_FLOAT = 530;
144 SQL_ARRAY = 540;
145 SQL_QUAD = 550;
146 SQL_TYPE_TIME = 560;
147 SQL_TYPE_DATE = 570;
148 SQL_INT64 = 580;
149 SQL_BOOLEAN = 32764;
150 SQL_DATE = SQL_TIMESTAMP;
151
152 type
153 TGDS_QUAD = record
154 gds_quad_high : ISC_LONG;
155 gds_quad_low : UISC_LONG;
156 end;
157 TGDS__QUAD = TGDS_QUAD;
158 TISC_QUAD = TGDS_QUAD;
159 PGDS_QUAD = ^TGDS_QUAD;
160 PGDS__QUAD = ^TGDS__QUAD;
161 PISC_QUAD = ^TISC_QUAD;
162
163 TIBSQLStatementTypes =
164 (SQLUnknown, SQLSelect, SQLInsert,
165 SQLUpdate, SQLDelete, SQLDDL,
166 SQLGetSegment, SQLPutSegment,
167 SQLExecProcedure, SQLStartTransaction,
168 SQLCommit, SQLRollback,
169 SQLSelectForUpdate, SQLSetGenerator);
170
171 TFBStatusCode = cardinal;
172 TByteArray = array of byte;
173
174 IAttachment = interface;
175 ITransaction = interface;
176
177 {The IParameterBlock generic interface provides the template for all parameter
178 block interfaces}
179
180 generic IParameterBlock<_IItem> = interface
181 function getCount: integer;
182 function Add(ParamType: byte): _IItem;
183 function getItems(index: integer): _IItem;
184 function Find(ParamType: byte): _IItem;
185 procedure PrintBuf; {can be used to print buffer in hex for debugging}
186 property Count: integer read getCount;
187 property Items[index: integer]: _IItem read getItems; default;
188 end;
189
190 {IParameterBlockItem is not used on its own but instead provides a base type for
191 different parameter block items }
192
193 IParameterBlockItem = interface
194 function getParamType: byte;
195 function getAsInteger: integer;
196 function getAsString: string;
197 function getAsByte: byte;
198 procedure setAsString(aValue: string);
199 procedure setAsByte(aValue: byte);
200 procedure SetAsInteger(aValue: integer);
201 property AsString: string read getAsString write setAsString;
202 property AsByte: byte read getAsByte write setAsByte;
203 property AsInteger: integer read getAsInteger write SetAsInteger;
204 end;
205
206
207 {The IStatus interface provides access to error information, if any, returned
208 by the last API call. It can also be used to customise the error message
209 returned by a database engine exception - see EIBInterbaseError.
210
211 This interface can be accessed from IFirebirdAPI.
212 }
213
214 IStatus = interface
215 function GetIBErrorCode: Long;
216 function Getsqlcode: Long;
217 function GetMessage: string;
218 function CheckStatusVector(ErrorCodes: array of TFBStatusCode): Boolean;
219 function GetIBDataBaseErrorMessages: TIBDataBaseErrorMessages;
220 procedure SetIBDataBaseErrorMessages(Value: TIBDataBaseErrorMessages);
221 end;
222
223 { The array metadata interface provides access to the metadata used to describe
224 an array column in a Firebird table.
225 }
226
227 TArrayBound = record
228 UpperBound: short;
229 LowerBound: short;
230 end;
231 TArrayBounds = array of TArrayBound;
232
233 IArrayMetaData = interface
234 function GetSQLType: cardinal;
235 function GetSQLTypeName: string;
236 function GetScale: integer;
237 function GetSize: cardinal;
238 function GetCharSetID: cardinal;
239 function GetTableName: string;
240 function GetColumnName: string;
241 function GetDimensions: integer;
242 function GetBounds: TArrayBounds;
243 end;
244
245 {The array interface provides access to and modification of the array data
246 contained in an array field of a Firebird Table. The array element is
247 selected by specifying its co-ordinates using an integer array. The
248 getter and setter methods used should be appropriate for the type of data
249 contained in the array. Automatic conversion is provided to and from strings.
250 That is GetAsString and SetAsString are safe to use for sql types other than
251 boolean.
252
253 The interface is returned by a GetAsArray getter method (see ISQLData). A new array
254 can be obtained from the IAttachment interface. The SetAsArray setter method
255 (See ISQLParam) is used to apply an updated or new array to the database using
256 an UPDATE or INSERT statement.
257
258 }
259
260 TArrayEventReason = (arChanging,arChanged);
261 IArray = interface;
262 TArrayEventHandler = procedure(Sender: IArray; Reason: TArrayEventReason) of object;
263
264 IArray = interface(IArrayMetaData)
265 function GetArrayID: TISC_QUAD;
266 procedure Clear;
267 function IsEmpty: boolean;
268 procedure PreLoad;
269 procedure CancelChanges;
270 procedure SaveChanges;
271 function GetAsInteger(index: array of integer): integer;
272 function GetAsBoolean(index: array of integer): boolean;
273 function GetAsCurrency(index: array of integer): Currency;
274 function GetAsInt64(index: array of integer): Int64;
275 function GetAsDateTime(index: array of integer): TDateTime;
276 function GetAsDouble(index: array of integer): Double;
277 function GetAsFloat(index: array of integer): Float;
278 function GetAsLong(index: array of integer): Long;
279 function GetAsShort(index: array of integer): Short;
280 function GetAsString(index: array of integer): String;
281 function GetAsVariant(index: array of integer): Variant;
282 procedure SetAsInteger(index: array of integer; AValue: integer);
283 procedure SetAsBoolean(index: array of integer; AValue: boolean);
284 procedure SetAsCurrency(index: array of integer; Value: Currency);
285 procedure SetAsInt64(index: array of integer; Value: Int64);
286 procedure SetAsDate(index: array of integer; Value: TDateTime);
287 procedure SetAsLong(index: array of integer; Value: Long);
288 procedure SetAsTime(index: array of integer; Value: TDateTime);
289 procedure SetAsDateTime(index: array of integer; Value: TDateTime);
290 procedure SetAsDouble(index: array of integer; Value: Double);
291 procedure SetAsFloat(index: array of integer; Value: Float);
292 procedure SetAsShort(index: array of integer; Value: Short);
293 procedure SetAsString(index: array of integer; Value: String);
294 procedure SetAsVariant(index: array of integer; Value: Variant);
295 procedure SetBounds(dim, UpperBound, LowerBound: integer);
296 function GetAttachment: IAttachment;
297 function GetTransaction: ITransaction;
298 procedure AddEventHandler(Handler: TArrayEventHandler);
299 procedure RemoveEventHandler(Handler: TArrayEventHandler);
300 end;
301
302 { The Blob metadata interface provides access to the metadata used to describe
303 a blob column in a Firebird table.
304 }
305
306 IBlobMetaData = interface
307 function GetSubType: integer;
308 function GetCharSetID: cardinal;
309 function GetCodePage: TSystemCodePage;
310 function GetSegmentSize: cardinal;
311 function GetRelationName: string;
312 function GetColumnName: string;
313 end;
314
315 {The Blob Parameter block is used to select a Blob Filter}
316
317 IBPBItem = interface (IParameterBlockItem) end;
318
319 IBPB = specialize IParameterBlock<IBPBItem>;
320
321 { The Blob Interface provides access to a blob data item.
322
323 The interface is returned by a GetAsBlob getter method (see ISQLData). A new Blob
324 can be obtained from the IAttachment interface. The SetAsBlob setter method
325 (See ISQLParam) is used to apply an updated or new array to the database using
326 an UPDATE or INSERT statement.
327 }
328
329 TFBBlobMode = (fbmRead,fbmWrite);
330 TBlobType = (btSegmented,btStream);
331
332 IBlob = interface(IBlobMetaData)
333 function GetBPB: IBPB;
334 procedure Cancel;
335 procedure Close;
336 function GetBlobID: TISC_QUAD;
337 function GetBlobMode: TFBBlobMode;
338 function GetBlobSize: Int64;
339 procedure GetInfo(var NumSegments: Int64; var MaxSegmentSize,
340 TotalSize: Int64; var BlobType: TBlobType);
341 function Read(var Buffer; Count: Longint): Longint;
342 function Write(const Buffer; Count: Longint): Longint;
343 function LoadFromFile(Filename: string): IBlob;
344 function LoadFromStream(S: TStream) : IBlob;
345 function SaveToFile(Filename: string): IBlob;
346 function SaveToStream(S: TStream): IBlob;
347 function GetAsString: rawbytestring;
348 procedure SetAsString(aValue: rawbytestring);
349 function SetString(aValue: rawbytestring): IBlob;
350 function GetAttachment: IAttachment;
351 function GetTransaction: ITransaction;
352 property AsString: rawbytestring read GetAsString write SetAsString;
353 end;
354
355 { The IColumnMetaData interface provides access to the per column metadata for
356 the output of an SQL Statement.
357 }
358
359 { IColumnMetaData }
360
361 IColumnMetaData = interface
362 function GetIndex: integer;
363 function GetSQLType: cardinal;
364 function GetSQLTypeName: string;
365 function getSubtype: integer;
366 function getRelationName: string;
367 function getOwnerName: string;
368 function getSQLName: string; {Name of the column}
369 function getAliasName: string; {Alias Name of column or Column Name if no alias}
370 function getName: string; {Disambiguated uppercase Field Name}
371 function getScale: integer;
372 function getCharSetID: cardinal;
373 function getCodePage: TSystemCodePage;
374 function getIsNullable: boolean;
375 function GetSize: cardinal;
376 function GetArrayMetaData: IArrayMetaData; {Valid only for Array SQL Type}
377 function GetBlobMetaData: IBlobMetaData; {Valid only for Blob SQL Type}
378 property Name: string read GetName;
379 property Size: cardinal read GetSize;
380 property SQLType: cardinal read GetSQLType;
381 property Scale: integer read getScale;
382 property SQLSubtype: integer read getSubtype;
383 property IsNullable: Boolean read GetIsNullable;
384 end;
385
386 {
387 The IMetaData interface provides access to the set of column metadata
388 for the output of an SQL Statement
389 }
390
391 { IMetaData }
392
393 IMetaData = interface
394 function getCount: integer;
395 function getColumnMetaData(index: integer): IColumnMetaData;
396 function GetUniqueRelationName: string; {Non empty if all columns come from the same table}
397 function ByName(Idx: String): IColumnMetaData;
398 property ColMetaData[index: integer]: IColumnMetaData read getColumnMetaData; default;
399 property Count: integer read getCount;
400 end;
401
402 {
403 The ISQLData interface provides access to the data returned in a field in the
404 current row returned from a query or the result of an SQL Execute statement.
405
406 It subclasses IColumnMetaData and so also provides access to the metadata
407 associated with the column.
408
409 The getter and setter methods, and the corresponding properties, provide typed
410 access to the field data. The method/property used should be consistent
411 with the SQL Type. Automatic conversion is provided from strings.
412 That is GetAsString is safe to use for sql types other than boolean.
413 }
414
415
416 ISQLData = interface(IColumnMetaData)
417 function GetAsBoolean: boolean;
418 function GetAsCurrency: Currency;
419 function GetAsInt64: Int64;
420 function GetAsDateTime: TDateTime;
421 function GetAsDouble: Double;
422 function GetAsFloat: Float;
423 function GetAsLong: Long;
424 function GetAsPointer: Pointer;
425 function GetAsQuad: TISC_QUAD;
426 function GetAsShort: short;
427 function GetAsString: String;
428 function GetIsNull: Boolean;
429 function GetAsVariant: Variant;
430 function GetAsBlob: IBlob; overload;
431 function GetAsBlob(BPB: IBPB): IBlob; overload;
432 function GetAsArray: IArray;
433 property AsDate: TDateTime read GetAsDateTime;
434 property AsBoolean:boolean read GetAsBoolean;
435 property AsTime: TDateTime read GetAsDateTime;
436 property AsDateTime: TDateTime read GetAsDateTime ;
437 property AsDouble: Double read GetAsDouble;
438 property AsFloat: Float read GetAsFloat;
439 property AsCurrency: Currency read GetAsCurrency;
440 property AsInt64: Int64 read GetAsInt64 ;
441 property AsInteger: Integer read GetAsLong;
442 property AsLong: Long read GetAsLong;
443 property AsPointer: Pointer read GetAsPointer;
444 property AsQuad: TISC_QUAD read GetAsQuad;
445 property AsShort: short read GetAsShort;
446 property AsString: String read GetAsString;
447 property AsVariant: Variant read GetAsVariant ;
448 property AsBlob: IBlob read GetAsBlob;
449 property AsArray: IArray read GetAsArray;
450 property IsNull: Boolean read GetIsNull;
451 property Value: Variant read GetAsVariant;
452 end;
453
454 { An IResults interface is returned as the result of an SQL Execute statement
455 and provides access to the fields returned, if any. It is a collection of
456 ISQLData interfaces which are, in turn, used to access the data returned by
457 each field of the result set.
458 }
459
460 IResults = interface
461 function getCount: integer;
462 function GetTransaction: ITransaction;
463 function ByName(Idx: String): ISQLData;
464 function getSQLData(index: integer): ISQLData;
465 procedure GetData(index: integer; var IsNull:boolean; var len: short; var data: PChar);
466 procedure SetRetainInterfaces(aValue: boolean);
467 property Data[index: integer]: ISQLData read getSQLData; default;
468 property Count: integer read getCount;
469 end;
470
471 { An IResultSet interface is returned as the result of an SQL Open Cursor statement
472 (e.g. Select Statement) and provides access to the fields returned, if any
473 for the current row. It is a collection of ISQLData interfaces which are,
474 in turn, used to access the data returned by each field of the current row.
475 }
476 IResultSet = interface(IResults)
477 function FetchNext: boolean;
478 function GetCursorName: string;
479 function IsEof: boolean;
480 procedure Close;
481 end;
482
483 {The ISQLParam interface is used to provide access to each parameter in a
484 parametised SQL Statement. It subclasses IColumnMetaData and this part of
485 the interface may be used to access information on the expected SQL Type, etc.
486
487 It also subclasses ISQLData and this part of the interface may be used to access
488 current values for each parameter.
489
490 Otherwise, the interface comprises the Setter Methods and properties used to
491 set the value of each parameter.
492
493 Automatic conversion is provided to and from strings. That is GetAsString and
494 SetAsString are safe to use for sql types other than boolean - provided automatic
495 conversion is possible.
496 }
497
498 ISQLParam = interface
499 function GetIndex: integer;
500 function GetSQLType: cardinal;
501 function GetSQLTypeName: string;
502 function getSubtype: integer;
503 function getName: string;
504 function getScale: integer;
505 function getCharSetID: cardinal;
506 function getCodePage: TSystemCodePage;
507 function getIsNullable: boolean;
508 function GetSize: cardinal;
509 function GetAsBoolean: boolean;
510 function GetAsCurrency: Currency;
511 function GetAsInt64: Int64;
512 function GetAsDateTime: TDateTime;
513 function GetAsDouble: Double;
514 function GetAsFloat: Float;
515 function GetAsLong: Long;
516 function GetAsPointer: Pointer;
517 function GetAsQuad: TISC_QUAD;
518 function GetAsShort: short;
519 function GetAsString: String;
520 function GetIsNull: boolean;
521 function GetAsVariant: Variant;
522 function GetAsBlob: IBlob;
523 function GetAsArray: IArray;
524 procedure Clear;
525 function GetModified: boolean;
526 procedure SetAsBoolean(AValue: boolean);
527 procedure SetAsCurrency(aValue: Currency);
528 procedure SetAsInt64(aValue: Int64);
529 procedure SetAsDate(aValue: TDateTime);
530 procedure SetAsLong(aValue: Long);
531 procedure SetAsTime(aValue: TDateTime);
532 procedure SetAsDateTime(aValue: TDateTime);
533 procedure SetAsDouble(aValue: Double);
534 procedure SetAsFloat(aValue: Float);
535 procedure SetAsPointer(aValue: Pointer);
536 procedure SetAsShort(aValue: Short);
537 procedure SetAsString(aValue: String);
538 procedure SetAsVariant(aValue: Variant);
539 procedure SetIsNull(aValue: Boolean);
540 procedure SetAsBlob(aValue: IBlob);
541 procedure SetAsArray(anArray: IArray);
542 procedure SetAsQuad(aValue: TISC_QUAD);
543 procedure SetCharSetID(aValue: cardinal);
544 property AsDate: TDateTime read GetAsDateTime write SetAsDate;
545 property AsBoolean:boolean read GetAsBoolean write SetAsBoolean;
546 property AsTime: TDateTime read GetAsDateTime write SetAsTime;
547 property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;
548 property AsDouble: Double read GetAsDouble write SetAsDouble;
549 property AsFloat: Float read GetAsFloat write SetAsFloat;
550 property AsCurrency: Currency read GetAsCurrency write SetAsCurrency;
551 property AsInt64: Int64 read GetAsInt64 write SetAsInt64;
552 property AsInteger: Integer read GetAsLong write SetAsLong;
553 property AsLong: Long read GetAsLong write SetAsLong;
554 property AsPointer: Pointer read GetAsPointer write SetAsPointer;
555 property AsShort: Short read GetAsShort write SetAsShort;
556 property AsString: String read GetAsString write SetAsString;
557 property AsVariant: Variant read GetAsVariant write SetAsVariant;
558 property AsBlob: IBlob read GetAsBlob write SetAsBlob;
559 property AsArray: IArray read GetAsArray write SetAsArray;
560 property AsQuad: TISC_QUAD read GetAsQuad write SetAsQuad;
561 property Value: Variant read GetAsVariant write SetAsVariant;
562 property IsNull: Boolean read GetIsNull write SetIsNull;
563 property IsNullable: Boolean read GetIsNullable;
564 property Modified: Boolean read getModified;
565 property Name: string read GetName;
566 property SQLType: cardinal read GetSQLType;
567 end;
568
569 {
570 The ISQLParams interface provides access to the collection of parameters used
571 for the input to an SQL Statement
572 }
573
574 ISQLParams = interface
575 function getCount: integer;
576 function getSQLParam(index: integer): ISQLParam;
577 function ByName(Idx: String): ISQLParam ;
578 function GetModified: Boolean;
579 property Modified: Boolean read GetModified;
580 property Params[index: integer]: ISQLParam read getSQLParam; default;
581 property Count: integer read getCount;
582 end;
583
584 {The IStatement interface provides access to an SQL Statement once it has been
585 initially prepared. The interface is returned from the IAttachment interface.
586 }
587
588 IStatement = interface
589 function GetMetaData: IMetaData; {Output Metadata}
590 function GetSQLParams: ISQLParams;{Statement Parameters}
591 function GetPlan: String;
592 function GetRowsAffected(var SelectCount, InsertCount, UpdateCount, DeleteCount: integer): boolean;
593 function GetSQLStatementType: TIBSQLStatementTypes;
594 function GetSQLText: string;
595 function GetSQLDialect: integer;
596 function IsPrepared: boolean;
597 procedure Prepare(aTransaction: ITransaction=nil);
598 function Execute(aTransaction: ITransaction=nil): IResults;
599 function OpenCursor(aTransaction: ITransaction=nil): IResultSet;
600 function GetAttachment: IAttachment;
601 function GetTransaction: ITransaction;
602 procedure SetRetainInterfaces(aValue: boolean);
603 property MetaData: IMetaData read GetMetaData;
604 property SQLParams: ISQLParams read GetSQLParams;
605 property SQLStatementType: TIBSQLStatementTypes read GetSQLStatementType;
606 end;
607
608 {Transaction Parameter Block: (TPB)
609
610 The TPB provides the parameters used when starting a transaction. It is allocated
611 empty by the FirebirdAPI and the parameters are then added to it. Each individual
612 parameter may be accessed by the ITPBItem interface which can be used to set the
613 value, if any, of the parameter.
614
615 The TPB parameters, and the associated symbolic codes and parameter values may be
616 found in the Interbase 6.0 API Guide.
617 }
618
619 ITPBItem = interface(IParameterBlockItem) end;
620
621 ITPB = specialize IParameterBlock<ITPBItem>;
622
623 {The ITransactionAction interface provides access to a Transaction once it
624 has been initially started. After a Commit or Rollback, a transaction
625 may be restarted, optinally with a new TPB.
626
627 A multi-database transaction is started from the FirebirdAPI. A single database
628 transaction is started from the IAttachment interface.
629 }
630
631 TTransactionAction = (TARollback, TACommit, TACommitRetaining, TARollbackRetaining);
632 TTransactionCompletion = TARollback.. TACommit;
633
634 ITransaction = interface
635 function getTPB: ITPB;
636 procedure Start(DefaultCompletion: TTransactionCompletion=taCommit);
637 function GetInTransaction: boolean;
638 procedure PrepareForCommit; {Two phase commit - stage 1}
639 procedure Commit(Force: boolean=false);
640 procedure CommitRetaining;
641 function HasActivity: boolean;
642 procedure Rollback(Force: boolean=false);
643 procedure RollbackRetaining;
644 function GetAttachmentCount: integer;
645 function GetAttachment(index: integer): IAttachment;
646 property InTransaction: boolean read GetInTransaction;
647 end;
648
649 { The IEvents Interface is used to handle events from a single database. The
650 interface is allocated from the IAttachment Interface.
651
652 Note that the EventHandler called when an event occurs following AsynWaitForEvent
653 is called in a different thread to the calling program and TThread.Synchronize
654 may be needed to pass the event back to the main thread.
655
656 Neither AsyncWaitForEvent nor WaitForEvent is intended to be thread safe
657 in a multi-threaded environment and should always be called from the main
658 thread.
659 }
660
661 TEventInfo = record
662 EventName: string;
663 Count: integer;
664 end;
665
666 TEventCounts = array of TEventInfo;
667 IEvents = interface;
668 TEventHandler = procedure(Sender: IEvents) of object;
669
670 { IEvents }
671
672 IEvents = interface
673 procedure GetEvents(EventNames: TStrings);
674 procedure SetEvents(EventNames: TStrings); overload;
675 procedure SetEvents(EventName: string); overload;
676 procedure Cancel;
677 function ExtractEventCounts: TEventCounts;
678 procedure WaitForEvent;
679 procedure AsyncWaitForEvent(EventHandler: TEventHandler);
680 function GetAttachment: IAttachment;
681 end;
682
683 {The IDBInformation Interface.
684
685 An IDBInformation interface is returned by the IAttachment GetDBInformation
686 method. The interface provides access to the information requested and
687 returned by the method.
688
689 IDBInformation itself gives access to a collection of IDBInfoItems. Each one
690 provides information requested, as indicated by the ItemType and the actual
691 value of the information. In some cases, the returned item is itself a
692 colletion of IDBInfoItems.
693
694 The IDBInformation items, and the associated symbolic codes and parameter values may be
695 found in the Interbase 6.0 API Guide.
696 }
697
698 TDBOperationCount = record
699 TableID: UShort;
700 Count: cardinal;
701 end;
702
703 TDBOperationCounts = array of TDBOperationCount;
704
705 IDBInfoItem = interface
706 function getItemType: byte;
707 function getSize: integer;
708 procedure getRawBytes(var Buffer);
709 function getAsString: string;
710 function getAsInteger: integer;
711 procedure DecodeIDCluster(var ConnectionType: integer; var DBFileName, DBSiteName: string);
712 function getAsBytes: TByteArray;
713 procedure DecodeVersionString(var Version: byte; var VersionString: string);
714 function getOperationCounts: TDBOperationCounts;
715 procedure DecodeUserNames(UserNames: TStrings);
716
717 {user names only}
718 function GetCount: integer;
719 function GetItem(index: integer): IDBInfoItem;
720 function Find(ItemType: byte): IDBInfoItem;
721 property AsInteger: integer read getAsInteger;
722 property AsString: string read GetAsString;
723 property Count: integer read GetCount;
724 property Items[index: integer]: IDBInfoItem read getItem; default;
725 end;
726
727 { IDBInformation }
728
729 IDBInformation = interface
730 function GetCount: integer;
731 function GetItem(index: integer): IDBInfoItem;
732 function Find(ItemType: byte): IDBInfoItem;
733 procedure PrintBuf; {can be used to print buffer in hex for debugging}
734 property Count: integer read GetCount;
735 property Items[index: integer]: IDBInfoItem read getItem; default;
736 end;
737
738 {The Database Parameter Block (DPB).
739
740 The DPB provides the parameters used when connecting to a database. It is allocated
741 empty by the FirebirdAPI and the parameters are then added to it. Each individual
742 parameter may be accessed by the IDPBItem interface which can be used to set the
743 value, if any, of the parameter.
744
745 The DPB parameters, and the associated symbolic codes and parameter values may be
746 found in the Interbase 6.0 API Guide.
747 }
748
749 IDPBItem = interface(IParameterBlockItem) end;
750
751 IDPB = specialize IParameterBlock<IDPBItem>;
752
753 {The IAttachment interface provides access to a Database Connection. It may be
754 used to:
755
756 a. Disconnect and reconnect to the database.
757
758 b. Start a Transaction on the database
759
760 c. Execute directly SQL DDL Statements and others that return no information.
761
762 d. OpenCursors (i.e. execute SQL Select statements and return the results)
763
764 e. Prepare SQL Statements, returning an IStatement interface for further processing.
765
766 f. Provide access to an SQL Event Handler.
767
768 g. Access Database Information.
769
770 h. Support the handling of Array and Blob data.
771
772 Note that SQL statements can be prepared with named parameters (PSQL style).
773 This then allows the parameters to be accessed by name. The same name can
774 be used for more than one parameter, allowing a single operation to be used
775 to set all parameters with the same name.
776 }
777
778 { IAttachment }
779
780 IAttachment = interface
781 function getDPB: IDPB;
782 function AllocateBPB: IBPB;
783 procedure Connect;
784 procedure Disconnect(Force: boolean=false);
785 function IsConnected: boolean;
786 procedure DropDatabase;
787 function StartTransaction(TPB: array of byte; DefaultCompletion: TTransactionCompletion=taCommit): ITransaction; overload;
788 function StartTransaction(TPB: ITPB; DefaultCompletion: TTransactionCompletion=taCommit): ITransaction; overload;
789 procedure ExecImmediate(transaction: ITransaction; sql: string; SQLDialect: integer); overload;
790 procedure ExecImmediate(TPB: array of byte; sql: string; SQLDialect: integer); overload;
791 procedure ExecImmediate(transaction: ITransaction; sql: string); overload;
792 procedure ExecImmediate(TPB: array of byte; sql: string); overload;
793 function ExecuteSQL(TPB: array of byte; sql: string; SQLDialect: integer; params: array of const): IResults; overload;
794 function ExecuteSQL(transaction: ITransaction; sql: string; SQLDialect: integer; params: array of const): IResults; overload;
795 function ExecuteSQL(TPB: array of byte; sql: string; params: array of const): IResults; overload;
796 function ExecuteSQL(transaction: ITransaction; sql: string; params: array of const): IResults; overload;
797 function OpenCursor(transaction: ITransaction; sql: string; aSQLDialect: integer): IResultSet; overload;
798 function OpenCursor(transaction: ITransaction; sql: string; aSQLDialect: integer;
799 params: array of const): IResultSet; overload;
800 function OpenCursor(transaction: ITransaction; sql: string): IResultSet; overload;
801 function OpenCursor(transaction: ITransaction; sql: string;
802 params: array of const): IResultSet; overload;
803 function OpenCursorAtStart(transaction: ITransaction; sql: string; aSQLDialect: integer): IResultSet; overload;
804 function OpenCursorAtStart(transaction: ITransaction; sql: string; aSQLDialect: integer;
805 params: array of const): IResultSet; overload;
806 function OpenCursorAtStart(transaction: ITransaction; sql: string): IResultSet; overload;
807 function OpenCursorAtStart(transaction: ITransaction; sql: string;
808 params: array of const): IResultSet; overload;
809 function OpenCursorAtStart(sql: string): IResultSet; overload;
810 function OpenCursorAtStart(sql: string;
811 params: array of const): IResultSet; overload;
812 function Prepare(transaction: ITransaction; sql: string; aSQLDialect: integer): IStatement; overload;
813 function Prepare(transaction: ITransaction; sql: string): IStatement; overload;
814 function PrepareWithNamedParameters(transaction: ITransaction; sql: string;
815 aSQLDialect: integer; GenerateParamNames: boolean=false): IStatement; overload;
816 function PrepareWithNamedParameters(transaction: ITransaction; sql: string;
817 GenerateParamNames: boolean=false): IStatement; overload;
818
819 {Events}
820 function GetEventHandler(Events: TStrings): IEvents; overload;
821 function GetEventHandler(Event: string): IEvents; overload;
822
823 {Blob - may use to open existing Blobs. However, ISQLData.AsBlob is preferred}
824
825 function CreateBlob(transaction: ITransaction; RelationName, ColumnName: string; BPB: IBPB=nil): IBlob; overload;
826 function CreateBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BPB: IBPB=nil): IBlob; overload;
827 function CreateBlob(transaction: ITransaction; SubType: integer; CharSetID: cardinal=0; BPB: IBPB=nil): IBlob; overload;
828 function OpenBlob(transaction: ITransaction; RelationName, ColumnName: string; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob;
829
830 {Array - may use to open existing arrays. However, ISQLData.AsArray is preferred}
831
832 function OpenArray(transaction: ITransaction; RelationName, ColumnName: string; ArrayID: TISC_QUAD): IArray;
833 function CreateArray(transaction: ITransaction; RelationName, ColumnName: string): IArray; overload;
834 function CreateArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData): IArray; overload;
835
836 {Database Information}
837 function GetSQLDialect: integer;
838 function GetBlobMetaData(Transaction: ITransaction; tableName, columnName: string): IBlobMetaData;
839 function GetArrayMetaData(Transaction: ITransaction; tableName, columnName: string): IArrayMetaData;
840 function GetDBInformation(Requests: array of byte): IDBInformation; overload;
841 function GetDBInformation(Request: byte): IDBInformation; overload;
842 function HasActivity: boolean;
843 end;
844
845 TProtocol = (TCP, SPX, NamedPipe, Local);
846
847 {Service Parameter Block (SPB).
848
849 The SPB provides the parameters used when connecting to a Service Manager. It is
850 allocated empty by the FirebirdAPI and the parameters are then added to it. Each
851 individual parameter may be accessed by the ISPBItem interface which can be used
852 to set the value, if any, of the parameter.
853
854 The SPB parameters, and the associated symbolic codes and parameter values may be
855 found in the Interbase 6.0 API Guide.
856
857 }
858
859 ISPBItem = interface(IParameterBlockItem) end;
860
861 ISPB = specialize IParameterBlock<ISPBItem>;
862
863 {Service Query Parameter Block (SQPB).
864
865 This is a specialised parameter block used to send data to a service manager
866 in a Query Request.
867 }
868
869 ISQPBItem = interface(IParameterBlockItem)
870 function CopyFrom(source: TStream; count: integer): integer;
871 end;
872
873 ISQPB = specialize IParameterBlock<ISQPBItem>;
874
875 {Service Request Block (SRB).
876
877 The SRB specifies what is requested from the Service Manager when starting a
878 service or querying a service. It is allocated empty by the ServiceManager API and
879 the parameters are then added to it. Each individual parameter may be accessed
880 by the ISRBItem interface which can be used to set the value, if any, of the parameter.
881
882 The SRB parameters, and the associated symbolic codes and parameter values may be
883 found in the Interbase 6.0 API Guide.
884
885 }
886
887 ISRBItem = interface(IParameterBlockItem) end;
888
889 ISRB = specialize IParameterBlock<ISRBItem>;
890
891 {The Service Query Results Interface.
892
893 An IServiceQueryResults interface is returned by the IServiceManager Query
894 method. The interface provides access to the information requested and
895 returned by the method.
896
897 IServiceQueryResults itself gives access to a collection of IServiceQueryResultItem.
898 Each one provides information requested, as indicated by the ItemType and the actual
899 value of the information. In some cases, the returned item is itself a
900 collection of IServiceQueryResultSubItem.
901
902 The IServiceQueryResultItem items, and the associated symbolic codes and parameter values may be
903 found in the Interbase 6.0 API Guide.
904 }
905
906 IServiceQueryResultSubItem = interface
907 function getItemType: byte;
908 function getSize: integer;
909 procedure getRawBytes(var Buffer);
910 function getAsString: string;
911 function getAsInteger: integer;
912 function getAsByte: byte;
913 function CopyTo(stream: TStream; count: integer): integer;
914 property AsString: string read getAsString;
915 property AsInteger: integer read getAsInteger;
916 property AsByte: byte read getAsByte;
917 end;
918
919 IServiceQueryResultItem = interface(IServiceQueryResultSubItem)
920 function getCount: integer;
921 function getItem(index: integer): IServiceQueryResultSubItem;
922 function find(ItemType: byte): IServiceQueryResultSubItem;
923 property Items[index: integer]: IServiceQueryResultSubItem read getItem; default;
924 property Count: integer read getCount;
925 end;
926
927 IServiceQueryResults = interface
928 function getCount: integer;
929 function getItem(index: integer): IServiceQueryResultItem;
930 function find(ItemType: byte): IServiceQueryResultItem;
931 procedure PrintBuf; {can be used to print buffer in hex for debugging}
932 property Items[index: integer]: IServiceQueryResultItem read getItem; default;
933 property Count: integer read getCount;
934 end;
935
936 {The IServiceManager interface provides access to a service manager. It can
937 used to Detach and re-attach to Service Manager, to start services and to
938 query the service manager.
939
940 The interface is returned by the FirebirdAPI GetService Manager method.
941 }
942
943 { IServiceManager }
944
945 IServiceManager = interface
946 function getSPB: ISPB;
947 function getServerName: string;
948 procedure Attach;
949 procedure Detach(Force: boolean=false);
950 function IsAttached: boolean;
951 function AllocateSRB: ISRB;
952 function AllocateSQPB: ISQPB;
953 procedure Start(Request: ISRB);
954 function Query(SQPB: ISQPB; Request: ISRB) :IServiceQueryResults; overload;
955 function Query(Request: ISRB) :IServiceQueryResults; overload;
956 end;
957
958 {The Firebird API.
959
960 This is the base interface and is used to create/open a database connection, to
961 start a transaction on multiple databases and the access the service manager.
962
963 The interface is returned by the FirebirdAPI function.
964 }
965
966 IFirebirdAPI = interface
967 {Database connections}
968 function AllocateDPB: IDPB;
969 function OpenDatabase(DatabaseName: string; DPB: IDPB; RaiseExceptionOnConnectError: boolean=true): IAttachment;
970 function CreateDatabase(DatabaseName: string; DPB: IDPB; RaiseExceptionOnError: boolean=true): IAttachment;
971
972 {Start Transaction against multiple databases}
973 function AllocateTPB: ITPB;
974 function StartTransaction(Attachments: array of IAttachment;
975 TPB: array of byte; DefaultCompletion: TTransactionCompletion=taCommit): ITransaction; overload;
976 function StartTransaction(Attachments: array of IAttachment;
977 TPB: ITPB; DefaultCompletion: TTransactionCompletion=taCommit): ITransaction; overload;
978
979 {Service Manager}
980 function HasServiceAPI: boolean;
981 function AllocateSPB: ISPB;
982 function GetServiceManager(ServerName: string; Protocol: TProtocol; SPB: ISPB): IServiceManager;
983
984 {Information}
985 function GetStatus: IStatus;
986 function GetLibraryName: string;
987 function HasRollbackRetaining: boolean;
988 function IsEmbeddedServer: boolean;
989 function GetImplementationVersion: string;
990
991 {Firebird 3 API}
992 function HasMasterIntf: boolean;
993 function GetIMaster: TObject;
994
995 {utility}
996 function GetCharsetName(CharSetID: integer): string;
997 function CharSetID2CodePage(CharSetID: integer; var CodePage: TSystemCodePage): boolean;
998 function CodePage2CharSetID(CodePage: TSystemCodePage; var CharSetID: integer): boolean;
999 function CharSetName2CharSetID(CharSetName: string; var CharSetID: integer): boolean;
1000 function CharSetWidth(CharSetID: integer; var Width: integer): boolean;
1001 end;
1002
1003 type
1004 TOnGetLibraryName = procedure(var libname: string);
1005
1006 const
1007 OnGetLibraryName: TOnGetLibraryName = nil;
1008 AllowUseOfFBLIB: boolean = false;
1009
1010 type
1011 { EIBError }
1012
1013 EIBError = class(EDatabaseError)
1014 private
1015 FSQLCode: Long;
1016 public
1017 constructor Create(ASQLCode: Long; Msg: string);
1018 property SQLCode: Long read FSQLCode;
1019 end;
1020
1021 { EIBInterBaseError - Firebird Engine errors}
1022
1023 EIBInterBaseError = class(EIBError)
1024 private
1025 FIBErrorCode: Long;
1026 public
1027 constructor Create(Status: IStatus); overload;
1028 constructor Create(ASQLCode: Long; AIBErrorCode: Long; Msg: string); overload;
1029 property IBErrorCode: Long read FIBErrorCode;
1030 end;
1031
1032 {IB Client Exceptions}
1033 EIBClientError = class(EIBError);
1034
1035 {IBError is used internally and by IBX to throw an EIBClientError}
1036
1037 procedure IBError(ErrMess: TIBClientError; const Args: array of const);
1038
1039 {The Firebird API function is used to access the IFirebirdAPI interface.
1040
1041 It will load the Firebird Client Library if this is not already loaded and
1042 select an implementation of the Firebird API (legacy 2.5 or 3.0.
1043 }
1044
1045 function FirebirdAPI: IFirebirdAPI;
1046
1047 {IBX support functions. Probably best ignored i.e. always used the FirebirdAPI
1048 functino to load the library and check if it's loaded.}
1049
1050 function TryIBLoad: Boolean;
1051 procedure CheckIBLoaded;
1052
1053 implementation
1054
1055 uses FBClientAPI
1056 {$IFDEF USELEGACYFIREBIRDAPI}, FB25ClientAPI {$ENDIF}
1057 {$IFDEF USEFIREBIRD3API}, FB30ClientAPI {$ENDIF};
1058
1059 var FFirebirdAPI: IFirebirdAPI;
1060
1061 function FirebirdAPI: IFirebirdAPI;
1062 begin
1063 if FFirebirdAPI = nil then
1064 CheckIBLoaded;
1065 Result := FFirebirdAPI;
1066 end;
1067
1068 function TryIBLoad: Boolean;
1069 begin
1070 Result := FFirebirdAPI <> nil;
1071 try
1072 {$IFDEF USEFIREBIRD3API}
1073 if not Result then
1074 begin
1075 FFirebirdAPI := TFB30ClientAPI.Create;
1076 Result := FFirebirdAPI.HasMasterIntf;
1077 end;
1078 {$ENDIF}
1079 {$IFDEF USELEGACYFIREBIRDAPI}
1080 if not Result then
1081 begin
1082 FFirebirdAPI := nil;
1083 FFirebirdAPI := TFB25ClientAPI.Create;
1084 Result := true;
1085 end;
1086 {$ENDIF}
1087 if Result and not (FFirebirdAPI as TFBClientAPI).IsLibraryLoaded then
1088 begin
1089 Result := false;
1090 FFirebirdAPI := nil;
1091 end;
1092 except
1093 SysUtils.showexception(ExceptObject,ExceptAddr);
1094 Result := false;
1095 end;
1096 end;
1097
1098 procedure CheckIBLoaded;
1099 begin
1100 if not TryIBLoad then
1101 IBError(ibxeInterBaseMissing, [nil]);
1102 end;
1103
1104 { EIBError }
1105
1106 constructor EIBError.Create(ASQLCode: Long; Msg: string);
1107 begin
1108 inherited Create(Msg);
1109 FSQLCode := ASQLCode;
1110 end;
1111
1112 { EIBInterBaseError }
1113
1114 constructor EIBInterBaseError.Create(Status: IStatus);
1115 begin
1116 inherited Create(Status.Getsqlcode,Status.GetMessage);
1117 FIBErrorCode := Status.GetIBErrorCode;
1118 end;
1119
1120 constructor EIBInterBaseError.Create(ASQLCode: Long; AIBErrorCode: Long;
1121 Msg: string);
1122 begin
1123 inherited Create(ASQLCode,Msg);
1124 FIBErrorCode := AIBErrorCode;
1125 end;
1126
1127 procedure IBError(ErrMess: TIBClientError; const Args: array of const);
1128 begin
1129 raise EIBClientError.Create(Ord(ErrMess),
1130 Format(GetErrorMessage(ErrMess), Args));
1131 end;
1132
1133 initialization
1134 FFirebirdAPI := nil;
1135
1136
1137 end.
1138