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

Comparing ibx/trunk/fbintf/client/3.0/FB30Statement.pas (file contents):
Revision 47 by tony, Mon Jan 9 15:31:51 2017 UTC vs.
Revision 338 by tony, Wed Jun 9 12:07:56 2021 UTC

# Line 25 | Line 25
25   *
26   *)
27   unit FB30Statement;
28 + {$IFDEF MSWINDOWS}
29 + {$DEFINE WINDOWS}
30 + {$ENDIF}
31  
32   {$IFDEF FPC}
33 < {$mode objfpc}{$H+}
33 > {$mode delphi}
34   {$codepage UTF8}
35   {$interfaces COM}
36   {$ENDIF}
# Line 84 | Line 87 | type
87    TIBXSQLVAR = class(TSQLVarData)
88    private
89      FStatement: TFB30Statement;
90 +    FFirebird30ClientAPI: TFB30ClientAPI;
91      FBlob: IBlob;             {Cache references}
92      FArray: IArray;
93      FNullIndicator: short;
# Line 94 | Line 98 | type
98      {SQL Var Type Data}
99      FSQLType: cardinal;
100      FSQLSubType: integer;
101 <    FSQLData: PChar; {Address of SQL Data in Message Buffer}
101 >    FSQLData: PByte; {Address of SQL Data in Message Buffer}
102      FSQLNullIndicator: PShort; {Address of null indicator}
103      FDataLength: integer;
104 +    FMetadataSize: integer;
105      FNullable: boolean;
106      FScale: integer;
107      FCharSetID: cardinal;
108 <    FRelationName: string;
109 <    FFieldName: string;
108 >    FRelationName: AnsiString;
109 >    FFieldName: AnsiString;
110  
111      protected
112       function GetSQLType: cardinal; override;
113       function GetSubtype: integer; override;
114 <     function GetAliasName: string;  override;
115 <     function GetFieldName: string; override;
116 <     function GetOwnerName: string;  override;
117 <     function GetRelationName: string;  override;
114 >     function GetAliasName: AnsiString;  override;
115 >     function GetFieldName: AnsiString; override;
116 >     function GetOwnerName: AnsiString;  override;
117 >     function GetRelationName: AnsiString;  override;
118       function GetScale: integer; override;
119       function GetCharSetID: cardinal; override;
120       function GetCodePage: TSystemCodePage; override;
121 +     function GetCharSetWidth: integer; override;
122       function GetIsNull: Boolean;   override;
123       function GetIsNullable: boolean; override;
124 <     function GetSQLData: PChar;  override;
124 >     function GetSQLData: PByte;  override;
125       function GetDataLength: cardinal; override;
126 +     function GetSize: cardinal; override;
127       procedure SetIsNull(Value: Boolean); override;
128       procedure SetIsNullable(Value: Boolean);  override;
129 <     procedure SetSQLData(AValue: PChar; len: cardinal); override;
129 >     procedure SetSQLData(AValue: PByte; len: cardinal); override;
130       procedure SetScale(aValue: integer); override;
131       procedure SetDataLength(len: cardinal); override;
132       procedure SetSQLType(aValue: cardinal); override;
# Line 145 | Line 152 | type
152      FSize: Integer;  {Number of TIBXSQLVARs in column list}
153      FMetaData: Firebird.IMessageMetadata;
154      FTransactionSeqNo: integer;
155 <  protected
155 > protected
156      FStatement: TFB30Statement;
157 +    FFirebird30ClientAPI: TFB30ClientAPI;
158      function GetTransactionSeqNo: integer; override;
159      procedure FreeXSQLDA; virtual;
160      function GetStatement: IStatement; override;
# Line 170 | Line 178 | type
178  
179    TIBXINPUTSQLDA = class(TIBXSQLDA)
180    private
181 <    FMessageBuffer: PChar; {Message Buffer}
181 >    FMessageBuffer: PByte; {Message Buffer}
182      FMsgLength: integer; {Message Buffer length}
183      FCurMetaData: Firebird.IMessageMetadata;
184      procedure FreeMessageBuffer;
185 <    function GetMessageBuffer: PChar;
185 >    function GetMessageBuffer: PByte;
186      function GetMetaData: Firebird.IMessageMetadata;
187      function GetModified: Boolean;
188      function GetMsgLength: integer;
189 +    procedure BuildMetadata;
190      procedure PackBuffer;
191    protected
192      procedure FreeXSQLDA; override;
# Line 188 | Line 197 | type
197      procedure Changed; override;
198      function IsInputDataArea: boolean; override;
199      property MetaData: Firebird.IMessageMetadata read GetMetaData;
200 <    property MessageBuffer: PChar read GetMessageBuffer;
200 >    property MessageBuffer: PByte read GetMessageBuffer;
201      property MsgLength: integer read GetMsgLength;
202    end;
203  
# Line 197 | Line 206 | type
206    TIBXOUTPUTSQLDA = class(TIBXSQLDA)
207    private
208      FTransaction: TFB30Transaction; {transaction used to execute the statement}
209 <    FMessageBuffer: PChar; {Message Buffer}
209 >    FMessageBuffer: PByte; {Message Buffer}
210      FMsgLength: integer; {Message Buffer length}
211    protected
212      procedure FreeXSQLDA; override;
213    public
214      procedure Bind(aMetaData: Firebird.IMessageMetadata);
215      procedure GetData(index: integer; var aIsNull: boolean; var len: short;
216 <      var data: PChar); override;
216 >      var data: PByte); override;
217      function IsInputDataArea: boolean; override;
218 <    property MessageBuffer: PChar read FMessageBuffer;
218 >    property MessageBuffer: PByte read FMessageBuffer;
219      property MsgLength: integer read FMsgLength;
220    end;
221  
# Line 221 | Line 230 | type
230      destructor Destroy; override;
231      {IResultSet}
232      function FetchNext: boolean;
233 <    function GetCursorName: string;
233 >    function GetCursorName: AnsiString;
234      function GetTransaction: ITransaction; override;
235      function IsEof: boolean;
236      procedure Close;
# Line 232 | Line 241 | type
241    TFB30Statement = class(TFBStatement,IStatement)
242    private
243      FStatementIntf: Firebird.IStatement;
244 +    FFirebird30ClientAPI: TFB30ClientAPI;
245      FSQLParams: TIBXINPUTSQLDA;
246      FSQLRecord: TIBXOUTPUTSQLDA;
247      FResultSet: Firebird.IResultSet;
# Line 242 | Line 252 | type
252      procedure InternalPrepare; override;
253      function InternalExecute(aTransaction: ITransaction): IResults; override;
254      function InternalOpenCursor(aTransaction: ITransaction): IResultSet; override;
255 +    procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); override;
256      procedure FreeHandle; override;
257      procedure InternalClose(Force: boolean); override;
258    public
259      constructor Create(Attachment: TFB30Attachment; Transaction: ITransaction;
260 <      sql: string; aSQLDialect: integer);
260 >      sql: AnsiString; aSQLDialect: integer);
261      constructor CreateWithParameterNames(Attachment: TFB30Attachment; Transaction: ITransaction;
262 <      sql: string;  aSQLDialect: integer; GenerateParamNames: boolean =false);
262 >      sql: AnsiString;  aSQLDialect: integer; GenerateParamNames: boolean =false;
263 >      CaseSensitiveParams: boolean=false);
264      destructor Destroy; override;
265      function FetchNext: boolean;
266      property StatementIntf: Firebird.IStatement read FStatementIntf;
# Line 257 | Line 269 | type
269      {IStatement}
270      function GetSQLParams: ISQLParams; override;
271      function GetMetaData: IMetaData; override;
272 <    function GetPlan: String;
272 >    function GetPlan: AnsiString;
273      function IsPrepared: boolean;
274      function CreateBlob(column: TColumnMetaData): IBlob; override;
275      function CreateArray(column: TColumnMetaData): IArray; override;
# Line 267 | Line 279 | end;
279  
280   implementation
281  
282 < uses IBUtils, FBMessages, FBBLob, FB30Blob, variants,  FBArray, FB30Array;
282 > uses IBUtils, FBMessages, FBBlob, FB30Blob, variants,  FBArray, FB30Array;
283  
284   const
285    ISQL_COUNTERS = 'CurrentMemory, MaxMemory, RealTime, UserTime, Buffers, Reads, Writes, Fetches';
# Line 290 | Line 302 | begin
302    Result := FSQLSubType;
303   end;
304  
305 < function TIBXSQLVAR.GetAliasName: string;
305 > function TIBXSQLVAR.GetAliasName: AnsiString;
306   begin
307 <  with Firebird30ClientAPI do
307 >  with FFirebird30ClientAPI do
308    begin
309      result := strpas(TIBXSQLDA(Parent).MetaData.getAlias(StatusIntf,Index));
310      Check4DataBaseError;
311    end;
312   end;
313  
314 < function TIBXSQLVAR.GetFieldName: string;
314 > function TIBXSQLVAR.GetFieldName: AnsiString;
315   begin
316    Result := FFieldName;
317   end;
318  
319 < function TIBXSQLVAR.GetOwnerName: string;
319 > function TIBXSQLVAR.GetOwnerName: AnsiString;
320   begin
321 <  with Firebird30ClientAPI do
321 >  with FFirebird30ClientAPI do
322    begin
323      result := strpas(TIBXSQLDA(Parent).MetaData.getOwner(StatusIntf,Index));
324      Check4DataBaseError;
325    end;
326   end;
327  
328 < function TIBXSQLVAR.GetRelationName: string;
328 > function TIBXSQLVAR.GetRelationName: AnsiString;
329   begin
330    Result := FRelationName;
331   end;
# Line 340 | Line 352 | begin
352      else
353        result := FCharSetID;
354    end;
355 +  result := result;
356   end;
357  
358   function TIBXSQLVAR.GetCodePage: TSystemCodePage;
359   begin
360    result := CP_NONE;
361 <  with Firebird30ClientAPI do
361 >  with Statement.GetAttachment do
362       CharSetID2CodePage(GetCharSetID,result);
363   end;
364  
365 + function TIBXSQLVAR.GetCharSetWidth: integer;
366 + begin
367 +  result := 1;
368 +  with Statement.GetAttachment DO
369 +    CharSetWidth(GetCharSetID,result);
370 + end;
371 +
372   function TIBXSQLVAR.GetIsNull: Boolean;
373   begin
374    Result := IsNullable and (FSQLNullIndicator^ = -1);
# Line 359 | Line 379 | begin
379    Result := FSQLNullIndicator <> nil;
380   end;
381  
382 < function TIBXSQLVAR.GetSQLData: PChar;
382 > function TIBXSQLVAR.GetSQLData: PByte;
383   begin
384    Result := FSQLData;
385   end;
# Line 369 | Line 389 | begin
389    Result := FDataLength;
390   end;
391  
392 + function TIBXSQLVAR.GetSize: cardinal;
393 + begin
394 +  Result := FMetadataSize;
395 + end;
396 +
397   function TIBXSQLVAR.GetArrayMetaData: IArrayMetaData;
398   begin
399    if GetSQLType <> SQL_ARRAY then
# Line 418 | Line 443 | begin
443    end
444    else
445      FSQLNullIndicator := nil;
446 +  Changed;
447   end;
448  
449 < procedure TIBXSQLVAR.SetSQLData(AValue: PChar; len: cardinal);
449 > procedure TIBXSQLVAR.SetSQLData(AValue: PByte; len: cardinal);
450   begin
451    if FOwnsSQLData then
452      FreeMem(FSQLData);
453    FSQLData := AValue;
454    FDataLength := len;
455    FOwnsSQLData := false;
456 +  Changed;
457   end;
458  
459   procedure TIBXSQLVAR.SetScale(aValue: integer);
460   begin
461    FScale := aValue;
462 +  Changed;
463   end;
464  
465   procedure TIBXSQLVAR.SetDataLength(len: cardinal);
# Line 439 | Line 467 | begin
467    if not FOwnsSQLData then
468      FSQLData := nil;
469    FDataLength := len;
470 <  with Firebird30ClientAPI do
470 >  with FFirebird30ClientAPI do
471      IBAlloc(FSQLData, 0, FDataLength);
472    FOwnsSQLData := true;
473 +  Changed;
474   end;
475  
476   procedure TIBXSQLVAR.SetSQLType(aValue: cardinal);
477   begin
478    FSQLType := aValue;
479 +  Changed;
480   end;
481  
482   procedure TIBXSQLVAR.SetCharSetID(aValue: cardinal);
483   begin
484    FCharSetID := aValue;
485 +  Changed;
486   end;
487  
488   constructor TIBXSQLVAR.Create(aParent: TIBXSQLDA; aIndex: integer);
489   begin
490    inherited Create(aParent,aIndex);
491    FStatement := aParent.Statement;
492 +  FFirebird30ClientAPI := aParent.FFirebird30ClientAPI;
493   end;
494  
495   procedure TIBXSQLVAR.RowChange;
# Line 543 | Line 575 | begin
575        FResults.Column[i].RowChange;
576   end;
577  
578 < function TResultSet.GetCursorName: string;
578 > function TResultSet.GetCursorName: AnsiString;
579   begin
580    IBError(ibxeNotSupported,[nil]);
581    Result := '';
# Line 595 | Line 627 | begin
627    FMsgLength := 0;
628   end;
629  
630 < function TIBXINPUTSQLDA.GetMessageBuffer: PChar;
630 > function TIBXINPUTSQLDA.GetMessageBuffer: PByte;
631   begin
632    PackBuffer;
633    Result := FMessageBuffer;
# Line 603 | Line 635 | end;
635  
636   function TIBXINPUTSQLDA.GetMetaData: Firebird.IMessageMetadata;
637   begin
638 <  PackBuffer;
638 >  BuildMetadata;
639    Result := FCurMetaData;
640   end;
641  
# Line 613 | Line 645 | begin
645    Result := FMsgLength;
646   end;
647  
648 < procedure TIBXINPUTSQLDA.PackBuffer;
648 > procedure TIBXINPUTSQLDA.BuildMetadata;
649   var Builder: Firebird.IMetadataBuilder;
650      i: integer;
651   begin
652 <  if FMsgLength > 0 then Exit;
653 <
622 <  with Firebird30ClientAPI do
652 >  if FCurMetaData = nil then
653 >  with FFirebird30ClientAPI do
654    begin
655      Builder := inherited MetaData.getBuilder(StatusIntf);
656      Check4DataBaseError;
# Line 643 | Line 674 | begin
674      finally
675        Builder.release;
676      end;
677 +  end;
678 + end;
679  
680 + procedure TIBXINPUTSQLDA.PackBuffer;
681 + var i: integer;
682 + begin
683 +  BuildMetadata;
684 +
685 +  if FMsgLength = 0 then
686 +  with FFirebird30ClientAPI do
687 +  begin
688      FMsgLength := FCurMetaData.getMessageLength(StatusIntf);
689      Check4DataBaseError;
690  
# Line 652 | Line 693 | begin
693      for i := 0 to Count - 1 do
694      with TIBXSQLVar(Column[i]) do
695      begin
696 +      if not Modified then
697 +        IBError(ibxeUninitializedInputParameter,[i,Name]);
698 +
699        if IsNull then
700          FillChar((FMessageBuffer + FCurMetaData.getOffset(StatusIntf,i))^,FDataLength,0)
701        else
702 +      if FSQLData <> nil then
703          Move(FSQLData^,(FMessageBuffer + FCurMetaData.getOffset(StatusIntf,i))^,FDataLength);
704        Check4DataBaseError;
705        if IsNullable then
# Line 688 | Line 733 | procedure TIBXINPUTSQLDA.Bind(aMetaData:
733   var i: integer;
734   begin
735    FMetaData := aMetaData;
736 <  with Firebird30ClientAPI do
736 >  with FFirebird30ClientAPI do
737    begin
738 <    Count := metadata.getCount(StatusIntf);
738 >    Count := aMetadata.getCount(StatusIntf);
739      Check4DataBaseError;
740      Initialize;
741  
# Line 707 | Line 752 | begin
752        else
753          FSQLSubType := 0;
754        FDataLength := aMetaData.getLength(StatusIntf,i);
755 +      FMetadataSize := FDataLength;
756        Check4DataBaseError;
757        case SQLType of
758          SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP,
759          SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT, SQL_BOOLEAN,
760 <        SQL_LONG, SQL_INT64, SQL_DOUBLE, SQL_FLOAT, SQL_D_FLOAT:
760 >        SQL_LONG, SQL_INT64, SQL_INT128, SQL_DOUBLE, SQL_FLOAT, SQL_D_FLOAT,
761 >        SQL_TIMESTAMP_TZ, SQL_TIME_TZ, SQL_DEC_FIXED, SQL_DEC16, SQL_DEC34,
762 >        SQL_TIMESTAMP_TZ_EX, SQL_TIME_TZ_EX:
763          begin
764            if (FDataLength = 0) then
765              { Make sure you get a valid pointer anyway
# Line 735 | Line 783 | begin
783          FSQLNullIndicator := nil;
784        FScale := aMetaData.getScale(StatusIntf,i);
785        Check4DataBaseError;
786 <      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i);
786 >      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i) and $FF;
787        Check4DataBaseError;
788      end;
789    end;
# Line 766 | Line 814 | procedure TIBXOUTPUTSQLDA.Bind(aMetaData
814   var i: integer;
815   begin
816    FMetaData := aMetaData;
817 <  with Firebird30ClientAPI do
817 >  with FFirebird30ClientAPI do
818    begin
819      Count := metadata.getCount(StatusIntf);
820      Check4DataBaseError;
# Line 794 | Line 842 | begin
842        Check4DataBaseError;
843        FDataLength := aMetaData.getLength(StatusIntf,i);
844        Check4DataBaseError;
845 +      FMetadataSize := FDataLength;
846        FRelationName := strpas(aMetaData.getRelation(StatusIntf,i));
847        Check4DataBaseError;
848        FFieldName := strpas(aMetaData.getField(StatusIntf,i));
# Line 809 | Line 858 | begin
858          FSQLNullIndicator := nil;
859        FScale := aMetaData.getScale(StatusIntf,i);
860        Check4DataBaseError;
861 <      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i);
861 >      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i) and $FF;
862        Check4DataBaseError;
863      end;
864    end;
# Line 817 | Line 866 | begin
866   end;
867  
868   procedure TIBXOUTPUTSQLDA.GetData(index: integer; var aIsNull: boolean;
869 <  var len: short; var data: PChar);
869 >  var len: short; var data: PByte);
870   begin
871    with TIBXSQLVAR(Column[index]) do
872    begin
# Line 826 | Line 875 | begin
875      len := FDataLength;
876      if not IsNull and (FSQLType = SQL_VARYING) then
877      begin
878 <      with Firebird30ClientAPI do
878 >      with FFirebird30ClientAPI do
879          len := DecodeInteger(data,2);
880        Inc(Data,2);
881      end;
# Line 843 | Line 892 | constructor TIBXSQLDA.Create(aStatement:
892   begin
893    inherited Create;
894    FStatement := aStatement;
895 +  FFirebird30ClientAPI := aStatement.FFirebird30ClientAPI;
896    FSize := 0;
897   //  writeln('Creating ',ClassName);
898   end;
# Line 959 | Line 1009 | end;
1009   procedure TFB30Statement.GetDSQLInfo(info_request: byte; buffer: ISQLInfoResults
1010    );
1011   begin
1012 <  with Firebird30ClientAPI, buffer as TSQLInfoResultsBuffer do
1012 >  with FFirebird30ClientAPI, buffer as TSQLInfoResultsBuffer do
1013    begin
1014      StatementIntf.getInfo(StatusIntf,1,BytePtr(@info_request),
1015                       GetBufSize, BytePtr(Buffer));
# Line 975 | Line 1025 | begin
1025      IBError(ibxeEmptyQuery, [nil]);
1026    try
1027      CheckTransaction(FTransactionIntf);
1028 <    with Firebird30ClientAPI do
1028 >    with FFirebird30ClientAPI do
1029      begin
1030        if FHasParamNames then
1031        begin
1032          if FProcessedSQL = '' then
1033 <          FSQLParams.PreprocessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
1033 >          ProcessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
1034          FStatementIntf := (GetAttachment as TFB30Attachment).AttachmentIntf.prepare(StatusIntf,
1035                              (FTransactionIntf as TFB30Transaction).TransactionIntf,
1036                              Length(FProcessedSQL),
1037 <                            PChar(FProcessedSQL),
1037 >                            PAnsiChar(FProcessedSQL),
1038                              FSQLDialect,
1039                              Firebird.IStatement.PREPARE_PREFETCH_METADATA);
1040        end
# Line 992 | Line 1042 | begin
1042        FStatementIntf := (GetAttachment as TFB30Attachment).AttachmentIntf.prepare(StatusIntf,
1043                            (FTransactionIntf as TFB30Transaction).TransactionIntf,
1044                            Length(FSQL),
1045 <                          PChar(FSQL),
1045 >                          PAnsiChar(FSQL),
1046                            FSQLDialect,
1047                            Firebird.IStatement.PREPARE_PREFETCH_METADATA);
1048        Check4DataBaseError;
# Line 1031 | Line 1081 | begin
1081        if (FStatementIntf <> nil) then
1082          FreeHandle;
1083        if E is EIBInterBaseError then
1084 <        raise EIBInterBaseError.Create(EIBInterBaseError(E).SQLCode,
1085 <                                       EIBInterBaseError(E).IBErrorCode,
1036 <                                       EIBInterBaseError(E).Message +
1037 <                                       sSQLErrorSeparator + FSQL)
1038 <      else
1039 <        raise;
1084 >        E.Message := E.Message + sSQLErrorSeparator + FSQL;
1085 >      raise;
1086      end;
1087    end;
1088    FPrepared := true;
# Line 1072 | Line 1118 | begin
1118      IBError(ibxeInterfaceOutofDate,[nil]);
1119  
1120    try
1121 <    with Firebird30ClientAPI do
1121 >    with FFirebird30ClientAPI do
1122      begin
1123        if FCollectStatistics then
1124        begin
# Line 1122 | Line 1168 | begin
1168         RemoveMonitor(aTransaction as TFB30Transaction);
1169    end;
1170    FExecTransactionIntf := aTransaction;
1171 +  FSQLRecord.FTransaction := (aTransaction as TFB30Transaction);
1172 +  FSQLRecord.FTransactionSeqNo := FSQLRecord.FTransaction.TransactionSeqNo;
1173    SignalActivity;
1174    Inc(FChangeSeqNo);
1175   end;
# Line 1141 | Line 1189 | begin
1189    if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB30transaction).TransactionSeqNo) then
1190      IBError(ibxeInterfaceOutofDate,[nil]);
1191  
1192 < with Firebird30ClientAPI do
1192 > with FFirebird30ClientAPI do
1193   begin
1194     if FCollectStatistics then
1195     begin
# Line 1181 | Line 1229 | begin
1229   Inc(FChangeSeqNo);
1230   end;
1231  
1232 + procedure TFB30Statement.ProcessSQL(sql: AnsiString; GenerateParamNames: boolean;
1233 +  var processedSQL: AnsiString);
1234 + begin
1235 +  FSQLParams.PreprocessSQL(sql,GenerateParamNames,processedSQL);
1236 + end;
1237 +
1238   procedure TFB30Statement.FreeHandle;
1239   begin
1240    Close;
# Line 1197 | Line 1251 | procedure TFB30Statement.InternalClose(F
1251   begin
1252    if (FStatementIntf <> nil) and (SQLStatementType = SQLSelect) and FOpen then
1253    try
1254 <    with Firebird30ClientAPI do
1254 >    with FFirebird30ClientAPI do
1255      begin
1256        if FResultSet <> nil then
1257        begin
# Line 1211 | Line 1265 | begin
1265        if not Force then Check4DataBaseError;
1266      end;
1267    finally
1268 <    if (FSQLRecord.FTransaction <> nil) and (FSQLRecord.FTransaction <> FTransactionIntf) then
1268 >    if (FSQLRecord.FTransaction <> nil) and (FSQLRecord.FTransaction <> (FTransactionIntf as TFB30Transaction)) then
1269        RemoveMonitor(FSQLRecord.FTransaction);
1270      FOpen := False;
1271      FExecTransactionIntf := nil;
# Line 1222 | Line 1276 | begin
1276   end;
1277  
1278   constructor TFB30Statement.Create(Attachment: TFB30Attachment;
1279 <  Transaction: ITransaction; sql: string; aSQLDialect: integer);
1279 >  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer);
1280   begin
1281    inherited Create(Attachment,Transaction,sql,aSQLDialect);
1282 +  FFirebird30ClientAPI := Attachment.Firebird30ClientAPI;
1283    FSQLParams := TIBXINPUTSQLDA.Create(self);
1284    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1285    InternalPrepare;
1286   end;
1287  
1288   constructor TFB30Statement.CreateWithParameterNames(
1289 <  Attachment: TFB30Attachment; Transaction: ITransaction; sql: string;
1290 <  aSQLDialect: integer; GenerateParamNames: boolean);
1289 >  Attachment: TFB30Attachment; Transaction: ITransaction; sql: AnsiString;
1290 >  aSQLDialect: integer; GenerateParamNames: boolean;
1291 >  CaseSensitiveParams: boolean);
1292   begin
1293    inherited CreateWithParameterNames(Attachment,Transaction,sql,aSQLDialect,GenerateParamNames);
1294 +  FFirebird30ClientAPI := Attachment.Firebird30ClientAPI;
1295    FSQLParams := TIBXINPUTSQLDA.Create(self);
1296 +  FSQLParams.CaseSensitiveParams := CaseSensitiveParams;
1297    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1298    InternalPrepare;
1299   end;
# Line 1256 | Line 1314 | begin
1314    if FEOF then
1315      IBError(ibxeEOF,[nil]);
1316  
1317 <  with Firebird30ClientAPI do
1317 >  with FFirebird30ClientAPI do
1318    begin
1319      { Go to the next record... }
1320      fetchResult := FResultSet.fetchNext(StatusIntf,FSQLRecord.MessageBuffer);
# Line 1281 | Line 1339 | begin
1339        FBOF := false;
1340        result := true;
1341      end;
1342 +    if FCollectStatistics then
1343 +    begin
1344 +      UtilIntf.getPerfCounters(StatusIntf,
1345 +                              (GetAttachment as TFB30Attachment).AttachmentIntf,
1346 +                              ISQL_COUNTERS,@FAfterStats);
1347 +      Check4DataBaseError;
1348 +      FStatisticsAvailable := true;
1349 +    end;
1350    end;
1351    FSQLRecord.RowChange;
1352    SignalActivity;
# Line 1304 | Line 1370 | begin
1370    Result := TMetaData(GetInterface(1));
1371   end;
1372  
1373 < function TFB30Statement.GetPlan: String;
1373 > function TFB30Statement.GetPlan: AnsiString;
1374   begin
1375    CheckHandle;
1376    if (not (FSQLStatementType in [SQLSelect, SQLSelectForUpdate,
# Line 1312 | Line 1378 | begin
1378         SQLUpdate, SQLDelete])) then
1379      result := ''
1380    else
1381 <  with Firebird30ClientAPI do
1381 >  with FFirebird30ClientAPI do
1382    begin
1383      Result := FStatementIntf.getPlan(StatusIntf,true);
1384      Check4DataBaseError;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines