ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/fbintf/client/3.0/FB30Attachment.pas
Revision: 266
Committed: Wed Dec 26 18:34:32 2018 UTC (5 years, 3 months ago) by tony
Content type: text/x-pascal
File size: 14045 byte(s)
Log Message:
Fixes Merged

File Contents

# Content
1 (*
2 * Firebird Interface (fbintf). The fbintf components provide a set of
3 * Pascal language bindings for the Firebird API.
4 *
5 * The contents of this file are subject to the Initial Developer's
6 * Public License Version 1.0 (the "License"); you may not use this
7 * file except in compliance with the License. You may obtain a copy
8 * of the License here:
9 *
10 * http://www.firebirdsql.org/index.php?op=doc&id=idpl
11 *
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing rights
15 * and limitations under the License.
16 *
17 * The Initial Developer of the Original Code is Tony Whyman.
18 *
19 * The Original Code is (C) 2016 Tony Whyman, MWA Software
20 * (http://www.mwasoftware.co.uk).
21 *
22 * All Rights Reserved.
23 *
24 * Contributor(s): ______________________________________.
25 *
26 *)
27 unit FB30Attachment;
28 {$IFDEF MSWINDOWS}
29 {$DEFINE WINDOWS}
30 {$ENDIF}
31
32 {$IFDEF FPC}
33 {$mode delphi}
34 {$interfaces COM}
35 {$ENDIF}
36
37 interface
38
39 uses
40 Classes, SysUtils, FBAttachment, FB30ClientAPI, Firebird, IB, FBActivityMonitor, FBParamBlock;
41
42 type
43
44 { TFB30Attachment }
45
46 TFB30Attachment = class(TFBAttachment,IAttachment, IActivityMonitor)
47 private
48 FAttachmentIntf: Firebird.IAttachment;
49 FFirebird30ClientAPI: TFB30ClientAPI;
50 protected
51 procedure CheckHandle; override;
52 public
53 constructor Create(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB;
54 RaiseExceptionOnConnectError: boolean);
55 constructor CreateDatabase(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB; RaiseExceptionOnError: boolean); overload;
56 constructor CreateDatabase(api: TFB30ClientAPI; sql: AnsiString; aSQLDialect: integer;
57 RaiseExceptionOnError: boolean); overload;
58 destructor Destroy; override;
59 function GetDBInfo(ReqBuffer: PByte; ReqBufLen: integer): IDBInformation;
60 override;
61 property AttachmentIntf: Firebird.IAttachment read FAttachmentIntf;
62 property Firebird30ClientAPI: TFB30ClientAPI read FFirebird30ClientAPI;
63
64 public
65 {IAttachment}
66 procedure Connect;
67 procedure Disconnect(Force: boolean=false); override;
68 function IsConnected: boolean; override;
69 procedure DropDatabase;
70 function StartTransaction(TPB: array of byte; DefaultCompletion: TTransactionCompletion): ITransaction; override;
71 function StartTransaction(TPB: ITPB; DefaultCompletion: TTransactionCompletion): ITransaction; override;
72 procedure ExecImmediate(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer); override;
73 function Prepare(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer): IStatement; override;
74 function PrepareWithNamedParameters(transaction: ITransaction; sql: AnsiString;
75 aSQLDialect: integer; GenerateParamNames: boolean=false): IStatement; override;
76
77 {Events}
78 function GetEventHandler(Events: TStrings): IEvents; override;
79
80 {Blob - may use to open existing Blobs. However, ISQLData.AsBlob is preferred}
81
82 function CreateBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BPB: IBPB=nil): IBlob; overload;
83 function CreateBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BPB: IBPB=nil): IBlob; overload;
84 function CreateBlob(transaction: ITransaction; SubType: integer; aCharSetID: cardinal=0; BPB: IBPB=nil): IBlob; overload;
85 function OpenBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob; overload;
86 function OpenBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob; overload; override;
87
88 {Array}
89 function OpenArray(transaction: ITransaction; RelationName, ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray;
90 function CreateArray(transaction: ITransaction; RelationName, ColumnName: AnsiString): IArray; overload;
91 function CreateArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData): IArray; overload;
92 function CreateArrayMetaData(SQLType: cardinal; tableName: AnsiString;
93 columnName: AnsiString; Scale: integer; size: cardinal; aCharSetID: cardinal;
94 dimensions: cardinal; bounds: TArrayBounds): IArrayMetaData;
95
96
97 {Database Information}
98 function GetBlobMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IBlobMetaData;
99 function GetArrayMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IArrayMetaData;
100 procedure getFBVersion(version: TStrings);
101 end;
102
103 implementation
104
105 uses FB30Transaction, FB30Statement, FB30Array, FB30Blob, FBMessages,
106 FBOutputBlock, FB30Events, IBUtils;
107
108 type
109 { TVersionCallback }
110
111 TVersionCallback = class(Firebird.IVersionCallbackImpl)
112 private
113 FOutput: TStrings;
114 public
115 constructor Create(output: TStrings);
116 procedure callback(status: Firebird.IStatus; text: PAnsiChar); override;
117 end;
118
119 { TVersionCallback }
120
121 constructor TVersionCallback.Create(output: TStrings);
122 begin
123 inherited Create;
124 FOutput := output;
125 end;
126
127 procedure TVersionCallback.callback(status: Firebird.IStatus; text: PAnsiChar);
128 begin
129 FOutput.Add(text);
130 end;
131
132
133 { TFB30Attachment }
134
135 procedure TFB30Attachment.CheckHandle;
136 begin
137 if FAttachmentIntf = nil then
138 IBError(ibxeDatabaseClosed,[nil]);
139 end;
140
141 constructor TFB30Attachment.Create(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB;
142 RaiseExceptionOnConnectError: boolean);
143 begin
144 FFirebird30ClientAPI := api;
145 if aDPB = nil then
146 begin
147 if RaiseExceptionOnConnectError then
148 IBError(ibxeNoDPB,[nil]);
149 Exit;
150 end;
151 inherited Create(api,DatabaseName,aDPB,RaiseExceptionOnConnectError);
152 Connect;
153 end;
154
155 constructor TFB30Attachment.CreateDatabase(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB;
156 RaiseExceptionOnError: boolean);
157 var Param: IDPBItem;
158 sql: AnsiString;
159 IsCreateDB: boolean;
160 begin
161 inherited Create(api,DatabaseName,aDPB,RaiseExceptionOnError);
162 FFirebird30ClientAPI := api;
163 IsCreateDB := true;
164 if aDPB <> nil then
165 begin
166 Param := aDPB.Find(isc_dpb_set_db_SQL_dialect);
167 if Param <> nil then
168 FSQLDialect := Param.AsByte;
169 end;
170 sql := GenerateCreateDatabaseSQL(DatabaseName,aDPB);
171 with FFirebird30ClientAPI do
172 begin
173 FAttachmentIntf := UtilIntf.executeCreateDatabase(StatusIntf,Length(sql),
174 PAnsiChar(sql),FSQLDialect,@IsCreateDB);
175 if FRaiseExceptionOnConnectError then Check4DataBaseError;
176 if InErrorState then
177 FAttachmentIntf := nil
178 else
179 if aDPB <> nil then
180 {Connect using known parameters}
181 begin
182 Disconnect;
183 Connect;
184 end
185 else
186 GetODSAndConnectionInfo;
187 end;
188 end;
189
190 constructor TFB30Attachment.CreateDatabase(api: TFB30ClientAPI; sql: AnsiString; aSQLDialect: integer;
191 RaiseExceptionOnError: boolean);
192 var IsCreateDB: boolean;
193 begin
194 inherited Create(api,'',nil,RaiseExceptionOnError);
195 FFirebird30ClientAPI := api;
196 FSQLDialect := aSQLDialect;
197 with FFirebird30ClientAPI do
198 begin
199 FAttachmentIntf := UtilIntf.executeCreateDatabase(StatusIntf,Length(sql),
200 PAnsiChar(sql),aSQLDialect,@IsCreateDB);
201 if FRaiseExceptionOnConnectError then Check4DataBaseError;
202 if InErrorState then
203 FAttachmentIntf := nil;
204 end;
205 GetODSAndConnectionInfo;
206 ExtractConnectString(sql,FDatabaseName);
207 DPBFromCreateSQL(sql);
208 end;
209
210 destructor TFB30Attachment.Destroy;
211 begin
212 inherited Destroy;
213 if assigned(FAttachmentIntf) then
214 FAttachmentIntf.release;
215 end;
216
217 function TFB30Attachment.GetDBInfo(ReqBuffer: PByte; ReqBufLen: integer): IDBInformation;
218 begin
219 Result := TDBInformation.Create(Firebird30ClientAPI);
220 with FFirebird30ClientAPI, Result as TDBInformation do
221 begin
222 FAttachmentIntf.getInfo(StatusIntf, ReqBufLen, BytePtr(ReqBuffer),
223 getBufSize, BytePtr(Buffer));
224 Check4DataBaseError;
225 end
226 end;
227
228 procedure TFB30Attachment.Connect;
229 begin
230 with FFirebird30ClientAPI do
231 begin
232 FAttachmentIntf := ProviderIntf.attachDatabase(StatusIntf,PAnsiChar(FDatabaseName),
233 (DPB as TDPB).getDataLength,
234 BytePtr((DPB as TDPB).getBuffer));
235 if FRaiseExceptionOnConnectError then Check4DataBaseError;
236 if InErrorState then
237 FAttachmentIntf := nil
238 else
239 GetODSAndConnectionInfo;
240 end;
241 end;
242
243 procedure TFB30Attachment.Disconnect(Force: boolean);
244 begin
245 if IsConnected then
246 with FFirebird30ClientAPI do
247 begin
248 EndAllTransactions;
249 FAttachmentIntf.Detach(StatusIntf);
250 if not Force and InErrorState then
251 IBDataBaseError;
252 FAttachmentIntf := nil;
253 FHasDefaultCharSet := false;
254 FCodePage := CP_NONE;
255 FCharSetID := 0;
256 end;
257 end;
258
259 function TFB30Attachment.IsConnected: boolean;
260 begin
261 Result := FAttachmentIntf <> nil;
262 end;
263
264 procedure TFB30Attachment.DropDatabase;
265 begin
266 if IsConnected then
267 with FFirebird30ClientAPI do
268 begin
269 EndAllTransactions;
270 FAttachmentIntf.dropDatabase(StatusIntf);
271 Check4DataBaseError;
272 FAttachmentIntf := nil;
273 end;
274 end;
275
276 function TFB30Attachment.StartTransaction(TPB: array of byte;
277 DefaultCompletion: TTransactionCompletion): ITransaction;
278 begin
279 CheckHandle;
280 Result := TFB30Transaction.Create(FFirebird30ClientAPI,self,TPB,DefaultCompletion);
281 end;
282
283 function TFB30Attachment.StartTransaction(TPB: ITPB;
284 DefaultCompletion: TTransactionCompletion): ITransaction;
285 begin
286 CheckHandle;
287 Result := TFB30Transaction.Create(FFirebird30ClientAPI,self,TPB,DefaultCompletion);
288 end;
289
290 procedure TFB30Attachment.ExecImmediate(transaction: ITransaction; sql: AnsiString;
291 aSQLDialect: integer);
292 begin
293 CheckHandle;
294 with FFirebird30ClientAPI do
295 begin
296 FAttachmentIntf.execute(StatusIntf,(transaction as TFB30Transaction).TransactionIntf,
297 Length(sql),PAnsiChar(sql),aSQLDialect,nil,nil,nil,nil);
298 Check4DataBaseError;
299 end;
300 end;
301
302 function TFB30Attachment.Prepare(transaction: ITransaction; sql: AnsiString;
303 aSQLDialect: integer): IStatement;
304 begin
305 CheckHandle;
306 Result := TFB30Statement.Create(self,transaction,sql,aSQLDialect);
307 end;
308
309 function TFB30Attachment.PrepareWithNamedParameters(transaction: ITransaction;
310 sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean): IStatement;
311 begin
312 CheckHandle;
313 Result := TFB30Statement.CreateWithParameterNames(self,transaction,sql,aSQLDialect,
314 GenerateParamNames);
315 end;
316
317 function TFB30Attachment.GetEventHandler(Events: TStrings): IEvents;
318 begin
319 CheckHandle;
320 Result := TFB30Events.Create(self,Events);
321 end;
322
323 function TFB30Attachment.CreateBlob(transaction: ITransaction; RelationName,
324 ColumnName: AnsiString; BPB: IBPB): IBlob;
325 begin
326 CheckHandle;
327 Result := TFB30Blob.Create(self,transaction as TFB30Transaction,
328 TFB30BlobMetaData.Create(self,Transaction as TFB30Transaction,RelationName,ColumnName),BPB);
329 end;
330
331 function TFB30Attachment.CreateBlob(transaction: ITransaction;
332 BlobMetaData: IBlobMetaData; BPB: IBPB): IBlob;
333 begin
334 CheckHandle;
335 Result := TFB30Blob.Create(self,transaction as TFB30Transaction, BlobMetaData,BPB);
336 end;
337
338 function TFB30Attachment.CreateBlob(transaction: ITransaction;
339 SubType: integer; aCharSetID: cardinal; BPB: IBPB): IBlob;
340 begin
341 CheckHandle;
342 Result := TFB30Blob.Create(self,transaction as TFB30Transaction, SubType,aCharSetID,BPB);
343 end;
344
345 function TFB30Attachment.OpenBlob(transaction: ITransaction; RelationName,
346 ColumnName: AnsiString; BlobID: TISC_QUAD; BPB: IBPB): IBlob;
347 begin
348 CheckHandle;
349 Result := TFB30Blob.Create(self,transaction as TFB30transaction,
350 TFB30BlobMetaData.Create(self,Transaction as TFB30Transaction,RelationName,ColumnName),
351 BlobID,BPB);
352 end;
353
354 function TFB30Attachment.OpenBlob(transaction: ITransaction;
355 BlobMetaData: IBlobMetaData; BlobID: TISC_QUAD; BPB: IBPB): IBlob;
356 begin
357 CheckHandle;
358 Result := TFB30Blob.Create(self,transaction as TFB30transaction,BlobMetaData,BlobID,BPB);
359 end;
360
361 function TFB30Attachment.OpenArray(transaction: ITransaction; RelationName,
362 ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray;
363 begin
364 CheckHandle;
365 Result := TFB30Array.Create(self,transaction as TFB30Transaction,
366 GetArrayMetaData(transaction,RelationName,ColumnName),ArrayID);
367 end;
368
369 function TFB30Attachment.CreateArray(transaction: ITransaction; RelationName,
370 ColumnName: AnsiString): IArray;
371 begin
372 CheckHandle;
373 Result := TFB30Array.Create(self,transaction as TFB30Transaction,
374 GetArrayMetaData(transaction,RelationName,ColumnName));
375 end;
376
377 function TFB30Attachment.CreateArray(transaction: ITransaction;
378 ArrayMetaData: IArrayMetaData): IArray;
379 begin
380 CheckHandle;
381 Result := TFB30Array.Create(self,transaction as TFB30Transaction,ArrayMetaData);
382 end;
383
384 function TFB30Attachment.CreateArrayMetaData(SQLType: cardinal; tableName: AnsiString; columnName: AnsiString;
385 Scale: integer; size: cardinal; aCharSetID: cardinal; dimensions: cardinal;
386 bounds: TArrayBounds): IArrayMetaData;
387 begin
388 Result := TFB30ArrayMetaData.Create(self,SQLType,tableName,ColumnName,Scale,size,aCharSetID, dimensions,bounds);
389 end;
390
391 function TFB30Attachment.GetBlobMetaData(Transaction: ITransaction; tableName,
392 columnName: AnsiString): IBlobMetaData;
393 begin
394 CheckHandle;
395 Result := TFB30BlobMetaData.Create(self,Transaction as TFB30Transaction,tableName,columnName);
396 end;
397
398 function TFB30Attachment.GetArrayMetaData(Transaction: ITransaction; tableName,
399 columnName: AnsiString): IArrayMetaData;
400 begin
401 CheckHandle;
402 Result := TFB30ArrayMetaData.Create(self,Transaction as TFB30Transaction,tableName,columnName);
403 end;
404
405 procedure TFB30Attachment.getFBVersion(version: TStrings);
406 var bufferObj: TVersionCallback;
407 begin
408 bufferObj := TVersionCallback.Create(version);
409 try
410 with FFirebird30ClientAPI do
411 UtilIntf.getFbVersion(StatusIntf,FAttachmentIntf,bufferObj);
412 finally
413 bufferObj.Free;
414 end;
415 end;
416
417 end.
418