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 309 by tony, Tue Jul 21 08:00:42 2020 UTC vs.
ibx/branches/journaling/fbintf/client/2.5/FB25Statement.pas (file contents), Revision 363 by tony, Tue Dec 7 13:30:05 2021 UTC

# Line 123 | Line 123 | type
123      FStatement: TFB25Statement;
124      FFirebird25ClientAPI: TFB25ClientAPI;
125      FBlob: IBlob;             {Cache references}
126    FArray: IArray;
126      FNullIndicator: short;
127      FOwnsSQLData: boolean;
128      FBlobMetaData: IBlobMetaData;
129      FArrayMetaData: IArrayMetaData;
130 +    FMetadataSize: short; {size of field from metadata}
131      FXSQLVAR: PXSQLVAR;       { Points to the PXSQLVAR in the owner object }
132    protected
133      function GetSQLType: cardinal; override;
# Line 144 | Line 144 | type
144      function GetIsNullable: boolean; override;
145      function GetSQLData: PByte;  override;
146      function GetDataLength: cardinal; override;
147 +    function GetSize: cardinal; override;
148 +    function GetAttachment: IAttachment; override;
149 +    function GetDefaultTextSQLType: cardinal; override;
150      procedure SetIsNull(Value: Boolean); override;
151      procedure SetIsNullable(Value: Boolean);  override;
152      procedure SetSQLData(AValue: PByte; len: cardinal); override;
# Line 155 | Line 158 | type
158      constructor Create(aParent: TIBXSQLDA; aIndex: integer);
159      procedure FreeSQLData;
160      procedure RowChange; override;
161 <    function GetAsArray(Array_ID: TISC_QUAD): IArray; override;
161 >    function GetAsArray: IArray; override;
162      function GetAsBlob(Blob_ID: TISC_QUAD; BPB: IBPB): IBlob; override;
163      function GetArrayMetaData: IArrayMetaData; override;
164      function GetBlobMetaData: IBlobMetaData; override;
# Line 163 | Line 166 | type
166      procedure Initialize; override;
167  
168      property Statement: TFB25Statement read FStatement;
169 +    property SQLType: cardinal read GetSQLType write SetSQLType;
170    end;
171  
172    TIBXINPUTSQLDA = class;
# Line 188 | Line 192 | type
192    public
193      constructor Create(aStatement: TFB25Statement);
194      destructor Destroy; override;
195 +    function CanChangeMetaData: boolean; override;
196      function CheckStatementStatus(Request: TStatementStatus): boolean; override;
197      function ColumnsInUseCount: integer; override;
198      function GetTransaction: TFB25Transaction; virtual;
# Line 231 | Line 236 | type
236      constructor Create(aResults: TIBXOUTPUTSQLDA);
237      destructor Destroy; override;
238      {IResultSet}
239 <    function FetchNext: boolean;
239 >    function FetchNext: boolean; {fetch next record}
240 >    function FetchPrior: boolean; {fetch previous record}
241 >    function FetchFirst:boolean; {fetch first record}
242 >    function FetchLast: boolean; {fetch last record}
243 >    function FetchAbsolute(position: Integer): boolean; {fetch record by its absolute position in result set}
244 >    function FetchRelative(offset: Integer): boolean; {fetch record by position relative to current}
245      function GetCursorName: AnsiString;
246      function GetTransaction: ITransaction; override;
247      function IsEof: boolean;
248 +    function IsBof: boolean;
249      procedure Close;
250    end;
251  
# Line 253 | Line 264 | type
264    protected
265      procedure CheckHandle; override;
266      procedure GetDsqlInfo(info_request: byte; buffer: ISQLInfoResults); override;
267 <    procedure InternalPrepare; override;
267 >    function GetStatementIntf: IStatement; override;
268 >    procedure InternalPrepare(CursorName: AnsiString=''); override;
269      function InternalExecute(aTransaction: ITransaction): IResults; override;
270 <    function InternalOpenCursor(aTransaction: ITransaction): IResultSet; override;
270 >    function InternalOpenCursor(aTransaction: ITransaction; Scrollable: boolean): IResultSet; override;
271      procedure ProcessSQL(sql: AnsiString; GenerateParamNames: boolean; var processedSQL: AnsiString); override;
272      procedure FreeHandle; override;
273      procedure InternalClose(Force: boolean); override;
274    public
275      constructor Create(Attachment: TFB25Attachment; Transaction: ITransaction;
276 <      sql: AnsiString; aSQLDialect: integer);
276 >      sql: AnsiString; aSQLDialect: integer; CursorName: AnsiString='');
277      constructor CreateWithParameterNames(Attachment: TFB25Attachment;
278        Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer; GenerateParamNames: boolean;
279 <      CaseSensitiveParams: boolean=false);
279 >      CaseSensitiveParams: boolean=false; CursorName: AnsiString='');
280      destructor Destroy; override;
281      function FetchNext: boolean;
282  
# Line 383 | Line 395 | begin
395    Result := FXSQLVAR^.sqllen;
396   end;
397  
398 + function TIBXSQLVAR.GetSize: cardinal;
399 + begin
400 +  Result := FMetadataSize;
401 + end;
402 +
403 + function TIBXSQLVAR.GetAttachment: IAttachment;
404 + begin
405 +  Result := FStatement.GetAttachment;
406 + end;
407 +
408   function TIBXSQLVAR.GetArrayMetaData: IArrayMetaData;
409   begin
410    if GetSQLType <> SQL_ARRAY then
# Line 408 | Line 430 | begin
430    Result := FBlobMetaData;
431   end;
432  
433 < function TIBXSQLVAR.GetAsArray(Array_ID: TISC_QUAD): IArray;
433 > function TIBXSQLVAR.GetAsArray: IArray;
434   begin
435    if SQLType <> SQL_ARRAY then
436      IBError(ibxeInvalidDataConversion,[nil]);
# Line 417 | Line 439 | begin
439      Result := nil
440    else
441    begin
442 <    if FArray = nil then
443 <      FArray := TFB25Array.Create(FStatement.GetAttachment as TFB25Attachment,
442 >    if FArrayIntf = nil then
443 >      FArrayIntf := TFB25Array.Create(FStatement.GetAttachment as TFB25Attachment,
444                                    TIBXSQLDA(Parent).GetTransaction,
445 <                                  GetArrayMetaData,Array_ID);
446 <    Result := FArray;
445 >                                  GetArrayMetaData,PISC_QUAD(SQLData)^);
446 >    Result := FArrayIntf;
447    end;
448   end;
449  
# Line 456 | Line 478 | begin
478    FOwnsSQLData := true;
479    with FFirebird25ClientAPI, FXSQLVar^ do
480    begin
481 +    FMetadataSize := sqllen;
482      case sqltype and (not 1) of
483        SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP,
484        SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT, SQL_BOOLEAN,
# Line 481 | Line 504 | begin
504      else
505        sqlInd :=  nil;
506    end;
507 +  SaveMetaData;
508   end;
509  
510   procedure TIBXSQLVAR.SetIsNull(Value: Boolean);
# Line 567 | Line 591 | begin
591    end;
592   end;
593  
594 + function TIBXSQLVAR.GetDefaultTextSQLType: cardinal;
595 + begin
596 +  Result := SQL_TEXT;
597 + end;
598 +
599   constructor TIBXSQLVAR.Create(aParent: TIBXSQLDA; aIndex: integer);
600   begin
601    inherited Create(aParent,aIndex);
# Line 586 | Line 615 | procedure TIBXSQLVAR.RowChange;
615   begin
616    inherited RowChange;
617    FBlob := nil;
589  FArray := nil;
618   end;
619  
620  
# Line 615 | Line 643 | begin
643        FResults.Column[i].RowChange;
644   end;
645  
646 + function TResultSet.FetchPrior: boolean;
647 + begin
648 +  IBError(ibxeNoScrollableCursors,[]);
649 + end;
650 +
651 + function TResultSet.FetchFirst: boolean;
652 + begin
653 +  IBError(ibxeNoScrollableCursors,[]);
654 + end;
655 +
656 + function TResultSet.FetchLast: boolean;
657 + begin
658 +  IBError(ibxeNoScrollableCursors,[]);
659 + end;
660 +
661 + function TResultSet.FetchAbsolute(position: Integer): boolean;
662 + begin
663 +  IBError(ibxeNoScrollableCursors,[]);
664 + end;
665 +
666 + function TResultSet.FetchRelative(offset: Integer): boolean;
667 + begin
668 +  IBError(ibxeNoScrollableCursors,[]);
669 + end;
670 +
671   function TResultSet.GetCursorName: AnsiString;
672   begin
673    Result := FResults.FStatement.FCursor;
# Line 630 | Line 683 | begin
683    Result := FResults.FStatement.FEof;
684   end;
685  
686 + function TResultSet.IsBof: boolean;
687 + begin
688 +  Result := FResults.FStatement.FBof;
689 + end;
690 +
691   procedure TResultSet.Close;
692   begin
693    if FCursorSeqNo = FResults.FStatement.FCursorSeqNo then
# Line 738 | Line 796 | begin
796    inherited Destroy;
797   end;
798  
799 + function TIBXSQLDA.CanChangeMetaData: boolean;
800 + begin
801 +  Result := true;
802 + end;
803 +
804   function TIBXSQLDA.CheckStatementStatus(Request: TStatementStatus): boolean;
805   begin
806    Result := false;
# Line 917 | Line 980 | begin
980      IBDatabaseError;
981   end;
982  
983 < procedure TFB25Statement.InternalPrepare;
983 > function TFB25Statement.GetStatementIntf: IStatement;
984 > begin
985 >  Result := self;
986 > end;
987 >
988 > procedure TFB25Statement.InternalPrepare(CursorName: AnsiString);
989   var
990 +  GUID: TGUID;
991    RB: ISQLInfoResults;
992    TRHandle: TISC_TR_HANDLE;
993   begin
994    if FPrepared then
995      Exit;
996 +
997    if (FSQL = '') then
998      IBError(ibxeEmptyQuery, [nil]);
999 +
1000 +  FCursor := CursorName;
1001 +  if FCursor = '' then
1002 +  begin
1003 +    CreateGuid(GUID);
1004 +    FCursor := GUIDToString(GUID);
1005 +  end;
1006 +
1007    try
1008      CheckTransaction(FTransactionIntf);
1009      with FFirebird25ClientAPI do
# Line 944 | Line 1022 | begin
1022          Call(isc_dsql_prepare(StatusVector, @(TRHandle), @FHandle, 0,
1023                   PAnsiChar(FSQL), FSQLDialect, nil), True);
1024      end;
1025 +
1026      { After preparing the statement, query the stmt type and possibly
1027        create a FSQLRecord "holder" }
1028      { Get the type of the statement }
# Line 953 | Line 1032 | begin
1032      else
1033        FSQLStatementType := SQLUnknown;
1034  
1035 +    if FSQLStatementType = SQLSelect then
1036 +    with FFirebird25ClientAPI do
1037 +      Call(
1038 +        isc_dsql_set_cursor_name(StatusVector, @FHandle, PAnsiChar(FCursor), 0),
1039 +        True);
1040 +
1041      case FSQLStatementType of
1042        SQLGetSegment,
1043        SQLPutSegment,
# Line 980 | Line 1065 | begin
1065        if (FHandle <> nil) then
1066          FreeHandle;
1067        if E is EIBInterBaseError then
1068 <        raise EIBInterBaseError.Create(EIBInterBaseError(E).SQLCode,
1069 <                                       EIBInterBaseError(E).IBErrorCode,
985 <                                       EIBInterBaseError(E).Message +
986 <                                       sSQLErrorSeparator + FSQL)
987 <      else
988 <        raise;
1068 >        E.Message := E.Message + sSQLErrorSeparator + FSQL;
1069 >      raise;
1070      end;
1071    end;
1072    FPrepared := true;
# Line 1017 | Line 1098 | begin
1098    CheckHandle;
1099    if aTransaction <> FTransactionIntf then
1100      AddMonitor(aTransaction as TFB25Transaction);
1101 <  if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1101 >  if FStaleReferenceChecks and (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1102      IBError(ibxeInterfaceOutofDate,[nil]);
1103  
1104    try
# Line 1066 | Line 1147 | begin
1147    Inc(FChangeSeqNo);
1148   end;
1149  
1150 < function TFB25Statement.InternalOpenCursor(aTransaction: ITransaction
1151 <  ): IResultSet;
1150 > function TFB25Statement.InternalOpenCursor(aTransaction: ITransaction;
1151 >  Scrollable: boolean): IResultSet;
1152   var TRHandle: TISC_TR_HANDLE;
1072    GUID : TGUID;
1153   begin
1154    if FSQLStatementType <> SQLSelect then
1155     IBError(ibxeIsASelectStatement,[]);
1156  
1157 +  if Scrollable then
1158 +    IBError(ibxeNoScrollableCursors,[]);
1159 +
1160   CheckTransaction(aTransaction);
1161    if not FPrepared then
1162      InternalPrepare;
1163    CheckHandle;
1164    if aTransaction <> FTransactionIntf then
1165      AddMonitor(aTransaction as TFB25Transaction);
1166 <  if (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1166 >  if FStaleReferenceChecks and (FSQLParams.FTransactionSeqNo < (FTransactionIntf as TFB25transaction).TransactionSeqNo) then
1167      IBError(ibxeInterfaceOutofDate,[nil]);
1168  
1169   with FFirebird25ClientAPI do
# Line 1095 | Line 1178 | begin
1178                         SQLDialect,
1179                         FSQLParams.AsXSQLDA,
1180                         nil), True);
1098   if FCursor = '' then
1099   begin
1100     CreateGuid(GUID);
1101     FCursor := GUIDToString(GUID);
1102     Call(
1103       isc_dsql_set_cursor_name(StatusVector, @FHandle, PAnsiChar(FCursor), 0),
1104       True);
1105   end;
1181  
1182     if FCollectStatistics then
1183     begin
# Line 1177 | Line 1252 | begin
1252   end;
1253  
1254   constructor TFB25Statement.Create(Attachment: TFB25Attachment;
1255 <  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer);
1255 >  Transaction: ITransaction; sql: AnsiString; aSQLDialect: integer;
1256 >  CursorName: AnsiString);
1257   begin
1258    inherited Create(Attachment,Transaction,sql,aSQLDialect);
1259    FDBHandle := Attachment.Handle;
# Line 1185 | Line 1261 | begin
1261    OnDatabaseError := FFirebird25ClientAPI.IBDataBaseError;
1262    FSQLParams := TIBXINPUTSQLDA.Create(self);
1263    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1264 <  InternalPrepare;
1264 >  InternalPrepare(CursorName);
1265   end;
1266  
1267   constructor TFB25Statement.CreateWithParameterNames(
1268    Attachment: TFB25Attachment; Transaction: ITransaction; sql: AnsiString;
1269    aSQLDialect: integer; GenerateParamNames: boolean;
1270 <  CaseSensitiveParams: boolean);
1270 >  CaseSensitiveParams: boolean; CursorName: AnsiString);
1271   begin
1272    inherited CreateWithParameterNames(Attachment,Transaction,sql,aSQLDialect,GenerateParamNames);
1273    FDBHandle := Attachment.Handle;
# Line 1200 | Line 1276 | begin
1276    FSQLParams := TIBXINPUTSQLDA.Create(self);
1277    FSQLParams.CaseSensitiveParams := CaseSensitiveParams;
1278    FSQLRecord := TIBXOUTPUTSQLDA.Create(self);
1279 <  InternalPrepare;
1279 >  InternalPrepare(CursorName);
1280   end;
1281  
1282   destructor TFB25Statement.Destroy;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines