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 56 by tony, Mon Mar 6 10:20:02 2017 UTC vs.
Revision 309 by tony, Tue Jul 21 08:00:42 2020 UTC

# Line 87 | 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 116 | Line 117 | type
117       function GetScale: integer; override;
118       function GetCharSetID: cardinal; override;
119       function GetCodePage: TSystemCodePage; override;
120 +     function GetCharSetWidth: integer; override;
121       function GetIsNull: Boolean;   override;
122       function GetIsNullable: boolean; override;
123       function GetSQLData: PByte;  override;
# Line 148 | Line 150 | type
150      FSize: Integer;  {Number of TIBXSQLVARs in column list}
151      FMetaData: Firebird.IMessageMetadata;
152      FTransactionSeqNo: integer;
153 <  protected
153 > protected
154      FStatement: TFB30Statement;
155 +    FFirebird30ClientAPI: TFB30ClientAPI;
156      function GetTransactionSeqNo: integer; override;
157      procedure FreeXSQLDA; virtual;
158      function GetStatement: IStatement; override;
# Line 181 | Line 184 | type
184      function GetMetaData: Firebird.IMessageMetadata;
185      function GetModified: Boolean;
186      function GetMsgLength: integer;
187 +    procedure BuildMetadata;
188      procedure PackBuffer;
189    protected
190      procedure FreeXSQLDA; override;
# Line 235 | Line 239 | type
239    TFB30Statement = class(TFBStatement,IStatement)
240    private
241      FStatementIntf: Firebird.IStatement;
242 +    FFirebird30ClientAPI: TFB30ClientAPI;
243      FSQLParams: TIBXINPUTSQLDA;
244      FSQLRecord: TIBXOUTPUTSQLDA;
245      FResultSet: Firebird.IResultSet;
# Line 245 | Line 250 | type
250      procedure InternalPrepare; override;
251      function InternalExecute(aTransaction: ITransaction): IResults; override;
252      function InternalOpenCursor(aTransaction: ITransaction): IResultSet; override;
253 +    procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); override;
254      procedure FreeHandle; override;
255      procedure InternalClose(Force: boolean); override;
256    public
257      constructor Create(Attachment: TFB30Attachment; Transaction: ITransaction;
258        sql: AnsiString; aSQLDialect: integer);
259      constructor CreateWithParameterNames(Attachment: TFB30Attachment; Transaction: ITransaction;
260 <      sql: AnsiString;  aSQLDialect: integer; GenerateParamNames: boolean =false);
260 >      sql: AnsiString;  aSQLDialect: integer; GenerateParamNames: boolean =false;
261 >      CaseSensitiveParams: boolean=false);
262      destructor Destroy; override;
263      function FetchNext: boolean;
264      property StatementIntf: Firebird.IStatement read FStatementIntf;
# Line 270 | Line 277 | end;
277  
278   implementation
279  
280 < uses IBUtils, FBMessages, FBBLob, FB30Blob, variants,  FBArray, FB30Array;
280 > uses IBUtils, FBMessages, FBBlob, FB30Blob, variants,  FBArray, FB30Array;
281  
282   const
283    ISQL_COUNTERS = 'CurrentMemory, MaxMemory, RealTime, UserTime, Buffers, Reads, Writes, Fetches';
# Line 295 | Line 302 | end;
302  
303   function TIBXSQLVAR.GetAliasName: AnsiString;
304   begin
305 <  with Firebird30ClientAPI do
305 >  with FFirebird30ClientAPI do
306    begin
307      result := strpas(TIBXSQLDA(Parent).MetaData.getAlias(StatusIntf,Index));
308      Check4DataBaseError;
# Line 309 | Line 316 | end;
316  
317   function TIBXSQLVAR.GetOwnerName: AnsiString;
318   begin
319 <  with Firebird30ClientAPI do
319 >  with FFirebird30ClientAPI do
320    begin
321      result := strpas(TIBXSQLDA(Parent).MetaData.getOwner(StatusIntf,Index));
322      Check4DataBaseError;
# Line 343 | Line 350 | begin
350      else
351        result := FCharSetID;
352    end;
353 +  result := result;
354   end;
355  
356   function TIBXSQLVAR.GetCodePage: TSystemCodePage;
357   begin
358    result := CP_NONE;
359 <  with Firebird30ClientAPI do
359 >  with Statement.GetAttachment do
360       CharSetID2CodePage(GetCharSetID,result);
361   end;
362  
363 + function TIBXSQLVAR.GetCharSetWidth: integer;
364 + begin
365 +  result := 1;
366 +  with Statement.GetAttachment DO
367 +    CharSetWidth(GetCharSetID,result);
368 + end;
369 +
370   function TIBXSQLVAR.GetIsNull: Boolean;
371   begin
372    Result := IsNullable and (FSQLNullIndicator^ = -1);
# Line 421 | Line 436 | begin
436    end
437    else
438      FSQLNullIndicator := nil;
439 +  Changed;
440   end;
441  
442   procedure TIBXSQLVAR.SetSQLData(AValue: PByte; len: cardinal);
# Line 430 | Line 446 | begin
446    FSQLData := AValue;
447    FDataLength := len;
448    FOwnsSQLData := false;
449 +  Changed;
450   end;
451  
452   procedure TIBXSQLVAR.SetScale(aValue: integer);
453   begin
454    FScale := aValue;
455 +  Changed;
456   end;
457  
458   procedure TIBXSQLVAR.SetDataLength(len: cardinal);
# Line 442 | Line 460 | begin
460    if not FOwnsSQLData then
461      FSQLData := nil;
462    FDataLength := len;
463 <  with Firebird30ClientAPI do
463 >  with FFirebird30ClientAPI do
464      IBAlloc(FSQLData, 0, FDataLength);
465    FOwnsSQLData := true;
466 +  Changed;
467   end;
468  
469   procedure TIBXSQLVAR.SetSQLType(aValue: cardinal);
470   begin
471    FSQLType := aValue;
472 +  Changed;
473   end;
474  
475   procedure TIBXSQLVAR.SetCharSetID(aValue: cardinal);
476   begin
477    FCharSetID := aValue;
478 +  Changed;
479   end;
480  
481   constructor TIBXSQLVAR.Create(aParent: TIBXSQLDA; aIndex: integer);
482   begin
483    inherited Create(aParent,aIndex);
484    FStatement := aParent.Statement;
485 +  FFirebird30ClientAPI := aParent.FFirebird30ClientAPI;
486   end;
487  
488   procedure TIBXSQLVAR.RowChange;
# Line 606 | Line 628 | end;
628  
629   function TIBXINPUTSQLDA.GetMetaData: Firebird.IMessageMetadata;
630   begin
631 <  PackBuffer;
631 >  BuildMetadata;
632    Result := FCurMetaData;
633   end;
634  
# Line 616 | Line 638 | begin
638    Result := FMsgLength;
639   end;
640  
641 < procedure TIBXINPUTSQLDA.PackBuffer;
641 > procedure TIBXINPUTSQLDA.BuildMetadata;
642   var Builder: Firebird.IMetadataBuilder;
643      i: integer;
644   begin
645 <  if FMsgLength > 0 then Exit;
646 <
625 <  with Firebird30ClientAPI do
645 >  if FCurMetaData = nil then
646 >  with FFirebird30ClientAPI do
647    begin
648      Builder := inherited MetaData.getBuilder(StatusIntf);
649      Check4DataBaseError;
# Line 646 | Line 667 | begin
667      finally
668        Builder.release;
669      end;
670 +  end;
671 + end;
672  
673 + procedure TIBXINPUTSQLDA.PackBuffer;
674 + var i: integer;
675 + begin
676 +  BuildMetadata;
677 +
678 +  if FMsgLength = 0 then
679 +  with FFirebird30ClientAPI do
680 +  begin
681      FMsgLength := FCurMetaData.getMessageLength(StatusIntf);
682      Check4DataBaseError;
683  
# Line 655 | Line 686 | begin
686      for i := 0 to Count - 1 do
687      with TIBXSQLVar(Column[i]) do
688      begin
689 +      if not Modified then
690 +        IBError(ibxeUninitializedInputParameter,[i,Name]);
691 +
692        if IsNull then
693          FillChar((FMessageBuffer + FCurMetaData.getOffset(StatusIntf,i))^,FDataLength,0)
694        else
695 +      if FSQLData <> nil then
696          Move(FSQLData^,(FMessageBuffer + FCurMetaData.getOffset(StatusIntf,i))^,FDataLength);
697        Check4DataBaseError;
698        if IsNullable then
# Line 691 | Line 726 | procedure TIBXINPUTSQLDA.Bind(aMetaData:
726   var i: integer;
727   begin
728    FMetaData := aMetaData;
729 <  with Firebird30ClientAPI do
729 >  with FFirebird30ClientAPI do
730    begin
731      Count := metadata.getCount(StatusIntf);
732      Check4DataBaseError;
# Line 738 | Line 773 | begin
773          FSQLNullIndicator := nil;
774        FScale := aMetaData.getScale(StatusIntf,i);
775        Check4DataBaseError;
776 <      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i);
776 >      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i) and $FF;
777        Check4DataBaseError;
778      end;
779    end;
# Line 769 | Line 804 | procedure TIBXOUTPUTSQLDA.Bind(aMetaData
804   var i: integer;
805   begin
806    FMetaData := aMetaData;
807 <  with Firebird30ClientAPI do
807 >  with FFirebird30ClientAPI do
808    begin
809      Count := metadata.getCount(StatusIntf);
810      Check4DataBaseError;
# Line 812 | Line 847 | begin
847          FSQLNullIndicator := nil;
848        FScale := aMetaData.getScale(StatusIntf,i);
849        Check4DataBaseError;
850 <      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i);
850 >      FCharSetID :=  aMetaData.getCharSet(StatusIntf,i) and $FF;
851        Check4DataBaseError;
852      end;
853    end;
# Line 829 | Line 864 | begin
864      len := FDataLength;
865      if not IsNull and (FSQLType = SQL_VARYING) then
866      begin
867 <      with Firebird30ClientAPI do
867 >      with FFirebird30ClientAPI do
868          len := DecodeInteger(data,2);
869        Inc(Data,2);
870      end;
# Line 846 | Line 881 | constructor TIBXSQLDA.Create(aStatement:
881   begin
882    inherited Create;
883    FStatement := aStatement;
884 +  FFirebird30ClientAPI := aStatement.FFirebird30ClientAPI;
885    FSize := 0;
886   //  writeln('Creating ',ClassName);
887   end;
# Line 962 | Line 998 | end;
998   procedure TFB30Statement.GetDSQLInfo(info_request: byte; buffer: ISQLInfoResults
999    );
1000   begin
1001 <  with Firebird30ClientAPI, buffer as TSQLInfoResultsBuffer do
1001 >  with FFirebird30ClientAPI, buffer as TSQLInfoResultsBuffer do
1002    begin
1003      StatementIntf.getInfo(StatusIntf,1,BytePtr(@info_request),
1004                       GetBufSize, BytePtr(Buffer));
# Line 978 | Line 1014 | begin
1014      IBError(ibxeEmptyQuery, [nil]);
1015    try
1016      CheckTransaction(FTransactionIntf);
1017 <    with Firebird30ClientAPI do
1017 >    with FFirebird30ClientAPI do
1018      begin
1019        if FHasParamNames then
1020        begin
1021          if FProcessedSQL = '' then
1022 <          FSQLParams.PreprocessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
1022 >          ProcessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
1023          FStatementIntf := (GetAttachment as TFB30Attachment).AttachmentIntf.prepare(StatusIntf,
1024                              (FTransactionIntf as TFB30Transaction).TransactionIntf,
1025                              Length(FProcessedSQL),
# Line 1075 | Line 1111 | begin
1111      IBError(ibxeInterfaceOutofDate,[nil]);
1112  
1113    try
1114 <    with Firebird30ClientAPI do
1114 >    with FFirebird30ClientAPI do
1115      begin
1116        if FCollectStatistics then
1117        begin
# Line 1125 | Line 1161 | begin
1161         RemoveMonitor(aTransaction as TFB30Transaction);
1162    end;
1163    FExecTransactionIntf := aTransaction;
1164 +  FSQLRecord.FTransaction := (aTransaction as TFB30Transaction);
1165 +  FSQLRecord.FTransactionSeqNo := FSQLRecord.FTransaction.TransactionSeqNo;
1166    SignalActivity;
1167    Inc(FChangeSeqNo);
1168   end;
# Line 1144 | Line 1182 | begin
1182    if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB30transaction).TransactionSeqNo) then
1183      IBError(ibxeInterfaceOutofDate,[nil]);
1184  
1185 < with Firebird30ClientAPI do
1185 > with FFirebird30ClientAPI do
1186   begin
1187     if FCollectStatistics then
1188     begin
# Line 1184 | Line 1222 | begin
1222   Inc(FChangeSeqNo);
1223   end;
1224  
1225 + procedure TFB30Statement.ProcessSQL(sql: AnsiString; GenerateParamNames: boolean;
1226 +  var processedSQL: AnsiString);
1227 + begin
1228 +  FSQLParams.PreprocessSQL(sql,GenerateParamNames,processedSQL);
1229 + end;
1230 +
1231   procedure TFB30Statement.FreeHandle;
1232   begin
1233    Close;
# Line 1200 | Line 1244 | procedure TFB30Statement.InternalClose(F
1244   begin
1245    if (FStatementIntf <> nil) and (SQLStatementType = SQLSelect) and FOpen then
1246    try
1247 <    with Firebird30ClientAPI do
1247 >    with FFirebird30ClientAPI do
1248      begin
1249        if FResultSet <> nil then
1250        begin
# Line 1228 | Line 1272 | constructor TFB30Statement.Create(Attach
1272    Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer);
1273   begin
1274    inherited Create(Attachment,Transaction,sql,aSQLDialect);
1275 +  FFirebird30ClientAPI := Attachment.Firebird30ClientAPI;
1276    FSQLParams := TIBXINPUTSQLDA.Create(self);
1277    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1278    InternalPrepare;
# Line 1235 | Line 1280 | end;
1280  
1281   constructor TFB30Statement.CreateWithParameterNames(
1282    Attachment: TFB30Attachment; Transaction: ITransaction; sql: AnsiString;
1283 <  aSQLDialect: integer; GenerateParamNames: boolean);
1283 >  aSQLDialect: integer; GenerateParamNames: boolean;
1284 >  CaseSensitiveParams: boolean);
1285   begin
1286    inherited CreateWithParameterNames(Attachment,Transaction,sql,aSQLDialect,GenerateParamNames);
1287 +  FFirebird30ClientAPI := Attachment.Firebird30ClientAPI;
1288    FSQLParams := TIBXINPUTSQLDA.Create(self);
1289 +  FSQLParams.CaseSensitiveParams := CaseSensitiveParams;
1290    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1291    InternalPrepare;
1292   end;
# Line 1259 | Line 1307 | begin
1307    if FEOF then
1308      IBError(ibxeEOF,[nil]);
1309  
1310 <  with Firebird30ClientAPI do
1310 >  with FFirebird30ClientAPI do
1311    begin
1312      { Go to the next record... }
1313      fetchResult := FResultSet.fetchNext(StatusIntf,FSQLRecord.MessageBuffer);
# Line 1284 | Line 1332 | begin
1332        FBOF := false;
1333        result := true;
1334      end;
1335 +    if FCollectStatistics then
1336 +    begin
1337 +      UtilIntf.getPerfCounters(StatusIntf,
1338 +                              (GetAttachment as TFB30Attachment).AttachmentIntf,
1339 +                              ISQL_COUNTERS,@FAfterStats);
1340 +      Check4DataBaseError;
1341 +      FStatisticsAvailable := true;
1342 +    end;
1343    end;
1344    FSQLRecord.RowChange;
1345    SignalActivity;
# Line 1315 | Line 1371 | begin
1371         SQLUpdate, SQLDelete])) then
1372      result := ''
1373    else
1374 <  with Firebird30ClientAPI do
1374 >  with FFirebird30ClientAPI do
1375    begin
1376      Result := FStatementIntf.getPlan(StatusIntf,true);
1377      Check4DataBaseError;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines