zeoslib  UNKNOWN
 All Files
ZDbcResultSet.pas
Go to the documentation of this file.
1 {*********************************************************}
2 { }
3 { Zeos Database Objects }
4 { Abstract Database Connectivity Classes }
5 { }
6 { Originally written by Sergey Seroukhov }
7 { }
8 {*********************************************************}
9 
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
12 { }
13 { License Agreement: }
14 { }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
20 { }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
39 { }
40 { }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
45 { }
46 { http://www.sourceforge.net/projects/zeoslib. }
47 { }
48 { }
49 { Zeos Development Group. }
50 {********************************************************@}
51 
52 unit ZDbcResultSet;
53 
54 interface
55 
56 {$I ZDbc.inc}
57 
58 uses
59 {$IFDEF MSWINDOWS}
60  Windows,
61 {$ENDIF}
62 {$IFDEF FPC}
63  {$IFDEF WIN32}
64  Comobj,
65  {$ENDIF}
66 {$ENDIF}
67  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,
68  ZDbcIntfs, ZClasses, ZCollections, ZSysUtils, ZCompatibility, ZVariant;
69 
70 {$IFDEF FPC}
71  {$HINTS OFF} //suppress not used params
72 {$ENDIF}
73 type
74  {** Implements Abstract ResultSet. }
75  TZAbstractResultSet = class(TZCodePagedObject, IZResultSet)
76  private
77  FTemp: String;
78  FRowNo: Integer;
79  FLastRowNo: Integer;
80  FMaxRows: Integer;
81  FClosed: Boolean;
82  FFetchDirection: TZFetchDirection;
83  FFetchSize: Integer;
84  FResultSetType: TZResultSetType;
85  FResultSetConcurrency: TZResultSetConcurrency;
86  FPostUpdates: TZPostUpdatesMode;
87  FLocateUpdates: TZLocateUpdatesMode;
88  FColumnsInfo: TObjectList;
89  FMetadata: TContainedObject;
90  FStatement: IZStatement;
91  protected
92  LastWasNull: Boolean;
93 
94  function InternalGetString(ColumnIndex: Integer): RawByteString; virtual;
95 
96  procedure RaiseUnsupportedException;
97  procedure RaiseForwardOnlyException;
98  procedure RaiseReadOnlyException;
99  procedure CheckClosed;
100  procedure CheckColumnConvertion(ColumnIndex: Integer; ResultType: TZSQLType);
101  procedure CheckBlobColumn(ColumnIndex: Integer);
102  procedure Open; virtual;
103  function GetColumnIndex(const ColumnName: string): Integer;
104  property RowNo: Integer read FRowNo write FRowNo;
105  property LastRowNo: Integer read FLastRowNo write FLastRowNo;
106  property MaxRows: Integer read FMaxRows write FMaxRows;
107  property Closed: Boolean read FClosed write FClosed;
108  property FetchDirection: TZFetchDirection
109  read FFetchDirection write FFetchDirection;
110  property FetchSize: Integer read FFetchSize write FFetchSize;
111  property ResultSetType: TZResultSetType
112  read FResultSetType write FResultSetType;
113  property ResultSetConcurrency: TZResultSetConcurrency
114  read FResultSetConcurrency write FResultSetConcurrency;
115  property Statement: IZStatement read FStatement;
116  property Metadata: TContainedObject read FMetadata write FMetadata;
117 
118  public
119  constructor Create(Statement: IZStatement; SQL: string;
120  Metadata: TContainedObject; ConSettings: PZConSettings);
121  destructor Destroy; override;
122 
123  procedure SetType(Value: TZResultSetType);
124  procedure SetConcurrency(Value: TZResultSetConcurrency);
125 
126  function Next: Boolean; virtual;
127  procedure Close; virtual;
128  function WasNull: Boolean; virtual;
129 
130  //======================================================================
131  // Methods for accessing results by column index
132  //======================================================================
133 
134  function IsNull(ColumnIndex: Integer): Boolean; virtual;
135  function GetPChar(ColumnIndex: Integer): PChar; virtual;
136  function GetString(ColumnIndex: Integer): String; virtual;
137  function GetBinaryString(ColumnIndex: Integer): RawByteString;
138  function GetUnicodeString(ColumnIndex: Integer): WideString; virtual;
139  function GetBoolean(ColumnIndex: Integer): Boolean; virtual;
140  function GetByte(ColumnIndex: Integer): Byte; virtual;
141  function GetShort(ColumnIndex: Integer): SmallInt; virtual;
142  function GetInt(ColumnIndex: Integer): Integer; virtual;
143  function GetLong(ColumnIndex: Integer): Int64; virtual;
144  function GetFloat(ColumnIndex: Integer): Single; virtual;
145  function GetDouble(ColumnIndex: Integer): Double; virtual;
146  function GetBigDecimal(ColumnIndex: Integer): Extended; virtual;
147  function GetBytes(ColumnIndex: Integer): TByteDynArray; virtual;
148  function GetDate(ColumnIndex: Integer): TDateTime; virtual;
149  function GetTime(ColumnIndex: Integer): TDateTime; virtual;
150  function GetTimestamp(ColumnIndex: Integer): TDateTime; virtual;
151  function GetAsciiStream(ColumnIndex: Integer): TStream; virtual;
152  function GetUnicodeStream(ColumnIndex: Integer): TStream; virtual;
153  function GetBinaryStream(ColumnIndex: Integer): TStream; virtual;
154  function GetBlob(ColumnIndex: Integer): IZBlob; virtual;
155  function GetDataSet(ColumnIndex: Integer): IZDataSet; virtual;
156  function GetValue(ColumnIndex: Integer): TZVariant; virtual;
157  function GetDefaultExpression(ColumnIndex: Integer): String; virtual;
158 
159  //======================================================================
160  // Methods for accessing results by column name
161  //======================================================================
162 
163  function IsNullByName(const ColumnName: string): Boolean; virtual;
164  function GetPCharByName(const ColumnName: string): PChar; virtual;
165  function GetStringByName(const ColumnName: string): String; virtual;
166  function GetBinaryStringByName(const ColumnName: string): RawByteString;
167  function GetUnicodeStringByName(const ColumnName: string): WideString; virtual;
168  function GetBooleanByName(const ColumnName: string): Boolean; virtual;
169  function GetByteByName(const ColumnName: string): Byte; virtual;
170  function GetShortByName(const ColumnName: string): SmallInt; virtual;
171  function GetIntByName(const ColumnName: string): Integer; virtual;
172  function GetLongByName(const ColumnName: string): Int64; virtual;
173  function GetFloatByName(const ColumnName: string): Single; virtual;
174  function GetDoubleByName(const ColumnName: string): Double; virtual;
175  function GetBigDecimalByName(const ColumnName: string): Extended; virtual;
176  function GetBytesByName(const ColumnName: string): TByteDynArray; virtual;
177  function GetDateByName(const ColumnName: string): TDateTime; virtual;
178  function GetTimeByName(const ColumnName: string): TDateTime; virtual;
179  function GetTimestampByName(const ColumnName: string): TDateTime; virtual;
180  function GetAsciiStreamByName(const ColumnName: string): TStream; virtual;
181  function GetUnicodeStreamByName(const ColumnName: string): TStream; virtual;
182  function GetBinaryStreamByName(const ColumnName: string): TStream; virtual;
183  function GetBlobByName(const ColumnName: string): IZBlob; virtual;
184  function GetDataSetByName(const ColumnName: String): IZDataSet; virtual;
185  function GetValueByName(const ColumnName: string): TZVariant; virtual;
186 
187  //=====================================================================
188  // Advanced features:
189  //=====================================================================
190 
191  function GetWarnings: EZSQLWarning; virtual;
192  procedure ClearWarnings; virtual;
193 
194  function GetCursorName: AnsiString; virtual;
195  function GetMetaData: IZResultSetMetaData; virtual;
196  function FindColumn(const ColumnName: string): Integer; virtual;
197 
198  //---------------------------------------------------------------------
199  // Traversal/Positioning
200  //---------------------------------------------------------------------
201 
202  function IsBeforeFirst: Boolean; virtual;
203  function IsAfterLast: Boolean; virtual;
204  function IsFirst: Boolean; virtual;
205  function IsLast: Boolean; virtual;
206  procedure BeforeFirst; virtual;
207  procedure AfterLast; virtual;
208  function First: Boolean; virtual;
209  function Last: Boolean; virtual;
210  function GetRow: Integer; virtual;
211  function MoveAbsolute(Row: Integer): Boolean; virtual;
212  function MoveRelative(Rows: Integer): Boolean; virtual;
213  function Previous: Boolean; virtual;
214 
215  //---------------------------------------------------------------------
216  // Properties
217  //---------------------------------------------------------------------
218 
219  procedure SetFetchDirection(Direction: TZFetchDirection); virtual;
220  function GetFetchDirection: TZFetchDirection; virtual;
221 
222  procedure SetFetchSize(Rows: Integer); virtual;
223  function GetFetchSize: Integer; virtual;
224 
225  function GetType: TZResultSetType; virtual;
226  function GetConcurrency: TZResultSetConcurrency; virtual;
227 
228  function GetPostUpdates: TZPostUpdatesMode;
229  function GetLocateUpdates: TZLocateUpdatesMode;
230 
231  //---------------------------------------------------------------------
232  // Updates
233  //---------------------------------------------------------------------
234 
235  function RowUpdated: Boolean; virtual;
236  function RowInserted: Boolean; virtual;
237  function RowDeleted: Boolean; virtual;
238 
239  procedure UpdateNull(ColumnIndex: Integer); virtual;
240  procedure UpdateBoolean(ColumnIndex: Integer; Value: Boolean); virtual;
241  procedure UpdateByte(ColumnIndex: Integer; Value: ShortInt); virtual;
242  procedure UpdateShort(ColumnIndex: Integer; Value: SmallInt); virtual;
243  procedure UpdateInt(ColumnIndex: Integer; Value: Integer); virtual;
244  procedure UpdateLong(ColumnIndex: Integer; Value: Int64); virtual;
245  procedure UpdateFloat(ColumnIndex: Integer; Value: Single); virtual;
246  procedure UpdateDouble(ColumnIndex: Integer; Value: Double); virtual;
247  procedure UpdateBigDecimal(ColumnIndex: Integer; Value: Extended); virtual;
248  procedure UpdatePChar(ColumnIndex: Integer; Value: PChar); virtual;
249  procedure UpdateString(ColumnIndex: Integer; const Value: String); virtual;
250  procedure UpdateBinaryString(ColumnIndex: Integer; const Value: RawByteString);
251  procedure UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString); virtual;
252  procedure UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray); virtual;
253  procedure UpdateDate(ColumnIndex: Integer; Value: TDateTime); virtual;
254  procedure UpdateTime(ColumnIndex: Integer; Value: TDateTime); virtual;
255  procedure UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime); virtual;
256  procedure UpdateAsciiStream(ColumnIndex: Integer; Value: TStream); virtual;
257  procedure UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream); virtual;
258  procedure UpdateBinaryStream(ColumnIndex: Integer; Value: TStream); virtual;
259  procedure UpdateDataSet(ColumnIndex: Integer; Value: IZDataSet); virtual;
260  procedure UpdateValue(ColumnIndex: Integer; const Value: TZVariant); virtual;
261  procedure UpdateDefaultExpression(ColumnIndex: Integer; const Value: string); virtual;
262 
263  //======================================================================
264  // Methods for accessing results by column name
265  //======================================================================
266 
267  procedure UpdateNullByName(const ColumnName: string); virtual;
268  procedure UpdateBooleanByName(const ColumnName: string; Value: Boolean); virtual;
269  procedure UpdateByteByName(const ColumnName: string; Value: ShortInt); virtual;
270  procedure UpdateShortByName(const ColumnName: string; Value: SmallInt); virtual;
271  procedure UpdateIntByName(const ColumnName: string; Value: Integer); virtual;
272  procedure UpdateLongByName(const ColumnName: string; Value: Int64); virtual;
273  procedure UpdateFloatByName(const ColumnName: string; Value: Single); virtual;
274  procedure UpdateDoubleByName(const ColumnName: string; Value: Double); virtual;
275  procedure UpdateBigDecimalByName(const ColumnName: string; Value: Extended); virtual;
276  procedure UpdatePCharByName(const ColumnName: string; Value: PChar); virtual;
277  procedure UpdateStringByName(const ColumnName: string; const Value: String); virtual;
278  procedure UpdateBinaryStringByName(const ColumnName: string; const Value: RawByteString);
279  procedure UpdateUnicodeStringByName(const ColumnName: string; const Value: WideString); virtual;
280  procedure UpdateBytesByName(const ColumnName: string; const Value: TByteDynArray); virtual;
281  procedure UpdateDateByName(const ColumnName: string; Value: TDateTime); virtual;
282  procedure UpdateTimeByName(const ColumnName: string; Value: TDateTime); virtual;
283  procedure UpdateTimestampByName(const ColumnName: string; Value: TDateTime); virtual;
284  procedure UpdateAsciiStreamByName(const ColumnName: string; Value: TStream); virtual;
285  procedure UpdateUnicodeStreamByName(const ColumnName: string; Value: TStream); virtual;
286  procedure UpdateBinaryStreamByName(const ColumnName: string; Value: TStream); virtual;
287  procedure UpdateDataSetByName(const ColumnName: string; Value: IZDataSet); virtual;
288  procedure UpdateValueByName(const ColumnName: string; const Value: TZVariant); virtual;
289 
290  procedure InsertRow; virtual;
291  procedure UpdateRow; virtual;
292  procedure DeleteRow; virtual;
293  procedure RefreshRow; virtual;
294  procedure CancelRowUpdates; virtual;
295  procedure MoveToInsertRow; virtual;
296  procedure MoveToCurrentRow; virtual;
297 
298  function CompareRows(Row1, Row2: Integer; const ColumnIndices: TIntegerDynArray;
299  const ColumnDirs: TBooleanDynArray): Integer; virtual;
300 
301  function GetStatement: IZStatement; virtual;
302 
303  function GetConSettings: PZConsettings;
304  property ColumnsInfo: TObjectList read FColumnsInfo write FColumnsInfo;
305  end;
306 
307  {** Implements external or internal blob wrapper object. }
308  TZAbstractBlob = class(TInterfacedObject, IZBlob)
309  private
310  FBlobData: Pointer;
311  FBlobSize: Integer;
312  FUpdated: Boolean;
313  protected
314  FConnection: IZConnection;
315  FDecoded: Boolean;
316  property BlobData: Pointer read FBlobData write FBlobData;
317  property BlobSize: Integer read FBlobSize write FBlobSize;
318  property Updated: Boolean read FUpdated write FUpdated;
319  public
320  constructor CreateWithStream(Stream: TStream; Connection: IZConnection = nil;
321  Decoded: Boolean = False);
322  constructor CreateWithData(Data: Pointer; Size: Integer;
323  Connection: IZConnection = nil; Decoded: Boolean = False);
324  destructor Destroy; override;
325 
326  function WasDecoded: Boolean;
327  function Connection: IZConnection;
328  function IsEmpty: Boolean; virtual;
329  function IsUpdated: Boolean; virtual;
330  function Length: LongInt; virtual;
331 
332  function GetString: RawByteString; virtual;
333  procedure SetString(const Value: RawByteString); virtual;
334  function GetUnicodeString: WideString; virtual;
335  procedure SetUnicodeString(const Value: WideString); virtual;
336  function GetBytes: TByteDynArray; virtual;
337  procedure SetBytes(const Value: TByteDynArray); virtual;
338  function GetUnicodeStream: TStream; virtual;
339  function GetStream: TStream; virtual;
340  procedure SetStream(Value: TStream; Decoded: Boolean = False); virtual;
341  function GetBuffer: Pointer;
342  procedure SetBuffer(Buffer: Pointer; Length: Integer);
343 
344  procedure Clear; virtual;
345  function Clone: IZBlob; virtual;
346  end;
347 
348 implementation
349 
350 uses ZMessages, ZDbcUtils, ZDbcResultSetMetadata, ZEncoding
351  {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}, AnsiStrings{$ENDIF};
352 
353 { TZAbstractResultSet }
354 
355 {**
356  Creates this object and assignes the main properties.
357  @param Statement an SQL statement object.
358  @param SQL an SQL query string.
359  @param Metadata a resultset metadata object.
360 }
361 constructor TZAbstractResultSet.Create(Statement: IZStatement; SQL: string;
362  Metadata: TContainedObject; ConSettings: PZConSettings);
363 var
364  DatabaseMetadata: IZDatabaseMetadata;
365 begin
366  Self.ConSettings := ConSettings;
367  LastWasNull := True;
368  FRowNo := 0;
369  FLastRowNo := 0;
370  FClosed := True;
371 
372  if Statement = nil then
373  begin
374  FResultSetType := rtForwardOnly;
375  FResultSetConcurrency := rcReadOnly;
376  FPostUpdates := poColumnsAll;
377  FLocateUpdates := loWhereAll;
378  FMaxRows := 0;
379  end
380  else
381  begin
382  FFetchDirection := Statement.GetFetchDirection;
383  FFetchSize := Statement.GetFetchSize;
384  FResultSetType := Statement.GetResultSetType;
385  FResultSetConcurrency := Statement.GetResultSetConcurrency;
386  FPostUpdates := Statement.GetPostUpdates;
387  FLocateUpdates := Statement.GetLocateUpdates;
388  FStatement := Statement;
389  FMaxRows := Statement.GetMaxRows;
390  end;
391 
392  if Metadata = nil then
393  begin
394  if Statement <> nil then
395  DatabaseMetadata := GetStatement.GetConnection.GetMetadata
396  else
397  DatabaseMetadata := nil;
398  FMetadata := TZAbstractResultSetMetadata.Create(DatabaseMetadata, SQL, Self);
399  end
400  else
401  FMetadata := Metadata;
402 
403  FColumnsInfo := TObjectList.Create(True); //Free the MemoryLeaks of TZColumnInfo
404 end;
405 
406 {**
407  Destroys this object and cleanups the memory.
408 }
409 destructor TZAbstractResultSet.Destroy;
410 begin
411  if not FClosed then
412  Close;
413 
414  if FMetadata <> nil then
415  FMetadata.Free;
416  FMetadata := nil;
417  FStatement := nil;
418 
419  FColumnsInfo.Free;
420  inherited Destroy;
421 end;
422 
423 function TZAbstractResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;
424 begin
425 {$IFNDEF DISABLE_CHECKING}
426  CheckColumnConvertion(ColumnIndex, stString);
427 {$ENDIF}
428  Result := '';
429 end;
430 
431 {**
432  Raises unsupported operation exception.
433 }
434 procedure TZAbstractResultSet.RaiseUnsupportedException;
435 begin
436  raise EZSQLException.Create(SUnsupportedOperation);
437 end;
438 
439 {**
440  Raises operation is not allowed in FORWARD ONLY mode exception.
441 }
442 procedure TZAbstractResultSet.RaiseForwardOnlyException;
443 begin
444  raise EZSQLException.Create(SOperationIsNotAllowed1);
445 end;
446 
447 {**
448  Raises operation is not allowed in READ ONLY mode exception.
449 }
450 procedure TZAbstractResultSet.RaiseReadOnlyException;
451 begin
452  raise EZSQLException.Create(SOperationIsNotAllowed2);
453 end;
454 
455 {**
456  Checks if result set is open and operation is allowed.
457 }
458 procedure TZAbstractResultSet.CheckClosed;
459 begin
460  if FClosed then
461  raise EZSQLException.Create(SOperationIsNotAllowed4);
462 end;
463 
464 {**
465  Checks is the column convertion from one type to another type allowed.
466  @param ColumnIndex an index of column.
467  @param ResultType a requested data type.
468 }
469 procedure TZAbstractResultSet.CheckColumnConvertion(ColumnIndex: Integer;
470  ResultType: TZSQLType);
471 var
472  InitialType: TZSQLType;
473  Metadata: TZAbstractResultSetMetadata;
474 begin
475  CheckClosed;
476  Metadata := TZAbstractResultSetMetadata(FMetadata);
477  if (Metadata = nil) or (ColumnIndex <= 0)
478  or (ColumnIndex > Metadata.GetColumnCount) then
479  begin
480  raise EZSQLException.Create(
481  Format(SColumnIsNotAccessable, [ColumnIndex]));
482  end;
483 
484  InitialType := Metadata.GetColumnType(ColumnIndex);
485  if not CheckConvertion(InitialType, ResultType) then
486  begin
487  raise EZSQLException.Create(Format(SConvertionIsNotPossible, [ColumnIndex,
488  DefineColumnTypeName(InitialType), DefineColumnTypeName(ResultType)]));
489  end;
490 end;
491 
492 {**
493  Checks for blob expected column.
494  @param ColumnIndex an index of column.
495 }
496 procedure TZAbstractResultSet.CheckBlobColumn(ColumnIndex: Integer);
497 var
498  InitialType: TZSQLType;
499  Metadata: TZAbstractResultSetMetadata;
500 begin
501  CheckClosed;
502  Metadata := TZAbstractResultSetMetadata(FMetadata);
503  if (Metadata = nil) or (ColumnIndex <= 0)
504  or (ColumnIndex > Metadata.GetColumnCount) then
505  begin
506  raise EZSQLException.Create(
507  Format(SColumnIsNotAccessable, [ColumnIndex]));
508  end;
509 
510  InitialType := Metadata.GetColumnType(ColumnIndex);
511  if not (InitialType in [stAsciiStream, stBinaryStream, stUnicodeStream]) then
512  begin
513  raise EZSQLException.Create(
514  Format(SCanNotAccessBlobRecord,
515  [ColumnIndex, DefineColumnTypeName(InitialType)]));
516  end;
517 end;
518 
519 {**
520  Set the concurrency mode of this <code>ResultSet</code> object.
521  The concurrency used is determined by the
522  <code>Statement</code> object that created the result set.
523 
524  @param the concurrency type, either <code>CONCUR_READ_ONLY</code>
525  or <code>CONCUR_UPDATABLE</code>
526 }
527 procedure TZAbstractResultSet.SetConcurrency(Value: TZResultSetConcurrency);
528 begin
529  ResultSetConcurrency := Value;
530 end;
531 
532 {**
533  Set the type of this <code>ResultSet</code> object.
534  The type is determined by the <code>Statement</code> object
535  that created the result set.
536 
537  @param <code>TYPE_FORWARD_ONLY</code>,
538  <code>TYPE_SCROLL_INSENSITIVE</code>,
539  or <code>TYPE_SCROLL_SENSITIVE</code>
540 }
541 procedure TZAbstractResultSet.SetType(Value: TZResultSetType);
542 begin
543  ResultSetType := Value;
544 end;
545 
546 {**
547  Opens this recordset.
548 }
549 procedure TZAbstractResultSet.Open;
550 begin
551  FClosed := False;
552 end;
553 
554 {**
555  Releases this <code>ResultSet</code> object's database and
556  JDBC resources immediately instead of waiting for
557  this to happen when it is automatically closed.
558 
559  <P><B>Note:</B> A <code>ResultSet</code> object
560  is automatically closed by the
561  <code>Statement</code> object that generated it when
562  that <code>Statement</code> object is closed,
563  re-executed, or is used to retrieve the next result from a
564  sequence of multiple results. A <code>ResultSet</code> object
565  is also automatically closed when it is garbage collected.
566 }
567 procedure TZAbstractResultSet.Close;
568 var
569  I: integer;
570  FColumnInfo: TZColumnInfo;
571 begin
572  LastWasNull := True;
573  FRowNo := 0;
574  FLastRowNo := 0;
575  FClosed := True;
576  for I := FColumnsInfo.Count - 1 downto 0 do
577  begin
578  FColumnInfo:=TZColumnInfo(FColumnsInfo.Extract(FColumnsInfo.Items[I]));
579  FColumnInfo.Free;
580  end;
581  FColumnsInfo.Clear;
582  FStatement := nil;
583 end;
584 
585 {**
586  Reports whether
587  the last column read had a value of SQL <code>NULL</code>.
588  Note that you must first call one of the <code>getXXX</code> methods
589  on a column to try to read its value and then call
590  the method <code>wasNull</code> to see if the value read was
591  SQL <code>NULL</code>.
592 
593  @return <code>true</code> if the last column value read was SQL
594  <code>NULL</code> and <code>false</code> otherwise
595 }
596 function TZAbstractResultSet.WasNull: Boolean;
597 begin
598  Result := LastWasNull;
599 end;
600 
601 //======================================================================
602 // Methods for accessing results by column index
603 //======================================================================
604 
605 {**
606  Indicates if the value of the designated column in the current row
607  of this <code>ResultSet</code> object is Null.
608 
609  @param columnIndex the first column is 1, the second is 2, ...
610  @return if the value is SQL <code>NULL</code>, the
611  value returned is <code>true</code>. <code>false</code> otherwise.
612 }
613 function TZAbstractResultSet.IsNull(ColumnIndex: Integer): Boolean;
614 begin
615  Result := True;
616 end;
617 
618 {**
619  Gets the value of the designated column in the current row
620  of this <code>ResultSet</code> object as
621  a <code>PAnsiChar</code> in the Delphi programming language.
622 
623  @param columnIndex the first column is 1, the second is 2, ...
624  @return the column value; if the value is SQL <code>NULL</code>, the
625  value returned is <code>null</code>
626 }
627 
628 function TZAbstractResultSet.GetPChar(ColumnIndex: Integer): PChar;
629 begin
630  FTemp := GetString(ColumnIndex);
631  Result := PChar(FTemp);
632 end;
633 
634 {**
635  Gets the value of the designated column in the current row
636  of this <code>ResultSet</code> object as
637  a <code>String</code> in the Java programming language.
638 
639  @param columnIndex the first column is 1, the second is 2, ...
640  @return the column value; if the value is SQL <code>NULL</code>, the
641  value returned is <code>null</code>
642 }
643 function TZAbstractResultSet.GetString(ColumnIndex: Integer): String;
644 begin
645  Result := ZDbcString(InternalGetString(ColumnIndex));
646 end;
647 
648 {**
649  Gets the value of the designated column in the current row
650  of this <code>ResultSet</code> object as
651  a <code>String</code> in the Java programming language.
652 
653  @param columnIndex the first column is 1, the second is 2, ...
654  @return the column value; if the value is SQL <code>NULL</code>, the
655  value returned is <code>null</code>
656 }
657 function TZAbstractResultSet.GetBinaryString(ColumnIndex: Integer): RawByteString;
658 begin
659  Result := InternalGetString(ColumnIndex);
660 end;
661 
662 {**
663  Gets the value of the designated column in the current row
664  of this <code>ResultSet</code> object as
665  a <code>WideString</code> in the Delphi programming language.
666 
667  @param columnIndex the first column is 1, the second is 2, ...
668  @return the column value; if the value is SQL <code>NULL</code>, the
669  value returned is <code>null</code>
670 }
671 function TZAbstractResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;
672 begin
673 {$IFNDEF DISABLE_CHECKING}
674  CheckColumnConvertion(ColumnIndex, stUnicodeString);
675 {$ENDIF}
676  Result := ZDbcUnicodeString(InternalGetString(ColumnIndex));
677 end;
678 
679 {**
680  Gets the value of the designated column in the current row
681  of this <code>ResultSet</code> object as
682  a <code>boolean</code> in the Java programming language.
683 
684  @param columnIndex the first column is 1, the second is 2, ...
685  @return the column value; if the value is SQL <code>NULL</code>, the
686  value returned is <code>false</code>
687 }
688 function TZAbstractResultSet.GetBoolean(ColumnIndex: Integer): Boolean;
689 begin
690 {$IFNDEF DISABLE_CHECKING}
691  CheckColumnConvertion(ColumnIndex, stBoolean);
692 {$ENDIF}
693  Result := False;
694 end;
695 
696 {**
697  Gets the value of the designated column in the current row
698  of this <code>ResultSet</code> object as
699  a <code>byte</code> in the Java programming language.
700 
701  @param columnIndex the first column is 1, the second is 2, ...
702  @return the column value; if the value is SQL <code>NULL</code>, the
703  value returned is <code>0</code>
704 }
705 function TZAbstractResultSet.GetByte(ColumnIndex: Integer): Byte;
706 begin
707 {$IFNDEF DISABLE_CHECKING}
708  CheckColumnConvertion(ColumnIndex, stByte);
709 {$ENDIF}
710  Result := 0;
711 end;
712 
713 {**
714  Gets the value of the designated column in the current row
715  of this <code>ResultSet</code> object as
716  a <code>short</code> in the Java programming language.
717 
718  @param columnIndex the first column is 1, the second is 2, ...
719  @return the column value; if the value is SQL <code>NULL</code>, the
720  value returned is <code>0</code>
721 }
722 function TZAbstractResultSet.GetShort(ColumnIndex: Integer): SmallInt;
723 begin
724 {$IFNDEF DISABLE_CHECKING}
725  CheckColumnConvertion(ColumnIndex, stShort);
726 {$ENDIF}
727  Result := 0;
728 end;
729 
730 {**
731  Gets the value of the designated column in the current row
732  of this <code>ResultSet</code> object as
733  an <code>int</code> in the Java programming language.
734 
735  @param columnIndex the first column is 1, the second is 2, ...
736  @return the column value; if the value is SQL <code>NULL</code>, the
737  value returned is <code>0</code>
738 }
739 function TZAbstractResultSet.GetInt(ColumnIndex: Integer): Integer;
740 begin
741 {$IFNDEF DISABLE_CHECKING}
742  CheckColumnConvertion(ColumnIndex, stInteger);
743 {$ENDIF}
744  Result := 0;
745 end;
746 
747 {**
748  Gets the value of the designated column in the current row
749  of this <code>ResultSet</code> object as
750  a <code>long</code> in the Java programming language.
751 
752  @param columnIndex the first column is 1, the second is 2, ...
753  @return the column value; if the value is SQL <code>NULL</code>, the
754  value returned is <code>0</code>
755 }
756 function TZAbstractResultSet.GetLong(ColumnIndex: Integer): Int64;
757 begin
758 {$IFNDEF DISABLE_CHECKING}
759  CheckColumnConvertion(ColumnIndex, stLong);
760 {$ENDIF}
761  Result := 0;
762 end;
763 
764 {**
765  Gets the value of the designated column in the current row
766  of this <code>ResultSet</code> object as
767  a <code>float</code> in the Java programming language.
768 
769  @param columnIndex the first column is 1, the second is 2, ...
770  @return the column value; if the value is SQL <code>NULL</code>, the
771  value returned is <code>0</code>
772 }
773 function TZAbstractResultSet.GetFloat(ColumnIndex: Integer): Single;
774 begin
775 {$IFNDEF DISABLE_CHECKING}
776  CheckColumnConvertion(ColumnIndex, stFloat);
777 {$ENDIF}
778  Result := 0;
779 end;
780 
781 {**
782  Gets the value of the designated column in the current row
783  of this <code>ResultSet</code> object as
784  a <code>double</code> in the Java programming language.
785 
786  @param columnIndex the first column is 1, the second is 2, ...
787  @return the column value; if the value is SQL <code>NULL</code>, the
788  value returned is <code>0</code>
789 }
790 function TZAbstractResultSet.GetDouble(ColumnIndex: Integer): Double;
791 begin
792 {$IFNDEF DISABLE_CHECKING}
793  CheckColumnConvertion(ColumnIndex, stDouble);
794 {$ENDIF}
795  Result := 0;
796 end;
797 
798 {**
799  Gets the value of the designated column in the current row
800  of this <code>ResultSet</code> object as
801  a <code>java.sql.BigDecimal</code> in the Java programming language.
802 
803  @param columnIndex the first column is 1, the second is 2, ...
804  @param scale the number of digits to the right of the decimal point
805  @return the column value; if the value is SQL <code>NULL</code>, the
806  value returned is <code>null</code>
807 }
808 function TZAbstractResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;
809 begin
810 {$IFNDEF DISABLE_CHECKING}
811  CheckColumnConvertion(ColumnIndex, stBigDecimal);
812 {$ENDIF}
813  Result := 0;
814 end;
815 
816 {**
817  Gets the value of the designated column in the current row
818  of this <code>ResultSet</code> object as
819  a <code>byte</code> array in the Java programming language.
820  The bytes represent the raw values returned by the driver.
821 
822  @param columnIndex the first column is 1, the second is 2, ...
823  @return the column value; if the value is SQL <code>NULL</code>, the
824  value returned is <code>null</code>
825 }
826 function TZAbstractResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;
827 begin
828 {$IFNDEF DISABLE_CHECKING}
829  CheckColumnConvertion(ColumnIndex, stBytes);
830 {$ENDIF}
831  Result := nil;
832 end;
833 
834 {**
835  Gets the value of the designated column in the current row
836  of this <code>ResultSet</code> object as
837  a <code>java.sql.Date</code> object in the Java programming language.
838 
839  @param columnIndex the first column is 1, the second is 2, ...
840  @return the column value; if the value is SQL <code>NULL</code>, the
841  value returned is <code>null</code>
842 }
843 function TZAbstractResultSet.GetDate(ColumnIndex: Integer): TDateTime;
844 begin
845 {$IFNDEF DISABLE_CHECKING}
846  CheckColumnConvertion(ColumnIndex, stDate);
847 {$ENDIF}
848  Result := 0;
849 end;
850 
851 {**
852  Gets the value of the designated column in the current row
853  of this <code>ResultSet</code> object as
854  a <code>java.sql.Time</code> object in the Java programming language.
855 
856  @param columnIndex the first column is 1, the second is 2, ...
857  @return the column value; if the value is SQL <code>NULL</code>, the
858  value returned is <code>null</code>
859 }
860 function TZAbstractResultSet.GetTime(ColumnIndex: Integer): TDateTime;
861 begin
862 {$IFNDEF DISABLE_CHECKING}
863  CheckColumnConvertion(ColumnIndex, stTime);
864 {$ENDIF}
865  Result := 0;
866 end;
867 
868 {**
869  Gets the value of the designated column in the current row
870  of this <code>ResultSet</code> object as
871  a <code>java.sql.Timestamp</code> object in the Java programming language.
872 
873  @param columnIndex the first column is 1, the second is 2, ...
874  @return the column value; if the value is SQL <code>NULL</code>, the
875  value returned is <code>null</code>
876  @exception SQLException if a database access error occurs
877 }
878 function TZAbstractResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;
879 begin
880 {$IFNDEF DISABLE_CHECKING}
881  CheckColumnConvertion(ColumnIndex, stTimestamp);
882 {$ENDIF}
883  Result := 0;
884 end;
885 
886 {**
887  Gets the value of the designated column in the current row
888  of this <code>ResultSet</code> object as
889  a stream of ASCII characters. The value can then be read in chunks from the
890  stream. This method is particularly
891  suitable for retrieving large <char>LONGVARCHAR</char> values.
892  The JDBC driver will
893  do any necessary conversion from the database format into ASCII.
894 
895  <P><B>Note:</B> All the data in the returned stream must be
896  read prior to getting the value of any other column. The next
897  call to a <code>getXXX</code> method implicitly closes the stream. Also, a
898  stream may return <code>0</code> when the method
899  <code>InputStream.available</code>
900  is called whether there is data available or not.
901 
902  @param columnIndex the first column is 1, the second is 2, ...
903  @return a Java input stream that delivers the database column value
904  as a stream of one-byte ASCII characters; if the value is SQL
905  <code>NULL</code>, the value returned is <code>null</code>
906 }
907 function TZAbstractResultSet.GetAsciiStream(ColumnIndex: Integer): TStream;
908 var
909  Blob: IZBlob;
910 begin
911 {$IFNDEF DISABLE_CHECKING}
912  CheckColumnConvertion(ColumnIndex, stAsciiStream);
913 {$ENDIF}
914  Result := nil;
915  if not IsNull(ColumnIndex) then
916  begin
917  Blob := GetBlob(ColumnIndex);
918  if Blob <> nil then
919  if Self.GetMetaData.GetColumnType(ColumnIndex) = stUnicodeStream then
920  Result := TStringStream.Create(GetValidatedAnsiStringFromBuffer(Blob.GetBuffer,
921  Blob.Length, ConSettings, ConSettings.CTRL_CP))
922  else
923  Result := Blob.GetStream;
924  end;
925  LastWasNull := (Result = nil);
926 end;
927 
928 {**
929  Gets the value of a column in the current row as a stream of
930  Gets the value of the designated column in the current row
931  of this <code>ResultSet</code> object as
932  as a stream of Unicode characters.
933  The value can then be read in chunks from the
934  stream. This method is particularly
935  suitable for retrieving large<code>LONGVARCHAR</code>values. The JDBC driver will
936  do any necessary conversion from the database format into Unicode.
937  The byte format of the Unicode stream must be Java UTF-8,
938  as specified in the Java virtual machine specification.
939 
940  <P><B>Note:</B> All the data in the returned stream must be
941  read prior to getting the value of any other column. The next
942  call to a <code>getXXX</code> method implicitly closes the stream. Also, a
943  stream may return <code>0</code> when the method
944  <code>InputStream.available</code>
945  is called whether there is data available or not.
946 
947  @param columnIndex the first column is 1, the second is 2, ...
948  @return a Java input stream that delivers the database column value
949  as a stream in Java UTF-8 byte format; if the value is SQL
950  <code>NULL</code>, the value returned is <code>null</code>
951 }
952 function TZAbstractResultSet.GetUnicodeStream(ColumnIndex: Integer): TStream;
953 var
954  Blob: IZBlob;
955 begin
956 {$IFNDEF DISABLE_CHECKING}
957  CheckColumnConvertion(ColumnIndex, stUnicodeStream);
958 {$ENDIF}
959  Result := nil;
960  if not IsNull(ColumnIndex) then
961  begin
962  Blob := GetBlob(ColumnIndex);
963  if Blob <> nil then
964  Result := Blob.GetUnicodeStream;
965  end;
966  LastWasNull := (Result = nil);
967 end;
968 
969 {**
970  Gets the value of a column in the current row as a stream of
971  Gets the value of the designated column in the current row
972  of this <code>ResultSet</code> object as a binary stream of
973  uninterpreted bytes. The value can then be read in chunks from the
974  stream. This method is particularly
975  suitable for retrieving large <code>LONGVARBINARY</code> values.
976 
977  <P><B>Note:</B> All the data in the returned stream must be
978  read prior to getting the value of any other column. The next
979  call to a <code>getXXX</code> method implicitly closes the stream. Also, a
980  stream may return <code>0</code> when the method
981  <code>InputStream.available</code>
982  is called whether there is data available or not.
983 
984  @param columnIndex the first column is 1, the second is 2, ...
985  @return a Java input stream that delivers the database column value
986  as a stream of uninterpreted bytes;
987  if the value is SQL <code>NULL</code>, the value returned is <code>null</code>
988 }
989 function TZAbstractResultSet.GetBinaryStream(ColumnIndex: Integer): TStream;
990 var
991  Blob: IZBlob;
992 begin
993 {$IFNDEF DISABLE_CHECKING}
994  CheckColumnConvertion(ColumnIndex, stBinaryStream);
995 {$ENDIF}
996  Result := nil;
997  if not IsNull(ColumnIndex) then
998  begin
999  Blob := GetBlob(ColumnIndex);
1000  if Blob <> nil then
1001  Result := Blob.GetStream;
1002  end;
1003  LastWasNull := (Result = nil);
1004 end;
1005 
1006 {**
1007  Returns the value of the designated column in the current row
1008  of this <code>ResultSet</code> object as a <code>Blob</code> object
1009  in the Java programming language.
1010 
1011  @param ColumnIndex the first column is 1, the second is 2, ...
1012  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in
1013  the specified column
1014 }
1015 function TZAbstractResultSet.GetBlob(ColumnIndex: Integer): IZBlob;
1016 begin
1017 {$IFNDEF DISABLE_CHECKING}
1018  CheckBlobColumn(ColumnIndex);
1019 {$ENDIF}
1020 
1021  Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);
1022 end;
1023 
1024 {**
1025  Returns the value of the designated column in the current row
1026  of this <code>ResultSet</code> object as a <code>IZResultSet</code> object
1027  in the Java programming language.
1028 
1029  @param ColumnIndex the first column is 1, the second is 2, ...
1030  @return a <code>IZResultSet</code> object representing the SQL
1031  <code>IZResultSet</code> value in the specified column
1032 }
1033 function TZAbstractResultSet.GetDataSet(ColumnIndex: Integer): IZDataSet;
1034 begin
1035  Result := nil;
1036 end;
1037 
1038 {**
1039  Returns the value of the designated column in the current row
1040  of this <code>ResultSet</code> object as a <code>Variant</code> object.
1041 
1042  @param ColumnIndex the first column is 1, the second is 2, ...
1043  @return a <code>Variant</code> object representing the SQL
1044  any value in the specified column
1045 }
1046 function TZAbstractResultSet.GetValue(ColumnIndex: Integer): TZVariant;
1047 var
1048  Metadata: TZAbstractResultSetMetadata;
1049 begin
1050 {$IFNDEF DISABLE_CHECKING}
1051  CheckClosed;
1052 {$ENDIF}
1053  Metadata := TZAbstractResultSetMetadata(FMetadata);
1054 {$IFNDEF DISABLE_CHECKING}
1055  if (Metadata = nil) or (ColumnIndex <= 0)
1056  or (ColumnIndex > Metadata.GetColumnCount) then
1057  begin
1058  raise EZSQLException.Create(
1059  Format(SColumnIsNotAccessable, [ColumnIndex]));
1060  end;
1061 {$ENDIF}
1062 
1063  case Metadata.GetColumnType(ColumnIndex) of
1064  stBoolean:
1065  begin
1066  Result.VType := vtBoolean;
1067  Result.VBoolean := GetBoolean(ColumnIndex);
1068  end;
1069  stByte, stShort, stInteger, stLong:
1070  begin
1071  Result.VType := vtInteger;
1072  Result.VInteger := GetLong(ColumnIndex);
1073  end;
1074  stFloat, stDouble, stBigDecimal:
1075  begin
1076  Result.VType := vtFloat;
1077  Result.VFloat := GetBigDecimal(ColumnIndex);
1078  end;
1079  stDate, stTime, stTimestamp:
1080  begin
1081  Result.VType := vtDateTime;
1082  Result.VDateTime := GetTimestamp(ColumnIndex);
1083  end;
1084  stString, stBytes, stAsciiStream, stBinaryStream:
1085  begin
1086  Result.VType := vtString;
1087  Result.VString := String(GetString(ColumnIndex));
1088  end;
1089  stUnicodeString, stUnicodeStream:
1090  begin
1091  Result.VType := vtUnicodeString;
1092  Result.VUnicodeString := GetUnicodeString(ColumnIndex);
1093  end;
1094  else
1095  Result.VType := vtNull;
1096  end;
1097 
1098  if WasNull then
1099  Result.VType := vtNull;
1100 end;
1101 
1102 {**
1103  Gets the DefaultExpression value of the designated column in the current row
1104  of this <code>ResultSet</code> object as
1105  a <code>String</code>.
1106 
1107  @param columnIndex the first column is 1, the second is 2, ...
1108  @return the DefaultExpression value
1109 }
1110 function TZAbstractResultSet.GetDefaultExpression(ColumnIndex: Integer): string;
1111 begin
1112 {$IFNDEF DISABLE_CHECKING}
1113  CheckColumnConvertion(ColumnIndex, stString);
1114 {$ENDIF}
1115  Result := '';
1116 end;
1117 
1118 //======================================================================
1119 // Methods for accessing results by column name
1120 //======================================================================
1121 
1122 {**
1123  Indicates if the value of the designated column in the current row
1124  of this <code>ResultSet</code> object is Null.
1125 
1126  @param columnName the SQL name of the column
1127  @return if the value is SQL <code>NULL</code>, the
1128  value returned is <code>true</code>. <code>false</code> otherwise.
1129 }
1130 function TZAbstractResultSet.IsNullByName(const ColumnName: string): Boolean;
1131 begin
1132  Result := IsNull(GetColumnIndex(ColumnName));
1133 end;
1134 
1135 {**
1136  Gets the value of the designated column in the current row
1137  of this <code>ResultSet</code> object as
1138  a <code>PAnsiChar</code> in the Delphi programming language.
1139 
1140  @param columnName the SQL name of the column
1141  @return the column value; if the value is SQL <code>NULL</code>, the
1142  value returned is <code>null</code>
1143 }
1144 function TZAbstractResultSet.GetPCharByName(const ColumnName: string): PChar;
1145 begin
1146  Result := GetPChar(GetColumnIndex(ColumnName));
1147 end;
1148 
1149 {**
1150  Gets the value of the designated column in the current row
1151  of this <code>ResultSet</code> object as
1152  a <code>String</code> in the Java programming language.
1153 
1154  @param columnName the SQL name of the column
1155  @return the column value; if the value is SQL <code>NULL</code>, the
1156  value returned is <code>null</code>
1157 }
1158 function TZAbstractResultSet.GetStringByName(const ColumnName: string): String;
1159 begin
1160  Result := GetString(GetColumnIndex(ColumnName));
1161 end;
1162 
1163 {**
1164  Gets the value of the designated column in the current row
1165  of this <code>ResultSet</code> object as
1166  a <code>String</code> in the Java programming language.
1167 
1168  @param columnName the SQL name of the column
1169  @return the column value; if the value is SQL <code>NULL</code>, the
1170  value returned is <code>null</code>
1171 }
1172 function TZAbstractResultSet.GetBinaryStringByName(const ColumnName: string): RawByteString;
1173 begin
1174  Result := GetBinaryString(GetColumnIndex(ColumnName));
1175 end;
1176 
1177 {**
1178  Gets the value of the designated column in the current row
1179  of this <code>ResultSet</code> object as
1180  a <code>WideString</code> in the Object Pascal programming language.
1181 
1182  @param columnName the SQL name of the column
1183  @return the column value; if the value is SQL <code>NULL</code>, the
1184  value returned is <code>null</code>
1185 }
1186 function TZAbstractResultSet.GetUnicodeStringByName(const ColumnName: string):
1187  WideString;
1188 begin
1189  Result := GetUnicodeString(GetColumnIndex(ColumnName));
1190 end;
1191 
1192 {**
1193  Gets the value of the designated column in the current row
1194  of this <code>ResultSet</code> object as
1195  a <code>boolean</code> in the Java programming language.
1196 
1197  @param columnName the SQL name of the column
1198  @return the column value; if the value is SQL <code>NULL</code>, the
1199  value returned is <code>false</code>
1200 }
1201 function TZAbstractResultSet.GetBooleanByName(const ColumnName: string): Boolean;
1202 begin
1203  Result := GetBoolean(GetColumnIndex(ColumnName));
1204 end;
1205 
1206 {**
1207  Gets the value of the designated column in the current row
1208  of this <code>ResultSet</code> object as
1209  a <code>byte</code> in the Java programming language.
1210 
1211  @param columnName the SQL name of the column
1212  @return the column value; if the value is SQL <code>NULL</code>, the
1213  value returned is <code>0</code>
1214 }
1215 function TZAbstractResultSet.GetByteByName(const ColumnName: string): Byte;
1216 begin
1217  Result := GetByte(GetColumnIndex(ColumnName));
1218 end;
1219 
1220 {**
1221  Gets the value of the designated column in the current row
1222  of this <code>ResultSet</code> object as
1223  a <code>short</code> in the Java programming language.
1224 
1225  @param columnName the SQL name of the column
1226  @return the column value; if the value is SQL <code>NULL</code>, the
1227  value returned is <code>0</code>
1228 }
1229 function TZAbstractResultSet.GetShortByName(const ColumnName: string): SmallInt;
1230 begin
1231  Result := GetShort(GetColumnIndex(ColumnName));
1232 end;
1233 
1234 {**
1235  Gets the value of the designated column in the current row
1236  of this <code>ResultSet</code> object as
1237  an <code>int</code> in the Java programming language.
1238 
1239  @param columnName the SQL name of the column
1240  @return the column value; if the value is SQL <code>NULL</code>, the
1241  value returned is <code>0</code>
1242 }
1243 function TZAbstractResultSet.GetIntByName(const ColumnName: string): Integer;
1244 begin
1245  Result := GetInt(GetColumnIndex(ColumnName));
1246 end;
1247 
1248 {**
1249  Gets the value of the designated column in the current row
1250  of this <code>ResultSet</code> object as
1251  a <code>long</code> in the Java programming language.
1252 
1253  @param columnName the SQL name of the column
1254  @return the column value; if the value is SQL <code>NULL</code>, the
1255  value returned is <code>0</code>
1256 }
1257 function TZAbstractResultSet.GetLongByName(const ColumnName: string): Int64;
1258 begin
1259  Result := GetLong(GetColumnIndex(ColumnName));
1260 end;
1261 
1262 {**
1263  Gets the value of the designated column in the current row
1264  of this <code>ResultSet</code> object as
1265  a <code>float</code> in the Java programming language.
1266 
1267  @param columnName the SQL name of the column
1268  @return the column value; if the value is SQL <code>NULL</code>, the
1269  value returned is <code>0</code>
1270 }
1271 function TZAbstractResultSet.GetFloatByName(const ColumnName: string): Single;
1272 begin
1273  Result := GetFloat(GetColumnIndex(ColumnName));
1274 end;
1275 
1276 {**
1277  Gets the value of the designated column in the current row
1278  of this <code>ResultSet</code> object as
1279  a <code>double</code> in the Java programming language.
1280 
1281  @param columnName the SQL name of the column
1282  @return the column value; if the value is SQL <code>NULL</code>, the
1283  value returned is <code>0</code>
1284 }
1285 function TZAbstractResultSet.GetDoubleByName(const ColumnName: string): Double;
1286 begin
1287  Result := GetDouble(GetColumnIndex(ColumnName));
1288 end;
1289 
1290 {**
1291  Gets the value of the designated column in the current row
1292  of this <code>ResultSet</code> object as
1293  a <code>java.math.BigDecimal</code> in the Java programming language.
1294 
1295  @param columnName the SQL name of the column
1296  @return the column value; if the value is SQL <code>NULL</code>, the
1297  value returned is <code>null</code>
1298 }
1299 function TZAbstractResultSet.GetBigDecimalByName(const ColumnName: string): Extended;
1300 begin
1301  Result := GetBigDecimal(GetColumnIndex(ColumnName));
1302 end;
1303 
1304 {**
1305  Gets the value of the designated column in the current row
1306  of this <code>ResultSet</code> object as
1307  a <code>byte</code> array in the Java programming language.
1308  The bytes represent the raw values returned by the driver.
1309 
1310  @param columnName the SQL name of the column
1311  @return the column value; if the value is SQL <code>NULL</code>, the
1312  value returned is <code>null</code>
1313 }
1314 function TZAbstractResultSet.GetBytesByName(const ColumnName: string): TByteDynArray;
1315 begin
1316  Result := GetBytes(GetColumnIndex(ColumnName));
1317 end;
1318 
1319 {**
1320  Gets the value of the designated column in the current row
1321  of this <code>ResultSet</code> object as
1322  a <code>java.sql.Date</code> object in the Java programming language.
1323 
1324  @param columnName the SQL name of the column
1325  @return the column value; if the value is SQL <code>NULL</code>, the
1326  value returned is <code>null</code>
1327 }
1328 function TZAbstractResultSet.GetDateByName(const ColumnName: string): TDateTime;
1329 begin
1330  Result := GetDate(GetColumnIndex(ColumnName));
1331 end;
1332 
1333 {**
1334  Gets the value of the designated column in the current row
1335  of this <code>ResultSet</code> object as
1336  a <code>java.sql.Time</code> object in the Java programming language.
1337 
1338  @param columnName the SQL name of the column
1339  @return the column value; if the value is SQL <code>NULL</code>,
1340  the value returned is <code>null</code>
1341 }
1342 function TZAbstractResultSet.GetTimeByName(const ColumnName: string): TDateTime;
1343 begin
1344  Result := GetTime(GetColumnIndex(ColumnName));
1345 end;
1346 
1347 {**
1348  Gets the value of the designated column in the current row
1349  of this <code>ResultSet</code> object as
1350  a <code>java.sql.Timestamp</code> object.
1351 
1352  @param columnName the SQL name of the column
1353  @return the column value; if the value is SQL <code>NULL</code>, the
1354  value returned is <code>null</code>
1355 }
1356 function TZAbstractResultSet.GetTimestampByName(const ColumnName: string): TDateTime;
1357 begin
1358  Result := GetTimestamp(GetColumnIndex(ColumnName));
1359 end;
1360 
1361 {**
1362  Gets the value of the designated column in the current row
1363  of this <code>ResultSet</code> object as a stream of
1364  ASCII characters. The value can then be read in chunks from the
1365  stream. This method is particularly
1366  suitable for retrieving large <code>LONGVARCHAR</code> values.
1367  The JDBC driver will
1368  do any necessary conversion from the database format into ASCII.
1369 
1370  <P><B>Note:</B> All the data in the returned stream must be
1371  read prior to getting the value of any other column. The next
1372  call to a <code>getXXX</code> method implicitly closes the stream. Also, a
1373  stream may return <code>0</code> when the method <code>available</code>
1374  is called whether there is data available or not.
1375 
1376  @param columnName the SQL name of the column
1377  @return a Java input stream that delivers the database column value
1378  as a stream of one-byte ASCII characters.
1379  If the value is SQL <code>NULL</code>,
1380  the value returned is <code>null</code>.
1381 }
1382 function TZAbstractResultSet.GetAsciiStreamByName(const ColumnName: string): TStream;
1383 begin
1384  Result := GetAsciiStream(GetColumnIndex(ColumnName));
1385 end;
1386 
1387 {**
1388  Gets the value of the designated column in the current row
1389  of this <code>ResultSet</code> object as a stream of
1390  Unicode characters. The value can then be read in chunks from the
1391  stream. This method is particularly
1392  suitable for retrieving large <code>LONGVARCHAR</code> values.
1393  The JDBC driver will
1394  do any necessary conversion from the database format into Unicode.
1395  The byte format of the Unicode stream must be Java UTF-8,
1396  as defined in the Java virtual machine specification.
1397 
1398  <P><B>Note:</B> All the data in the returned stream must be
1399  read prior to getting the value of any other column. The next
1400  call to a <code>getXXX</code> method implicitly closes the stream. Also, a
1401  stream may return <code>0</code> when the method <code>available</code>
1402  is called whether there is data available or not.
1403 
1404  @param columnName the SQL name of the column
1405  @return a Java input stream that delivers the database column value
1406  as a stream of two-byte Unicode characters.
1407  If the value is SQL <code>NULL</code>, the value returned is <code>null</code>.
1408 }
1409 function TZAbstractResultSet.GetUnicodeStreamByName(const ColumnName: string): TStream;
1410 begin
1411  Result := GetUnicodeStream(GetColumnIndex(ColumnName));
1412 end;
1413 
1414 {**
1415  Gets the value of the designated column in the current row
1416  of this <code>ResultSet</code> object as a stream of uninterpreted
1417  <code>byte</code>s.
1418  The value can then be read in chunks from the
1419  stream. This method is particularly
1420  suitable for retrieving large <code>LONGVARBINARY</code>
1421  values.
1422 
1423  <P><B>Note:</B> All the data in the returned stream must be
1424  read prior to getting the value of any other column. The next
1425  call to a <code>getXXX</code> method implicitly closes the stream. Also, a
1426  stream may return <code>0</code> when the method <code>available</code>
1427  is called whether there is data available or not.
1428 
1429  @param columnName the SQL name of the column
1430  @return a Java input stream that delivers the database column value
1431  as a stream of uninterpreted bytes;
1432  if the value is SQL <code>NULL</code>, the result is <code>null</code>
1433 }
1434 function TZAbstractResultSet.GetBinaryStreamByName(const ColumnName: string): TStream;
1435 begin
1436  Result := GetBinaryStream(GetColumnIndex(ColumnName));
1437 end;
1438 
1439 {**
1440  Returns the value of the designated column in the current row
1441  of this <code>ResultSet</code> object as a <code>Blob</code> object
1442  in the Java programming language.
1443 
1444  @param colName the name of the column from which to retrieve the value
1445  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in
1446  the specified column
1447 }
1448 function TZAbstractResultSet.GetBlobByName(const ColumnName: string): IZBlob;
1449 begin
1450  Result := GetBlob(GetColumnIndex(ColumnName));
1451 end;
1452 
1453 function TZAbstractResultSet.GetDataSetByName(const ColumnName: string): IZDataSet;
1454 begin
1455  Result := GetDataSet(GetColumnIndex(ColumnName));
1456 end;
1457 
1458 {**
1459  Returns the value of the designated column in the current row
1460  of this <code>ResultSet</code> object as a <code>Variant</code> object.
1461 
1462  @param colName the name of the column from which to retrieve the value
1463  @return a <code>Blob</code> object representing the SQL <code>Any</code>
1464  value in the specified column
1465 }
1466 function TZAbstractResultSet.GetValueByName(const ColumnName: string): TZVariant;
1467 begin
1468  Result := GetValue(GetColumnIndex(ColumnName));
1469 end;
1470 
1471 //=====================================================================
1472 // Advanced features:
1473 //=====================================================================
1474 
1475 {**
1476  Returns the first warning reported by calls on this
1477  <code>ResultSet</code> object.
1478  Subsequent warnings on this <code>ResultSet</code> object
1479  will be chained to the <code>SQLWarning</code> object that
1480  this method returns.
1481 
1482  <P>The warning chain is automatically cleared each time a new
1483  row is read.
1484 
1485  <P><B>Note:</B> This warning chain only covers warnings caused
1486  by <code>ResultSet</code> methods. Any warning caused by
1487  <code>Statement</code> methods
1488  (such as reading OUT parameters) will be chained on the
1489  <code>Statement</code> object.
1490 
1491  @return the first <code>SQLWarning</code> object reported or <code>null</code>
1492 }
1493 function TZAbstractResultSet.GetWarnings: EZSQLWarning;
1494 begin
1495  Result := nil;
1496 end;
1497 
1498 {**
1499  Clears all warnings reported on this <code>ResultSet</code> object.
1500  After this method is called, the method <code>getWarnings</code>
1501  returns <code>null</code> until a new warning is
1502  reported for this <code>ResultSet</code> object.
1503 }
1504 procedure TZAbstractResultSet.ClearWarnings;
1505 begin
1506 end;
1507 
1508 {**
1509  Gets the name of the SQL cursor used by this <code>ResultSet</code>
1510  object.
1511 
1512  <P>In SQL, a result table is retrieved through a cursor that is
1513  named. The current row of a result set can be updated or deleted
1514  using a positioned update/delete statement that references the
1515  cursor name. To insure that the cursor has the proper isolation
1516  level to support update, the cursor's <code>select</code> statement should be
1517  of the form 'select for update'. If the 'for update' clause is
1518  omitted, the positioned updates may fail.
1519 
1520  <P>The JDBC API supports this SQL feature by providing the name of the
1521  SQL cursor used by a <code>ResultSet</code> object.
1522  The current row of a <code>ResultSet</code> object
1523  is also the current row of this SQL cursor.
1524 
1525  <P><B>Note:</B> If positioned update is not supported, a
1526  <code>SQLException</code> is thrown.
1527 
1528  @return the SQL name for this <code>ResultSet</code> object's cursor
1529 }
1530 function TZAbstractResultSet.GetCursorName: AnsiString;
1531 begin
1532  Result := '';
1533 end;
1534 
1535 {**
1536  Retrieves the number, types and properties of
1537  this <code>ResultSet</code> object's columns.
1538  @return the description of this <code>ResultSet</code> object's columns
1539 }
1540 function TZAbstractResultSet.GetMetaData: IZResultSetMetaData;
1541 begin
1542  Result := TZAbstractResultSetMetadata(FMetadata);
1543 end;
1544 
1545 {**
1546  Maps the given <code>ResultSet</code> column name to its
1547  <code>ResultSet</code> column index.
1548 
1549  @param columnName the name of the column
1550  @return the column index of the given column name
1551 }
1552 function TZAbstractResultSet.GetColumnIndex(const ColumnName: string): Integer;
1553 begin
1554  Result := FindColumn(ColumnName);
1555 
1556  if Result < 1 then
1557  raise EZSQLException.Create(Format(SColumnWasNotFound, [ColumnName]));
1558 end;
1559 
1560 {**
1561  Maps the given <code>ResultSet</code> column name to its
1562  <code>ResultSet</code> column index.
1563 
1564  @param columnName the name of the column
1565  @return the column index of the given column name
1566 }
1567 function TZAbstractResultSet.FindColumn(const ColumnName: string): Integer;
1568 var
1569  I: Integer;
1570  Metadata: TZAbstractResultSetMetadata;
1571 begin
1572  CheckClosed;
1573  Metadata := TZAbstractResultSetMetadata(FMetadata);
1574  Result := 0;
1575 
1576  { Search for case sensitive columns. }
1577  for I := 1 to Metadata.GetColumnCount do
1578  begin
1579  if Metadata.GetColumnLabel(I) = ColumnName then
1580  begin
1581  Result := I;
1582  Exit;
1583  end;
1584  end;
1585 
1586  { Search for case insensitive columns. }
1587  for I := 1 to Metadata.GetColumnCount do
1588  begin
1589  if AnsiUpperCase(Metadata.GetColumnLabel(I)) = AnsiUpperCase(ColumnName) then
1590  begin
1591  Result := I;
1592  Exit;
1593  end;
1594  end;
1595 end;
1596 
1597 //---------------------------------------------------------------------
1598 // Traversal/Positioning
1599 //---------------------------------------------------------------------
1600 
1601 {**
1602  Indicates whether the cursor is before the first row in
1603  this <code>ResultSet</code> object.
1604 
1605  @return <code>true</code> if the cursor is before the first row;
1606  <code>false</code> if the cursor is at any other position or the
1607  result set contains no rows
1608 }
1609 function TZAbstractResultSet.IsBeforeFirst: Boolean;
1610 begin
1611  Result := (FRowNo = 0);
1612 end;
1613 
1614 {**
1615  Indicates whether the cursor is after the last row in
1616  this <code>ResultSet</code> object.
1617 
1618  @return <code>true</code> if the cursor is after the last row;
1619  <code>false</code> if the cursor is at any other position or the
1620  result set contains no rows
1621 }
1622 function TZAbstractResultSet.IsAfterLast: Boolean;
1623 begin
1624  Result := {(FLastRowNo > 0) and} (FRowNo > FLastRowNo);
1625 end;
1626 
1627 {**
1628  Indicates whether the cursor is on the first row of
1629  this <code>ResultSet</code> object.
1630 
1631  @return <code>true</code> if the cursor is on the first row;
1632  <code>false</code> otherwise
1633 }
1634 function TZAbstractResultSet.IsFirst: Boolean;
1635 begin
1636  Result := (FRowNo = 1);
1637 end;
1638 
1639 {**
1640  Indicates whether the cursor is on the last row of
1641  this <code>ResultSet</code> object.
1642  Note: Calling the method <code>isLast</code> may be expensive
1643  because the JDBC driver
1644  might need to fetch ahead one row in order to determine
1645  whether the current row is the last row in the result set.
1646 
1647  @return <code>true</code> if the cursor is on the last row;
1648  <code>false</code> otherwise
1649 }
1650 function TZAbstractResultSet.IsLast: Boolean;
1651 begin
1652  Result := {(FLastRowNo > 0) and} (FRowNo = FLastRowNo);
1653 end;
1654 
1655 {**
1656  Moves the cursor to the front of
1657  this <code>ResultSet</code> object, just before the
1658  first row. This method has no effect if the result set contains no rows.
1659 }
1660 procedure TZAbstractResultSet.BeforeFirst;
1661 begin
1662  MoveAbsolute(0);
1663 end;
1664 
1665 {**
1666  Moves the cursor to the end of
1667  this <code>ResultSet</code> object, just after the
1668  last row. This method has no effect if the result set contains no rows.
1669 }
1670 procedure TZAbstractResultSet.AfterLast;
1671 begin
1672  Last;
1673  Next;
1674 end;
1675 
1676 {**
1677  Moves the cursor to the first row in
1678  this <code>ResultSet</code> object.
1679 
1680  @return <code>true</code> if the cursor is on a valid row;
1681  <code>false</code> if there are no rows in the result set
1682 }
1683 function TZAbstractResultSet.First: Boolean;
1684 begin
1685  Result := MoveAbsolute(1);
1686 end;
1687 
1688 {**
1689  Moves the cursor to the last row in
1690  this <code>ResultSet</code> object.
1691 
1692  @return <code>true</code> if the cursor is on a valid row;
1693  <code>false</code> if there are no rows in the result set
1694 }
1695 function TZAbstractResultSet.Last: Boolean;
1696 begin
1697  Result := MoveAbsolute(FLastRowNo);
1698 end;
1699 
1700 {**
1701  Retrieves the current row number. The first row is number 1, the
1702  second number 2, and so on.
1703  @return the current row number; <code>0</code> if there is no current row
1704 }
1705 function TZAbstractResultSet.GetRow: Integer;
1706 begin
1707  Result := FRowNo;
1708 end;
1709 
1710 {**
1711  Moves the cursor to the given row number in
1712  this <code>ResultSet</code> object.
1713 
1714  <p>If the row number is positive, the cursor moves to
1715  the given row number with respect to the
1716  beginning of the result set. The first row is row 1, the second
1717  is row 2, and so on.
1718 
1719  <p>If the given row number is negative, the cursor moves to
1720  an absolute row position with respect to
1721  the end of the result set. For example, calling the method
1722  <code>absolute(-1)</code> positions the
1723  cursor on the last row; calling the method <code>absolute(-2)</code>
1724  moves the cursor to the next-to-last row, and so on.
1725 
1726  <p>An attempt to position the cursor beyond the first/last row in
1727  the result set leaves the cursor before the first row or after
1728  the last row.
1729 
1730  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same
1731  as calling <code>first()</code>. Calling <code>absolute(-1)</code>
1732  is the same as calling <code>last()</code>.
1733 
1734  @return <code>true</code> if the cursor is on the result set;
1735  <code>false</code> otherwise
1736 }
1737 function TZAbstractResultSet.MoveAbsolute(Row: Integer): Boolean;
1738 begin
1739  Result := False;
1740  RaiseForwardOnlyException;
1741 end;
1742 
1743 {**
1744  Moves the cursor a relative number of rows, either positive or negative.
1745  Attempting to move beyond the first/last row in the
1746  result set positions the cursor before/after the
1747  the first/last row. Calling <code>relative(0)</code> is valid, but does
1748  not change the cursor position.
1749 
1750  <p>Note: Calling the method <code>relative(1)</code>
1751  is different from calling the method <code>next()</code>
1752  because is makes sense to call <code>next()</code> when there
1753  is no current row,
1754  for example, when the cursor is positioned before the first row
1755  or after the last row of the result set.
1756 
1757  @return <code>true</code> if the cursor is on a row;
1758  <code>false</code> otherwise
1759 }
1760 function TZAbstractResultSet.MoveRelative(Rows: Integer): Boolean;
1761 begin
1762  Result := MoveAbsolute(FRowNo + Rows);
1763 end;
1764 
1765 {**
1766  Moves the cursor to the previous row in this
1767  <code>ResultSet</code> object.
1768 
1769  <p><B>Note:</B> Calling the method <code>previous()</code> is not the same as
1770  calling the method <code>relative(-1)</code> because it
1771  makes sense to call</code>previous()</code> when there is no current row.
1772 
1773  @return <code>true</code> if the cursor is on a valid row;
1774  <code>false</code> if it is off the result set
1775 }
1776 function TZAbstractResultSet.Previous: Boolean;
1777 begin
1778  Result := MoveAbsolute(FRowNo - 1);
1779 end;
1780 
1781 {**
1782  Moves the cursor down one row from its current position.
1783  A <code>ResultSet</code> cursor is initially positioned
1784  before the first row; the first call to the method
1785  <code>next</code> makes the first row the current row; the
1786  second call makes the second row the current row, and so on.
1787 
1788  <P>If an input stream is open for the current row, a call
1789  to the method <code>next</code> will
1790  implicitly close it. A <code>ResultSet</code> object's
1791  warning chain is cleared when a new row is read.
1792 
1793  @return <code>true</code> if the new current row is valid;
1794  <code>false</code> if there are no more rows
1795 }
1796 function TZAbstractResultSet.Next: Boolean;
1797 begin
1798  Result := MoveAbsolute(FRowNo + 1);
1799 end;
1800 
1801 //---------------------------------------------------------------------
1802 // Properties
1803 //---------------------------------------------------------------------
1804 
1805 {**
1806  Returns the fetch direction for this
1807  <code>ResultSet</code> object.
1808  @return the current fetch direction for this <code>ResultSet</code> object
1809 }
1810 function TZAbstractResultSet.GetFetchDirection: TZFetchDirection;
1811 begin
1812  Result := FFetchDirection;
1813 end;
1814 
1815 {**
1816  Gives a hint as to the direction in which the rows in this
1817  <code>ResultSet</code> object will be processed.
1818  The initial value is determined by the
1819  <code>Statement</code> object
1820  that produced this <code>ResultSet</code> object.
1821  The fetch direction may be changed at any time.
1822 }
1823 procedure TZAbstractResultSet.SetFetchDirection(Direction: TZFetchDirection);
1824 begin
1825  if Direction <> fdForward then
1826  RaiseUnsupportedException;
1827 end;
1828 
1829 {**
1830  Returns the fetch size for this
1831  <code>ResultSet</code> object.
1832  @return the current fetch size for this <code>ResultSet</code> object
1833 }
1834 function TZAbstractResultSet.GetFetchSize: Integer;
1835 begin
1836  Result := FFetchSize;
1837 end;
1838 
1839 {**
1840  Gives the JDBC driver a hint as to the number of rows that should
1841  be fetched from the database when more rows are needed for this
1842  <code>ResultSet</code> object.
1843  If the fetch size specified is zero, the JDBC driver
1844  ignores the value and is free to make its own best guess as to what
1845  the fetch size should be. The default value is set by the
1846  <code>Statement</code> object
1847  that created the result set. The fetch size may be changed at any time.
1848 
1849  @param rows the number of rows to fetch
1850 }
1851 procedure TZAbstractResultSet.SetFetchSize(Rows: Integer);
1852 begin
1853  FFetchSize := Rows;
1854 end;
1855 
1856 {**
1857  Returns the type of this <code>ResultSet</code> object.
1858  The type is determined by the <code>Statement</code> object
1859  that created the result set.
1860 
1861  @return <code>TYPE_FORWARD_ONLY</code>,
1862  <code>TYPE_SCROLL_INSENSITIVE</code>,
1863  or <code>TYPE_SCROLL_SENSITIVE</code>
1864 }
1865 function TZAbstractResultSet.GetType: TZResultSetType;
1866 begin
1867  Result := FResultSetType;
1868 end;
1869 
1870 {**
1871  Returns the concurrency mode of this <code>ResultSet</code> object.
1872  The concurrency used is determined by the
1873  <code>Statement</code> object that created the result set.
1874 
1875  @return the concurrency type, either <code>CONCUR_READ_ONLY</code>
1876  or <code>CONCUR_UPDATABLE</code>
1877 }
1878 function TZAbstractResultSet.GetConcurrency: TZResultSetConcurrency;
1879 begin
1880  Result := FResultSetConcurrency;
1881 end;
1882 
1883 {**
1884  Gets an assigned post locate mode.
1885  @param the assigned post locate mode.
1886 }
1887 function TZAbstractResultSet.GetLocateUpdates: TZLocateUpdatesMode;
1888 begin
1889  Result := FLocateUpdates;
1890 end;
1891 
1892 function TZAbstractResultSet.GetPostUpdates: TZPostUpdatesMode;
1893 begin
1894  Result := FPostUpdates;
1895 end;
1896 
1897 //---------------------------------------------------------------------
1898 // Updates
1899 //---------------------------------------------------------------------
1900 
1901 {**
1902  Indicates whether the current row has been updated. The value returned
1903  depends on whether or not the result set can detect updates.
1904 
1905  @return <code>true</code> if the row has been visibly updated
1906  by the owner or another, and updates are detected
1907 }
1908 function TZAbstractResultSet.RowUpdated: Boolean;
1909 begin
1910  Result := False;
1911 end;
1912 
1913 {**
1914  Indicates whether the current row has had an insertion.
1915  The value returned depends on whether or not this
1916  <code>ResultSet</code> object can detect visible inserts.
1917 
1918  @return <code>true</code> if a row has had an insertion
1919  and insertions are detected; <code>false</code> otherwise
1920 }
1921 function TZAbstractResultSet.RowInserted: Boolean;
1922 begin
1923  Result := False;
1924 end;
1925 
1926 {**
1927  Indicates whether a row has been deleted. A deleted row may leave
1928  a visible "hole" in a result set. This method can be used to
1929  detect holes in a result set. The value returned depends on whether
1930  or not this <code>ResultSet</code> object can detect deletions.
1931 
1932  @return <code>true</code> if a row was deleted and deletions are detected;
1933  <code>false</code> otherwise
1934 }
1935 function TZAbstractResultSet.RowDeleted: Boolean;
1936 begin
1937  Result := False;
1938 end;
1939 
1940 {**
1941  Gives a nullable column a null value.
1942 
1943  The <code>updateXXX</code> methods are used to update column values in the
1944  current row or the insert row. The <code>updateXXX</code> methods do not
1945  update the underlying database; instead the <code>updateRow</code>
1946  or <code>insertRow</code> methods are called to update the database.
1947 
1948  @param columnIndex the first column is 1, the second is 2, ...
1949 }
1950 procedure TZAbstractResultSet.UpdateNull(ColumnIndex: Integer);
1951 begin
1952  RaiseReadOnlyException;
1953 end;
1954 
1955 {**
1956  Updates the designated column with a <code>boolean</code> value.
1957  The <code>updateXXX</code> methods are used to update column values in the
1958  current row or the insert row. The <code>updateXXX</code> methods do not
1959  update the underlying database; instead the <code>updateRow</code> or
1960  <code>insertRow</code> methods are called to update the database.
1961 
1962  @param columnIndex the first column is 1, the second is 2, ...
1963  @param x the new column value
1964 }
1965 procedure TZAbstractResultSet.UpdateBoolean(ColumnIndex: Integer; Value: Boolean);
1966 begin
1967  RaiseReadOnlyException;
1968 end;
1969 
1970 {**
1971  Updates the designated column with a <code>byte</code> value.
1972  The <code>updateXXX</code> methods are used to update column values in the
1973  current row or the insert row. The <code>updateXXX</code> methods do not
1974  update the underlying database; instead the <code>updateRow</code> or
1975  <code>insertRow</code> methods are called to update the database.
1976 
1977 
1978  @param columnIndex the first column is 1, the second is 2, ...
1979  @param x the new column value
1980 }
1981 procedure TZAbstractResultSet.UpdateByte(ColumnIndex: Integer;
1982  Value: ShortInt);
1983 begin
1984  RaiseReadOnlyException;
1985 end;
1986 
1987 {**
1988  Updates the designated column with a <code>short</code> value.
1989  The <code>updateXXX</code> methods are used to update column values in the
1990  current row or the insert row. The <code>updateXXX</code> methods do not
1991  update the underlying database; instead the <code>updateRow</code> or
1992  <code>insertRow</code> methods are called to update the database.
1993 
1994  @param columnIndex the first column is 1, the second is 2, ...
1995  @param x the new column value
1996 }
1997 procedure TZAbstractResultSet.UpdateShort(ColumnIndex: Integer; Value: SmallInt);
1998 begin
1999  RaiseReadOnlyException;
2000 end;
2001 
2002 {**
2003  Updates the designated column with an <code>int</code> value.
2004  The <code>updateXXX</code> methods are used to update column values in the
2005  current row or the insert row. The <code>updateXXX</code> methods do not
2006  update the underlying database; instead the <code>updateRow</code> or
2007  <code>insertRow</code> methods are called to update the database.
2008 
2009  @param columnIndex the first column is 1, the second is 2, ...
2010  @param x the new column value
2011 }
2012 procedure TZAbstractResultSet.UpdateInt(ColumnIndex: Integer; Value: Integer);
2013 begin
2014  RaiseReadOnlyException;
2015 end;
2016 
2017 {**
2018  Updates the designated column with a <code>long</code> value.
2019  The <code>updateXXX</code> methods are used to update column values in the
2020  current row or the insert row. The <code>updateXXX</code> methods do not
2021  update the underlying database; instead the <code>updateRow</code> or
2022  <code>insertRow</code> methods are called to update the database.
2023 
2024  @param columnIndex the first column is 1, the second is 2, ...
2025  @param x the new column value
2026 }
2027 procedure TZAbstractResultSet.UpdateLong(ColumnIndex: Integer; Value: Int64);
2028 begin
2029  RaiseReadOnlyException;
2030 end;
2031 
2032 {**
2033  Updates the designated column with a <code>float</code> value.
2034  The <code>updateXXX</code> methods are used to update column values in the
2035  current row or the insert row. The <code>updateXXX</code> methods do not
2036  update the underlying database; instead the <code>updateRow</code> or
2037  <code>insertRow</code> methods are called to update the database.
2038 
2039  @param columnIndex the first column is 1, the second is 2, ...
2040  @param x the new column value
2041 }
2042 procedure TZAbstractResultSet.UpdateFloat(ColumnIndex: Integer; Value: Single);
2043 begin
2044  RaiseReadOnlyException;
2045 end;
2046 
2047 {**
2048  Updates the designated column with a <code>double</code> value.
2049  The <code>updateXXX</code> methods are used to update column values in the
2050  current row or the insert row. The <code>updateXXX</code> methods do not
2051  update the underlying database; instead the <code>updateRow</code> or
2052  <code>insertRow</code> methods are called to update the database.
2053 
2054  @param columnIndex the first column is 1, the second is 2, ...
2055  @param x the new column value
2056 }
2057 procedure TZAbstractResultSet.UpdateDouble(ColumnIndex: Integer; Value: Double);
2058 begin
2059  RaiseReadOnlyException;
2060 end;
2061 
2062 {**
2063  Updates the designated column with a <code>java.math.BigDecimal</code>
2064  value.
2065  The <code>updateXXX</code> methods are used to update column values in the
2066  current row or the insert row. The <code>updateXXX</code> methods do not
2067  update the underlying database; instead the <code>updateRow</code> or
2068  <code>insertRow</code> methods are called to update the database.
2069 
2070  @param columnIndex the first column is 1, the second is 2, ...
2071  @param x the new column value
2072 }
2073 procedure TZAbstractResultSet.UpdateBigDecimal(ColumnIndex: Integer;
2074  Value: Extended);
2075 begin
2076  RaiseReadOnlyException;
2077 end;
2078 
2079 {**
2080  Updates the designated column with a <code>String</code> value.
2081  The <code>updateXXX</code> methods are used to update column values in the
2082  current row or the insert row. The <code>updateXXX</code> methods do not
2083  update the underlying database; instead the <code>updateRow</code> or
2084  <code>insertRow</code> methods are called to update the database.
2085 
2086  @param columnIndex the first column is 1, the second is 2, ...
2087  @param x the new column value
2088 }
2089 procedure TZAbstractResultSet.UpdatePChar(ColumnIndex: Integer; Value: PChar);
2090 begin
2091  UpdateString(ColumnIndex, Value);
2092 end;
2093 
2094 {**
2095  Updates the designated column with a <code>String</code> value.
2096  The <code>updateXXX</code> methods are used to update column values in the
2097  current row or the insert row. The <code>updateXXX</code> methods do not
2098  update the underlying database; instead the <code>updateRow</code> or
2099  <code>insertRow</code> methods are called to update the database.
2100 
2101  @param columnIndex the first column is 1, the second is 2, ...
2102  @param x the new column value
2103 }
2104 procedure TZAbstractResultSet.UpdateString(ColumnIndex: Integer; const Value: String);
2105 begin
2106  RaiseReadOnlyException;
2107 end;
2108 
2109 {**
2110  Updates the designated column with a <code>String</code> value.
2111  The <code>updateXXX</code> methods are used to update column values in the
2112  current row or the insert row. The <code>updateXXX</code> methods do not
2113  update the underlying database; instead the <code>updateRow</code> or
2114  <code>insertRow</code> methods are called to update the database.
2115 
2116  @param columnIndex the first column is 1, the second is 2, ...
2117  @param x the new column value
2118 }
2119 procedure TZAbstractResultSet.UpdateBinaryString(ColumnIndex: Integer; const Value: RawByteString);
2120 begin
2121  case GetMetaData.GetColumnType(ColumnIndex) of
2122  stBytes: UpdateBytes(ColumnIndex, StrToBytes(Value));
2123  stBinaryStream: GetBlob(ColumnIndex).SetString(Value);
2124  else
2125  UpdateString(ColumnIndex, ZDbcString(Value));
2126  end;
2127 end;
2128 
2129 {**
2130  Updates the designated column with a <code>WideString</code> value.
2131  The <code>updateXXX</code> methods are used to update column values in the
2132  current row or the insert row. The <code>updateXXX</code> methods do not
2133  update the underlying database; instead the <code>updateRow</code> or
2134  <code>insertRow</code> methods are called to update the database.
2135 
2136  @param columnIndex the first column is 1, the second is 2, ...
2137  @param x the new column value
2138 }
2139 procedure TZAbstractResultSet.UpdateUnicodeString(ColumnIndex: Integer;
2140  const Value: WideString);
2141 begin
2142  RaiseReadOnlyException;
2143 end;
2144 
2145 {**
2146  Updates the designated column with a <code>byte</code> array value.
2147  The <code>updateXXX</code> methods are used to update column values in the
2148  current row or the insert row. The <code>updateXXX</code> methods do not
2149  update the underlying database; instead the <code>updateRow</code> or
2150  <code>insertRow</code> methods are called to update the database.
2151 
2152  @param columnIndex the first column is 1, the second is 2, ...
2153  @param x the new column value
2154 }
2155 procedure TZAbstractResultSet.UpdateBytes(ColumnIndex: Integer;
2156  const Value: TByteDynArray);
2157 begin
2158  RaiseReadOnlyException;
2159 end;
2160 
2161 {**
2162  Updates the designated column with a <code>java.sql.Date</code> value.
2163  The <code>updateXXX</code> methods are used to update column values in the
2164  current row or the insert row. The <code>updateXXX</code> methods do not
2165  update the underlying database; instead the <code>updateRow</code> or
2166  <code>insertRow</code> methods are called to update the database.
2167 
2168  @param columnIndex the first column is 1, the second is 2, ...
2169  @param x the new column value
2170 }
2171 procedure TZAbstractResultSet.UpdateDate(ColumnIndex: Integer; Value: TDateTime);
2172 begin
2173  RaiseReadOnlyException;
2174 end;
2175 
2176 {**
2177  Updates the designated column with a <code>java.sql.Time</code> value.
2178  The <code>updateXXX</code> methods are used to update column values in the
2179  current row or the insert row. The <code>updateXXX</code> methods do not
2180  update the underlying database; instead the <code>updateRow</code> or
2181  <code>insertRow</code> methods are called to update the database.
2182 
2183  @param columnIndex the first column is 1, the second is 2, ...
2184  @param x the new column value
2185 }
2186 procedure TZAbstractResultSet.UpdateTime(ColumnIndex: Integer; Value: TDateTime);
2187 begin
2188  RaiseReadOnlyException;
2189 end;
2190 
2191 {**
2192  Updates the designated column with a <code>java.sql.Timestamp</code>
2193  value.
2194  The <code>updateXXX</code> methods are used to update column values in the
2195  current row or the insert row. The <code>updateXXX</code> methods do not
2196  update the underlying database; instead the <code>updateRow</code> or
2197  <code>insertRow</code> methods are called to update the database.
2198 
2199  @param columnIndex the first column is 1, the second is 2, ...
2200  @param x the new column value
2201 }
2202 procedure TZAbstractResultSet.UpdateTimestamp(ColumnIndex: Integer;
2203  Value: TDateTime);
2204 begin
2205  RaiseReadOnlyException;
2206 end;
2207 
2208 {**
2209  Updates the designated column with an ascii stream value.
2210  The <code>updateXXX</code> methods are used to update column values in the
2211  current row or the insert row. The <code>updateXXX</code> methods do not
2212  update the underlying database; instead the <code>updateRow</code> or
2213  <code>insertRow</code> methods are called to update the database.
2214 
2215  @param columnIndex the first column is 1, the second is 2, ...
2216  @param x the new column value
2217 }
2218 procedure TZAbstractResultSet.UpdateAsciiStream(ColumnIndex: Integer;
2219  Value: TStream);
2220 begin
2221  RaiseReadOnlyException;
2222 end;
2223 
2224 {**
2225  Updates the designated column with a binary stream value.
2226  The <code>updateXXX</code> methods are used to update column values in the
2227  current row or the insert row. The <code>updateXXX</code> methods do not
2228  update the underlying database; instead the <code>updateRow</code> or
2229  <code>insertRow</code> methods are called to update the database.
2230 
2231  @param columnIndex the first column is 1, the second is 2, ...
2232  @param x the new column value
2233  @param length the length of the stream
2234 }
2235 procedure TZAbstractResultSet.UpdateBinaryStream(ColumnIndex: Integer;
2236  Value: TStream);
2237 begin
2238  RaiseReadOnlyException;
2239 end;
2240 
2241 procedure TZAbstractResultSet.UpdateDataSet(ColumnIndex: Integer; Value: IZDataSet);
2242 begin
2243  RaiseReadOnlyException;
2244 end;
2245 {**
2246  Updates the designated column with a character stream value.
2247  The <code>updateXXX</code> methods are used to update column values in the
2248  current row or the insert row. The <code>updateXXX</code> methods do not
2249  update the underlying database; instead the <code>updateRow</code> or
2250  <code>insertRow</code> methods are called to update the database.
2251 
2252  @param columnIndex the first column is 1, the second is 2, ...
2253  @param x the new column value
2254 }
2255 procedure TZAbstractResultSet.UpdateUnicodeStream(ColumnIndex: Integer;
2256  Value: TStream);
2257 begin
2258  RaiseReadOnlyException;
2259 end;
2260 
2261 {**
2262  Updates the designated column with a variant value.
2263  The <code>updateXXX</code> methods are used to update column values in the
2264  current row or the insert row. The <code>updateXXX</code> methods do not
2265  update the underlying database; instead the <code>updateRow</code> or
2266  <code>insertRow</code> methods are called to update the database.
2267 
2268  @param columnIndex the first column is 1, the second is 2, ...
2269  @param x the new column value
2270 }
2271 procedure TZAbstractResultSet.UpdateValue(ColumnIndex: Integer;
2272  const Value: TZVariant);
2273 begin
2274  case Value.VType of
2275  vtBoolean: UpdateBoolean(ColumnIndex, Value.VBoolean);
2276  vtInteger: UpdateLong(ColumnIndex, Value.VInteger);
2277  vtFloat: UpdateBigDecimal(ColumnIndex, Value.VFloat);
2278  vtString: UpdateString(ColumnIndex, Value.VString);
2279  vtDateTime: UpdateTimestamp(ColumnIndex, Value.VDateTime);
2280  vtUnicodeString: UpdateUnicodeString(ColumnIndex, Value.VUnicodeString);
2281  else
2282  UpdateNull(ColumnIndex);
2283  end;
2284 end;
2285 
2286 {**
2287  Updates the DefaultExpression of the designated column with a <code>String</code> value.
2288  This changes the behaviour of the RowAccessor used by the Resultset
2289  @param columnIndex the first column is 1, the second is 2, ...
2290  @param x the new DefaultExpression value for the column
2291 }
2292 procedure TZAbstractResultSet.UpdateDefaultExpression(ColumnIndex: Integer; const Value: string);
2293 begin
2294  RaiseReadOnlyException;
2295 end;
2296 
2297 {**
2298  Updates the designated column with a <code>null</code> value.
2299  The <code>updateXXX</code> methods are used to update column values in the
2300  current row or the insert row. The <code>updateXXX</code> methods do not
2301  update the underlying database; instead the <code>updateRow</code> or
2302  <code>insertRow</code> methods are called to update the database.
2303 
2304  @param columnName the name of the column
2305 }
2306 procedure TZAbstractResultSet.UpdateNullByName(const ColumnName: string);
2307 begin
2308  UpdateNull(GetColumnIndex(ColumnName));
2309 end;
2310 
2311 {**
2312  Updates the designated column with a <code>boolean</code> value.
2313  The <code>updateXXX</code> methods are used to update column values in the
2314  current row or the insert row. The <code>updateXXX</code> methods do not
2315  update the underlying database; instead the <code>updateRow</code> or
2316  <code>insertRow</code> methods are called to update the database.
2317 
2318  @param columnName the name of the column
2319  @param x the new column value
2320 }
2321 procedure TZAbstractResultSet.UpdateBooleanByName(const ColumnName: string;
2322  Value: Boolean);
2323 begin
2324  UpdateBoolean(GetColumnIndex(ColumnName), Value);
2325 end;
2326 
2327 {**
2328  Updates the designated column with a <code>byte</code> value.
2329  The <code>updateXXX</code> methods are used to update column values in the
2330  current row or the insert row. The <code>updateXXX</code> methods do not
2331  update the underlying database; instead the <code>updateRow</code> or
2332  <code>insertRow</code> methods are called to update the database.
2333 
2334  @param columnName the name of the column
2335  @param x the new column value
2336 }
2337 procedure TZAbstractResultSet.UpdateByteByName(const ColumnName: string;
2338  Value: ShortInt);
2339 begin
2340  UpdateByte(GetColumnIndex(ColumnName), Value);
2341 end;
2342 
2343 {**
2344  Updates the designated column with a <code>short</code> value.
2345  The <code>updateXXX</code> methods are used to update column values in the
2346  current row or the insert row. The <code>updateXXX</code> methods do not
2347  update the underlying database; instead the <code>updateRow</code> or
2348  <code>insertRow</code> methods are called to update the database.
2349 
2350  @param columnName the name of the column
2351  @param x the new column value
2352 }
2353 procedure TZAbstractResultSet.UpdateShortByName(const ColumnName: string;
2354  Value: SmallInt);
2355 begin
2356  UpdateShort(GetColumnIndex(ColumnName), Value);
2357 end;
2358 
2359 {**
2360  Updates the designated column with an <code>int</code> value.
2361  The <code>updateXXX</code> methods are used to update column values in the
2362  current row or the insert row. The <code>updateXXX</code> methods do not
2363  update the underlying database; instead the <code>updateRow</code> or
2364  <code>insertRow</code> methods are called to update the database.
2365 
2366  @param columnName the name of the column
2367  @param x the new column value
2368 }
2369 procedure TZAbstractResultSet.UpdateIntByName(const ColumnName: string;
2370  Value: Integer);
2371 begin
2372  UpdateInt(GetColumnIndex(ColumnName), Value);
2373 end;
2374 
2375 {**
2376  Updates the designated column with a <code>long</code> value.
2377  The <code>updateXXX</code> methods are used to update column values in the
2378  current row or the insert row. The <code>updateXXX</code> methods do not
2379  update the underlying database; instead the <code>updateRow</code> or
2380  <code>insertRow</code> methods are called to update the database.
2381 
2382  @param columnName the name of the column
2383  @param x the new column value
2384 }
2385 procedure TZAbstractResultSet.UpdateLongByName(const ColumnName: string;
2386  Value: Int64);
2387 begin
2388  UpdateLong(GetColumnIndex(ColumnName), Value);
2389 end;
2390 
2391 {**
2392  Updates the designated column with a <code>float </code> value.
2393  The <code>updateXXX</code> methods are used to update column values in the
2394  current row or the insert row. The <code>updateXXX</code> methods do not
2395  update the underlying database; instead the <code>updateRow</code> or
2396  <code>insertRow</code> methods are called to update the database.
2397 
2398  @param columnName the name of the column
2399  @param x the new column value
2400 }
2401 procedure TZAbstractResultSet.UpdateFloatByName(const ColumnName: string;
2402  Value: Single);
2403 begin
2404  UpdateFloat(GetColumnIndex(ColumnName), Value);
2405 end;
2406 
2407 {**
2408  Updates the designated column with a <code>double</code> value.
2409  The <code>updateXXX</code> methods are used to update column values in the
2410  current row or the insert row. The <code>updateXXX</code> methods do not
2411  update the underlying database; instead the <code>updateRow</code> or
2412  <code>insertRow</code> methods are called to update the database.
2413 
2414  @param columnName the name of the column
2415  @param x the new column value
2416 }
2417 procedure TZAbstractResultSet.UpdateDoubleByName(const ColumnName: string;
2418  Value: Double);
2419 begin
2420  UpdateDouble(GetColumnIndex(ColumnName), Value);
2421 end;
2422 
2423 {**
2424  Updates the designated column with a <code>java.sql.BigDecimal</code>
2425  value.
2426  The <code>updateXXX</code> methods are used to update column values in the
2427  current row or the insert row. The <code>updateXXX</code> methods do not
2428  update the underlying database; instead the <code>updateRow</code> or
2429  <code>insertRow</code> methods are called to update the database.
2430 
2431  @param columnName the name of the column
2432  @param x the new column value
2433 }
2434 procedure TZAbstractResultSet.UpdateBigDecimalByName(const ColumnName: string;
2435  Value: Extended);
2436 begin
2437  UpdateBigDecimal(GetColumnIndex(ColumnName), Value);
2438 end;
2439 
2440 {**
2441  Updates the designated column with a <code>String</code> value.
2442  The <code>updateXXX</code> methods are used to update column values in the
2443  current row or the insert row. The <code>updateXXX</code> methods do not
2444  update the underlying database; instead the <code>updateRow</code> or
2445  <code>insertRow</code> methods are called to update the database.
2446 
2447  @param columnName the name of the column
2448  @param x the new column value
2449 }
2450 procedure TZAbstractResultSet.UpdatePCharByName(const ColumnName: string;
2451  Value: PChar);
2452 begin
2453  UpdatePChar(GetColumnIndex(ColumnName), Value);
2454 end;
2455 
2456 {**
2457  Updates the designated column with a <code>String</code> value.
2458  The <code>updateXXX</code> methods are used to update column values in the
2459  current row or the insert row. The <code>updateXXX</code> methods do not
2460  update the underlying database; instead the <code>updateRow</code> or
2461  <code>insertRow</code> methods are called to update the database.
2462 
2463  @param columnName the name of the column
2464  @param x the new column value
2465 }
2466 procedure TZAbstractResultSet.UpdateStringByName(const ColumnName: string;
2467  const Value: String);
2468 begin
2469  UpdateString(GetColumnIndex(ColumnName), Value);
2470 end;
2471 
2472 {**
2473  Updates the designated column with a <code>String</code> value.
2474  The <code>updateXXX</code> methods are used to update column values in the
2475  current row or the insert row. The <code>updateXXX</code> methods do not
2476  update the underlying database; instead the <code>updateRow</code> or
2477  <code>insertRow</code> methods are called to update the database.
2478 
2479  @param columnName the name of the column
2480  @param x the new column value
2481 }
2482 procedure TZAbstractResultSet.UpdateBinaryStringByName(const ColumnName: string;
2483  const Value: RawByteString);
2484 begin
2485  UpdateBinaryString(GetColumnIndex(ColumnName), Value);
2486 end;
2487 
2488 {**
2489  Updates the designated column with a <code>WideString</code> value.
2490  The <code>updateXXX</code> methods are used to update column values in the
2491  current row or the insert row. The <code>updateXXX</code> methods do not
2492  update the underlying database; instead the <code>updateRow</code> or
2493  <code>insertRow</code> methods are called to update the database.
2494 
2495  @param columnName the name of the column
2496  @param x the new column value
2497 }
2498 procedure TZAbstractResultSet.UpdateUnicodeStringByName(const ColumnName: string;
2499  const Value: WideString);
2500 begin
2501  UpdateUnicodeString(GetColumnIndex(ColumnName), Value);
2502 end;
2503 
2504 {**
2505  Updates the designated column with a <code>boolean</code> value.
2506  The <code>updateXXX</code> methods are used to update column values in the
2507  current row or the insert row. The <code>updateXXX</code> methods do not
2508  update the underlying database; instead the <code>updateRow</code> or
2509  <code>insertRow</code> methods are called to update the database.
2510 
2511  JDBC 2.0
2512 
2513  Updates a column with a byte array value.
2514 
2515  The <code>updateXXX</code> methods are used to update column values in the
2516  current row, or the insert row. The <code>updateXXX</code> methods do not
2517  update the underlying database; instead the <code>updateRow</code> or <code>insertRow</code>
2518  methods are called to update the database.
2519 
2520  @param columnName the name of the column
2521  @param x the new column value
2522 }
2523 procedure TZAbstractResultSet.UpdateBytesByName(const ColumnName: string;
2524  const Value: TByteDynArray);
2525 begin
2526  UpdateBytes(GetColumnIndex(ColumnName), Value);
2527 end;
2528 
2529 {**
2530  Updates the designated column with a <code>java.sql.Date</code> value.
2531  The <code>updateXXX</code> methods are used to update column values in the
2532  current row or the insert row. The <code>updateXXX</code> methods do not
2533  update the underlying database; instead the <code>updateRow</code> or
2534  <code>insertRow</code> methods are called to update the database.
2535 
2536  @param columnName the name of the column
2537  @param x the new column value
2538 }
2539 procedure TZAbstractResultSet.UpdateDateByName(const ColumnName: string;
2540  Value: TDateTime);
2541 begin
2542  UpdateDate(GetColumnIndex(ColumnName), Value);
2543 end;
2544 
2545 {**
2546  Updates the designated column with a <code>java.sql.Time</code> value.
2547  The <code>updateXXX</code> methods are used to update column values in the
2548  current row or the insert row. The <code>updateXXX</code> methods do not
2549  update the underlying database; instead the <code>updateRow</code> or
2550  <code>insertRow</code> methods are called to update the database.
2551 
2552  @param columnName the name of the column
2553  @param x the new column value
2554 }
2555 procedure TZAbstractResultSet.UpdateTimeByName(const ColumnName: string;
2556  Value: TDateTime);
2557 begin
2558  UpdateTime(GetColumnIndex(ColumnName), Value);
2559 end;
2560 
2561 {**
2562  Updates the designated column with a <code>java.sql.Timestamp</code>
2563  value.
2564  The <code>updateXXX</code> methods are used to update column values in the
2565  current row or the insert row. The <code>updateXXX</code> methods do not
2566  update the underlying database; instead the <code>updateRow</code> or
2567  <code>insertRow</code> methods are called to update the database.
2568 
2569  @param columnName the name of the column
2570  @param x the new column value
2571 }
2572 procedure TZAbstractResultSet.UpdateTimestampByName(const ColumnName: string;
2573  Value: TDateTime);
2574 begin
2575  UpdateTimestamp(GetColumnIndex(ColumnName), Value);
2576 end;
2577 
2578 {**
2579  Updates the designated column with an ascii stream value.
2580  The <code>updateXXX</code> methods are used to update column values in the
2581  current row or the insert row. The <code>updateXXX</code> methods do not
2582  update the underlying database; instead the <code>updateRow</code> or
2583  <code>insertRow</code> methods are called to update the database.
2584 
2585  @param columnName the name of the column
2586  @param x the new column value
2587 }
2588 procedure TZAbstractResultSet.UpdateAsciiStreamByName(const ColumnName: string;
2589  Value: TStream);
2590 begin
2591  UpdateAsciiStream(GetColumnIndex(ColumnName), Value);
2592 end;
2593 
2594 {**
2595  Updates the designated column with a binary stream value.
2596  The <code>updateXXX</code> methods are used to update column values in the
2597  current row or the insert row. The <code>updateXXX</code> methods do not
2598  update the underlying database; instead the <code>updateRow</code> or
2599  <code>insertRow</code> methods are called to update the database.
2600 
2601  @param columnName the name of the column
2602  @param x the new column value
2603 }
2604 procedure TZAbstractResultSet.UpdateBinaryStreamByName(const ColumnName: string;
2605  Value: TStream);
2606 begin
2607  UpdateBinaryStream(GetColumnIndex(ColumnName), Value);
2608 end;
2609 
2610 procedure TZAbstractResultSet.UpdateDataSetByName(const ColumnName: string;
2611  Value: IZDataSet);
2612 begin
2613  UpdateDataSet(GetColumnIndex(ColumnName), Value);
2614 end;
2615 
2616 {**
2617  Updates the designated column with a character stream value.
2618  The <code>updateXXX</code> methods are used to update column values in the
2619  current row or the insert row. The <code>updateXXX</code> methods do not
2620  update the underlying database; instead the <code>updateRow</code> or
2621  <code>insertRow</code> methods are called to update the database.
2622 
2623  @param columnName the name of the column
2624  @param x the new column value
2625 }
2626 procedure TZAbstractResultSet.UpdateUnicodeStreamByName(const ColumnName: string;
2627  Value: TStream);
2628 begin
2629  UpdateUnicodeStream(GetColumnIndex(ColumnName), Value);
2630 end;
2631 
2632 {**
2633  Updates the designated column with a <code>Variant</code> value.
2634  The <code>updateXXX</code> methods are used to update column values in the
2635  current row or the insert row. The <code>updateXXX</code> methods do not
2636  update the underlying database; instead the <code>updateRow</code> or
2637  <code>insertRow</code> methods are called to update the database.
2638 
2639  @param columnName the name of the column
2640  @param x the new column value
2641 }
2642 procedure TZAbstractResultSet.UpdateValueByName(const ColumnName: string;
2643  const Value: TZVariant);
2644 begin
2645  UpdateValue(GetColumnIndex(ColumnName), Value);
2646 end;
2647 
2648 {**
2649  Inserts the contents of the insert row into this
2650  <code>ResultSet</code> objaect and into the database.
2651  The cursor must be on the insert row when this method is called.
2652 }
2653 procedure TZAbstractResultSet.InsertRow;
2654 begin
2655  RaiseReadOnlyException;
2656 end;
2657 
2658 {**
2659  Updates the underlying database with the new contents of the
2660  current row of this <code>ResultSet</code> object.
2661  This method cannot be called when the cursor is on the insert row.
2662 }
2663 procedure TZAbstractResultSet.UpdateRow;
2664 begin
2665  RaiseReadOnlyException;
2666 end;
2667 
2668 {**
2669  Deletes the current row from this <code>ResultSet</code> object
2670  and from the underlying database. This method cannot be called when
2671  the cursor is on the insert row.
2672 }
2673 procedure TZAbstractResultSet.DeleteRow;
2674 begin
2675  RaiseReadOnlyException;
2676 end;
2677 
2678 {**
2679  Refreshes the current row with its most recent value in
2680  the database. This method cannot be called when
2681  the cursor is on the insert row.
2682 
2683  <P>The <code>refreshRow</code> method provides a way for an
2684  application to
2685  explicitly tell the JDBC driver to refetch a row(s) from the
2686  database. An application may want to call <code>refreshRow</code> when
2687  caching or prefetching is being done by the JDBC driver to
2688  fetch the latest value of a row from the database. The JDBC driver
2689  may actually refresh multiple rows at once if the fetch size is
2690  greater than one.
2691 
2692  <P> All values are refetched subject to the transaction isolation
2693  level and cursor sensitivity. If <code>refreshRow</code> is called after
2694  calling an <code>updateXXX</code> method, but before calling
2695  the method <code>updateRow</code>, then the
2696  updates made to the row are lost. Calling the method
2697  <code>refreshRow</code> frequently will likely slow performance.
2698 }
2699 procedure TZAbstractResultSet.RefreshRow;
2700 begin
2701  RaiseUnsupportedException;
2702 end;
2703 
2704 {**
2705  Cancels the updates made to the current row in this
2706  <code>ResultSet</code> object.
2707  This method may be called after calling an
2708  <code>updateXXX</code> method(s) and before calling
2709  the method <code>updateRow</code> to roll back
2710  the updates made to a row. If no updates have been made or
2711  <code>updateRow</code> has already been called, this method has no
2712  effect.
2713 }
2714 procedure TZAbstractResultSet.CancelRowUpdates;
2715 begin
2716  RaiseReadOnlyException;
2717 end;
2718 
2719 {**
2720  Moves the cursor to the insert row. The current cursor position is
2721  remembered while the cursor is positioned on the insert row.
2722 
2723  The insert row is a special row associated with an updatable
2724  result set. It is essentially a buffer where a new row may
2725  be constructed by calling the <code>updateXXX</code> methods prior to
2726  inserting the row into the result set.
2727 
2728  Only the <code>updateXXX</code>, <code>getXXX</code>,
2729  and <code>insertRow</code> methods may be
2730  called when the cursor is on the insert row. All of the columns in
2731  a result set must be given a value each time this method is
2732  called before calling <code>insertRow</code>.
2733  An <code>updateXXX</code> method must be called before a
2734  <code>getXXX</code> method can be called on a column value.
2735 }
2736 procedure TZAbstractResultSet.MoveToInsertRow;
2737 begin
2738  RaiseReadOnlyException;
2739 end;
2740 
2741 {**
2742  Moves the cursor to the remembered cursor position, usually the
2743  current row. This method has no effect if the cursor is not on
2744  the insert row.
2745 }
2746 procedure TZAbstractResultSet.MoveToCurrentRow;
2747 begin
2748 end;
2749 
2750 {**
2751  Compares fields from two row buffers.
2752  @param Row1 the first row buffer to compare.
2753  @param Row2 the second row buffer to compare.
2754  @param ColumnIndices column indices to compare.
2755  @param ColumnDirs compare direction for each columns.
2756 }
2757 function TZAbstractResultSet.CompareRows(Row1, Row2: Integer;
2758  const ColumnIndices: TIntegerDynArray; const ColumnDirs: TBooleanDynArray): Integer;
2759 var
2760  I: Integer;
2761  ColumnIndex: Integer;
2762  SaveRowNo: Integer;
2763  Value1, Value2: TZVariant;
2764 
2765  function CompareFloat(Value1, Value2: Extended): Integer;
2766  begin
2767  Value1 := Value1 - Value2;
2768  if Value1 > 0 then
2769  Result := 1
2770  else if Value1 < 0 then
2771  Result := -1
2772  else
2773  Result := 0;
2774  end;
2775 
2776 begin
2777  Result := 0;
2778  SaveRowNo := RowNo;
2779  try
2780  for I := Low(ColumnIndices) to High(ColumnIndices) do
2781  begin
2782  ColumnIndex := ColumnIndices[I];
2783 
2784  MoveAbsolute(Row1);
2785  Value1 := GetValue(ColumnIndex);
2786  MoveAbsolute(Row2);
2787  Value2 := GetValue(ColumnIndex);
2788 
2789  { Checks for both Null columns. }
2790  if (Value1.VType = vtNull) and (Value2.VType = vtNull) then
2791  Continue;
2792  { Checks for not-Null and Null columns. }
2793  if (Value1.VType = vtNull) or (Value2.VType = vtNull) then
2794  begin
2795  if Value1.VType <> vtNull then
2796  Result := 1
2797  else
2798  Result := -1;
2799  if not ColumnDirs[I] then
2800  Result := -Result;
2801  Break;
2802  end;
2803  case Value1.VType of
2804  vtBoolean:
2805  begin
2806  if Value1.VBoolean = Value2.VBoolean then
2807  Result := 0
2808  else if Value1.VBoolean = True then
2809  Result := 1
2810  else
2811  Result := -1;
2812  end;
2813  vtInteger:
2814  Result := Value1.VInteger - Value2.VInteger;
2815  vtFloat:
2816  Result := CompareFloat(Value1.VFloat, Value2.VFloat);
2817  vtDateTime:
2818  Result := CompareFloat(Value1.VDateTime, Value2.VDateTime);
2819  vtString:
2820  Result := AnsiCompareStr(Value1.VString, Value2.VString);
2821  vtUnicodeString:
2822  Result := WideCompareStr(Value1.VUnicodeString, Value2.VUnicodeString);
2823  end;
2824  if Result <> 0 then
2825  begin
2826  if not ColumnDirs[I] then
2827  Result := -Result;
2828  Break;
2829  end;
2830  end;
2831  finally
2832  MoveAbsolute(SaveRowNo);
2833  end;
2834 end;
2835 
2836 {**
2837  Returns the <code>Statement</code> object that produced this
2838  <code>ResultSet</code> object.
2839  If the result set was generated some other way, such as by a
2840  <code>DatabaseMetaData</code> method, this method returns
2841  <code>null</code>.
2842 
2843  @return the <code>Statment</code> object that produced
2844  this <code>ResultSet</code> object or <code>null</code>
2845  if the result set was produced some other way
2846 }
2847 function TZAbstractResultSet.GetStatement: IZStatement;
2848 begin
2849  Result := FStatement;
2850 end;
2851 
2852 function TZAbstractResultSet.GetConSettings: PZConsettings;
2853 begin
2854  Result := ConSettings;
2855 end;
2856 
2857 { TZAbstractBlob }
2858 
2859 {**
2860  Constructs this class and assignes the main properties.
2861  @param Stream a data string object.
2862 }
2863 constructor TZAbstractBlob.CreateWithStream(Stream: TStream;
2864  Connection: IZConnection = Nil; Decoded: Boolean = False);
2865 begin
2866  inherited Create;
2867  FUpdated := False;
2868  FConnection := Connection;
2869  FDecoded := Decoded;
2870  if Assigned(Stream) then
2871  begin
2872  FBlobSize := Stream.Size;
2873  if FBlobSize > 0 then
2874  begin
2875  GetMem(FBlobData, FBlobSize);
2876  Stream.Position := 0;
2877  Stream.ReadBuffer(FBlobData^, FBlobSize);
2878  end;
2879  end
2880  else
2881  begin
2882  FBlobSize := -1;
2883  FBlobData := nil;
2884  end;
2885 end;
2886 
2887 {**
2888  Constructs this class and assignes the main properties.
2889  @param Data a pointer to the blobdata.
2890  @param Size the size of the blobdata.
2891 }
2892 constructor TZAbstractBlob.CreateWithData(Data: Pointer; Size: Integer;
2893  Connection: IZConnection = nil; Decoded: Boolean = False);
2894 begin
2895  inherited Create;
2896  FConnection := Connection;
2897  FBlobData := nil;
2898  FBlobSize := Size;
2899  FDecoded := Decoded;
2900  if FBlobSize > 0 then
2901  begin
2902  GetMem(FBlobData, FBlobSize);
2903  System.Move(Data^, FBlobData^, FBlobSize);
2904  end;
2905  FUpdated := False;
2906 end;
2907 
2908 {**
2909  Destroys this object and cleanups the memory.
2910 }
2911 destructor TZAbstractBlob.Destroy;
2912 begin
2913  Clear;
2914  inherited Destroy;
2915 end;
2916 
2917 {**
2918  Clears the content of this blob.
2919 }
2920 procedure TZAbstractBlob.Clear;
2921 begin
2922  if Assigned(FBlobData) then
2923  FreeMem(FBlobData);
2924  FBlobData := nil;
2925  FBlobSize := -1;
2926  FUpdated := True;
2927 end;
2928 
2929 {**
2930  Clones this blob object.
2931  @return a clonned blob object.
2932 }
2933 function TZAbstractBlob.Clone: IZBlob;
2934 begin
2935  Result := TZAbstractBlob.CreateWithData(FBlobData, FBlobSize, FConnection, FDecoded);
2936 end;
2937 
2938 {**
2939  Checks if this Text-blob was right Decoded.
2940  @return <code>True</code> if this blob is empty.
2941 }
2942 function TZAbstractBlob.WasDecoded: Boolean;
2943 begin
2944  Result := FDecoded;
2945 end;
2946 
2947 {**
2948  Returns the IZConnection which is propable needed to handle the encoding
2949  @return <code>IZConnection</code> if assigned
2950 }
2951 function TZAbstractBlob.Connection: IZConnection;
2952 begin
2953  Result := FConnection;
2954 end;
2955 
2956 {**
2957  Checks if this blob has an empty content.
2958  @return <code>True</code> if this blob is empty.
2959 }
2960 function TZAbstractBlob.IsEmpty: Boolean;
2961 begin
2962  Result := FBlobSize < 0;
2963 end;
2964 
2965 {**
2966  Checks if the content of this blob was updated.
2967  @return <code>True</code> is this blob was updated.
2968 }
2969 function TZAbstractBlob.IsUpdated: Boolean;
2970 begin
2971  Result := FUpdated;
2972 end;
2973 
2974 {**
2975  Gets the length of the stored data.
2976  @return the length of the stored data or null if the blob is empty.
2977 }
2978 function TZAbstractBlob.Length: LongInt;
2979 begin
2980  Result := FBlobSize;
2981 end;
2982 
2983 {**
2984  Gets the string from the stored data.
2985  @return a string which contains the stored data.
2986 }
2987 function TZAbstractBlob.GetString: RawByteString;
2988 begin
2989  if (FBlobSize > 0) and Assigned(FBlobData) then
2990  if FDecoded then
2991  Result := FConnection.GetIZPlainDriver.ZPlainString(GetUnicodeString, FConnection.GetConSettings)
2992  else
2993  begin
2994  {$IFDEF WITH_RAWBYTESTRING}
2995  SetLength(Result, FBlobSize);
2996  System.Move(PAnsiChar(FBlobData)^, PAnsiChar(Result)^, FBlobSize);
2997  {$ELSE}
2998  System.SetString(Result, PAnsiChar(FBlobData), FBlobSize);
2999  {$ENDIF}
3000  end
3001  else
3002  Result := '';
3003 end;
3004 
3005 {**
3006  Sets a new string data to this blob content.
3007  @param Value a new string data.
3008 }
3009 procedure TZAbstractBlob.SetString(const Value: RawByteString);
3010 begin
3011  Clear;
3012  FBlobSize := System.Length(Value);
3013  if FBlobSize > 0 then
3014  begin
3015  GetMem(FBlobData, FBlobSize);
3016  System.Move(PAnsiChar(Value)^, FBlobData^, FBlobSize);
3017  end;
3018  FUpdated := True;
3019 end;
3020 
3021 {**
3022  Gets the wide string from the stored data.
3023  @return a string which contains the stored data.
3024 }
3025 function TZAbstractBlob.GetUnicodeString: WideString;
3026 var
3027  Bytes: TByteDynArray;
3028 begin
3029  if (FBlobSize > 0) and Assigned(FBlobData) then
3030  if FDecoded then
3031  begin
3032  SetLength(Result, FBlobSize div 2);
3033  System.Move(PWidechar(FBlobData)^, PWideChar(Result)^, FBlobSize);
3034  end
3035  else
3036  begin
3037  SetLength(Bytes, FBlobSize +2);
3038  System.move(FBlobData^, Pointer(Bytes)^, FBlobSize);
3039  if ( not ( {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(Bytes)) = Cardinal(FBlobSize) ) ) and
3040  ( {$IFDEF DELPHI14_UP}StrLen{$ELSE}System.Length{$ENDIF}(PWideChar(Bytes)) = Cardinal(FBlobSize) div 2 ) then
3041  begin
3042  SetLength(Result, FBlobSize div 2);
3043  System.Move(PWidechar(Bytes)^, PWideChar(Result)^, FBlobSize);
3044  end
3045  else
3046  Result := FConnection.GetIZPlainDriver.ZDbcUnicodeString(PAnsiChar(Bytes), FConnection.GetConSettings.CTRL_CP);
3047  SetLength(Bytes, 0);
3048  end
3049  else
3050  Result := '';
3051 end;
3052 
3053 {**
3054  Sets a new string data to this blob content.
3055  @param Value a new wide string data.
3056 }
3057 procedure TZAbstractBlob.SetUnicodeString(const Value: WideString);
3058 begin
3059  Clear;
3060  FBlobSize := System.Length(Value) *2;
3061  if FBlobSize > 0 then
3062  begin
3063  GetMem(FBlobData, FBlobSize);
3064  System.Move(PWideChar(Value)^, FBlobData^, FBlobSize);
3065  end;
3066  FUpdated := True;
3067  FDecoded := True;
3068 end;
3069 
3070 {**
3071  Gets the byte buffer from the stored data.
3072  @return a byte buffer which contains the stored data.
3073 }
3074 function TZAbstractBlob.GetBytes: TByteDynArray;
3075 begin
3076  if not IsEmpty then
3077  begin
3078  if (FBlobSize > 0) and Assigned(FBlobData) then begin
3079  SetLength(Result, FBlobSize);
3080  Move(FBlobData^, Result[0], FBlobSize);
3081  end else
3082  Result := nil;
3083  end
3084  else
3085  Result := nil;
3086 end;
3087 
3088 {**
3089  Sets a new byte buffer to this blob content.
3090  @param Value a new byte buffer.
3091 }
3092 procedure TZAbstractBlob.SetBytes(const Value: TByteDynArray);
3093 begin
3094  Clear;
3095  if Value <> nil then
3096  begin
3097  FBlobSize := System.Length(Value);
3098  if FBlobSize > 0 then
3099  begin
3100  GetMem(FBlobData, FBlobSize);
3101  System.Move(Value[0], FBlobData^, FBlobSize);
3102  end;
3103  end;
3104  FUpdated := True;
3105 end;
3106 
3107 function TZAbstractBlob.GetUnicodeStream: TStream;
3108 var
3109  ws: WideString;
3110 begin
3111  Result := TMemoryStream.Create;
3112  if (FBlobSize > 0) and Assigned(FBlobData) then
3113  begin
3114  if ( not ( {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(FBlobData)) = Cardinal(FBlobSize) ) ) and
3115  ( {$IFDEF DELPHI14_UP}StrLen{$ELSE}System.Length{$ENDIF}(PWideChar(FBlobData)) = Cardinal(FBlobSize) div 2 ) then
3116  begin
3117  Result.Size := FBlobSize;
3118  System.Move(PWidechar(FBlobData)^, TMemoryStream(Result).Memory^, FBlobSize);
3119  end
3120  else
3121  begin
3122  ws:=GetUnicodeString;
3123  Result.Size := System.Length(WS)*2;
3124  System.Move(ws[1], TMemoryStream(Result).Memory^, Result.Size);
3125  end;
3126  end;
3127  Result.Position := 0;
3128 end;
3129 
3130 {**
3131  Gets the associated stream object.
3132  @return an associated or newly created stream object.
3133 }
3134 function TZAbstractBlob.GetStream: TStream;
3135 begin
3136  Result := TMemoryStream.Create;
3137  if (FBlobSize > 0) and Assigned(FBlobData) then
3138  begin
3139  Result.Size := FBlobSize;
3140  System.Move(FBlobData^, TMemoryStream(Result).Memory^, FBlobSize);
3141  end;
3142  Result.Position := 0;
3143 end;
3144 
3145 {**
3146  Sets a data from the specified stream into this blob.
3147  @param Value a stream object to be stored into this blob.
3148 }
3149 procedure TZAbstractBlob.SetStream(Value: TStream; Decoded: Boolean = False);
3150 begin
3151  Clear;
3152  if Assigned(Value) then
3153  begin
3154  FBlobSize := Value.Size;
3155  if FBlobSize > 0 then
3156  begin
3157  GetMem(FBlobData, FBlobSize);
3158  Value.Position := 0;
3159  Value.ReadBuffer(FBlobData^, FBlobSize);
3160  end;
3161  end
3162  else
3163  begin
3164  FBlobSize := -1;
3165  FBlobData := nil;
3166  end;
3167  FUpdated := True;
3168  FDecoded := Decoded;
3169 end;
3170 
3171 function TZAbstractBlob.GetBuffer: Pointer;
3172 begin
3173  Result := FBlobData;
3174 end;
3175 
3176 procedure TZAbstractBlob.SetBuffer(Buffer: Pointer; Length: Integer);
3177 begin
3178  FBlobSize := Length;
3179  if Assigned(Buffer) and ( Length > 0 ) then
3180  begin
3181  FBlobData := nil;
3182  GetMem(FBlobData, Length);
3183  Move(FBlobData^, Buffer^, Length);
3184  end
3185  else
3186  begin
3187  FBlobSize := -1;
3188  FBlobData := nil;
3189  end;
3190  FUpdated := True;
3191 end;
3192 
3193 end.