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 45 by tony, Tue Dec 6 10:33:46 2016 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, 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';
286  
287   { TIBXSQLVAR }
288  
# Line 287 | 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 337 | 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 356 | 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 366 | 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 388 | Line 416 | begin
416                FStatement.GetTransaction as TFB30Transaction,
417                GetRelationName,GetFieldName,
418                GetSubType);
419 +  (FBlobMetaData as TFBBlobMetaData).SetCharSetID(GetCharSetID);
420    Result := FBlobMetaData;
421   end;
422  
# Line 401 | Line 430 | begin
430    else
431    if IsNullable then
432      FNullIndicator := 0;
433 +  Changed;
434   end;
435  
436   procedure TIBXSQLVAR.SetIsNullable(Value: Boolean);
# Line 413 | 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 434 | 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 538 | 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 590 | 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 598 | Line 635 | end;
635  
636   function TIBXINPUTSQLDA.GetMetaData: Firebird.IMessageMetadata;
637   begin
638 <  PackBuffer;
638 >  BuildMetadata;
639    Result := FCurMetaData;
640   end;
641  
# Line 608 | 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 <
617 <  with Firebird30ClientAPI do
652 >  if FCurMetaData = nil then
653 >  with FFirebird30ClientAPI do
654    begin
655      Builder := inherited MetaData.getBuilder(StatusIntf);
656      Check4DataBaseError;
# Line 638 | 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 647 | Line 693 | begin
693      for i := 0 to Count - 1 do
694      with TIBXSQLVar(Column[i]) do
695      begin
696 <      Move(FSQLData^,(FMessageBuffer + FCurMetaData.getOffset(StatusIntf,i))^,FDataLength);
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
706        begin
# Line 680 | 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 699 | 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 712 | Line 768 | begin
768            else
769              IBAlloc(FSQLData, 0, FDataLength)
770          end;
771 <        SQL_VARYING: begin
771 >        SQL_VARYING:
772            IBAlloc(FSQLData, 0, FDataLength + 2);
717        end;
773         else
774            IBError(ibxeUnknownSQLDataType, [sqltype and (not 1)])
775        end;
# Line 728 | 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 759 | 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 787 | 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 802 | 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 810 | 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 819 | 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 836 | 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 952 | 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 968 | 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 985 | 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 1024 | 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,
1029 <                                       EIBInterBaseError(E).Message +
1030 <                                       sSQLErrorSeparator + FSQL)
1031 <      else
1032 <        raise;
1084 >        E.Message := E.Message + sSQLErrorSeparator + FSQL;
1085 >      raise;
1086      end;
1087    end;
1088    FPrepared := true;
# Line 1065 | Line 1118 | begin
1118      IBError(ibxeInterfaceOutofDate,[nil]);
1119  
1120    try
1121 <    with Firebird30ClientAPI do
1069 <    case FSQLStatementType of
1070 <    SQLSelect:
1071 <      IBError(ibxeIsAExecuteProcedure,[]);
1072 <
1073 <    SQLExecProcedure:
1121 >    with FFirebird30ClientAPI do
1122      begin
1123 <      FStatementIntf.execute(StatusIntf,
1124 <                             (aTransaction as TFB30Transaction).TransactionIntf,
1125 <                             FSQLParams.MetaData,
1126 <                             FSQLParams.MessageBuffer,
1127 <                             FSQLRecord.MetaData,
1128 <                             FSQLRecord.MessageBuffer);
1129 <      Check4DataBaseError;
1123 >      if FCollectStatistics then
1124 >      begin
1125 >        UtilIntf.getPerfCounters(StatusIntf,
1126 >                      (GetAttachment as TFB30Attachment).AttachmentIntf,
1127 >                      ISQL_COUNTERS,@FBeforeStats);
1128 >        Check4DataBaseError;
1129 >      end;
1130  
1131 <      Result := TResults.Create(FSQLRecord);
1132 <      FSingleResults := true;
1133 <    end
1134 <    else
1135 <      FStatementIntf.execute(StatusIntf,
1136 <                             (aTransaction as TFB30Transaction).TransactionIntf,
1137 <                             FSQLParams.MetaData,
1138 <                             FSQLParams.MessageBuffer,
1139 <                             nil,
1140 <                             nil);
1141 <      Check4DataBaseError;
1131 >      case FSQLStatementType of
1132 >      SQLSelect:
1133 >        IBError(ibxeIsAExecuteProcedure,[]);
1134 >
1135 >      SQLExecProcedure:
1136 >      begin
1137 >        FStatementIntf.execute(StatusIntf,
1138 >                               (aTransaction as TFB30Transaction).TransactionIntf,
1139 >                               FSQLParams.MetaData,
1140 >                               FSQLParams.MessageBuffer,
1141 >                               FSQLRecord.MetaData,
1142 >                               FSQLRecord.MessageBuffer);
1143 >        Check4DataBaseError;
1144 >
1145 >        Result := TResults.Create(FSQLRecord);
1146 >        FSingleResults := true;
1147 >      end
1148 >      else
1149 >        FStatementIntf.execute(StatusIntf,
1150 >                               (aTransaction as TFB30Transaction).TransactionIntf,
1151 >                               FSQLParams.MetaData,
1152 >                               FSQLParams.MessageBuffer,
1153 >                               nil,
1154 >                               nil);
1155 >        Check4DataBaseError;
1156 >      end;
1157 >      if FCollectStatistics then
1158 >      begin
1159 >        UtilIntf.getPerfCounters(StatusIntf,
1160 >                  (GetAttachment as TFB30Attachment).AttachmentIntf,
1161 >                  ISQL_COUNTERS, @FAfterStats);
1162 >        Check4DataBaseError;
1163 >        FStatisticsAvailable := true;
1164 >      end;
1165      end;
1166    finally
1167      if aTransaction <> FTransactionIntf then
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 1116 | 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
1196 +     UtilIntf.getPerfCounters(StatusIntf,
1197 +                             (GetAttachment as TFB30Attachment).AttachmentIntf,
1198 +                              ISQL_COUNTERS, @FBeforeStats);
1199 +     Check4DataBaseError;
1200 +   end;
1201 +
1202     FResultSet := FStatementIntf.openCursor(StatusIntf,
1203                            (aTransaction as TFB30Transaction).TransactionIntf,
1204                            FSQLParams.MetaData,
# Line 1125 | Line 1206 | begin
1206                            FSQLRecord.MetaData,
1207                            0);
1208     Check4DataBaseError;
1209 +
1210 +   if FCollectStatistics then
1211 +   begin
1212 +     UtilIntf.getPerfCounters(StatusIntf,
1213 +                             (GetAttachment as TFB30Attachment).AttachmentIntf,
1214 +                             ISQL_COUNTERS,@FAfterStats);
1215 +     Check4DataBaseError;
1216 +     FStatisticsAvailable := true;
1217 +   end;
1218   end;
1219   Inc(FCursorSeqNo);
1220   FSingleResults := false;
# Line 1139 | 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 1155 | 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 1169 | 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 1180 | 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 1214 | 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 1239 | 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 1262 | 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 1270 | 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