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: 267
Committed: Fri Dec 28 10:44:23 2018 UTC (5 years, 3 months ago) by tony
Content type: text/x-pascal
File size: 14109 byte(s)
Log Message:
Fixes Merged

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.
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 tony 56 {$IFDEF MSWINDOWS}
29     {$DEFINE WINDOWS}
30     {$ENDIF}
31 tony 45
32     {$IFDEF FPC}
33 tony 56 {$mode delphi}
34 tony 45 {$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 tony 263 FFirebird30ClientAPI: TFB30ClientAPI;
50 tony 45 protected
51     procedure CheckHandle; override;
52     public
53 tony 263 constructor Create(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB;
54 tony 45 RaiseExceptionOnConnectError: boolean);
55 tony 263 constructor CreateDatabase(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB; RaiseExceptionOnError: boolean); overload;
56     constructor CreateDatabase(api: TFB30ClientAPI; sql: AnsiString; aSQLDialect: integer;
57 tony 47 RaiseExceptionOnError: boolean); overload;
58 tony 45 destructor Destroy; override;
59 tony 143 function GetDBInfo(ReqBuffer: PByte; ReqBufLen: integer): IDBInformation;
60     override;
61 tony 45 property AttachmentIntf: Firebird.IAttachment read FAttachmentIntf;
62 tony 263 property Firebird30ClientAPI: TFB30ClientAPI read FFirebird30ClientAPI;
63 tony 45
64     public
65     {IAttachment}
66     procedure Connect;
67     procedure Disconnect(Force: boolean=false); override;
68 tony 117 function IsConnected: boolean; override;
69 tony 45 procedure DropDatabase;
70     function StartTransaction(TPB: array of byte; DefaultCompletion: TTransactionCompletion): ITransaction; override;
71     function StartTransaction(TPB: ITPB; DefaultCompletion: TTransactionCompletion): ITransaction; override;
72 tony 56 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 tony 45 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 tony 56 function CreateBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BPB: IBPB=nil): IBlob; overload;
83 tony 45 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 tony 56 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 tony 45
88     {Array}
89 tony 56 function OpenArray(transaction: ITransaction; RelationName, ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray;
90     function CreateArray(transaction: ITransaction; RelationName, ColumnName: AnsiString): IArray; overload;
91 tony 45 function CreateArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData): IArray; overload;
92 tony 56 function CreateArrayMetaData(SQLType: cardinal; tableName: AnsiString;
93     columnName: AnsiString; Scale: integer; size: cardinal; aCharSetID: cardinal;
94 tony 263 dimensions: cardinal; bounds: TArrayBounds): IArrayMetaData;
95 tony 45
96 tony 47
97 tony 45 {Database Information}
98 tony 56 function GetBlobMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IBlobMetaData;
99     function GetArrayMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IArrayMetaData;
100 tony 266 procedure getFBVersion(version: TStrings);
101 tony 45 end;
102    
103     implementation
104    
105     uses FB30Transaction, FB30Statement, FB30Array, FB30Blob, FBMessages,
106 tony 117 FBOutputBlock, FB30Events, IBUtils;
107 tony 45
108 tony 266 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 tony 45 { TFB30Attachment }
134    
135     procedure TFB30Attachment.CheckHandle;
136     begin
137     if FAttachmentIntf = nil then
138     IBError(ibxeDatabaseClosed,[nil]);
139     end;
140    
141 tony 263 constructor TFB30Attachment.Create(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB;
142 tony 45 RaiseExceptionOnConnectError: boolean);
143     begin
144 tony 263 FFirebird30ClientAPI := api;
145 tony 45 if aDPB = nil then
146     begin
147     if RaiseExceptionOnConnectError then
148     IBError(ibxeNoDPB,[nil]);
149     Exit;
150     end;
151 tony 263 inherited Create(api,DatabaseName,aDPB,RaiseExceptionOnConnectError);
152 tony 45 Connect;
153     end;
154    
155 tony 263 constructor TFB30Attachment.CreateDatabase(api: TFB30ClientAPI; DatabaseName: AnsiString; aDPB: IDPB;
156 tony 45 RaiseExceptionOnError: boolean);
157     var Param: IDPBItem;
158 tony 56 sql: AnsiString;
159 tony 45 IsCreateDB: boolean;
160     begin
161 tony 263 inherited Create(api,DatabaseName,aDPB,RaiseExceptionOnError);
162     FFirebird30ClientAPI := api;
163 tony 45 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 tony 263 with FFirebird30ClientAPI do
172 tony 45 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 tony 117 end
185     else
186     GetODSAndConnectionInfo;
187 tony 45 end;
188     end;
189    
190 tony 263 constructor TFB30Attachment.CreateDatabase(api: TFB30ClientAPI; sql: AnsiString; aSQLDialect: integer;
191 tony 47 RaiseExceptionOnError: boolean);
192     var IsCreateDB: boolean;
193     begin
194 tony 263 inherited Create(api,'',nil,RaiseExceptionOnError);
195     FFirebird30ClientAPI := api;
196 tony 47 FSQLDialect := aSQLDialect;
197 tony 263 with FFirebird30ClientAPI do
198 tony 47 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 tony 117 GetODSAndConnectionInfo;
206     ExtractConnectString(sql,FDatabaseName);
207     DPBFromCreateSQL(sql);
208 tony 47 end;
209    
210 tony 45 destructor TFB30Attachment.Destroy;
211     begin
212     inherited Destroy;
213     if assigned(FAttachmentIntf) then
214     FAttachmentIntf.release;
215     end;
216    
217 tony 143 function TFB30Attachment.GetDBInfo(ReqBuffer: PByte; ReqBufLen: integer): IDBInformation;
218     begin
219 tony 263 Result := TDBInformation.Create(Firebird30ClientAPI);
220     with FFirebird30ClientAPI, Result as TDBInformation do
221 tony 143 begin
222     FAttachmentIntf.getInfo(StatusIntf, ReqBufLen, BytePtr(ReqBuffer),
223     getBufSize, BytePtr(Buffer));
224     Check4DataBaseError;
225     end
226     end;
227    
228 tony 45 procedure TFB30Attachment.Connect;
229     begin
230 tony 263 with FFirebird30ClientAPI do
231 tony 45 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 tony 117 GetODSAndConnectionInfo;
240 tony 45 end;
241     end;
242    
243     procedure TFB30Attachment.Disconnect(Force: boolean);
244     begin
245     if IsConnected then
246 tony 263 with FFirebird30ClientAPI do
247 tony 45 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 tony 263 with FFirebird30ClientAPI do
268 tony 45 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 tony 263 Result := TFB30Transaction.Create(FFirebird30ClientAPI,self,TPB,DefaultCompletion);
281 tony 45 end;
282    
283     function TFB30Attachment.StartTransaction(TPB: ITPB;
284     DefaultCompletion: TTransactionCompletion): ITransaction;
285     begin
286     CheckHandle;
287 tony 263 Result := TFB30Transaction.Create(FFirebird30ClientAPI,self,TPB,DefaultCompletion);
288 tony 45 end;
289    
290 tony 56 procedure TFB30Attachment.ExecImmediate(transaction: ITransaction; sql: AnsiString;
291 tony 45 aSQLDialect: integer);
292     begin
293     CheckHandle;
294 tony 263 with FFirebird30ClientAPI do
295 tony 45 begin
296     FAttachmentIntf.execute(StatusIntf,(transaction as TFB30Transaction).TransactionIntf,
297 tony 56 Length(sql),PAnsiChar(sql),aSQLDialect,nil,nil,nil,nil);
298 tony 45 Check4DataBaseError;
299     end;
300     end;
301    
302 tony 56 function TFB30Attachment.Prepare(transaction: ITransaction; sql: AnsiString;
303 tony 45 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 tony 56 sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean): IStatement;
311 tony 45 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 tony 56 ColumnName: AnsiString; BPB: IBPB): IBlob;
325 tony 45 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 tony 56 ColumnName: AnsiString; BlobID: TISC_QUAD; BPB: IBPB): IBlob;
347 tony 45 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 tony 56 ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray;
363 tony 45 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 tony 56 ColumnName: AnsiString): IArray;
371 tony 45 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 tony 56 function TFB30Attachment.CreateArrayMetaData(SQLType: cardinal; tableName: AnsiString; columnName: AnsiString;
385 tony 47 Scale: integer; size: cardinal; aCharSetID: cardinal; dimensions: cardinal;
386     bounds: TArrayBounds): IArrayMetaData;
387     begin
388 tony 60 Result := TFB30ArrayMetaData.Create(self,SQLType,tableName,ColumnName,Scale,size,aCharSetID, dimensions,bounds);
389 tony 47 end;
390    
391 tony 45 function TFB30Attachment.GetBlobMetaData(Transaction: ITransaction; tableName,
392 tony 56 columnName: AnsiString): IBlobMetaData;
393 tony 45 begin
394     CheckHandle;
395     Result := TFB30BlobMetaData.Create(self,Transaction as TFB30Transaction,tableName,columnName);
396     end;
397    
398     function TFB30Attachment.GetArrayMetaData(Transaction: ITransaction; tableName,
399 tony 56 columnName: AnsiString): IArrayMetaData;
400 tony 45 begin
401     CheckHandle;
402     Result := TFB30ArrayMetaData.Create(self,Transaction as TFB30Transaction,tableName,columnName);
403     end;
404    
405 tony 266 procedure TFB30Attachment.getFBVersion(version: TStrings);
406     var bufferObj: TVersionCallback;
407     begin
408 tony 267 version.Clear;
409 tony 266 bufferObj := TVersionCallback.Create(version);
410     try
411     with FFirebird30ClientAPI do
412 tony 267 begin
413 tony 266 UtilIntf.getFbVersion(StatusIntf,FAttachmentIntf,bufferObj);
414 tony 267 Check4DataBaseError;
415     end;
416 tony 266 finally
417     bufferObj.Free;
418     end;
419     end;
420    
421 tony 45 end.
422