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

Comparing ibx/trunk/fbintf/client/2.5/FB25Statement.pas (file contents):
Revision 45 by tony, Tue Dec 6 10:33:46 2016 UTC vs.
Revision 309 by tony, Tue Jul 21 08:00:42 2020 UTC

# Line 60 | Line 60
60   {                                                                        }
61   {************************************************************************}
62   unit FB25Statement;
63 + {$IFDEF MSWINDOWS}
64 + {$DEFINE WINDOWS}
65 + {$ENDIF}
66  
67   {$IFDEF FPC}
68 < {$mode objfpc}{$H+}
68 > {$mode delphi}
69   {$codepage UTF8}
70   {$interfaces COM}
71   {$ENDIF}
# Line 118 | Line 121 | type
121    TIBXSQLVAR = class(TSQLVarData)
122    private
123      FStatement: TFB25Statement;
124 +    FFirebird25ClientAPI: TFB25ClientAPI;
125      FBlob: IBlob;             {Cache references}
126      FArray: IArray;
127      FNullIndicator: short;
# Line 128 | Line 132 | type
132    protected
133      function GetSQLType: cardinal; override;
134      function GetSubtype: integer; override;
135 <    function GetAliasName: string;  override;
136 <    function GetFieldName: string; override;
137 <    function GetOwnerName: string;  override;
138 <    function GetRelationName: string;  override;
135 >    function GetAliasName: AnsiString;  override;
136 >    function GetFieldName: AnsiString; override;
137 >    function GetOwnerName: AnsiString;  override;
138 >    function GetRelationName: AnsiString;  override;
139      function GetScale: integer; override;
140      function GetCharSetID: cardinal; override;
141      function GetCodePage: TSystemCodePage; override;
142 +    function GetCharSetWidth: integer; override;
143      function GetIsNull: Boolean;   override;
144      function GetIsNullable: boolean; override;
145 <    function GetSQLData: PChar;  override;
145 >    function GetSQLData: PByte;  override;
146      function GetDataLength: cardinal; override;
147      procedure SetIsNull(Value: Boolean); override;
148      procedure SetIsNullable(Value: Boolean);  override;
149 <    procedure SetSQLData(AValue: PChar; len: cardinal); override;
149 >    procedure SetSQLData(AValue: PByte; len: cardinal); override;
150      procedure SetScale(aValue: integer); override;
151      procedure SetDataLength(len: cardinal); override;
152      procedure SetSQLType(aValue: cardinal); override;
# Line 174 | Line 179 | type
179      function GetXSQLDA: PXSQLDA;
180    protected
181      FStatement: TFB25Statement;
182 +    FFirebird25ClientAPI: TFB25ClientAPI;
183      function GetTransactionSeqNo: integer; override;
184      procedure FreeXSQLDA;
185      function GetStatement: IStatement; override;
# Line 211 | Line 217 | type
217      procedure Bind;
218      function GetTransaction: TFB25Transaction; override;
219      procedure GetData(index: integer; var aIsNull: boolean; var len: short;
220 <      var data: PChar); override;
220 >      var data: PByte); override;
221      function IsInputDataArea: boolean; override;
222    end;
223  
# Line 226 | Line 232 | type
232      destructor Destroy; override;
233      {IResultSet}
234      function FetchNext: boolean;
235 <    function GetCursorName: string;
235 >    function GetCursorName: AnsiString;
236      function GetTransaction: ITransaction; override;
237      function IsEof: boolean;
238      procedure Close;
# Line 238 | Line 244 | type
244    private
245      FDBHandle: TISC_DB_HANDLE;
246      FHandle: TISC_STMT_HANDLE;
247 +    FFirebird25ClientAPI: TFB25ClientAPI;
248      FSQLParams: TIBXINPUTSQLDA;
249      FSQLRecord: TIBXOUTPUTSQLDA;
250 <    FCursor: String;               { Cursor name...}
250 >    FCursor: AnsiString;               { Cursor name...}
251      FCursorSeqNo: integer;
252 +    procedure GetPerfCounters(var counters: TPerfStatistics);
253    protected
254      procedure CheckHandle; override;
255      procedure GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults); override;
256      procedure InternalPrepare; override;
257      function InternalExecute(aTransaction: ITransaction): IResults; override;
258      function InternalOpenCursor(aTransaction: ITransaction): IResultSet; override;
259 +    procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); override;
260      procedure FreeHandle; override;
261      procedure InternalClose(Force: boolean); override;
262    public
263      constructor Create(Attachment: TFB25Attachment; Transaction: ITransaction;
264 <      sql: string; aSQLDialect: integer);
264 >      sql: AnsiString; aSQLDialect: integer);
265      constructor CreateWithParameterNames(Attachment: TFB25Attachment;
266 <      Transaction: ITransaction; sql: string; aSQLDialect: integer; GenerateParamNames: boolean);
266 >      Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean;
267 >      CaseSensitiveParams: boolean=false);
268      destructor Destroy; override;
269      function FetchNext: boolean;
270  
# Line 262 | Line 272 | type
272      {IStatement}
273      function GetSQLParams: ISQLParams; override;
274      function GetMetaData: IMetaData; override;
275 <    function GetPlan: String;
275 >    function GetPlan: AnsiString;
276      function IsPrepared: boolean;
277      function CreateBlob(column: TColumnMetaData): IBlob; override;
278      function CreateArray(column: TColumnMetaData): IArray; override;
# Line 273 | Line 283 | end;
283  
284   implementation
285  
286 < uses IBUtils, FBMessages, FB25Blob, variants, IBErrorCodes, FBArray, FB25Array;
286 > uses IBUtils, FBMessages, FBBlob, FB25Blob, variants, IBErrorCodes, FBArray, FB25Array
287 >  {$IFDEF UNIX}, BaseUnix {$ENDIF};
288  
289  
290   { TIBXSQLVAR }
# Line 291 | Line 302 | begin
302      result := 0;
303   end;
304  
305 < function TIBXSQLVAR.GetAliasName: string;
305 > function TIBXSQLVAR.GetAliasName: AnsiString;
306   begin
307    result := strpas(FXSQLVAR^.aliasname);
308   end;
309  
310 < function TIBXSQLVAR.GetFieldName: string;
310 > function TIBXSQLVAR.GetFieldName: AnsiString;
311   begin
312    result := strpas(FXSQLVAR^.sqlname);
313   end;
314  
315 < function TIBXSQLVAR.GetOwnerName: string;
315 > function TIBXSQLVAR.GetOwnerName: AnsiString;
316   begin
317    result := strpas(FXSQLVAR^.ownname);
318   end;
319  
320 < function TIBXSQLVAR.GetRelationName: string;
320 > function TIBXSQLVAR.GetRelationName: AnsiString;
321   begin
322    result := strpas(FXSQLVAR^.relname);
323   end;
# Line 330 | Line 341 | begin
341    SQL_BLOB:
342      if (SQLSubType = 1)  then
343        {see http://firebirdsql.org/rlsnotesh/rlsnotes210.html}
344 <      result := FXSQLVAR^.sqlscale;
344 >      result := FXSQLVAR^.sqlscale and $FF;
345  
346    SQL_ARRAY:
347      if (GetRelationName <> '') and (GetFieldName <> '') then
# Line 341 | Line 352 | end;
352   function TIBXSQLVAR.GetCodePage: TSystemCodePage;
353   begin
354    result := CP_NONE;
355 <  with FirebirdClientAPI do
355 >  with Statement.GetAttachment do
356       CharSetID2CodePage(GetCharSetID,result);
357   end;
358  
359 + function TIBXSQLVAR.GetCharSetWidth: integer;
360 + begin
361 +  result := 1;
362 +  with Statement.GetAttachment DO
363 +    CharSetWidth(GetCharSetID,result);
364 + end;
365 +
366   function TIBXSQLVAR.GetIsNull: Boolean;
367   begin
368    result := IsNullable and (FNullIndicator = -1);
# Line 355 | Line 373 | begin
373    result := (FXSQLVAR^.sqltype and 1 = 1);
374   end;
375  
376 < function TIBXSQLVAR.GetSQLData: PChar;
376 > function TIBXSQLVAR.GetSQLData: PByte;
377   begin
378    Result := FXSQLVAR^.sqldata;
379   end;
# Line 386 | Line 404 | begin
404      FBlobMetaData := TFB25BlobMetaData.Create(FStatement.GetAttachment as TFB25Attachment,
405                  FStatement.GetTransaction as TFB25Transaction,
406                  GetRelationName,GetFieldName,GetSubType);
407 +  (FBlobMetaData as TFBBlobMetaData).SetCharSetID(GetCharSetID);
408    Result := FBlobMetaData;
409   end;
410  
# Line 435 | Line 454 | procedure TIBXSQLVAR.Initialize;
454   begin
455    inherited Initialize;
456    FOwnsSQLData := true;
457 <  with FirebirdClientAPI, FXSQLVar^ do
457 >  with FFirebird25ClientAPI, FXSQLVar^ do
458    begin
459      case sqltype and (not 1) of
460        SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP,
# Line 468 | Line 487 | procedure TIBXSQLVAR.SetIsNull(Value: Bo
487   begin
488    if Value then
489    begin
490 <    if not IsNullable then
491 <      IsNullable := True;
473 <
474 <      FNullIndicator := -1;
490 >    IsNullable := true;
491 >    FNullIndicator := -1;
492      Changed;
493    end
494    else
# Line 498 | Line 515 | begin
515        FXSQLVAR^.sqlind := nil;
516      end;
517    end;
518 +  Changed;
519   end;
520  
521 < procedure TIBXSQLVAR.SetSQLData(AValue: PChar; len: cardinal);
521 > procedure TIBXSQLVAR.SetSQLData(AValue: PByte; len: cardinal);
522   begin
523    if FOwnsSQLData then
524      FreeMem(FXSQLVAR^.sqldata);
525    FXSQLVAR^.sqldata := AValue;
526    FXSQLVAR^.sqllen := len;
527    FOwnsSQLData := false;
528 +  Changed;
529   end;
530  
531   procedure TIBXSQLVAR.SetScale(aValue: integer);
532   begin
533    FXSQLVAR^.sqlscale := aValue;
534 +  Changed;
535   end;
536  
537   procedure TIBXSQLVAR.SetDataLength(len: cardinal);
# Line 519 | Line 539 | begin
539    if not FOwnsSQLData then
540      FXSQLVAR^.sqldata := nil;
541    FXSQLVAR^.sqllen := len;
542 <  with FirebirdClientAPI do
542 >  with FFirebird25ClientAPI do
543      IBAlloc(FXSQLVAR^.sqldata, 0, FXSQLVAR^.sqllen);
544    FOwnsSQLData := true;
545 +  Changed;
546   end;
547  
548   procedure TIBXSQLVAR.SetSQLType(aValue: cardinal);
549   begin
550    FXSQLVAR^.sqltype := aValue or (FXSQLVAR^.sqltype and 1);
551 +  Changed;
552   end;
553  
554   procedure TIBXSQLVAR.SetCharSetID(aValue: cardinal);
555   begin
556    if aValue <> GetCharSetID then
557 <  case SQLType of
558 <  SQL_VARYING, SQL_TEXT:
559 <      FXSQLVAR^.sqlsubtype := (aValue and $FF) or (FXSQLVAR^.sqlsubtype and not $FF);
560 <
561 <  SQL_BLOB,
562 <  SQL_ARRAY:
563 <    IBError(ibxeInvalidDataConversion,[nil]);
557 >  begin
558 >    case SQLType of
559 >    SQL_VARYING, SQL_TEXT:
560 >        FXSQLVAR^.sqlsubtype := (aValue and $FF) or (FXSQLVAR^.sqlsubtype and not $FF);
561 >
562 >    SQL_BLOB,
563 >    SQL_ARRAY:
564 >      IBError(ibxeInvalidDataConversion,[nil]);
565 >    end;
566 >  Changed;
567    end;
568   end;
569  
# Line 546 | Line 571 | constructor TIBXSQLVAR.Create(aParent: T
571   begin
572    inherited Create(aParent,aIndex);
573    FStatement := aParent.Statement;
574 +  FFirebird25ClientAPI := aParent.FFirebird25ClientAPI;
575   end;
576  
577   procedure TIBXSQLVAR.FreeSQLData;
# Line 589 | Line 615 | begin
615        FResults.Column[i].RowChange;
616   end;
617  
618 < function TResultSet.GetCursorName: string;
618 > function TResultSet.GetCursorName: AnsiString;
619   begin
620    Result := FResults.FStatement.FCursor;
621   end;
# Line 616 | Line 642 | procedure TIBXINPUTSQLDA.Bind;
642   begin
643    if Count = 0 then
644      Count := 1;
645 <  with Firebird25ClientAPI do
645 >  with FFirebird25ClientAPI do
646    begin
647      if (FXSQLDA <> nil) then
648         if isc_dsql_describe_bind(StatusVector, @(FStatement.Handle), FStatement.SQLDialect,
# Line 648 | Line 674 | procedure TIBXOUTPUTSQLDA.Bind;
674   begin
675    { Allocate an initial output descriptor (with one column) }
676    Count := 1;
677 <  with Firebird25ClientAPI do
677 >  with FFirebird25ClientAPI do
678    begin
679      { Using isc_dsql_describe, get the right size for the columns... }
680      if isc_dsql_describe(StatusVector, @(FStatement.Handle), FStatement.SQLDialect, FXSQLDA) > 0 then
# Line 674 | Line 700 | begin
700   end;
701  
702   procedure TIBXOUTPUTSQLDA.GetData(index: integer; var aIsNull:boolean; var len: short;
703 <  var data: PChar);
703 >  var data: PByte);
704   begin
705    with TIBXSQLVAR(Column[index]), FXSQLVAR^ do
706    begin
# Line 683 | Line 709 | begin
709      len := sqllen;
710      if not IsNull and ((sqltype and (not 1)) = SQL_VARYING) then
711      begin
712 <      with FirebirdClientAPI do
712 >      with FFirebird25ClientAPI do
713          len := DecodeInteger(data,2);
714        Inc(data,2);
715      end;
# Line 700 | Line 726 | constructor TIBXSQLDA.Create(aStatement:
726   begin
727    inherited Create;
728    FStatement := aStatement;
729 +  FFirebird25ClientAPI := aStatement.FFirebird25ClientAPI;
730    FSize := 0;
731   //  writeln('Creating ',ClassName);
732   end;
# Line 786 | Line 813 | begin
813        OldSize := 0;
814      if Count > FSize then
815      begin
816 <      Firebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
816 >      FFirebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
817        SetLength(FColumnList, FCount);
818        FXSQLDA^.version := SQLDA_VERSION1;
819        p := @FXSQLDA^.sqlvar[0];
# Line 795 | Line 822 | begin
822          if i >= FSize then
823            FColumnList[i] := TIBXSQLVAR.Create(self,i);
824          TIBXSQLVAR(Column[i]).FXSQLVAR := p;
825 <        p := Pointer(PChar(p) + sizeof(FXSQLDA^.sqlvar));
825 >        p := Pointer(PAnsiChar(p) + sizeof(FXSQLDA^.sqlvar));
826        end;
827        FSize := inherited Count;
828      end;
# Line 836 | Line 863 | end;
863  
864   { TFB25Statement }
865  
866 + procedure TFB25Statement.GetPerfCounters(var counters: TPerfStatistics);
867 + var DBInfo: IDBInformation;
868 +    i: integer;
869 + {$IFDEF UNIX}
870 +  times: tms;
871 + {$ENDIF}
872 + begin
873 +  {$IFDEF UNIX}
874 +  FpTimes(times);
875 +  counters[psUserTime] := times.tms_utime;
876 +  {$ELSE}
877 +  counters[psUserTime] := 0;
878 +  {$ENDIF}
879 +  counters[psRealTime] := TimeStampToMSecs(DateTimeToTimeStamp(Now));
880 +
881 +  DBInfo := GetAttachment.GetDBInformation([isc_info_reads,isc_info_writes,
882 +         isc_info_fetches, isc_info_num_buffers, isc_info_current_memory,
883 +         isc_info_max_memory]);
884 +  if DBInfo <> nil then
885 +  begin
886 +    for i := 0 to DBInfo.Count - 1 do
887 +    with DBInfo[i] do
888 +    case getItemType of
889 +    isc_info_reads:
890 +      counters[psReads] := AsInteger;
891 +    isc_info_writes:
892 +      counters[psWrites] := AsInteger;
893 +    isc_info_fetches:
894 +      counters[psFetches] := AsInteger;
895 +    isc_info_num_buffers:
896 +      counters[psBuffers] := AsInteger;
897 +    isc_info_current_memory:
898 +      counters[psCurrentMemory] := AsInteger;
899 +    isc_info_max_memory:
900 +      counters[psMaxMemory] := AsInteger;
901 +    end;
902 +  end;
903 + end;
904 +
905   procedure TFB25Statement.CheckHandle;
906   begin
907    if FHandle = nil then
# Line 845 | Line 911 | end;
911   procedure TFB25Statement.GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults
912    );
913   begin
914 <  with Firebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
914 >  with FFirebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
915    if isc_dsql_sql_info(StatusVector, @(FHandle), 1, @info_request,
916                       GetBufSize, Buffer) > 0 then
917      IBDatabaseError;
# Line 862 | Line 928 | begin
928      IBError(ibxeEmptyQuery, [nil]);
929    try
930      CheckTransaction(FTransactionIntf);
931 <    with Firebird25ClientAPI do
931 >    with FFirebird25ClientAPI do
932      begin
933        Call(isc_dsql_alloc_statement2(StatusVector, @(FDBHandle),
934                                        @FHandle), True);
# Line 870 | Line 936 | begin
936        if FHasParamNames then
937        begin
938          if FProcessedSQL = '' then
939 <          FSQLParams.PreprocessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
939 >          ProcessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
940          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
941 <                 PChar(FProcessedSQL), FSQLDialect, nil), True);
941 >                 PAnsiChar(FProcessedSQL), FSQLDialect, nil), True);
942        end
943        else
944          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
945 <                 PChar(FSQL), FSQLDialect, nil), True);
945 >                 PAnsiChar(FSQL), FSQLDialect, nil), True);
946      end;
947      { After preparing the statement, query the stmt type and possibly
948        create a FSQLRecord "holder" }
# Line 887 | Line 953 | begin
953      else
954        FSQLStatementType := SQLUnknown;
955  
890    { Done getting the type }
956      case FSQLStatementType of
957        SQLGetSegment,
958        SQLPutSegment,
# Line 957 | Line 1022 | begin
1022  
1023    try
1024      TRHandle := (aTransaction as TFB25Transaction).Handle;
1025 <    with Firebird25ClientAPI do
961 <    case FSQLStatementType of
962 <    SQLSelect:
963 <      IBError(ibxeIsAExecuteProcedure,[]);
964 <
965 <    SQLExecProcedure:
1025 >    with FFirebird25ClientAPI do
1026      begin
1027 <      Call(isc_dsql_execute2(StatusVector,
1028 <                          @(TRHandle),
969 <                          @FHandle,
970 <                          SQLDialect,
971 <                          FSQLParams.AsXSQLDA,
972 <                          FSQLRecord.AsXSQLDA), True);
973 <      Result := TResults.Create(FSQLRecord);
974 <      FSingleResults := true;
975 <    end
976 <    else
977 <      Call(isc_dsql_execute(StatusVector,
978 <                           @(TRHandle),
979 <                           @FHandle,
980 <                           SQLDialect,
981 <                           FSQLParams.AsXSQLDA), True);
1027 >      if FCollectStatistics then
1028 >        GetPerfCounters(FBeforeStats);
1029  
1030 +      case FSQLStatementType of
1031 +      SQLSelect:
1032 +        IBError(ibxeIsAExecuteProcedure,[]);
1033 +
1034 +      SQLExecProcedure:
1035 +      begin
1036 +        Call(isc_dsql_execute2(StatusVector,
1037 +                            @(TRHandle),
1038 +                            @FHandle,
1039 +                            SQLDialect,
1040 +                            FSQLParams.AsXSQLDA,
1041 +                            FSQLRecord.AsXSQLDA), True);
1042 +        Result := TResults.Create(FSQLRecord);
1043 +        FSingleResults := true;
1044 +      end
1045 +      else
1046 +        Call(isc_dsql_execute(StatusVector,
1047 +                             @(TRHandle),
1048 +                             @FHandle,
1049 +                             SQLDialect,
1050 +                             FSQLParams.AsXSQLDA), True);
1051 +
1052 +      end;
1053 +      if FCollectStatistics then
1054 +      begin
1055 +        GetPerfCounters(FAfterStats);
1056 +        FStatisticsAvailable := true;
1057 +      end;
1058      end;
1059    finally
1060      if aTransaction <> FTransactionIntf then
1061         RemoveMonitor(aTransaction as TFB25Transaction);
1062    end;
1063    FExecTransactionIntf := aTransaction;
1064 +  FSQLRecord.FTransaction := aTransaction as TFB25Transaction;
1065 +  FSQLRecord.FTransactionSeqNo := FSQLRecord.FTransaction.TransactionSeqNo;
1066    Inc(FChangeSeqNo);
1067   end;
1068  
# Line 1006 | Line 1083 | begin
1083    if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1084      IBError(ibxeInterfaceOutofDate,[nil]);
1085  
1086 < with Firebird25ClientAPI do
1086 > with FFirebird25ClientAPI do
1087   begin
1088 +   if FCollectStatistics then
1089 +     GetPerfCounters(FBeforeStats);
1090 +
1091     TRHandle := (aTransaction as TFB25Transaction).Handle;
1092     Call(isc_dsql_execute2(StatusVector,
1093                         @(TRHandle),
# Line 1020 | Line 1100 | begin
1100       CreateGuid(GUID);
1101       FCursor := GUIDToString(GUID);
1102       Call(
1103 <       isc_dsql_set_cursor_name(StatusVector, @FHandle, PChar(FCursor), 0),
1103 >       isc_dsql_set_cursor_name(StatusVector, @FHandle, PAnsiChar(FCursor), 0),
1104         True);
1105     end;
1106 +
1107 +   if FCollectStatistics then
1108 +   begin
1109 +     GetPerfCounters(FAfterStats);
1110 +     FStatisticsAvailable := true;
1111 +   end;
1112   end;
1113   Inc(FCursorSeqNo);
1114   FSingleResults := false;
# Line 1036 | Line 1122 | begin
1122   Inc(FChangeSeqNo);
1123   end;
1124  
1125 + procedure TFB25Statement.ProcessSQL(sql: AnsiString; GenerateParamNames: boolean;
1126 +  var processedSQL: AnsiString);
1127 + begin
1128 +  FSQLParams.PreprocessSQL(sql,GenerateParamNames, processedSQL);
1129 + end;
1130 +
1131   procedure TFB25Statement.FreeHandle;
1132   var
1133    isc_res: ISC_STATUS;
# Line 1044 | Line 1136 | begin
1136    ReleaseInterfaces;
1137    try
1138      if FHandle <> nil then
1139 <    with Firebird25ClientAPI do
1139 >    with FFirebird25ClientAPI do
1140      begin
1141        isc_res :=
1142          Call(isc_dsql_free_statement(StatusVector, @FHandle, DSQL_drop), False);
# Line 1064 | Line 1156 | var
1156   begin
1157    if (FHandle <> nil) and (SQLStatementType = SQLSelect) and FOpen then
1158    try
1159 <    with Firebird25ClientAPI do
1159 >    with FFirebird25ClientAPI do
1160      begin
1161        isc_res := Call(
1162                     isc_dsql_free_statement(StatusVector, @FHandle, DSQL_close),
# Line 1075 | Line 1167 | begin
1167          IBDatabaseError;
1168      end;
1169    finally
1170 <    if (FSQLRecord.FTransaction <> nil) and (FSQLRecord.FTransaction <> FTransactionIntf) then
1170 >    if (FSQLRecord.FTransaction <> nil) and (FSQLRecord.FTransaction <> (FTransactionIntf as TFB25Transaction)) then
1171        RemoveMonitor(FSQLRecord.FTransaction);
1172      FOpen := False;
1173      FExecTransactionIntf := nil;
# Line 1085 | Line 1177 | begin
1177   end;
1178  
1179   constructor TFB25Statement.Create(Attachment: TFB25Attachment;
1180 <  Transaction: ITransaction; sql: string; aSQLDialect: integer);
1180 >  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer);
1181   begin
1182    inherited Create(Attachment,Transaction,sql,aSQLDialect);
1183    FDBHandle := Attachment.Handle;
1184 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1185 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1186    FSQLParams := TIBXINPUTSQLDA.Create(self);
1187    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1188    InternalPrepare;
1189   end;
1190  
1191 < constructor TFB25Statement.CreateWithParameterNames(Attachment: TFB25Attachment;
1192 <  Transaction: ITransaction; sql: string; aSQLDialect: integer;
1193 <  GenerateParamNames: boolean);
1191 > constructor TFB25Statement.CreateWithParameterNames(
1192 >  Attachment: TFB25Attachment; Transaction: ITransaction; sql: AnsiString;
1193 >  aSQLDialect: integer; GenerateParamNames: boolean;
1194 >  CaseSensitiveParams: boolean);
1195   begin
1196    inherited CreateWithParameterNames(Attachment,Transaction,sql,aSQLDialect,GenerateParamNames);
1197    FDBHandle := Attachment.Handle;
1198 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1199 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1200    FSQLParams := TIBXINPUTSQLDA.Create(self);
1201 +  FSQLParams.CaseSensitiveParams := CaseSensitiveParams;
1202    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1203    InternalPrepare;
1204   end;
# Line 1122 | Line 1220 | begin
1220    if FEOF then
1221      IBError(ibxeEOF,[nil]);
1222  
1223 <  with Firebird25ClientAPI do
1223 >  with FFirebird25ClientAPI do
1224    begin
1225      { Go to the next record... }
1226      fetch_res :=
# Line 1148 | Line 1246 | begin
1246        FBOF := false;
1247        result := true;
1248      end;
1249 +    if FCollectStatistics then
1250 +    begin
1251 +      GetPerfCounters(FAfterStats);
1252 +      FStatisticsAvailable := true;
1253 +    end;
1254    end;
1255    FSQLRecord.RowChange;
1256    if FEOF then
# Line 1170 | Line 1273 | begin
1273    Result := TMetaData(GetInterface(1));
1274   end;
1275  
1276 < function TFB25Statement.GetPlan: String;
1276 > function TFB25Statement.GetPlan: AnsiString;
1277   var
1278      RB: ISQLInfoResults;
1279   begin
# Line 1180 | Line 1283 | begin
1283      result := ''
1284    else
1285    begin
1286 <    RB := TSQLInfoResultsBuffer.Create(4*4096);
1286 >    RB := TSQLInfoResultsBuffer.Create(FFirebird25ClientAPI,4*4096);
1287      GetDsqlInfo(isc_info_sql_get_plan,RB);
1288       if RB.Count > 0 then
1289       Result := RB[0].GetAsString;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines