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 60 by tony, Mon Mar 27 15:21:02 2017 UTC vs.
Revision 315 by tony, Thu Feb 25 11:56:36 2021 UTC

# Line 121 | 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;
128      FOwnsSQLData: boolean;
129      FBlobMetaData: IBlobMetaData;
130      FArrayMetaData: IArrayMetaData;
131 +    FMetadataSize: short; {size of field from metadata}
132      FXSQLVAR: PXSQLVAR;       { Points to the PXSQLVAR in the owner object }
133    protected
134      function GetSQLType: cardinal; override;
# Line 138 | Line 140 | type
140      function GetScale: integer; override;
141      function GetCharSetID: cardinal; override;
142      function GetCodePage: TSystemCodePage; override;
143 +    function GetCharSetWidth: integer; override;
144      function GetIsNull: Boolean;   override;
145      function GetIsNullable: boolean; override;
146      function GetSQLData: PByte;  override;
147      function GetDataLength: cardinal; override;
148 +    function GetSize: cardinal; override;
149      procedure SetIsNull(Value: Boolean); override;
150      procedure SetIsNullable(Value: Boolean);  override;
151      procedure SetSQLData(AValue: PByte; len: cardinal); override;
# Line 177 | Line 181 | type
181      function GetXSQLDA: PXSQLDA;
182    protected
183      FStatement: TFB25Statement;
184 +    FFirebird25ClientAPI: TFB25ClientAPI;
185      function GetTransactionSeqNo: integer; override;
186      procedure FreeXSQLDA;
187      function GetStatement: IStatement; override;
# Line 241 | Line 246 | type
246    private
247      FDBHandle: TISC_DB_HANDLE;
248      FHandle: TISC_STMT_HANDLE;
249 +    FFirebird25ClientAPI: TFB25ClientAPI;
250      FSQLParams: TIBXINPUTSQLDA;
251      FSQLRecord: TIBXOUTPUTSQLDA;
252      FCursor: AnsiString;               { Cursor name...}
# Line 252 | Line 258 | type
258      procedure InternalPrepare; override;
259      function InternalExecute(aTransaction: ITransaction): IResults; override;
260      function InternalOpenCursor(aTransaction: ITransaction): IResultSet; override;
261 +    procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); override;
262      procedure FreeHandle; override;
263      procedure InternalClose(Force: boolean); override;
264    public
265      constructor Create(Attachment: TFB25Attachment; Transaction: ITransaction;
266        sql: AnsiString; aSQLDialect: integer);
267      constructor CreateWithParameterNames(Attachment: TFB25Attachment;
268 <      Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean);
268 >      Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean;
269 >      CaseSensitiveParams: boolean=false);
270      destructor Destroy; override;
271      function FetchNext: boolean;
272  
# Line 350 | Line 358 | begin
358       CharSetID2CodePage(GetCharSetID,result);
359   end;
360  
361 + function TIBXSQLVAR.GetCharSetWidth: integer;
362 + begin
363 +  result := 1;
364 +  with Statement.GetAttachment DO
365 +    CharSetWidth(GetCharSetID,result);
366 + end;
367 +
368   function TIBXSQLVAR.GetIsNull: Boolean;
369   begin
370    result := IsNullable and (FNullIndicator = -1);
# Line 370 | Line 385 | begin
385    Result := FXSQLVAR^.sqllen;
386   end;
387  
388 + function TIBXSQLVAR.GetSize: cardinal;
389 + begin
390 +  Result := FMetadataSize;
391 + end;
392 +
393   function TIBXSQLVAR.GetArrayMetaData: IArrayMetaData;
394   begin
395    if GetSQLType <> SQL_ARRAY then
# Line 441 | Line 461 | procedure TIBXSQLVAR.Initialize;
461   begin
462    inherited Initialize;
463    FOwnsSQLData := true;
464 <  with FirebirdClientAPI, FXSQLVar^ do
464 >  with FFirebird25ClientAPI, FXSQLVar^ do
465    begin
466 +    FMetadataSize := sqllen;
467      case sqltype and (not 1) of
468        SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP,
469        SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT, SQL_BOOLEAN,
# Line 502 | Line 523 | begin
523        FXSQLVAR^.sqlind := nil;
524      end;
525    end;
526 +  Changed;
527   end;
528  
529   procedure TIBXSQLVAR.SetSQLData(AValue: PByte; len: cardinal);
# Line 511 | Line 533 | begin
533    FXSQLVAR^.sqldata := AValue;
534    FXSQLVAR^.sqllen := len;
535    FOwnsSQLData := false;
536 +  Changed;
537   end;
538  
539   procedure TIBXSQLVAR.SetScale(aValue: integer);
540   begin
541    FXSQLVAR^.sqlscale := aValue;
542 +  Changed;
543   end;
544  
545   procedure TIBXSQLVAR.SetDataLength(len: cardinal);
# Line 523 | Line 547 | begin
547    if not FOwnsSQLData then
548      FXSQLVAR^.sqldata := nil;
549    FXSQLVAR^.sqllen := len;
550 <  with FirebirdClientAPI do
550 >  with FFirebird25ClientAPI do
551      IBAlloc(FXSQLVAR^.sqldata, 0, FXSQLVAR^.sqllen);
552    FOwnsSQLData := true;
553 +  Changed;
554   end;
555  
556   procedure TIBXSQLVAR.SetSQLType(aValue: cardinal);
557   begin
558    FXSQLVAR^.sqltype := aValue or (FXSQLVAR^.sqltype and 1);
559 +  Changed;
560   end;
561  
562   procedure TIBXSQLVAR.SetCharSetID(aValue: cardinal);
563   begin
564    if aValue <> GetCharSetID then
565 <  case SQLType of
566 <  SQL_VARYING, SQL_TEXT:
567 <      FXSQLVAR^.sqlsubtype := (aValue and $FF) or (FXSQLVAR^.sqlsubtype and not $FF);
568 <
569 <  SQL_BLOB,
570 <  SQL_ARRAY:
571 <    IBError(ibxeInvalidDataConversion,[nil]);
565 >  begin
566 >    case SQLType of
567 >    SQL_VARYING, SQL_TEXT:
568 >        FXSQLVAR^.sqlsubtype := (aValue and $FF) or (FXSQLVAR^.sqlsubtype and not $FF);
569 >
570 >    SQL_BLOB,
571 >    SQL_ARRAY:
572 >      IBError(ibxeInvalidDataConversion,[nil]);
573 >    end;
574 >  Changed;
575    end;
576   end;
577  
# Line 550 | Line 579 | constructor TIBXSQLVAR.Create(aParent: T
579   begin
580    inherited Create(aParent,aIndex);
581    FStatement := aParent.Statement;
582 +  FFirebird25ClientAPI := aParent.FFirebird25ClientAPI;
583   end;
584  
585   procedure TIBXSQLVAR.FreeSQLData;
# Line 620 | Line 650 | procedure TIBXINPUTSQLDA.Bind;
650   begin
651    if Count = 0 then
652      Count := 1;
653 <  with Firebird25ClientAPI do
653 >  with FFirebird25ClientAPI do
654    begin
655      if (FXSQLDA <> nil) then
656         if isc_dsql_describe_bind(StatusVector, @(FStatement.Handle), FStatement.SQLDialect,
# Line 652 | Line 682 | procedure TIBXOUTPUTSQLDA.Bind;
682   begin
683    { Allocate an initial output descriptor (with one column) }
684    Count := 1;
685 <  with Firebird25ClientAPI do
685 >  with FFirebird25ClientAPI do
686    begin
687      { Using isc_dsql_describe, get the right size for the columns... }
688      if isc_dsql_describe(StatusVector, @(FStatement.Handle), FStatement.SQLDialect, FXSQLDA) > 0 then
# Line 687 | Line 717 | begin
717      len := sqllen;
718      if not IsNull and ((sqltype and (not 1)) = SQL_VARYING) then
719      begin
720 <      with FirebirdClientAPI do
720 >      with FFirebird25ClientAPI do
721          len := DecodeInteger(data,2);
722        Inc(data,2);
723      end;
# Line 704 | Line 734 | constructor TIBXSQLDA.Create(aStatement:
734   begin
735    inherited Create;
736    FStatement := aStatement;
737 +  FFirebird25ClientAPI := aStatement.FFirebird25ClientAPI;
738    FSize := 0;
739   //  writeln('Creating ',ClassName);
740   end;
# Line 790 | Line 821 | begin
821        OldSize := 0;
822      if Count > FSize then
823      begin
824 <      Firebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
824 >      FFirebird25ClientAPI.IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(Count));
825        SetLength(FColumnList, FCount);
826        FXSQLDA^.version := SQLDA_VERSION1;
827        p := @FXSQLDA^.sqlvar[0];
# Line 888 | Line 919 | end;
919   procedure TFB25Statement.GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults
920    );
921   begin
922 <  with Firebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
922 >  with FFirebird25ClientAPI, buffer as TSQLInfoResultsBuffer do
923    if isc_dsql_sql_info(StatusVector, @(FHandle), 1, @info_request,
924                       GetBufSize, Buffer) > 0 then
925      IBDatabaseError;
# Line 905 | Line 936 | begin
936      IBError(ibxeEmptyQuery, [nil]);
937    try
938      CheckTransaction(FTransactionIntf);
939 <    with Firebird25ClientAPI do
939 >    with FFirebird25ClientAPI do
940      begin
941        Call(isc_dsql_alloc_statement2(StatusVector, @(FDBHandle),
942                                        @FHandle), True);
# Line 913 | Line 944 | begin
944        if FHasParamNames then
945        begin
946          if FProcessedSQL = '' then
947 <          FSQLParams.PreprocessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
947 >          ProcessSQL(FSQL,FGenerateParamNames,FProcessedSQL);
948          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
949                   PAnsiChar(FProcessedSQL), FSQLDialect, nil), True);
950        end
# Line 957 | Line 988 | begin
988        if (FHandle <> nil) then
989          FreeHandle;
990        if E is EIBInterBaseError then
991 <        raise EIBInterBaseError.Create(EIBInterBaseError(E).SQLCode,
992 <                                       EIBInterBaseError(E).IBErrorCode,
962 <                                       EIBInterBaseError(E).Message +
963 <                                       sSQLErrorSeparator + FSQL)
964 <      else
965 <        raise;
991 >        E.Message := E.Message + sSQLErrorSeparator + FSQL;
992 >      raise;
993      end;
994    end;
995    FPrepared := true;
# Line 999 | Line 1026 | begin
1026  
1027    try
1028      TRHandle := (aTransaction as TFB25Transaction).Handle;
1029 <    with Firebird25ClientAPI do
1029 >    with FFirebird25ClientAPI do
1030      begin
1031        if FCollectStatistics then
1032          GetPerfCounters(FBeforeStats);
# Line 1038 | Line 1065 | begin
1065         RemoveMonitor(aTransaction as TFB25Transaction);
1066    end;
1067    FExecTransactionIntf := aTransaction;
1068 +  FSQLRecord.FTransaction := aTransaction as TFB25Transaction;
1069 +  FSQLRecord.FTransactionSeqNo := FSQLRecord.FTransaction.TransactionSeqNo;
1070    Inc(FChangeSeqNo);
1071   end;
1072  
# Line 1058 | Line 1087 | begin
1087    if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1088      IBError(ibxeInterfaceOutofDate,[nil]);
1089  
1090 < with Firebird25ClientAPI do
1090 > with FFirebird25ClientAPI do
1091   begin
1092     if FCollectStatistics then
1093       GetPerfCounters(FBeforeStats);
# Line 1097 | Line 1126 | begin
1126   Inc(FChangeSeqNo);
1127   end;
1128  
1129 + procedure TFB25Statement.ProcessSQL(sql: AnsiString; GenerateParamNames: boolean;
1130 +  var processedSQL: AnsiString);
1131 + begin
1132 +  FSQLParams.PreprocessSQL(sql,GenerateParamNames, processedSQL);
1133 + end;
1134 +
1135   procedure TFB25Statement.FreeHandle;
1136   var
1137    isc_res: ISC_STATUS;
# Line 1105 | Line 1140 | begin
1140    ReleaseInterfaces;
1141    try
1142      if FHandle <> nil then
1143 <    with Firebird25ClientAPI do
1143 >    with FFirebird25ClientAPI do
1144      begin
1145        isc_res :=
1146          Call(isc_dsql_free_statement(StatusVector, @FHandle, DSQL_drop), False);
# Line 1125 | Line 1160 | var
1160   begin
1161    if (FHandle <> nil) and (SQLStatementType = SQLSelect) and FOpen then
1162    try
1163 <    with Firebird25ClientAPI do
1163 >    with FFirebird25ClientAPI do
1164      begin
1165        isc_res := Call(
1166                     isc_dsql_free_statement(StatusVector, @FHandle, DSQL_close),
# Line 1150 | Line 1185 | constructor TFB25Statement.Create(Attach
1185   begin
1186    inherited Create(Attachment,Transaction,sql,aSQLDialect);
1187    FDBHandle := Attachment.Handle;
1188 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1189 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1190    FSQLParams := TIBXINPUTSQLDA.Create(self);
1191    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1192    InternalPrepare;
1193   end;
1194  
1195 < constructor TFB25Statement.CreateWithParameterNames(Attachment: TFB25Attachment;
1196 <  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1197 <  GenerateParamNames: boolean);
1195 > constructor TFB25Statement.CreateWithParameterNames(
1196 >  Attachment: TFB25Attachment; Transaction: ITransaction; sql: AnsiString;
1197 >  aSQLDialect: integer; GenerateParamNames: boolean;
1198 >  CaseSensitiveParams: boolean);
1199   begin
1200    inherited CreateWithParameterNames(Attachment,Transaction,sql,aSQLDialect,GenerateParamNames);
1201    FDBHandle := Attachment.Handle;
1202 +  FFirebird25ClientAPI := Attachment.Firebird25ClientAPI;
1203 +  OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1204    FSQLParams := TIBXINPUTSQLDA.Create(self);
1205 +  FSQLParams.CaseSensitiveParams := CaseSensitiveParams;
1206    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1207    InternalPrepare;
1208   end;
# Line 1183 | Line 1224 | begin
1224    if FEOF then
1225      IBError(ibxeEOF,[nil]);
1226  
1227 <  with Firebird25ClientAPI do
1227 >  with FFirebird25ClientAPI do
1228    begin
1229      { Go to the next record... }
1230      fetch_res :=
# Line 1209 | Line 1250 | begin
1250        FBOF := false;
1251        result := true;
1252      end;
1253 +    if FCollectStatistics then
1254 +    begin
1255 +      GetPerfCounters(FAfterStats);
1256 +      FStatisticsAvailable := true;
1257 +    end;
1258    end;
1259    FSQLRecord.RowChange;
1260    if FEOF then
# Line 1241 | Line 1287 | begin
1287      result := ''
1288    else
1289    begin
1290 <    RB := TSQLInfoResultsBuffer.Create(4*4096);
1290 >    RB := TSQLInfoResultsBuffer.Create(FFirebird25ClientAPI,4*4096);
1291      GetDsqlInfo(isc_info_sql_get_plan,RB);
1292       if RB.Count > 0 then
1293       Result := RB[0].GetAsString;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines