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

Comparing ibx/trunk/fbintf/client/FBSQLData.pas (file contents):
Revision 45 by tony, Tue Dec 6 10:33:46 2016 UTC vs.
Revision 291 by tony, Fri Apr 17 10:26:08 2020 UTC

# Line 60 | Line 60
60   {                                                                        }
61   {************************************************************************}
62   unit FBSQLData;
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 73 | Line 76 | unit FBSQLData;
76    methods are needed for SQL parameters only. The string getters and setters
77    are virtual as SQLVar and Array encodings of string data is different.}
78  
76 { $define ALLOWDIALECT3PARAMNAMES}
77
78 {$ifndef ALLOWDIALECT3PARAMNAMES}
79
80 { Note on SQL Dialects and SQL Parameter Names
81  --------------------------------------------
82
83  Even when dialect 3 quoted format parameter names are not supported, IBX still processes
84  parameter names case insensitive. This does result in some additional overhead
85  due to a call to "AnsiUpperCase". This can be avoided by undefining
86  "UseCaseInSensitiveParamName" below.
87
88  Note: do not define "UseCaseSensitiveParamName" when "ALLOWDIALECT3PARAMNAMES"
89  is defined. This will not give a useful result.
90 }
91 {$define UseCaseInSensitiveParamName}
92 {$endif}
79  
80   interface
81  
82   uses
83 <  Classes, SysUtils, IBExternals, IBHeader, IB,  FBActivityMonitor;
83 >  Classes, SysUtils, IBExternals, IBHeader, IB,  FBActivityMonitor, FBClientAPI;
84  
85   type
86  
# Line 102 | Line 88 | type
88  
89    TSQLDataItem = class(TFBInterfacedObject)
90    private
91 +     FFirebirdClientAPI: TFBClientAPI;
92       function AdjustScale(Value: Int64; aScale: Integer): Double;
93       function AdjustScaleToInt64(Value: Int64; aScale: Integer): Int64;
94       function AdjustScaleToCurrency(Value: Int64; aScale: Integer): Currency;
95 +     function GetTimestampFormatStr: AnsiString;
96 +     function GetDateFormatStr(IncludeTime: boolean): AnsiString;
97 +     function GetTimeFormatStr: AnsiString;
98       procedure SetAsInteger(AValue: Integer);
99    protected
100       function AdjustScaleFromCurrency(Value: Currency; aScale: Integer): Int64;
# Line 113 | Line 103 | type
103       function GetSQLDialect: integer; virtual; abstract;
104       procedure Changed; virtual;
105       procedure Changing; virtual;
106 <     procedure InternalSetAsString(Value: String); virtual;
107 <     function SQLData: PChar; virtual; abstract;
106 >     procedure InternalSetAsString(Value: AnsiString); virtual;
107 >     function SQLData: PByte; virtual; abstract;
108       function GetDataLength: cardinal; virtual; abstract;
109       function GetCodePage: TSystemCodePage; virtual; abstract;
110 <     function Transliterate(s: string; CodePage: TSystemCodePage): RawByteString;
110 >     function getCharSetID: cardinal; virtual; abstract;
111 >     function Transliterate(s: AnsiString; CodePage: TSystemCodePage): RawByteString;
112       procedure SetScale(aValue: integer); virtual;
113       procedure SetDataLength(len: cardinal); virtual;
114       procedure SetSQLType(aValue: cardinal); virtual;
115       property DataLength: cardinal read GetDataLength write SetDataLength;
116  
117    public
118 +     constructor Create(api: TFBClientAPI);
119       function GetSQLType: cardinal; virtual; abstract;
120 <     function GetSQLTypeName: string; overload;
121 <     class function GetSQLTypeName(SQLType: short): string; overload;
122 <     function GetName: string; virtual; abstract;
120 >     function GetSQLTypeName: AnsiString; overload;
121 >     class function GetSQLTypeName(SQLType: short): AnsiString; overload;
122 >     function GetStrDataLength: short;
123 >     function GetName: AnsiString; virtual; abstract;
124       function GetScale: integer; virtual; abstract;
125       function GetAsBoolean: boolean;
126       function GetAsCurrency: Currency;
# Line 139 | Line 132 | type
132       function GetAsPointer: Pointer;
133       function GetAsQuad: TISC_QUAD;
134       function GetAsShort: short;
135 <     function GetAsString: String; virtual;
135 >     function GetAsString: AnsiString; virtual;
136       function GetIsNull: Boolean; virtual;
137 <     function getIsNullable: boolean; virtual;
137 >     function GetIsNullable: boolean; virtual;
138       function GetAsVariant: Variant;
139       function GetModified: boolean; virtual;
140 +     function GetDateTimeStrLength(DateTimeFormat: TIBDateTimeFormats): integer;
141       procedure SetAsBoolean(AValue: boolean); virtual;
142       procedure SetAsCurrency(Value: Currency); virtual;
143       procedure SetAsInt64(Value: Int64); virtual;
# Line 156 | Line 150 | type
150       procedure SetAsPointer(Value: Pointer);
151       procedure SetAsQuad(Value: TISC_QUAD);
152       procedure SetAsShort(Value: short); virtual;
153 <     procedure SetAsString(Value: String); virtual;
153 >     procedure SetAsString(Value: AnsiString); virtual;
154       procedure SetAsVariant(Value: Variant);
155 +     procedure SetAsNumeric(Value: Int64; aScale: integer);
156       procedure SetIsNull(Value: Boolean); virtual;
157       procedure SetIsNullable(Value: Boolean); virtual;
158 <     procedure SetName(aValue: string); virtual;
158 >     procedure SetName(aValue: AnsiString); virtual;
159       property AsDate: TDateTime read GetAsDateTime write SetAsDate;
160       property AsBoolean:boolean read GetAsBoolean write SetAsBoolean;
161       property AsTime: TDateTime read GetAsDateTime write SetAsTime;
# Line 174 | Line 169 | type
169       property AsPointer: Pointer read GetAsPointer write SetAsPointer;
170       property AsQuad: TISC_QUAD read GetAsQuad write SetAsQuad;
171       property AsShort: short read GetAsShort write SetAsShort;
172 <     property AsString: String read GetAsString write SetAsString;
172 >     property AsString: AnsiString read GetAsString write SetAsString;
173       property AsVariant: Variant read GetAsVariant write SetAsVariant;
174       property Modified: Boolean read getModified;
175       property IsNull: Boolean read GetIsNull write SetIsNull;
# Line 191 | Line 186 | type
186  
187    TSQLDataArea = class
188    private
189 +    FCaseSensitiveParams: boolean;
190      function GetColumn(index: integer): TSQLVarData;
191      function GetCount: integer;
192    protected
193 <    FUniqueRelationName: string;
193 >    FUniqueRelationName: AnsiString;
194      FColumnList: array of TSQLVarData;
195      function GetStatement: IStatement; virtual; abstract;
196      function GetPrepareSeqNo: integer; virtual; abstract;
# Line 204 | Line 200 | type
200    public
201      procedure Initialize; virtual;
202      function IsInputDataArea: boolean; virtual; abstract; {Input to Database}
203 <    procedure PreprocessSQL(sSQL: string; GenerateParamNames: boolean;
204 <      var sProcessedSQL: string);
203 >    procedure PreprocessSQL(sSQL: AnsiString; GenerateParamNames: boolean;
204 >      var sProcessedSQL: AnsiString);
205      function ColumnsInUseCount: integer; virtual;
206 <    function ColumnByName(Idx: string): TSQLVarData;
206 >    function ColumnByName(Idx: AnsiString): TSQLVarData;
207      function CheckStatementStatus(Request: TStatementStatus): boolean; virtual; abstract;
208      procedure GetData(index: integer; var IsNull: boolean; var len: short;
209 <      var data: PChar); virtual;
209 >      var data: PByte); virtual;
210      procedure RowChange;
211      function StateChanged(var ChangeSeqNo: integer): boolean; virtual; abstract;
212 +    property CaseSensitiveParams: boolean read FCaseSensitiveParams
213 +                                            write FCaseSensitiveParams; {Only used when IsInputDataArea true}
214      property Count: integer read GetCount;
215      property Column[index: integer]: TSQLVarData read GetColumn;
216 <    property UniqueRelationName: string read FUniqueRelationName;
216 >    property UniqueRelationName: AnsiString read FUniqueRelationName;
217      property Statement: IStatement read GetStatement;
218      property PrepareSeqNo: integer read GetPrepareSeqNo;
219      property TransactionSeqNo: integer read GetTransactionSeqNo;
# Line 226 | Line 224 | type
224    TSQLVarData = class
225    private
226      FParent: TSQLDataArea;
227 <    FName: string;
227 >    FName: AnsiString;
228      FIndex: integer;
229      FModified: boolean;
230      FUniqueName: boolean;
231      FVarString: RawByteString;
232      function GetStatement: IStatement;
233 <    procedure SetName(AValue: string);
233 >    procedure SetName(AValue: AnsiString);
234    protected
235      function GetSQLType: cardinal; virtual; abstract;
236      function GetSubtype: integer; virtual; abstract;
237 <    function GetAliasName: string;  virtual; abstract;
238 <    function GetFieldName: string; virtual; abstract;
239 <    function GetOwnerName: string;  virtual; abstract;
240 <    function GetRelationName: string;  virtual; abstract;
237 >    function GetAliasName: AnsiString;  virtual; abstract;
238 >    function GetFieldName: AnsiString; virtual; abstract;
239 >    function GetOwnerName: AnsiString;  virtual; abstract;
240 >    function GetRelationName: AnsiString;  virtual; abstract;
241      function GetScale: integer; virtual; abstract;
242      function GetCharSetID: cardinal; virtual; abstract;
243      function GetCodePage: TSystemCodePage; virtual; abstract;
244      function GetIsNull: Boolean;   virtual; abstract;
245      function GetIsNullable: boolean; virtual; abstract;
246 <    function GetSQLData: PChar;  virtual; abstract;
246 >    function GetSQLData: PByte;  virtual; abstract;
247      function GetDataLength: cardinal; virtual; abstract;
248      procedure SetIsNull(Value: Boolean); virtual; abstract;
249      procedure SetIsNullable(Value: Boolean);  virtual; abstract;
250 <    procedure SetSQLData(AValue: PChar; len: cardinal); virtual; abstract;
250 >    procedure SetSQLData(AValue: PByte; len: cardinal); virtual; abstract;
251      procedure SetScale(aValue: integer); virtual; abstract;
252      procedure SetDataLength(len: cardinal); virtual; abstract;
253      procedure SetSQLType(aValue: cardinal); virtual; abstract;
254      procedure SetCharSetID(aValue: cardinal); virtual; abstract;
255    public
256      constructor Create(aParent: TSQLDataArea; aIndex: integer);
257 <    procedure SetString(aValue: string);
257 >    procedure SetString(aValue: AnsiString);
258      procedure Changed; virtual;
259      procedure RowChange; virtual;
260      function GetAsArray(Array_ID: TISC_QUAD): IArray; virtual; abstract;
# Line 267 | Line 265 | type
265      procedure Initialize; virtual;
266  
267    public
268 <    property AliasName: string read GetAliasName;
269 <    property FieldName: string read GetFieldName;
270 <    property OwnerName: string read GetOwnerName;
271 <    property RelationName: string read GetRelationName;
268 >    property AliasName: AnsiString read GetAliasName;
269 >    property FieldName: AnsiString read GetFieldName;
270 >    property OwnerName: AnsiString read GetOwnerName;
271 >    property RelationName: AnsiString read GetRelationName;
272      property Parent: TSQLDataArea read FParent;
273      property Index: integer read FIndex;
274 <    property Name: string read FName write SetName;
274 >    property Name: AnsiString read FName write SetName;
275      property CharSetID: cardinal read GetCharSetID write SetCharSetID;
276      property SQLType: cardinal read GetSQLType write SetSQLType;
277      property SQLSubtype: integer read GetSubtype;
278 <    property SQLData: PChar read GetSQLData;
278 >    property SQLData: PByte read GetSQLData;
279      property DataLength: cardinal read GetDataLength write SetDataLength;
280      property IsNull: Boolean read GetIsNull write SetIsNull;
281      property IsNullable: Boolean read GetIsNullable write SetIsNullable;
# Line 295 | Line 293 | type
293      FIBXSQLVAR: TSQLVarData;
294      FOwner: IUnknown;         {Keep reference to ensure Metadata/statement not discarded}
295      FPrepareSeqNo: integer;
298    FStatement: IStatement;
296      FChangeSeqNo: integer;
297    protected
298      procedure CheckActive; override;
299 <    function SQLData: PChar; override;
299 >    function SQLData: PByte; override;
300      function GetDataLength: cardinal; override;
301      function GetCodePage: TSystemCodePage; override;
302  
# Line 307 | Line 304 | type
304      constructor Create(aOwner: IUnknown; aIBXSQLVAR: TSQLVarData);
305      destructor Destroy; override;
306      function GetSQLDialect: integer; override;
310    property Statement: IStatement read FStatement;
307  
308    public
309      {IColumnMetaData}
310      function GetIndex: integer;
311      function GetSQLType: cardinal; override;
312      function getSubtype: integer;
313 <    function getRelationName: string;
314 <    function getOwnerName: string;
315 <    function getSQLName: string;    {Name of the column}
316 <    function getAliasName: string;  {Alias Name of column or Column Name if not alias}
317 <    function GetName: string; override;      {Disambiguated uppercase Field Name}
313 >    function getRelationName: AnsiString;
314 >    function getOwnerName: AnsiString;
315 >    function getSQLName: AnsiString;    {Name of the column}
316 >    function getAliasName: AnsiString;  {Alias Name of column or Column Name if not alias}
317 >    function GetName: AnsiString; override;      {Disambiguated uppercase Field Name}
318      function GetScale: integer; override;
319 <    function getCharSetID: cardinal;
319 >    function getCharSetID: cardinal; override;
320      function GetIsNullable: boolean; override;
321      function GetSize: cardinal;
322      function GetArrayMetaData: IArrayMetaData;
323      function GetBlobMetaData: IBlobMetaData;
324 <    property Name: string read GetName;
324 >    function GetStatement: IStatement;
325 >    function GetTransaction: ITransaction; virtual;
326 >    property Name: AnsiString read GetName;
327      property Size: cardinal read GetSize;
328      property CharSetID: cardinal read getCharSetID;
329      property SQLSubtype: integer read getSubtype;
330      property IsNullable: Boolean read GetIsNullable;
331 +  public
332 +    property Statement: IStatement read GetStatement;
333    end;
334  
335    { TIBSQLData }
336  
337    TIBSQLData = class(TColumnMetaData,ISQLData)
338 +  private
339 +    FTransaction: ITransaction;
340    protected
341      procedure CheckActive; override;
342    public
343 +    function GetTransaction: ITransaction; override;
344      function GetIsNull: Boolean; override;
345      function GetAsArray: IArray;
346      function GetAsBlob: IBlob; overload;
347      function GetAsBlob(BPB: IBPB): IBlob; overload;
348 <    function GetAsString: String; override;
348 >    function GetAsString: AnsiString; override;
349      property AsBlob: IBlob read GetAsBlob;
350   end;
351  
# Line 352 | Line 355 | type
355    protected
356      procedure CheckActive; override;
357      procedure Changed; override;
358 <    procedure InternalSetAsString(Value: String); override;
358 >    procedure InternalSetAsString(Value: AnsiString); override;
359      procedure SetScale(aValue: integer); override;
360      procedure SetDataLength(len: cardinal); override;
361      procedure SetSQLType(aValue: cardinal); override;
# Line 360 | Line 363 | type
363      procedure Clear;
364      function GetModified: boolean; override;
365      function GetAsPointer: Pointer;
366 <    procedure SetName(Value: string); override;
366 >    procedure SetName(Value: AnsiString); override;
367      procedure SetIsNull(Value: Boolean);  override;
368      procedure SetIsNullable(Value: Boolean); override;
369      procedure SetAsArray(anArray: IArray);
# Line 377 | Line 380 | type
380      procedure SetAsFloat(AValue: Float);
381      procedure SetAsPointer(AValue: Pointer);
382      procedure SetAsShort(AValue: Short);
383 <    procedure SetAsString(AValue: String); override;
383 >    procedure SetAsString(AValue: AnsiString); override;
384      procedure SetAsVariant(AValue: Variant);
385      procedure SetAsBlob(aValue: IBlob);
386      procedure SetAsQuad(AValue: TISC_QUAD);
# Line 400 | Line 403 | type
403      destructor Destroy; override;
404    public
405      {IMetaData}
406 <    function GetUniqueRelationName: string;
406 >    function GetUniqueRelationName: AnsiString;
407      function getCount: integer;
408      function getColumnMetaData(index: integer): IColumnMetaData;
409 <    function ByName(Idx: String): IColumnMetaData;
409 >    function ByName(Idx: AnsiString): IColumnMetaData;
410    end;
411  
412    { TSQLParams }
# Line 422 | Line 425 | type
425      {ISQLParams}
426      function getCount: integer;
427      function getSQLParam(index: integer): ISQLParam;
428 <    function ByName(Idx: String): ISQLParam ;
428 >    function ByName(Idx: AnsiString): ISQLParam ;
429      function GetModified: Boolean;
430 +    function GetHasCaseSensitiveParams: Boolean;
431    end;
432  
433    { TResults }
# Line 442 | Line 446 | type
446       constructor Create(aResults: TSQLDataArea);
447        {IResults}
448       function getCount: integer;
449 <     function ByName(Idx: String): ISQLData;
449 >     function ByName(Idx: AnsiString): ISQLData;
450       function getSQLData(index: integer): ISQLData;
451 <     procedure GetData(index: integer; var IsNull:boolean; var len: short; var data: PChar);
451 >     procedure GetData(index: integer; var IsNull:boolean; var len: short; var data: PByte);
452 >     function GetStatement: IStatement;
453       function GetTransaction: ITransaction; virtual;
454       procedure SetRetainInterfaces(aValue: boolean);
455   end;
456  
457   implementation
458  
459 < uses FBMessages, FBClientAPI, variants, IBUtils, FBTransaction;
459 > uses FBMessages, variants, IBUtils, FBTransaction, DateUtils;
460  
461   { TSQLDataArea }
462  
# Line 471 | Line 476 | procedure TSQLDataArea.SetUniqueRelation
476   var
477    i: Integer;
478    bUnique: Boolean;
479 <  RelationName: string;
479 >  RelationName: AnsiString;
480   begin
481    bUnique := True;
482    for i := 0 to ColumnsInUseCount - 1 do
# Line 502 | Line 507 | begin
507      Column[i].Initialize;
508   end;
509  
510 < procedure TSQLDataArea.PreprocessSQL(sSQL: string; GenerateParamNames: boolean;
511 <  var sProcessedSQL: string);
507 < var
508 <  cCurChar, cNextChar, cQuoteChar: Char;
509 <  sParamName: String;
510 <  j, i, iLenSQL, iSQLPos: Integer;
511 <  iCurState {$ifdef ALLOWDIALECT3PARAMNAMES}, iCurParamState {$endif}: Integer;
512 <  iParamSuffix: Integer;
513 <  slNames: TStrings;
514 <  StrBuffer: PChar;
515 <  found: boolean;
516 <
517 < const
518 <  DefaultState = 0;
519 <  CommentState = 1;
520 <  QuoteState = 2;
521 <  ParamState = 3;
522 < {$ifdef ALLOWDIALECT3PARAMNAMES}
523 <  ParamDefaultState = 0;
524 <  ParamQuoteState = 1;
525 <  {$endif}
510 > procedure TSQLDataArea.PreprocessSQL(sSQL: AnsiString; GenerateParamNames: boolean;
511 >  var sProcessedSQL: AnsiString);
512  
513 <  procedure AddToProcessedSQL(cChar: Char);
528 <  begin
529 <    StrBuffer[iSQLPos] := cChar;
530 <    Inc(iSQLPos);
531 <  end;
532 <
533 < begin
534 <  if not IsInputDataArea then
535 <    IBError(ibxeNotPermitted,[nil]);
513 > var slNames: TStrings;
514  
515 <  sParamName := '';
516 <  iLenSQL := Length(sSQL);
517 <  GetMem(StrBuffer,iLenSQL + 1);
518 <  slNames := TStringList.Create;
519 <  try
542 <    { Do some initializations of variables }
543 <    iParamSuffix := 0;
544 <    cQuoteChar := '''';
545 <    i := 1;
546 <    iSQLPos := 0;
547 <    iCurState := DefaultState;
548 <    {$ifdef ALLOWDIALECT3PARAMNAMES}
549 <    iCurParamState := ParamDefaultState;
550 <    {$endif}
551 <    { Now, traverse through the SQL string, character by character,
552 <     picking out the parameters and formatting correctly for InterBase }
553 <    while (i <= iLenSQL) do begin
554 <      { Get the current token and a look-ahead }
555 <      cCurChar := sSQL[i];
556 <      if i = iLenSQL then
557 <        cNextChar := #0
558 <      else
559 <        cNextChar := sSQL[i + 1];
560 <      { Now act based on the current state }
561 <      case iCurState of
562 <        DefaultState: begin
563 <          case cCurChar of
564 <            '''', '"': begin
565 <              cQuoteChar := cCurChar;
566 <              iCurState := QuoteState;
567 <            end;
568 <            '?', ':': begin
569 <              iCurState := ParamState;
570 <              AddToProcessedSQL('?');
571 <            end;
572 <            '/': if (cNextChar = '*') then begin
573 <              AddToProcessedSQL(cCurChar);
574 <              Inc(i);
575 <              iCurState := CommentState;
576 <            end;
577 <          end;
578 <        end;
579 <        CommentState: begin
580 <          if (cNextChar = #0) then
581 <            IBError(ibxeSQLParseError, [SEOFInComment])
582 <          else if (cCurChar = '*') then begin
583 <            if (cNextChar = '/') then
584 <              iCurState := DefaultState;
585 <          end;
586 <        end;
587 <        QuoteState: begin
588 <          if cNextChar = #0 then
589 <            IBError(ibxeSQLParseError, [SEOFInString])
590 <          else if (cCurChar = cQuoteChar) then begin
591 <            if (cNextChar = cQuoteChar) then begin
592 <              AddToProcessedSQL(cCurChar);
593 <              Inc(i);
594 <            end else
595 <              iCurState := DefaultState;
596 <          end;
597 <        end;
598 <        ParamState:
599 <        begin
600 <          { collect the name of the parameter }
601 <          {$ifdef ALLOWDIALECT3PARAMNAMES}
602 <          if iCurParamState = ParamDefaultState then
603 <          begin
604 <            if cCurChar = '"' then
605 <              iCurParamState := ParamQuoteState
606 <            else
607 <            {$endif}
608 <            if (cCurChar in ['A'..'Z', 'a'..'z', '0'..'9', '_', '$']) then
609 <                sParamName := sParamName + cCurChar
610 <            else if GenerateParamNames then
611 <            begin
612 <              sParamName := 'IBXParam' + IntToStr(iParamSuffix); {do not localize}
613 <              Inc(iParamSuffix);
614 <              iCurState := DefaultState;
615 <              slNames.AddObject(sParamName,self); //Note local convention
616 <                                                  //add pointer to self to mark entry
617 <              sParamName := '';
618 <            end
619 <            else
620 <              IBError(ibxeSQLParseError, [SParamNameExpected]);
621 <          {$ifdef ALLOWDIALECT3PARAMNAMES}
622 <          end
623 <          else begin
624 <            { determine if Quoted parameter name is finished }
625 <            if cCurChar = '"' then
626 <            begin
627 <              Inc(i);
628 <              slNames.Add(sParamName);
629 <              SParamName := '';
630 <              iCurParamState := ParamDefaultState;
631 <              iCurState := DefaultState;
632 <            end
633 <            else
634 <              sParamName := sParamName + cCurChar
635 <          end;
636 <          {$endif}
637 <          { determine if the unquoted parameter name is finished }
638 <          if {$ifdef ALLOWDIALECT3PARAMNAMES}(iCurParamState <> ParamQuoteState) and {$endif}
639 <            (iCurState <> DefaultState) then
640 <          begin
641 <            if not (cNextChar in ['A'..'Z', 'a'..'z',
642 <                                  '0'..'9', '_', '$']) then begin
643 <              Inc(i);
644 <              iCurState := DefaultState;
645 <              slNames.Add(sParamName);
646 <              sParamName := '';
647 <            end;
648 <          end;
649 <        end;
650 <      end;
651 <      if (iCurState <> ParamState) and (i <= iLenSQL) then
652 <        AddToProcessedSQL(sSQL[i]);
653 <      Inc(i);
654 <    end;
655 <    AddToProcessedSQL(#0);
656 <    sProcessedSQL := strpas(StrBuffer);
515 >  procedure SetColumnNames(slNames: TStrings);
516 >  var i, j: integer;
517 >      found: boolean;
518 >  begin
519 >    found := false;
520      SetCount(slNames.Count);
521      for i := 0 to slNames.Count - 1 do
522      begin
# Line 674 | Line 537 | begin
537          Column[i].UniqueName := not found;
538        end;
539      end;
540 +  end;
541 +
542 + begin
543 +  if not IsInputDataArea then
544 +    IBError(ibxeNotPermitted,[nil]);
545 +
546 +  slNames := TStringList.Create;
547 +  try
548 +    sProcessedSQL := TSQLParamProcessor.Execute(sSQL,GenerateParamNames,slNames);
549 +    SetColumnNames(slNames);
550    finally
551      slNames.Free;
679    FreeMem(StrBuffer);
552    end;
553   end;
554  
# Line 685 | Line 557 | begin
557    Result := Count;
558   end;
559  
560 < function TSQLDataArea.ColumnByName(Idx: string): TSQLVarData;
560 > function TSQLDataArea.ColumnByName(Idx: AnsiString): TSQLVarData;
561   var
562 <  s: String;
562 >  s: AnsiString;
563    i: Integer;
564   begin
565 <  {$ifdef UseCaseInSensitiveParamName}
566 <   s := AnsiUpperCase(Idx);
567 <  {$else}
565 >  if not IsInputDataArea or not CaseSensitiveParams then
566 >   s := AnsiUpperCase(Idx)
567 >  else
568     s := Idx;
569 <  {$endif}
569 >
570    for i := 0 to Count - 1 do
571      if Column[i].Name = s then
572      begin
# Line 705 | Line 577 | begin
577   end;
578  
579   procedure TSQLDataArea.GetData(index: integer; var IsNull: boolean;
580 <  var len: short; var data: PChar);
580 >  var len: short; var data: PByte);
581   begin
582    //Do Nothing
583   end;
# Line 724 | Line 596 | begin
596    Result := FParent.Statement;
597   end;
598  
599 < procedure TSQLVarData.SetName(AValue: string);
599 > procedure TSQLVarData.SetName(AValue: AnsiString);
600   begin
601 <  if FName = AValue then Exit;
730 <  {$ifdef UseCaseInSensitiveParamName}
731 <  if Parent.IsInputDataArea then
601 >  if not Parent.IsInputDataArea or not Parent.CaseSensitiveParams then
602      FName := AnsiUpperCase(AValue)
603    else
734  {$endif}
604      FName := AValue;
605   end;
606  
# Line 743 | Line 612 | begin
612    FUniqueName := true;
613   end;
614  
615 < procedure TSQLVarData.SetString(aValue: string);
615 > procedure TSQLVarData.SetString(aValue: AnsiString);
616   begin
617    {we take full advantage here of reference counted strings. When setting a string
618     value, a reference is kept in FVarString and a pointer to it placed in the
619 <   SQLVar. This avoids string copies. Note that PChar is guaranteed to point to
619 >   SQLVar. This avoids string copies. Note that PAnsiChar is guaranteed to point to
620     a zero byte when the string is empty, neatly avoiding a nil pointer error.}
621  
622    FVarString := aValue;
623    SQLType := SQL_TEXT;
624 <  SetSQLData(PChar(FVarString),Length(aValue));
624 >  Scale := 0;
625 >  SetSQLData(PByte(PAnsiChar(FVarString)),Length(aValue));
626   end;
627  
628   procedure TSQLVarData.Changed;
# Line 768 | Line 638 | end;
638  
639   procedure TSQLVarData.Initialize;
640  
641 <  function FindVarByName(idx: string; limit: integer): TSQLVarData;
641 >  function FindVarByName(idx: AnsiString; limit: integer): TSQLVarData;
642    var
643      k: integer;
644    begin
# Line 783 | Line 653 | procedure TSQLVarData.Initialize;
653  
654   var
655    j, j_len: Integer;
656 <  st: String;
657 <  sBaseName: string;
656 >  st: AnsiString;
657 >  sBaseName: AnsiString;
658   begin
659    RowChange;
660  
# Line 871 | Line 741 | function TSQLDataItem.AdjustScaleToCurre
741   var
742    Scaling : Int64;
743    i : Integer;
744 <  FractionText, PadText, CurrText: string;
744 >  FractionText, PadText, CurrText: AnsiString;
745   begin
746    Result := 0;
747    Scaling := 1;
# Line 890 | Line 760 | begin
760        FractionText := IntToStr(abs(Value mod Scaling));
761        for i := Length(FractionText) to -aScale -1 do
762          PadText := '0' + PadText;
763 +      {$IF declared(DefaultFormatSettings)}
764 +      with DefaultFormatSettings do
765 +      {$ELSE}
766 +      {$IF declared(FormatSettings)}
767 +      with FormatSettings do
768 +      {$IFEND}
769 +      {$IFEND}
770        if Value < 0 then
771 <        CurrText := '-' + IntToStr(Abs(Value div Scaling)) + DefaultFormatSettings.DecimalSeparator + PadText + FractionText
771 >        CurrText := '-' + IntToStr(Abs(Value div Scaling)) + DecimalSeparator + PadText + FractionText
772        else
773 <        CurrText := IntToStr(Abs(Value div Scaling)) + DefaultFormatSettings.DecimalSeparator + PadText + FractionText;
773 >        CurrText := IntToStr(Abs(Value div Scaling)) + DecimalSeparator + PadText + FractionText;
774        try
775          result := StrToCurr(CurrText);
776        except
# Line 905 | Line 782 | begin
782        result := Value;
783   end;
784  
785 + function TSQLDataItem.GetDateFormatStr(IncludeTime: boolean): AnsiString;
786 + begin
787 +  {$IF declared(DefaultFormatSettings)}
788 +  with DefaultFormatSettings do
789 +  {$ELSE}
790 +  {$IF declared(FormatSettings)}
791 +  with FormatSettings do
792 +  {$IFEND}
793 +  {$IFEND}
794 +  case GetSQLDialect of
795 +    1:
796 +      if IncludeTime then
797 +        result := ShortDateFormat + ' ' + LongTimeFormat
798 +      else
799 +        result := ShortDateFormat;
800 +    3:
801 +      result := ShortDateFormat;
802 +  end;
803 + end;
804 +
805 + function TSQLDataItem.GetTimeFormatStr: AnsiString;
806 + begin
807 +  {$IF declared(DefaultFormatSettings)}
808 +  with DefaultFormatSettings do
809 +  {$ELSE}
810 +  {$IF declared(FormatSettings)}
811 +  with FormatSettings do
812 +  {$IFEND}
813 +  {$IFEND}
814 +    Result := LongTimeFormat;
815 + end;
816 +
817 + function TSQLDataItem.GetTimestampFormatStr: AnsiString;
818 + begin
819 +  {$IF declared(DefaultFormatSettings)}
820 +  with DefaultFormatSettings do
821 +  {$ELSE}
822 +  {$IF declared(FormatSettings)}
823 +  with FormatSettings do
824 +  {$IFEND}
825 +  {$IFEND}
826 +    Result := ShortDateFormat + ' ' +  LongTimeFormat + '.zzz';
827 + end;
828 +
829   procedure TSQLDataItem.SetAsInteger(AValue: Integer);
830   begin
831    SetAsLong(aValue);
# Line 975 | Line 896 | begin
896    //Do nothing by default
897   end;
898  
899 < procedure TSQLDataItem.InternalSetAsString(Value: String);
899 > procedure TSQLDataItem.InternalSetAsString(Value: AnsiString);
900   begin
901    //Do nothing by default
902   end;
903  
904 < function TSQLDataItem.Transliterate(s: string; CodePage: TSystemCodePage
904 > function TSQLDataItem.Transliterate(s: AnsiString; CodePage: TSystemCodePage
905    ): RawByteString;
906   begin
907    Result := s;
# Line 1003 | Line 924 | begin
924     //Do nothing by default
925   end;
926  
927 < function TSQLDataItem.GetSQLTypeName: string;
927 > constructor TSQLDataItem.Create(api: TFBClientAPI);
928 > begin
929 >  inherited Create;
930 >  FFirebirdClientAPI := api;
931 > end;
932 >
933 > function TSQLDataItem.GetSQLTypeName: AnsiString;
934   begin
935    Result := GetSQLTypeName(GetSQLType);
936   end;
937  
938 < class function TSQLDataItem.GetSQLTypeName(SQLType: short): string;
938 > class function TSQLDataItem.GetSQLTypeName(SQLType: short): AnsiString;
939   begin
940    Result := 'Unknown';
941    case SQLType of
# Line 1029 | Line 956 | begin
956    end;
957   end;
958  
959 + function TSQLDataItem.GetStrDataLength: short;
960 + begin
961 +  with FFirebirdClientAPI do
962 +  if SQLType = SQL_VARYING then
963 +    Result := DecodeInteger(SQLData, 2)
964 +  else
965 +    Result := DataLength;
966 + end;
967 +
968   function TSQLDataItem.GetAsBoolean: boolean;
969   begin
970    CheckActive;
# Line 1109 | Line 1045 | begin
1045    CheckActive;
1046    result := 0;
1047    if not IsNull then
1048 <    with FirebirdClientAPI do
1048 >    with FFirebirdClientAPI do
1049      case SQLType of
1050        SQL_TEXT, SQL_VARYING: begin
1051          try
# Line 1239 | Line 1175 | begin
1175   end;
1176  
1177  
1178 < function TSQLDataItem.GetAsString: String;
1178 > function TSQLDataItem.GetAsString: AnsiString;
1179   var
1180 <  sz: PChar;
1180 >  sz: PByte;
1181    str_len: Integer;
1182    rs: RawByteString;
1183   begin
# Line 1249 | Line 1185 | begin
1185    result := '';
1186    { Check null, if so return a default string }
1187    if not IsNull then
1188 <  with FirebirdClientAPI do
1188 >  with FFirebirdClientAPI do
1189      case SQLType of
1190        SQL_BOOLEAN:
1191          if AsBoolean then
# Line 1266 | Line 1202 | begin
1202            str_len := DecodeInteger(SQLData, 2);
1203            Inc(sz, 2);
1204          end;
1205 <        SetString(rs, sz, str_len);
1205 >        SetString(rs, PAnsiChar(sz), str_len);
1206          SetCodePage(rs,GetCodePage,false);
1207 <        Result := Trim(rs);
1207 >        if (SQLType = SQL_TEXT) and (GetCharSetID <> 1) then
1208 >          Result := TrimRight(rs)
1209 >        else
1210 >          Result := rs
1211        end;
1212        SQL_TYPE_DATE:
1213 <        case GetSQLDialect of
1275 <          1 : result := DateTimeToStr(AsDateTime);
1276 <          3 : result := DateToStr(AsDateTime);
1277 <        end;
1213 >        result := FormatDateTime(GetDateFormatStr(TimeOf(AsDateTime)<>0),AsDateTime);
1214        SQL_TYPE_TIME :
1215 <        result := TimeToStr(AsDateTime);
1215 >        result := FormatDateTime(GetTimeFormatStr,AsDateTime);
1216        SQL_TIMESTAMP:
1217 <        result := FormatDateTime(FormatSettings.ShortDateFormat + ' ' +
1282 <                            FormatSettings.LongTimeFormat+'.zzz',AsDateTime);
1217 >        result := FormatDateTime(GetTimestampFormatStr,AsDateTime);
1218        SQL_SHORT, SQL_LONG:
1219          if Scale = 0 then
1220            result := IntToStr(AsLong)
# Line 1307 | Line 1242 | begin
1242    Result := false;
1243   end;
1244  
1245 < function TSQLDataItem.getIsNullable: boolean;
1245 > function TSQLDataItem.GetIsNullable: boolean;
1246   begin
1247    CheckActive;
1248    Result := false;
# Line 1355 | Line 1290 | begin
1290    Result := false;
1291   end;
1292  
1293 + function TSQLDataItem.GetDateTimeStrLength(DateTimeFormat: TIBDateTimeFormats
1294 +  ): integer;
1295 + begin
1296 +  case DateTimeFormat of
1297 +  dfTimestamp:
1298 +    Result := Length(GetTimestampFormatStr);
1299 +  dfDateTime:
1300 +    Result := Length(GetDateFormatStr(true));
1301 +  dfTime:
1302 +    Result := Length(GetTimeFormatStr);
1303 +  else
1304 +    Result := 0;
1305 +  end;
1306 + end;
1307 +
1308  
1309   procedure TSQLDataItem.SetIsNull(Value: Boolean);
1310   begin
# Line 1366 | Line 1316 | begin
1316    //ignore unless overridden
1317   end;
1318  
1319 < procedure TSQLDataItem.SetName(aValue: string);
1319 > procedure TSQLDataItem.SetName(aValue: AnsiString);
1320   begin
1321    //ignore unless overridden
1322   end;
# Line 1418 | Line 1368 | begin
1368  
1369    SQLType := SQL_TYPE_DATE;
1370    DataLength := SizeOf(ISC_DATE);
1371 <  with FirebirdClientAPI do
1371 >  with FFirebirdClientAPI do
1372      SQLEncodeDate(Value,SQLData);
1373    Changed;
1374   end;
# Line 1438 | Line 1388 | begin
1388  
1389    SQLType := SQL_TYPE_TIME;
1390    DataLength := SizeOf(ISC_TIME);
1391 <  with FirebirdClientAPI do
1391 >  with FFirebirdClientAPI do
1392      SQLEncodeTime(Value,SQLData);
1393    Changed;
1394   end;
# Line 1451 | Line 1401 | begin
1401  
1402    Changing;
1403    SQLType := SQL_TIMESTAMP;
1404 <  DataLength := SizeOf(TISC_QUAD);
1405 <  with FirebirdClientAPI do
1404 >  DataLength := SizeOf(ISC_TIME) + sizeof(ISC_DATE);
1405 >  with FFirebirdClientAPI do
1406      SQLEncodeDateTime(Value,SQLData);
1407    Changed;
1408   end;
# Line 1542 | Line 1492 | begin
1492    Changed;
1493   end;
1494  
1495 < procedure TSQLDataItem.SetAsString(Value: String);
1495 > procedure TSQLDataItem.SetAsString(Value: AnsiString);
1496   begin
1497    InternalSetAsString(Value);
1498   end;
# Line 1577 | Line 1527 | begin
1527    end;
1528   end;
1529  
1530 + procedure TSQLDataItem.SetAsNumeric(Value: Int64; aScale: integer);
1531 + begin
1532 +  CheckActive;
1533 +  Changing;
1534 +  if IsNullable then
1535 +    IsNull := False;
1536 +
1537 +  SQLType := SQL_INT64;
1538 +  Scale := aScale;
1539 +  DataLength := SizeOf(Int64);
1540 +  PInt64(SQLData)^ := Value;
1541 +  Changed;
1542 + end;
1543 +
1544   procedure TSQLDataItem.SetAsBoolean(AValue: boolean);
1545   begin
1546    CheckActive;
# Line 1607 | Line 1571 | begin
1571      IBError(ibxeStatementNotPrepared, [nil]);
1572   end;
1573  
1574 < function TColumnMetaData.SQLData: PChar;
1574 > function TColumnMetaData.SQLData: PByte;
1575   begin
1576    Result := FIBXSQLVAR.SQLData;
1577   end;
# Line 1624 | Line 1588 | end;
1588  
1589   constructor TColumnMetaData.Create(aOwner: IUnknown; aIBXSQLVAR: TSQLVarData);
1590   begin
1591 <  inherited Create;
1591 >  inherited Create(aIBXSQLVAR.GetStatement.GetAttachment.getFirebirdAPI as TFBClientAPI);
1592    FIBXSQLVAR := aIBXSQLVAR;
1593    FOwner := aOwner;
1594    FPrepareSeqNo := FIBXSQLVAR.Parent.PrepareSeqNo;
# Line 1660 | Line 1624 | begin
1624    result := FIBXSQLVAR.SQLSubtype;
1625   end;
1626  
1627 < function TColumnMetaData.getRelationName: string;
1627 > function TColumnMetaData.getRelationName: AnsiString;
1628   begin
1629    CheckActive;
1630     result :=  FIBXSQLVAR.RelationName;
1631   end;
1632  
1633 < function TColumnMetaData.getOwnerName: string;
1633 > function TColumnMetaData.getOwnerName: AnsiString;
1634   begin
1635    CheckActive;
1636    result :=  FIBXSQLVAR.OwnerName;
1637   end;
1638  
1639 < function TColumnMetaData.getSQLName: string;
1639 > function TColumnMetaData.getSQLName: AnsiString;
1640   begin
1641    CheckActive;
1642    result :=  FIBXSQLVAR.FieldName;
1643   end;
1644  
1645 < function TColumnMetaData.getAliasName: string;
1645 > function TColumnMetaData.getAliasName: AnsiString;
1646   begin
1647    CheckActive;
1648    result := FIBXSQLVAR.AliasName;
1649   end;
1650  
1651 < function TColumnMetaData.GetName: string;
1651 > function TColumnMetaData.GetName: AnsiString;
1652   begin
1653    CheckActive;
1654    Result := FIBXSQLVAR. Name;
# Line 1726 | Line 1690 | begin
1690    result := FIBXSQLVAR.GetBlobMetaData;
1691   end;
1692  
1693 + function TColumnMetaData.GetStatement: IStatement;
1694 + begin
1695 +  Result := FIBXSQLVAR.GetStatement;
1696 + end;
1697 +
1698 + function TColumnMetaData.GetTransaction: ITransaction;
1699 + begin
1700 +  Result := GetStatement.GetTransaction;
1701 + end;
1702 +
1703   { TIBSQLData }
1704  
1705   procedure TIBSQLData.CheckActive;
# Line 1745 | Line 1719 | begin
1719      IBError(ibxeBOF,[nil]);
1720   end;
1721  
1722 + function TIBSQLData.GetTransaction: ITransaction;
1723 + begin
1724 +  if FTransaction = nil then
1725 +    Result := inherited GetTransaction
1726 +  else
1727 +    Result := FTransaction;
1728 + end;
1729 +
1730   function TIBSQLData.GetIsNull: Boolean;
1731   begin
1732    CheckActive;
# Line 1769 | Line 1751 | begin
1751    result := FIBXSQLVAR.GetAsBlob(AsQuad,BPB);
1752   end;
1753  
1754 < function TIBSQLData.GetAsString: String;
1754 > function TIBSQLData.GetAsString: AnsiString;
1755   begin
1756    CheckActive;
1757    Result := '';
# Line 1777 | Line 1759 | begin
1759    if not IsNull then
1760    case SQLType of
1761      SQL_ARRAY:
1762 <      result := '(Array)'; {do not localize}
1762 >      result := SArray;
1763      SQL_BLOB:
1764 <      Result := Trim(FIBXSQLVAR.GetAsBlob(AsQuad,nil).GetAsString);
1764 >      Result := FIBXSQLVAR.GetAsBlob(AsQuad,nil).GetAsString;
1765      else
1766        Result := inherited GetAsString;
1767    end;
# Line 1787 | Line 1769 | end;
1769  
1770   { TSQLParam }
1771  
1772 < procedure TSQLParam.InternalSetAsString(Value: String);
1772 > procedure TSQLParam.InternalSetAsString(Value: AnsiString);
1773 >
1774 > procedure DoSetString;
1775 > begin
1776 >  Changing;
1777 >  FIBXSQLVar.SetString(Transliterate(Value,GetCodePage));
1778 >  Changed;
1779 > end;
1780 >
1781   var b: IBlob;
1782 +    dt: TDateTime;
1783 +    CurrValue: Currency;
1784 +    FloatValue: single;
1785   begin
1786    CheckActive;
1787    if IsNullable then
1788      IsNull := False;
1789    case SQLTYPE of
1790    SQL_BOOLEAN:
1791 <    if CompareText(Value,STrue) = 0 then
1791 >    if AnsiCompareText(Value,STrue) = 0 then
1792        AsBoolean := true
1793      else
1794 <    if CompareText(Value,SFalse) = 0 then
1794 >    if AnsiCompareText(Value,SFalse) = 0 then
1795        AsBoolean := false
1796      else
1797        IBError(ibxeInvalidDataConversion,[nil]);
# Line 1814 | Line 1807 | begin
1807  
1808    SQL_VARYING,
1809    SQL_TEXT:
1810 <    begin
1818 <      Changing;
1819 <      FIBXSQLVar.SetString(Transliterate(Value,GetCodePage));
1820 <      Changed;
1821 <    end;
1810 >    DoSetString;
1811  
1812      SQL_SHORT,
1813      SQL_LONG,
1814      SQL_INT64:
1815 <      SetAsInt64(StrToInt(Value));
1815 >      if TryStrToCurr(Value,CurrValue) then
1816 >        SetAsNumeric(AdjustScaleFromCurrency(CurrValue,GetScale),GetScale)
1817 >      else
1818 >        DoSetString;
1819  
1820      SQL_D_FLOAT,
1821      SQL_DOUBLE,
1822      SQL_FLOAT:
1823 <      SetAsDouble(StrToFloat(Value));
1823 >      if TryStrToFloat(Value,FloatValue) then
1824 >        SetAsDouble(FloatValue)
1825 >      else
1826 >        DoSetString;
1827  
1828      SQL_TIMESTAMP:
1829 <      SetAsDateTime(StrToDateTime(Value));
1829 >      if TryStrToDateTime(Value,dt) then
1830 >        SetAsDateTime(dt)
1831 >      else
1832 >        DoSetString;
1833  
1834      SQL_TYPE_DATE:
1835 <      SetAsDate(StrToDateTime(Value));
1835 >      if TryStrToDateTime(Value,dt) then
1836 >        SetAsDate(dt)
1837 >      else
1838 >        DoSetString;
1839  
1840      SQL_TYPE_TIME:
1841 <      SetAsTime(StrToDateTime(Value));
1841 >      if TryStrToDateTime(Value,dt) then
1842 >        SetAsTime(dt)
1843 >      else
1844 >        DoSetString;
1845  
1846      else
1847        IBError(ibxeInvalidDataConversion,[nil]);
# Line 1891 | Line 1895 | begin
1895    Result := inherited GetAsPointer;
1896   end;
1897  
1898 < procedure TSQLParam.SetName(Value: string);
1898 > procedure TSQLParam.SetName(Value: AnsiString);
1899   begin
1900    CheckActive;
1901    FIBXSQLVAR.Name := Value;
# Line 2197 | Line 2201 | begin
2201    end;
2202   end;
2203  
2204 < procedure TSQLParam.SetAsString(AValue: String);
2204 > procedure TSQLParam.SetAsString(AValue: AnsiString);
2205   var i: integer;
2206      OldSQLVar: TSQLVarData;
2207   begin
# Line 2310 | Line 2314 | begin
2314    inherited Destroy;
2315   end;
2316  
2317 < function TMetaData.GetUniqueRelationName: string;
2317 > function TMetaData.GetUniqueRelationName: AnsiString;
2318   begin
2319    CheckActive;
2320    Result := FMetaData.UniqueRelationName;
# Line 2338 | Line 2342 | begin
2342    end;
2343   end;
2344  
2345 < function TMetaData.ByName(Idx: String): IColumnMetaData;
2345 > function TMetaData.ByName(Idx: AnsiString): IColumnMetaData;
2346   var aIBXSQLVAR: TSQLVarData;
2347   begin
2348    CheckActive;
# Line 2398 | Line 2402 | begin
2402    end;
2403   end;
2404  
2405 < function TSQLParams.ByName(Idx: String): ISQLParam;
2405 > function TSQLParams.ByName(Idx: AnsiString): ISQLParam;
2406   var aIBXSQLVAR: TSQLVarData;
2407   begin
2408    CheckActive;
# Line 2423 | Line 2427 | begin
2427      end;
2428   end;
2429  
2430 + function TSQLParams.GetHasCaseSensitiveParams: Boolean;
2431 + begin
2432 +  Result := FSQLParams.CaseSensitiveParams;
2433 + end;
2434 +
2435   { TResults }
2436  
2437   procedure TResults.CheckActive;
# Line 2441 | Line 2450 | begin
2450   end;
2451  
2452   function TResults.GetISQLData(aIBXSQLVAR: TSQLVarData): ISQLData;
2453 + var col: TIBSQLData;
2454   begin
2455    if (aIBXSQLVAR.Index < 0) or (aIBXSQLVAR.Index >= getCount) then
2456      IBError(ibxeInvalidColumnIndex,[nil]);
2457  
2458    if not HasInterface(aIBXSQLVAR.Index) then
2459      AddInterface(aIBXSQLVAR.Index, TIBSQLData.Create(self,aIBXSQLVAR));
2460 <  Result := TIBSQLData(GetInterface(aIBXSQLVAR.Index));
2460 >  col := TIBSQLData(GetInterface(aIBXSQLVAR.Index));
2461 >  col.FTransaction := GetTransaction;
2462 >  Result := col;
2463   end;
2464  
2465   constructor TResults.Create(aResults: TSQLDataArea);
# Line 2466 | Line 2478 | begin
2478    Result := FResults.Count;
2479   end;
2480  
2481 < function TResults.ByName(Idx: String): ISQLData;
2481 > function TResults.ByName(Idx: AnsiString): ISQLData;
2482   var col: TSQLVarData;
2483   begin
2484    Result := nil;
# Line 2498 | Line 2510 | begin
2510   end;
2511  
2512   procedure TResults.GetData(index: integer; var IsNull: boolean; var len: short;
2513 <  var data: PChar);
2513 >  var data: PByte);
2514   begin
2515    CheckActive;
2516    FResults.GetData(index,IsNull, len,data);
2517   end;
2518  
2519 + function TResults.GetStatement: IStatement;
2520 + begin
2521 +  Result := FStatement;
2522 + end;
2523 +
2524   function TResults.GetTransaction: ITransaction;
2525   begin
2526    Result := FStatement.GetTransaction;
# Line 2514 | Line 2531 | begin
2531    RetainInterfaces := aValue;
2532   end;
2533  
2517
2534   end.
2535  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines