ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/journaling/fbintf/client/FBStatement.pas
(Generate patch)

Comparing ibx/trunk/fbintf/client/FBStatement.pas (file contents):
Revision 45 by tony, Tue Dec 6 10:33:46 2016 UTC vs.
Revision 350 by tony, Wed Oct 20 14:58:56 2021 UTC

# Line 28 | Line 28
28   *
29   *)
30   unit FBStatement;
31 + {$IFDEF MSWINDOWS}
32 + {$DEFINE WINDOWS}
33 + {$ENDIF}
34  
35   {$IFDEF FPC}
36 < {$mode objfpc}{$H+}
36 > {$mode delphi}
37   {$codepage UTF8}
38   {$interfaces COM}
39   {$ENDIF}
# Line 41 | Line 44 | uses
44    Classes, SysUtils,  IB,  FBClientAPI, FBSQLData, FBOutputBlock, FBActivityMonitor,
45    FBTransaction;
46  
47 + const
48 +  DefaultBatchRowLimit = 1000;
49 +
50   type
51 +  TPerfStatistics = array[psCurrentMemory..psFetches] of Int64;
52  
53    { TFBStatement }
54  
55 <  TFBStatement = class(TActivityReporter)
55 >  TFBStatement = class(TActivityReporter,ITransactionUser)
56    private
57      FAttachmentIntf: IAttachment;
58 +    FFirebirdClientAPI: TFBClientAPI;
59    protected
60      FTransactionIntf: ITransaction;
61      FExecTransactionIntf: ITransaction;
62 +    FStaleReferenceChecks: boolean;
63      FSQLStatementType: TIBSQLStatementTypes;         { Select, update, delete, insert, create, alter, etc...}
64      FSQLDialect: integer;
65      FOpen: boolean;
66      FPrepared: boolean;
67      FPrepareSeqNo: integer; {used to check for out of date references from interfaces}
68 <    FSQL: string;
69 <    FProcessedSQL: string;
68 >    FSQL: AnsiString;
69 >    FProcessedSQL: AnsiString;
70      FHasParamNames: boolean;
71      FBOF: boolean;
72      FEOF: boolean;
73      FSingleResults: boolean;
74      FGenerateParamNames: boolean;
75      FChangeSeqNo: integer;
76 +    FCollectStatistics: boolean;
77 +    FStatisticsAvailable: boolean;
78 +    FBeforeStats: TPerfStatistics;
79 +    FAfterStats: TPerfStatistics;
80 +    FCaseSensitiveParams: boolean;
81 +    FBatchRowLimit: integer;
82 +    procedure CheckChangeBatchRowLimit; virtual;
83      procedure CheckHandle; virtual; abstract;
84      procedure CheckTransaction(aTransaction: ITransaction);
85      procedure GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults); overload; virtual; abstract;
86 <    procedure InternalPrepare;  virtual; abstract;
87 <    function InternalExecute(aTransaction: ITransaction): IResults;  virtual; abstract;
88 <    function InternalOpenCursor(aTransaction: ITransaction): IResultSet;   virtual; abstract;
86 >    procedure InternalPrepare(CursorName: AnsiString='');  virtual; abstract;
87 >    function InternalExecute(Transaction: ITransaction): IResults;  virtual; abstract;
88 >    function InternalOpenCursor(aTransaction: ITransaction; Scrollable: boolean): IResultSet;   virtual; abstract;
89 >    procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); virtual; abstract;
90      procedure FreeHandle;  virtual; abstract;
91      procedure InternalClose(Force: boolean); virtual; abstract;
92 +    function TimeStampToMSecs(const TimeStamp: TTimeStamp): Int64;
93    public
94      constructor Create(Attachment: IAttachment; Transaction: ITransaction;
95 <      sql: string; SQLDialect: integer);
95 >      sql: AnsiString; SQLDialect: integer);
96      constructor CreateWithParameterNames(Attachment: IAttachment; Transaction: ITransaction;
97 <      sql: string;  SQLDialect: integer; GenerateParamNames: boolean =false);
97 >      sql: AnsiString;  SQLDialect: integer; GenerateParamNames: boolean =false;
98 >      CaseSensitiveParams: boolean = false);
99      destructor Destroy; override;
100      procedure Close;
101      procedure TransactionEnding(aTransaction: ITransaction; Force: boolean);
102      property SQLDialect: integer read FSQLDialect;
103 +    property FirebirdClientAPI: TFBClientAPI read FFirebirdClientAPI;
104  
105    public
106      function GetSQLParams: ISQLParams; virtual; abstract;
# Line 88 | Line 108 | type
108      function GetRowsAffected(var SelectCount, InsertCount, UpdateCount,
109        DeleteCount: integer): boolean;
110      function GetSQLStatementType: TIBSQLStatementTypes;
111 <    function GetSQLText: string;
111 >    function GetSQLStatementTypeName: AnsiString;
112 >    function GetSQLText: AnsiString;
113 >    function GetProcessedSQLText: AnsiString;
114      function GetSQLDialect: integer;
115  
116      {GetDSQLInfo only supports isc_info_sql_stmt_type, isc_info_sql_get_plan, isc_info_sql_records}
117 <    procedure Prepare(aTransaction: ITransaction=nil); virtual;
117 >    procedure Prepare(aTransaction: ITransaction=nil);  overload;
118 >    procedure Prepare(CursorName: AnsiString; aTransaction: ITransaction=nil); overload; virtual;
119      function Execute(aTransaction: ITransaction=nil): IResults;
120 <    function OpenCursor(aTransaction: ITransaction=nil): IResultSet;
121 <    function CreateBlob(paramName: string): IBlob; overload;
120 >    function OpenCursor(aTransaction: ITransaction=nil): IResultSet; overload;
121 >    function OpenCursor(Scrollable: boolean; aTransaction: ITransaction=nil): IResultSet; overload;
122 >    function CreateBlob(paramName: AnsiString): IBlob; overload;
123      function CreateBlob(index: integer): IBlob; overload;
124      function CreateBlob(column: TColumnMetaData): IBlob; overload; virtual; abstract;
125 <    function CreateArray(paramName: string): IArray; overload;
125 >    function CreateArray(paramName: AnsiString): IArray; overload;
126      function CreateArray(index: integer): IArray;  overload;
127      function CreateArray(column: TColumnMetaData): IArray; overload; virtual; abstract;
128      function GetAttachment: IAttachment;
129      function GetTransaction: ITransaction;
130      function GetDSQLInfo(Request: byte): ISQLInfoResults; overload;
131      procedure SetRetainInterfaces(aValue: boolean); virtual;
132 +    procedure EnableStatistics(aValue: boolean);
133 +    function GetPerfStatistics(var stats: TPerfCounters): boolean;
134 +    function IsInBatchMode: boolean; virtual;
135 +    function HasBatchMode: boolean; virtual;
136 +  public
137 +    {IBatch support}
138 +    procedure AddToBatch; virtual;
139 +    function ExecuteBatch(aTransaction: ITransaction): IBatchCompletion; virtual;
140 +    procedure CancelBatch; virtual;
141 +    function GetBatchCompletion: IBatchCompletion; virtual;
142 +    function GetBatchRowLimit: integer;
143 +    procedure SetBatchRowLimit(aLimit: integer);
144 +    {Stale Reference Check}
145 +    procedure SetStaleReferenceChecks(Enable:boolean); {default true}
146 +    function GetStaleReferenceChecks: boolean;
147 +  public
148      property ChangeSeqNo: integer read FChangeSeqNo;
149      property SQLParams: ISQLParams read GetSQLParams;
150      property SQLStatementType: TIBSQLStatementTypes read GetSQLStatementType;
# Line 116 | Line 156 | uses FBMessages;
156  
157   { TFBStatement }
158  
159 + procedure TFBStatement.CheckChangeBatchRowLimit;
160 + begin
161 +  //Do Nothing
162 + end;
163 +
164   procedure TFBStatement.CheckTransaction(aTransaction: ITransaction);
165   begin
166    if (aTransaction = nil) then
# Line 125 | Line 170 | begin
170      IBError(ibxeNotInTransaction,[]);
171   end;
172  
173 + function TFBStatement.TimeStampToMSecs(const TimeStamp: TTimeStamp): Int64;
174 + begin
175 +  Result := TimeStamp.Time + Int64(timestamp.date)*msecsperday;
176 + end;
177 +
178   constructor TFBStatement.Create(Attachment: IAttachment;
179 <  Transaction: ITransaction; sql: string; SQLDialect: integer);
179 >  Transaction: ITransaction; sql: AnsiString; SQLDialect: integer);
180   begin
181    inherited Create(Transaction as TFBTransaction,2);
182    FAttachmentIntf := Attachment;
183    FTransactionIntf := Transaction;
184 +  FFirebirdClientAPI := Attachment.getFirebirdAPI as TFBClientAPI;
185    FSQLDialect := SQLDialect;
186    FSQL := sql;
187 +  FBatchRowLimit := DefaultBatchRowLimit;
188 +  FStaleReferenceChecks := true;
189   end;
190  
191   constructor TFBStatement.CreateWithParameterNames(Attachment: IAttachment;
192 <  Transaction: ITransaction; sql: string; SQLDialect: integer;
193 <  GenerateParamNames: boolean);
192 >  Transaction: ITransaction; sql: AnsiString; SQLDialect: integer;
193 >  GenerateParamNames: boolean; CaseSensitiveParams: boolean);
194   begin
195    FHasParamNames := true;
196    FGenerateParamNames := GenerateParamNames;
197 +  FCaseSensitiveParams := CaseSensitiveParams;
198    Create(Attachment,Transaction,sql,SQLDialect);
199   end;
200  
# Line 159 | Line 213 | end;
213   procedure TFBStatement.TransactionEnding(aTransaction: ITransaction;
214    Force: boolean);
215   begin
216 <  if FOpen and (FExecTransactionIntf = aTransaction) then
216 >  if FOpen and ((FExecTransactionIntf as TObject) = (aTransaction as TObject)) then
217      InternalClose(Force);
218  
219    if FTransactionIntf = aTransaction then
# Line 207 | Line 261 | begin
261    Result := FSQLStatementType;
262   end;
263  
264 < function TFBStatement.GetSQLText: string;
264 > function TFBStatement.GetSQLStatementTypeName: AnsiString;
265 > begin
266 >  case FSQLStatementType of
267 >  SQLUnknown: Result := 'SQL_Unknown';
268 >  SQLSelect: Result := 'SQL_Select';
269 >  SQLInsert: Result := 'SQL_Insert';
270 >  SQLUpdate: Result := 'SQL_Update';
271 >  SQLDelete: Result := 'SQL_Delete';
272 >  SQLDDL: Result := 'SQL_DDL';
273 >  SQLGetSegment: Result := 'SQL_GetSegment';
274 >  SQLPutSegment: Result := 'SQL_PutSegment';
275 >  SQLExecProcedure: Result := 'SQL_ExecProcedure';
276 >  SQLStartTransaction: Result := 'SQL_StartTransaction';
277 >  SQLCommit: Result := 'SQL_Commit';
278 >  SQLRollback: Result := 'SQL_Rollback';
279 >  SQLSelectForUpdate: Result := 'SQL_SelectForUpdate';
280 >  SQLSetGenerator: Result := 'SQL_SetGenerator';
281 >  SQLSavePoint: Result := 'SQL_SavePoint';
282 >  end;
283 > end;
284 >
285 > function TFBStatement.GetSQLText: AnsiString;
286   begin
287    Result := FSQL;
288   end;
289  
290 + function TFBStatement.GetProcessedSQLText: AnsiString;
291 + begin
292 +  if FProcessedSQL = '' then
293 +    ProcessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
294 +  Result := FProcessedSQL
295 + end;
296 +
297   function TFBStatement.GetSQLDialect: integer;
298   begin
299    Result := FSQLDialect;
# Line 219 | Line 301 | end;
301  
302   procedure TFBStatement.Prepare(aTransaction: ITransaction);
303   begin
304 +  Prepare('',aTransaction);
305 + end;
306 +
307 + procedure TFBStatement.Prepare(CursorName: AnsiString;
308 +  aTransaction: ITransaction);
309 + begin
310    if FPrepared then FreeHandle;
311    if aTransaction <> nil then
312    begin
# Line 226 | Line 314 | begin
314      FTransactionIntf := aTransaction;
315      AddMonitor(FTransactionIntf as TFBTransaction);
316    end;
317 <  InternalPrepare;
317 >  InternalPrepare(CursorName);
318   end;
319  
320   function TFBStatement.Execute(aTransaction: ITransaction): IResults;
# Line 237 | Line 325 | begin
325      Result := InternalExecute(aTransaction);
326   end;
327  
328 + procedure TFBStatement.AddToBatch;
329 + begin
330 +  IBError(ibxeBatchModeNotSupported,[]);
331 + end;
332 +
333 + function TFBStatement.ExecuteBatch(aTransaction: ITransaction
334 +  ): IBatchCompletion;
335 + begin
336 +  IBError(ibxeBatchModeNotSupported,[]);
337 + end;
338 +
339 + procedure TFBStatement.CancelBatch;
340 + begin
341 +  IBError(ibxeBatchModeNotSupported,[]);
342 + end;
343 +
344 + function TFBStatement.GetBatchCompletion: IBatchCompletion;
345 + begin
346 +  IBError(ibxeBatchModeNotSupported,[]);
347 + end;
348 +
349 + function TFBStatement.GetBatchRowLimit: integer;
350 + begin
351 +  Result := FBatchRowLimit;
352 + end;
353 +
354 + procedure TFBStatement.SetBatchRowLimit(aLimit: integer);
355 + begin
356 +  CheckChangeBatchRowLimit;
357 +  FBatchRowLimit := aLimit;
358 + end;
359 +
360 + procedure TFBStatement.SetStaleReferenceChecks(Enable: boolean);
361 + begin
362 +  FStaleReferenceChecks := Enable;
363 + end;
364 +
365 + function TFBStatement.GetStaleReferenceChecks: boolean;
366 + begin
367 +  Result := FStaleReferenceChecks;
368 + end;
369 +
370   function TFBStatement.OpenCursor(aTransaction: ITransaction): IResultSet;
371   begin
372 +  Result := OpenCursor(false,aTransaction);
373 + end;
374 +
375 + function TFBStatement.OpenCursor(Scrollable: boolean; aTransaction: ITransaction
376 +  ): IResultSet;
377 + begin
378    Close;
379    if aTransaction = nil then
380 <    Result := InternalOpenCursor(FTransactionIntf)
380 >    Result := InternalOpenCursor(FTransactionIntf,Scrollable)
381    else
382 <    Result := InternalOpenCursor(aTransaction);
382 >    Result := InternalOpenCursor(aTransaction,Scrollable);
383   end;
384  
385 < function TFBStatement.CreateBlob(paramName: string): IBlob;
385 > function TFBStatement.CreateBlob(paramName: AnsiString): IBlob;
386   var column: TColumnMetaData;
387   begin
388    InternalPrepare;
# Line 262 | Line 398 | begin
398    Result := CreateBlob(SQLParams[index] as TSQLParam);
399   end;
400  
401 < function TFBStatement.CreateArray(paramName: string): IArray;
401 > function TFBStatement.CreateArray(paramName: AnsiString): IArray;
402   var column: TColumnMetaData;
403   begin
404    InternalPrepare;
# Line 290 | Line 426 | end;
426  
427   function TFBStatement.GetDSQLInfo(Request: byte): ISQLInfoResults;
428   begin
429 <  Result := TSQLInfoResultsBuffer.Create;
429 >  Result := TSQLInfoResultsBuffer.Create(FFirebirdClientAPI);
430    GetDsqlInfo(Request,Result);
431   end;
432  
# Line 299 | Line 435 | begin
435    RetainInterfaces := aValue;
436   end;
437  
438 + procedure TFBStatement.EnableStatistics(aValue: boolean);
439 + begin
440 +  if FCollectStatistics <> aValue then
441 +  begin
442 +    FCollectStatistics := aValue;
443 +    FStatisticsAvailable := false;
444 +  end;
445 + end;
446 +
447 + function TFBStatement.GetPerfStatistics(var stats: TPerfCounters): boolean;
448 + begin
449 +  Result := FStatisticsAvailable;
450 +  if Result then
451 +  begin
452 +    stats[psCurrentMemory] := FAfterStats[psCurrentMemory];
453 +    stats[psDeltaMemory] := FAfterStats[psCurrentMemory] - FBeforeStats[psCurrentMemory];
454 +    stats[psMaxMemory] := FAfterStats[psMaxMemory];
455 +    stats[psRealTime] :=  FAfterStats[psRealTime] - FBeforeStats[psRealTime];
456 +    stats[psUserTime] :=  FAfterStats[psUserTime] - FBeforeStats[psUserTime];
457 +    stats[psReads] := FAfterStats[psReads] - FBeforeStats[psReads];
458 +    stats[psWrites] := FAfterStats[psWrites] - FBeforeStats[psWrites];
459 +    stats[psFetches] := FAfterStats[psFetches] - FBeforeStats[psFetches];
460 +    stats[psBuffers] :=  FAfterStats[psBuffers];
461 +  end;
462 + end;
463 +
464 + function TFBStatement.IsInBatchMode: boolean;
465 + begin
466 +  Result := false;
467 + end;
468 +
469 + function TFBStatement.HasBatchMode: boolean;
470 + begin
471 +  Result := false;
472 + end;
473 +
474   end.
475  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines