1 {*********************************************************}
3 { Zeos Database Objects }
4 { Caching Classes and Interfaces }
6 { Originally written by Sergey Seroukhov }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
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. }
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. }
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) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
63 Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,
64 ZClasses, ZDbcIntfs, ZDbcResultSet, ZDbcResultSetMetadata, ZVariant,
69 {** Defines a row status type. }
70 TZRowUpdateType = (utUnmodified, utModified, utInserted, utDeleted);
71 TZRowUpdateTypes = set of TZRowUpdateType;
73 TZByteArray = array[0..4096 * SizeOf(Pointer)] of Byte;
74 {** Defines a header for row buffer. }
75 {ludob. Notes on alignment:
76 Columns contains a record per field with the structure
79 field records are addressed through offsets in Columns stored in FColumnOffsets.
80 Since anything can be stored as fielddata including pointers, fielddata needs
81 to be aligned to pointer. To do this Columns is aligned to pointer and
82 FColumnOffsets is aligned to pointer - 1 (the null:byte). The latter is
83 done in TZRowAccessor.Create where FColumnOffsets is filled in.
84 FPC_REQUIRES_PROPER_ALIGNMENT is a fpc build in define}
85 TZRowBuffer = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record
87 UpdateType: TZRowUpdateType;
89 {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
94 PZRowBuffer = ^TZRowBuffer;
96 {** Implements a column buffer accessor. }
97 TZRowAccessor = class(TZCodePagedObject)
100 FColumnsSize: Integer;
101 FColumnCount: Integer;
102 FColumnNames: array of string;
103 FColumnCases: array of Boolean;
104 FColumnTypes: array of TZSQLType;
105 FColumnLengths: array of Integer;
106 FColumnOffsets: array of Integer;
107 FColumnDefaultExpressions: array of string;
108 FBuffer: PZRowBuffer;
112 function GetColumnSize(ColumnInfo: TZColumnInfo): Integer;
113 function GetBlobObject(Buffer: PZRowBuffer; ColumnIndex: Integer): IZBlob;
114 procedure SetBlobObject(Buffer: PZRowBuffer; ColumnIndex: Integer;
116 function InternalGetBytes(Buffer: PZRowBuffer; ColumnIndex: Integer): TByteDynArray;
117 procedure InternalSetBytes(Buffer: PZRowBuffer; ColumnIndex: Integer;
118 Value: TByteDynArray; NewPointer: Boolean = False);
119 procedure InternalSetString(Buffer: PZRowBuffer; ColumnIndex: Integer;
120 Value: String; NewPointer: Boolean = False);
121 procedure InternalSetUnicodeString(Buffer: PZRowBuffer; ColumnIndex: Integer;
122 Value: ZWideString; NewPointer: Boolean = False);
124 procedure CheckColumnIndex(ColumnIndex: Integer);
125 procedure CheckColumnConvertion(ColumnIndex: Integer; ResultType: TZSQLType);
128 constructor Create(ColumnsInfo: TObjectList; ConSettings: PZConSettings);
129 destructor Destroy; override;
131 function AllocBuffer(var Buffer: PZRowBuffer): PZRowBuffer;
132 procedure InitBuffer(Buffer: PZRowBuffer);
133 procedure CopyBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);
134 procedure MoveBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);
135 procedure CloneBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);
136 procedure ClearBuffer(Buffer: PZRowBuffer);
137 procedure DisposeBuffer(Buffer: PZRowBuffer);
139 function CompareBuffers(Buffer1, Buffer2: PZRowBuffer;
140 ColumnIndices: TIntegerDynArray; ColumnDirs: TBooleanDynArray): Integer;
142 function Alloc: PZRowBuffer;
144 procedure CopyTo(DestBuffer: PZRowBuffer);
145 procedure CopyFrom(SrcBuffer: PZRowBuffer);
146 procedure MoveTo(DestBuffer: PZRowBuffer);
147 procedure MoveFrom(SrcBuffer: PZRowBuffer);
148 procedure CloneTo(DestBuffer: PZRowBuffer);
149 procedure CloneFrom(SrcBuffer: PZRowBuffer);
153 function GetColumnData(ColumnIndex: Integer; var IsNull: Boolean): Pointer;
154 function GetColumnDataSize(ColumnIndex: Integer): Integer;
156 function GetColumnName(ColumnIndex: Integer): string;
157 function GetColumnCase(ColumnIndex: Integer): Boolean;
158 function GetColumnType(ColumnIndex: Integer): TZSQLType;
159 function GetColumnLength(ColumnIndex: Integer): Integer;
160 function GetColumnOffSet(ColumnIndex: Integer): Integer;
161 function GetColumnDefaultExpression(ColumnIndex: Integer): string;
162 procedure SetColumnDefaultExpression(ColumnIndex: Integer; Value: string);
164 //======================================================================
165 // Methods for accessing results by column index
166 //======================================================================
168 function IsNull(ColumnIndex: Integer): Boolean;
169 function GetPChar(ColumnIndex: Integer; var IsNull: Boolean): PChar;
170 function GetString(ColumnIndex: Integer; var IsNull: Boolean): String;
171 function GetUnicodeString(ColumnIndex: Integer; var IsNull: Boolean): WideString;
172 function GetBoolean(ColumnIndex: Integer; var IsNull: Boolean): Boolean;
173 function GetByte(ColumnIndex: Integer; var IsNull: Boolean): ShortInt;
174 function GetShort(ColumnIndex: Integer; var IsNull: Boolean): SmallInt;
175 function GetInt(ColumnIndex: Integer; var IsNull: Boolean): Integer;
176 function GetLong(ColumnIndex: Integer; var IsNull: Boolean): Int64;
177 function GetFloat(ColumnIndex: Integer; var IsNull: Boolean): Single;
178 function GetDouble(ColumnIndex: Integer; var IsNull: Boolean): Double;
179 function GetBigDecimal(ColumnIndex: Integer; var IsNull: Boolean): Extended;
180 function GetBytes(ColumnIndex: Integer; var IsNull: Boolean): TByteDynArray;
181 function GetDate(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;
182 function GetTime(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;
183 function GetTimestamp(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;
184 function GetAsciiStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;
185 function GetUnicodeStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;
186 function GetBinaryStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;
187 function GetBlob(ColumnIndex: Integer; var IsNull: Boolean): IZBlob;
188 function GetDataSet(ColumnIndex: Integer; var IsNull: Boolean): IZDataSet;
189 function GetValue(ColumnIndex: Integer): TZVariant;
191 //---------------------------------------------------------------------
193 //---------------------------------------------------------------------
195 procedure SetNotNull(ColumnIndex: Integer);
196 procedure SetNull(ColumnIndex: Integer);
197 procedure SetBoolean(ColumnIndex: Integer; Value: Boolean);
198 procedure SetByte(ColumnIndex: Integer; Value: ShortInt);
199 procedure SetShort(ColumnIndex: Integer; Value: SmallInt);
200 procedure SetInt(ColumnIndex: Integer; Value: Integer);
201 procedure SetLong(ColumnIndex: Integer; Value: Int64);
202 procedure SetFloat(ColumnIndex: Integer; Value: Single);
203 procedure SetDouble(ColumnIndex: Integer; Value: Double);
204 procedure SetBigDecimal(ColumnIndex: Integer; Value: Extended);
205 procedure SetPChar(ColumnIndex: Integer; Value: PChar);
206 procedure SetString(ColumnIndex: Integer; Value: String);
207 procedure SetUnicodeString(ColumnIndex: Integer; Value: WideString);
208 procedure SetBytes(ColumnIndex: Integer; Value: TByteDynArray);
209 procedure SetDate(ColumnIndex: Integer; Value: TDateTime);
210 procedure SetTime(ColumnIndex: Integer; Value: TDateTime);
211 procedure SetTimestamp(ColumnIndex: Integer; Value: TDateTime);
212 procedure SetAsciiStream(ColumnIndex: Integer; Value: TStream);
213 procedure SetUnicodeStream(ColumnIndex: Integer; Value: TStream);
214 procedure SetBinaryStream(ColumnIndex: Integer; Value: TStream);
215 procedure SetBlob(ColumnIndex: Integer; Value: IZBlob);
216 procedure SetDataSet(ColumnIndex: Integer; Value: IZDataSet);
217 procedure SetValue(ColumnIndex: Integer; Value: TZVariant);
219 property ColumnsSize: Integer read FColumnsSize;
220 property RowSize: Integer read FRowSize;
221 property RowBuffer: PZRowBuffer read FBuffer write FBuffer;
225 RowHeaderSize = SizeOf(TZRowBuffer) - SizeOf(TZByteArray);
229 uses Math, ZMessages, ZSysUtils, ZDbcUtils
230 {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};
235 Creates this object and assignes the main properties.
236 @param ColumnsInfo a collection with column information.
238 constructor TZRowAccessor.Create(ColumnsInfo: TObjectList; ConSettings: PZConSettings);
241 Current: TZColumnInfo;
243 Self.ConSettings := ConSettings;
245 FColumnCount := ColumnsInfo.Count;
247 {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
248 FColumnsSize:=align(FColumnsSize+1,sizeof(pointer))-1;
250 SetLength(FColumnNames, FColumnCount);
251 SetLength(FColumnCases, FColumnCount);
252 SetLength(FColumnTypes, FColumnCount);
253 SetLength(FColumnLengths, FColumnCount);
254 SetLength(FColumnOffsets, FColumnCount);
255 SetLength(FColumnDefaultExpressions, FColumnCount);
258 for I := 0 to FColumnCount - 1 do
260 Current := TZColumnInfo(ColumnsInfo[I]);
261 FColumnNames[I] := Current.ColumnName;
262 FColumnCases[I] := Current.CaseSensitive;
263 FColumnTypes[I] := Current.ColumnType;
264 FColumnLengths[I] := GetColumnSize(Current);
265 FColumnOffsets[I] := FColumnsSize;
266 FColumnDefaultExpressions[I] := Current.DefaultExpression;
267 Inc(FColumnsSize, FColumnLengths[I] + 1);
268 {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
269 FColumnsSize:=align(FColumnsSize+1,sizeof(pointer))-1;
271 if Current.ColumnType in [stBytes, stString, stUnicodeString] then
272 FColumnLengths[I] := Current.Precision;
273 if Current.ColumnType = stGUID then
274 FColumnLengths[I] := 16;
275 if FColumnsSize > SizeOf(TZByteArray)-1 then
276 raise EZSQLException.Create(SRowBufferWidthExceeded);
277 FHasBlobs := FHasBlobs
278 or (FColumnTypes[I] in [stAsciiStream, stUnicodeStream, stBinaryStream]);
280 FRowSize := FColumnsSize + RowHeaderSize;
284 Destroys this object and cleanups the memory.
286 destructor TZRowAccessor.Destroy;
292 Checks is the column index correct and row buffer is available.
293 @param ColumnIndex an index of column.
295 procedure TZRowAccessor.CheckColumnIndex(ColumnIndex: Integer);
297 if not Assigned(FBuffer) then
298 raise EZSQLException.Create(SRowBufferIsNotAssigned);
300 if (ColumnIndex <= 0) or (ColumnIndex > FColumnCount) then
302 raise EZSQLException.Create(
303 Format(SColumnIsNotAccessable, [ColumnIndex]));
308 Checks is the column convertion from one type to another type allowed.
309 @param ColumnIndex an index of column.
310 @param ResultType a requested data type.
311 @return <code>true</code> if convertion is allowed or throw exception
314 procedure TZRowAccessor.CheckColumnConvertion(ColumnIndex: Integer;
315 ResultType: TZSQLType);
317 if not Assigned(FBuffer) then
318 raise EZSQLException.Create(SRowBufferIsNotAssigned);
320 if (ColumnIndex <= 0) or (ColumnIndex > FColumnCount) then
322 raise EZSQLException.Create(
323 Format(SColumnIsNotAccessable, [ColumnIndex]));
326 if not CheckConvertion(FColumnTypes[ColumnIndex - 1], ResultType) then
328 raise EZSQLException.Create(
329 Format(SConvertionIsNotPossible, [ColumnIndex,
330 DefineColumnTypeName(FColumnTypes[ColumnIndex - 1]),
331 DefineColumnTypeName(ResultType)]));
336 Gets a size of column with the specified type.
337 @param ColumnInfo a column information struct.
338 @return a size for the column with the specified type.
340 function TZRowAccessor.GetColumnSize(ColumnInfo: TZColumnInfo): Integer;
342 case ColumnInfo.ColumnType of
344 Result := SizeOf(WordBool);
346 Result := SizeOf(Byte);
348 Result := SizeOf(SmallInt);
350 Result := SizeOf(Integer);
352 Result := SizeOf(Int64);
354 Result := SizeOf(Single);
356 Result := SizeOf(Double);
358 Result := SizeOf(Extended);
360 Result := SizeOf(Pointer);
362 Result := SizeOf(Pointer);
364 Result := SizeOf(Pointer) + SizeOf(SmallInt);
365 stDate, stTime, stTimestamp:
366 Result := SizeOf(TDateTime);
367 stAsciiStream, stUnicodeStream, stBinaryStream, stDataSet:
368 Result := SizeOf(Pointer);
375 Gets a stream from the specified columns.
376 @param Buffer a row buffer.
377 @param ColumnIndex an index of the column.
379 function TZRowAccessor.GetBlobObject(Buffer: PZRowBuffer;
380 ColumnIndex: Integer): IZBlob;
383 NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};
385 BlobPtr := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
386 NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1]]);
389 if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then //M.A. if NullPtr^ = 0 then
393 Result := IZBlob(BlobPtr^)
399 Sets a blob into the specified columns.
400 @param Buffer a row buffer.
401 @param ColumnIndex an index of the column.
402 @param Value a stream object to be set.
404 procedure TZRowAccessor.SetBlobObject(Buffer: PZRowBuffer; ColumnIndex: Integer;
408 NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};
410 BlobPtr := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
411 NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1]]);
414 if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then //M.A. if NullPtr^ = 0 then
418 IZBlob(BlobPtr^) := nil
422 IZBlob(BlobPtr^) := Value;
426 NullPtr^ := {$IFDEF WIN64}false{$ELSE}0{$ENDIF} //M.A. NullPtr^ := 0
428 NullPtr^ := {$IFDEF WIN64}true{$ELSE}1{$ENDIF}; //M.A. NullPtr^ := 1;
436 function TZRowAccessor.InternalGetBytes(Buffer: PZRowBuffer;
437 ColumnIndex: Integer): TByteDynArray;
443 if ( Buffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 )then
445 L := PSmallInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1 + SizeOf(Pointer)])^;
446 SetLength(Result, L);
449 P := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
450 Move(P^^, Pointer(Result)^, L);
455 procedure TZRowAccessor.InternalSetBytes(Buffer: PZRowBuffer; ColumnIndex: Integer;
456 Value: TByteDynArray; NewPointer: Boolean = False);
461 if Assigned(Buffer) then
464 PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;
465 P := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
466 L := Min(Length(Value), FColumnLengths[ColumnIndex - 1]);
467 PSmallInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1 + SizeOf(Pointer)])^ := L;
471 System.Move(Pointer(Value)^, P^^, L);
474 if PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ > 0 then
477 PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;
482 procedure TZRowAccessor.InternalSetString(Buffer: PZRowBuffer;
483 ColumnIndex: Integer; Value: String; NewPointer: Boolean = False);
488 if Assigned(Buffer) then
491 PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;
492 C := PPChar(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
493 L := Min(FColumnLengths[ColumnIndex - 1], Length(Value));
494 ReallocMem(C^, L * SizeOf(Char) + SizeOf(Char));
495 System.Move(PChar(Value)^, C^^, L * SizeOf(Char));
496 (C^+L)^ := #0; //set #0 terminator if a truncation is required
500 procedure TZRowAccessor.InternalSetUnicodeString(Buffer: PZRowBuffer;
501 ColumnIndex: Integer; Value: ZWideString; NewPointer: Boolean = False);
506 if Assigned(Buffer) then
509 PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;
510 W := ZPPWideChar(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
511 L := Min(Length(Value), FColumnLengths[ColumnIndex - 1]);
512 Value := System.Copy(Value, 1, L);
515 System.Move(PWideChar(Value)^, W^^, L);
520 Allocates a new row buffer and sets it into the variable.
521 @param Buffer a pointer to row buffer.
522 @return a pointer to the allocated buffer.
524 function TZRowAccessor.AllocBuffer(var Buffer: PZRowBuffer): PZRowBuffer;
526 GetMem(Buffer, FRowSize);
532 Disposes the specified row buffer.
533 @param Buffer a pointer to row buffer.
535 procedure TZRowAccessor.DisposeBuffer(Buffer: PZRowBuffer);
537 if Assigned(Buffer) then
545 Initializes the row buffer.
546 @param Buffer a pointer to row buffer.
548 procedure TZRowAccessor.InitBuffer(Buffer: PZRowBuffer);
552 if Assigned(Buffer) then
556 BookmarkFlag := 0;//bfCurrent;
557 UpdateType := utUnmodified;
558 FillChar(Columns, FColumnsSize, 0);
559 for I := 0 to FColumnCount - 1 do Columns[FColumnOffsets[I]] := 1;
564 Copies the row buffer from source to destination row.
565 @param SrcBuffer a pointer to source row buffer.
566 @param DestBuffer a pointer to destination row buffer.
568 procedure TZRowAccessor.CopyBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);
572 ClearBuffer(DestBuffer);
575 Index := SrcBuffer^.Index;
576 UpdateType := SrcBuffer^.UpdateType;
577 BookmarkFlag := SrcBuffer^.BookmarkFlag;
578 System.Move(SrcBuffer^.Columns, Columns, FColumnsSize);
579 for I := 0 to FColumnCount - 1 do
580 case FColumnTypes[I] of
581 stAsciiStream, stUnicodeStream, stBinaryStream:
582 if (Columns[FColumnOffsets[I]] = 0) then
584 Columns[FColumnOffsets[I]] := 1;
585 SetBlobObject(DestBuffer, I + 1, GetBlobObject(SrcBuffer, I + 1));
587 stString: InternalSetString(DestBuffer, I +1,
588 PPChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);
589 stUnicodeString: InternalSetUnicodeString(DestBuffer, I +1,
590 ZPPWideChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);
591 stBytes,stGUID: InternalSetBytes(DestBuffer, I +1, InternalGetBytes(SrcBuffer, I +1), True);
597 Moves the row buffer from source to destination row.
598 Source buffer is cleaned up after the operation.
599 @param SrcBuffer a pointer to source row buffer.
600 @param DestBuffer a pointer to destination row buffer.
602 procedure TZRowAccessor.MoveBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);
604 CopyBuffer(SrcBuffer, DestBuffer);
605 ClearBuffer(SrcBuffer);
609 Clones the row buffer from source to destination row.
610 @param SrcBuffer a pointer to source row buffer.
611 @param DestBuffer a pointer to destination row buffer.
613 procedure TZRowAccessor.CloneBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);
618 ClearBuffer(DestBuffer);
621 Index := SrcBuffer^.Index;
622 UpdateType := SrcBuffer^.UpdateType;
623 BookmarkFlag := SrcBuffer^.BookmarkFlag;
624 System.Move(SrcBuffer^.Columns, Columns, FColumnsSize);
625 for I := 0 to FColumnCount - 1 do
626 case FColumnTypes[I] of
627 stAsciiStream, stUnicodeStream, stBinaryStream:
628 if (Columns[FColumnOffsets[I]] = 0) then
630 Columns[FColumnOffsets[I]] := 1;
631 Blob := GetBlobObject(SrcBuffer, I + 1);
634 SetBlobObject(DestBuffer, I + 1, Blob);
636 stString: InternalSetString(DestBuffer, I +1,
637 PPChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);
638 stUnicodeString: InternalSetUnicodeString(DestBuffer, I +1,
639 ZPPWideChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);
640 stBytes,stGUID: InternalSetBytes(DestBuffer, I +1, InternalGetBytes(SrcBuffer, I +1), True);
646 Compares fields from two row buffers.
647 @param Buffer1 the first row buffer to compare.
648 @param Buffer2 the second row buffer to compare.
649 @param ColumnIndices column indices to compare.
650 @param ColumnDirs compare direction for each columns.
652 function TZRowAccessor.CompareBuffers(Buffer1, Buffer2: PZRowBuffer;
653 ColumnIndices: TIntegerDynArray; ColumnDirs: TBooleanDynArray): Integer;
656 ColumnIndex: Integer;
657 Length1, Length2: SmallInt;
658 ValuePtr1, ValuePtr2: Pointer;
659 Blob1, Blob2: IZBlob;
660 BlobEmpty1, BlobEmpty2: Boolean;
661 Bts1, Bts2: TByteDynArray;
664 for I := Low(ColumnIndices) to High(ColumnIndices) do
666 ColumnIndex := ColumnIndices[I] - 1;
667 { Checks for both Null columns. }
668 if (Buffer1.Columns[FColumnOffsets[ColumnIndex]] = 1) and
669 (Buffer2.Columns[FColumnOffsets[ColumnIndex]] = 1) then
671 { Checks for not-Null and Null columns. }
672 if Buffer1.Columns[FColumnOffsets[ColumnIndex]] <>
673 Buffer2.Columns[FColumnOffsets[ColumnIndex]] then
675 if not (FColumnTypes[ColumnIndex]
676 in [stAsciiStream, stUnicodeStream, stBinaryStream]) then
678 Result := Buffer2.Columns[FColumnOffsets[ColumnIndex]] -
679 Buffer1.Columns[FColumnOffsets[ColumnIndex]];
680 if not ColumnDirs[I] then
685 { Compares column values. }
686 ValuePtr1 := @Buffer1.Columns[FColumnOffsets[ColumnIndex] + 1];
687 ValuePtr2 := @Buffer2.Columns[FColumnOffsets[ColumnIndex] + 1];
688 case FColumnTypes[ColumnIndex] of
690 Result := Ord((PByte(ValuePtr1)^ > PByte(ValuePtr2)^))-Ord((PByte(ValuePtr1)^ < PByte(ValuePtr2)^));
692 Result := Ord((PShortInt(ValuePtr1)^ > PShortInt(ValuePtr2)^))-Ord((PShortInt(ValuePtr1)^ < PShortInt(ValuePtr2)^));
694 Result := Ord((PLongInt(ValuePtr1)^ > PLongInt(ValuePtr2)^))-Ord((PLongInt(ValuePtr1)^ < PLongInt(ValuePtr2)^));
696 Result := Ord((PInt64(ValuePtr1)^ > PInt64(ValuePtr2)^))-Ord((PInt64(ValuePtr1)^ < PInt64(ValuePtr2)^));
698 Result := Ord((PSingle(ValuePtr1)^ > PSingle(ValuePtr2)^))-Ord((PSingle(ValuePtr1)^ < PSingle(ValuePtr2)^));
700 Result := Ord((PDouble(ValuePtr1)^ > PDouble(ValuePtr2)^))-Ord((PDouble(ValuePtr1)^ < PDouble(ValuePtr2)^));
702 Result := Ord((PExtended(ValuePtr1)^ > PExtended(ValuePtr2)^))-Ord((PExtended(ValuePtr1)^ < PExtended(ValuePtr2)^));
704 Result := Ord((PWordBool(ValuePtr1)^ > PWordBool(ValuePtr2)^))-Ord((PWordBool(ValuePtr1)^ < PWordBool(ValuePtr2)^));
705 stDate, stTime, stTimestamp:
706 Result := Ord((PDateTime(ValuePtr1)^ > PDateTime(ValuePtr2)^))-Ord((PDateTime(ValuePtr1)^ < PDateTime(ValuePtr2)^));
708 stUnicodeString,stString:
709 Result := WideCompareStr(PWideChar(ValuePtr1^), PWideChar(ValuePtr2^));
712 {$IFDEF MSWINDOWS} //Windows can handle nil pointers Linux not FPC-Bug?
713 Result := AnsiStrComp(PAnsiChar(ValuePtr1^), PAnsiChar(ValuePtr2^));
715 if Assigned(PPAnsichar(ValuePtr1)^) and Assigned(PPAnsiChar(ValuePtr2)^) then
716 Result := AnsiStrComp(PAnsiChar(ValuePtr1^), PAnsiChar(ValuePtr2^))
718 if not Assigned(PPAnsichar(ValuePtr1)^) and not Assigned(PPAnsiChar(ValuePtr2)^) then
724 Result := WideCompareStr(PWideChar(ValuePtr1^), PWideChar(ValuePtr2^));
728 Length1 := PSmallInt(@Buffer1.Columns[FColumnOffsets[ColumnIndex] + 1 + SizeOf(Pointer)])^;
729 Length2 := PSmallInt(@Buffer2.Columns[FColumnOffsets[ColumnIndex] + 1 + SizeOf(Pointer)])^;
730 Result := Length1 - Length2;
733 Bts1 := InternalGetBytes(Buffer1, ColumnIndex+1);
734 Bts2 := InternalGetBytes(Buffer2, ColumnIndex+1);
735 if (Assigned(Bts1) and Assigned(Bts2)) then
736 if MemLCompAnsi(PAnsiChar(Bts1), PAnsiChar(Bts2), Length1) then
740 else if not Assigned(Bts1) and not Assigned(Bts2) then
742 else if Assigned(Bts1) then
748 stAsciiStream, stBinaryStream, stUnicodeStream:
750 Blob1 := GetBlobObject(Buffer1, ColumnIndex + 1);
751 BlobEmpty1 := (Blob1 = nil) or (Blob1.IsEmpty);
752 Blob2 := GetBlobObject(Buffer2, ColumnIndex + 1);
753 BlobEmpty2 := (Blob2 = nil) or (Blob2.IsEmpty);
754 if (BlobEmpty1 = True) and (BlobEmpty2 = True) then
756 else if (BlobEmpty1 <> BlobEmpty2) then
763 else if FColumnTypes[ColumnIndex] = stAsciiStream then
764 {$IFDEF WITH_UNITANSISTRINGS}
765 Result := AnsiStrings.AnsiCompareStr(Blob1.GetString, Blob2.GetString)
767 Result := AnsiCompareStr(Blob1.GetString, Blob2.GetString)
769 else if FColumnTypes[ColumnIndex] = stBinaryStream then
770 Result := CompareStr(Blob1.GetString, Blob2.GetString)
771 else if FColumnTypes[ColumnIndex] = stUnicodeStream then
772 Result := WideCompareStr(Blob1.GetUnicodeString, Blob2.GetUnicodeString);
777 if not ColumnDirs[I] then
785 Cleans the specified row buffer.
786 @param Buffer a pointer to row buffer.
788 procedure TZRowAccessor.ClearBuffer(Buffer: PZRowBuffer);
796 UpdateType := utUnmodified;
798 for I := 0 to FColumnCount - 1 do
799 case FColumnTypes[I] of
800 stAsciiStream, stUnicodeStream, stBinaryStream:
801 if (Columns[FColumnOffsets[I]] = 0) then
802 SetBlobObject(Buffer, I + 1, nil);
803 stBytes,stGUID,stString, stUnicodeString:
804 if PNativeUInt(@Columns[FColumnOffsets[I] +1])^ > 0 then
806 P := PPointer(@Columns[FColumnOffsets[I] +1]);
810 FillChar(Columns, FColumnsSize, 0);
811 for I := 0 to FColumnCount - 1 do Columns[FColumnOffsets[I]] := 1;
816 Allocates a new row buffer.
817 @return a pointer to the allocated buffer.
819 function TZRowAccessor.Alloc: PZRowBuffer;
821 Result := AllocBuffer(FBuffer);
825 Disposes an associated row buffer.
827 procedure TZRowAccessor.Dispose;
829 DisposeBuffer(FBuffer);
834 Initializes the associated row buffer.
836 procedure TZRowAccessor.Init;
842 Copies the associated row buffer into a specified one.
843 @param DestBuffer a destination row buffer.
845 procedure TZRowAccessor.CopyTo(DestBuffer: PZRowBuffer);
847 CopyBuffer(FBuffer, DestBuffer);
851 Copies the associated row buffer from a specified one.
852 @param SrcBuffer a source row buffer.
854 procedure TZRowAccessor.CopyFrom(SrcBuffer: PZRowBuffer);
856 CopyBuffer(SrcBuffer, FBuffer);
860 Moves the associated row buffer into a specified one.
861 @param DestBuffer a destination row buffer.
863 procedure TZRowAccessor.MoveTo(DestBuffer: PZRowBuffer);
865 MoveBuffer(FBuffer, DestBuffer);
869 Moves the associated row buffer from a specified one.
870 @param SrcBuffer a source row buffer.
872 procedure TZRowAccessor.MoveFrom(SrcBuffer: PZRowBuffer);
874 MoveBuffer(SrcBuffer, FBuffer);
878 Clones the associated row buffer into a specified one.
879 @param DestBuffer a destination row buffer.
881 procedure TZRowAccessor.CloneTo(DestBuffer: PZRowBuffer);
883 CloneBuffer(FBuffer, DestBuffer);
887 Clones the associated row buffer from a specified one.
888 @param SrcBuffer a source row buffer.
890 procedure TZRowAccessor.CloneFrom(SrcBuffer: PZRowBuffer);
892 CloneBuffer(SrcBuffer, FBuffer);
896 Cleans the associated row buffer.
898 procedure TZRowAccessor.Clear;
900 ClearBuffer(FBuffer);
904 Gets the case sensitive flag of a column data buffer.
906 @param ColumnIndex the first column is 1, the second is 2, ...
907 @return the case sensitive flag of the column data buffer.
909 function TZRowAccessor.GetColumnCase(ColumnIndex: Integer): Boolean;
911 CheckColumnIndex(ColumnIndex);
912 Result := FColumnCases[ColumnIndex-1];
916 Gets a pointer to the column data buffer.
918 @param ColumnIndex the first column is 1, the second is 2, ...
919 @return a pointer to the column data buffer.
921 function TZRowAccessor.GetColumnData(ColumnIndex: Integer;
922 var IsNull: Boolean): Pointer;
924 CheckColumnConvertion(ColumnIndex, stString);
925 Result := @FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1];
926 IsNull := FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 1;
930 Gets a size of the column data buffer.
932 @param ColumnIndex the first column is 1, the second is 2, ...
933 @return a size of the column data buffer.
935 function TZRowAccessor.GetColumnDataSize(ColumnIndex: Integer): Integer;
937 CheckColumnConvertion(ColumnIndex, stString);
938 Result := FColumnLengths[ColumnIndex - 1];
942 Gets then length of a column data buffer.
944 @param ColumnIndex the first column is 1, the second is 2, ...
945 @return the length of the column data buffer.
947 function TZRowAccessor.GetColumnLength(ColumnIndex: Integer): Integer;
949 CheckColumnIndex(ColumnIndex);
950 Result := FColumnLengths[ColumnIndex-1];
954 Gets then name of a column data buffer.
956 @param ColumnIndex the first column is 1, the second is 2, ...
957 @return the name of the column data buffer.
959 function TZRowAccessor.GetColumnName(ColumnIndex: Integer): string;
961 CheckColumnIndex(ColumnIndex);
962 Result := FColumnNames[ColumnIndex-1];
966 Gets then offset of a column data buffer.
968 @param ColumnIndex the first column is 1, the second is 2, ...
969 @return then offset of the column data buffer.
971 function TZRowAccessor.GetColumnOffSet(ColumnIndex: Integer): Integer;
973 CheckColumnIndex(ColumnIndex);
974 Result := FColumnOffSets[ColumnIndex-1];
978 Gets then SQLType of a column data buffer.
980 @param ColumnIndex the first column is 1, the second is 2, ...
981 @return the SQLType of the column data buffer.
983 function TZRowAccessor.GetColumnType(ColumnIndex: Integer): TZSQLType;
985 CheckColumnIndex(ColumnIndex);
986 Result := FColumnTypes[ColumnIndex-1];
989 function TZRowAccessor.GetColumnDefaultExpression(ColumnIndex: Integer): string;
991 CheckColumnIndex(ColumnIndex);
992 Result := FColumnDefaultExpressions[ColumnIndex-1];
995 procedure TZRowAccessor.SetColumnDefaultExpression(ColumnIndex: Integer; Value: string);
997 FColumnDefaultExpressions[ColumnIndex-1] := Value;
1001 //======================================================================
1002 // Methods for accessing results by column index
1003 //======================================================================
1006 Indicates if the value of the designated column in the current row
1007 of this <code>ResultSet</code> object is Null.
1009 @param ColumnIndex the first column is 1, the second is 2, ...
1010 @return if the value is SQL <code>NULL</code>, the
1011 value returned is <code>true</code>. <code>false</code> otherwise.
1013 function TZRowAccessor.IsNull(ColumnIndex: Integer): Boolean;
1017 CheckColumnConvertion(ColumnIndex, stString);
1018 Result := FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 1;
1019 if not Result and (FColumnTypes[ColumnIndex - 1] in [stAsciiStream,
1020 stBinaryStream, stUnicodeStream]) then
1022 TempBlob := GetBlobObject(FBuffer, ColumnIndex);
1023 Result := (TempBlob = nil) or TempBlob.IsEmpty;
1028 Gets the value of the designated column in the current row
1029 of this <code>ResultSet</code> object as
1030 a <code>PChar</code> in the Delphi programming language.
1032 @param columnIndex the first column is 1, the second is 2, ...
1033 @return the column value; if the value is SQL <code>NULL</code>, the
1034 value returned is <code>null</code>
1036 function TZRowAccessor.GetPChar(ColumnIndex: Integer; var IsNull: Boolean): PChar;
1038 {$IFNDEF DISABLE_CHECKING}
1039 CheckColumnConvertion(ColumnIndex, stString);
1042 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1044 case FColumnTypes[ColumnIndex - 1] of
1045 stString{$IFDEF UNICODE}, stUnicodeString{$ENDIF}:
1046 Result := PPChar(FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1049 FTemp := GetString(ColumnIndex, IsNull);
1050 Result := PChar(FTemp);
1060 Gets the value of the designated column in the current row
1061 of this <code>ResultSet</code> object as
1062 a <code>String</code> in the Java programming language.
1064 @param columnIndex the first column is 1, the second is 2, ...
1065 @return the column value; if the value is SQL <code>NULL</code>, the
1066 value returned is <code>null</code>
1068 function TZRowAccessor.GetString(ColumnIndex: Integer; var IsNull: Boolean): String;
1073 {$IFNDEF DISABLE_CHECKING}
1074 CheckColumnConvertion(ColumnIndex, stString);
1077 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1079 case FColumnTypes[ColumnIndex - 1] of
1081 if GetBoolean(ColumnIndex, IsNull) then
1085 stByte: Result := IntToStr(GetByte(ColumnIndex, IsNull));
1086 stShort: Result := IntToStr(GetShort(ColumnIndex, IsNull));
1087 stInteger: Result := IntToStr(GetInt(ColumnIndex, IsNull));
1088 stLong: Result := IntToStr(GetLong(ColumnIndex, IsNull));
1089 stFloat: Result := FloatToSQLStr(GetFloat(ColumnIndex, IsNull));
1090 stDouble: Result := FloatToSQLStr(GetDouble(ColumnIndex, IsNull));
1091 stBigDecimal: Result := FloatToSQLStr(GetBigDecimal(ColumnIndex, IsNull));
1092 stString: Result := PPChar(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1093 stUnicodeString, stUnicodeStream: Result := ZDbcString(GetUnicodeString(ColumnIndex, IsNull)); //wide down to expect codpage Ansi
1094 stBytes: Result := String(BytesToStr(GetBytes(ColumnIndex, IsNull)));
1097 System.Move(Pointer(GetBytes(ColumnIndex, IsNull))^, GUID, 16);
1098 Result := GUIDToString(GUID);
1100 stDate: Result := FormatDateTime('yyyy-mm-dd', GetDate(ColumnIndex, IsNull));
1101 stTime: Result := FormatDateTime('hh:mm:ss', GetTime(ColumnIndex, IsNull));
1102 stTimestamp: Result := FormatDateTime('yyyy-mm-dd hh:mm:ss',
1103 GetTimestamp(ColumnIndex, IsNull));
1104 stAsciiStream, stBinaryStream:
1106 TempBlob := GetBlobObject(FBuffer, ColumnIndex);
1107 if (TempBlob <> nil) and not TempBlob.IsEmpty then
1108 Result := String(TempBlob.GetString);
1118 Gets the value of the designated column in the current row
1119 of this <code>ResultSet</code> object as
1120 a <code>WideString</code> in the ObjectPascal programming language.
1122 @param columnIndex the first column is 1, the second is 2, ...
1123 @return the column value; if the value is SQL <code>NULL</code>, the
1124 value returned is <code>null</code>
1126 function TZRowAccessor.GetUnicodeString(ColumnIndex: Integer; var IsNull: Boolean):
1131 {$IFNDEF DISABLE_CHECKING}
1132 CheckColumnConvertion(ColumnIndex, stUnicodeString);
1135 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1137 case FColumnTypes[ColumnIndex - 1] of
1138 stUnicodeString{$IFDEF UNICODE}, stString{$ENDIF}:
1139 Result := ZPPWideChar(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1142 TempBlob := GetBlobObject(FBuffer, ColumnIndex);
1143 if (TempBlob <> nil) and not TempBlob.IsEmpty then
1144 Result := TempBlob.GetUnicodeString;
1147 stString: Result := ZDbcUnicodeString(GetString(ColumnIndex, IsNull), ConSettings.CTRL_CP);
1150 Result := WideString(GetString(ColumnIndex, IsNull));
1159 Gets the value of the designated column in the current row
1160 of this <code>ResultSet</code> object as
1161 a <code>boolean</code> in the Java programming language.
1163 @param columnIndex the first column is 1, the second is 2, ...
1164 @return the column value; if the value is SQL <code>NULL</code>, the
1165 value returned is <code>false</code>
1167 function TZRowAccessor.GetBoolean(ColumnIndex: Integer; var IsNull: Boolean): Boolean;
1171 {$IFNDEF DISABLE_CHECKING}
1172 CheckColumnConvertion(ColumnIndex, stBoolean);
1175 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1177 case FColumnTypes[ColumnIndex - 1] of
1179 Result := PWordBool(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1180 stByte: Result := GetByte(ColumnIndex, IsNull) <> 0;
1181 stShort: Result := GetShort(ColumnIndex, IsNull) <> 0;
1182 stInteger: Result := GetInt(ColumnIndex, IsNull) <> 0;
1183 stLong: Result := GetLong(ColumnIndex, IsNull) <> 0;
1184 stFloat: Result := GetFloat(ColumnIndex, IsNull) <> 0;
1185 stDouble: Result := GetDouble(ColumnIndex, IsNull) <> 0;
1186 stBigDecimal: Result := GetBigDecimal(ColumnIndex, IsNull) <> 0;
1187 stString, stUnicodeString:
1189 TempStr := UpperCase(GetString(ColumnIndex, IsNull));
1190 Result := (TempStr = 'T') or (TempStr = 'Y') or (TempStr = 'TRUE')
1191 or (TempStr = 'YES');
1201 Gets the value of the designated column in the current row
1202 of this <code>ResultSet</code> object as
1203 a <code>byte</code> in the Java programming language.
1205 @param columnIndex the first column is 1, the second is 2, ...
1206 @return the column value; if the value is SQL <code>NULL</code>, the
1207 value returned is <code>0</code>
1209 function TZRowAccessor.GetByte(ColumnIndex: Integer; var IsNull: Boolean): ShortInt;
1211 {$IFNDEF DISABLE_CHECKING}
1212 CheckColumnConvertion(ColumnIndex, stByte);
1215 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1217 case FColumnTypes[ColumnIndex - 1] of
1219 if GetBoolean(ColumnIndex, IsNull) then
1223 stByte: Result := PShortInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1224 stShort: Result := GetShort(ColumnIndex, IsNull);
1225 stInteger: Result := GetInt(ColumnIndex, IsNull);
1226 stLong: Result := GetLong(ColumnIndex, IsNull);
1227 stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));
1228 stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));
1229 stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));
1230 stString, stUnicodeString: Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);
1239 Gets the value of the designated column in the current row
1240 of this <code>ResultSet</code> object as
1241 a <code>short</code> in the Java programming language.
1243 @param columnIndex the first column is 1, the second is 2, ...
1244 @return the column value; if the value is SQL <code>NULL</code>, the
1245 value returned is <code>0</code>
1247 function TZRowAccessor.GetShort(ColumnIndex: Integer; var IsNull: Boolean): SmallInt;
1249 {$IFNDEF DISABLE_CHECKING}
1250 CheckColumnConvertion(ColumnIndex, stShort);
1253 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1255 case FColumnTypes[ColumnIndex - 1] of
1257 if GetBoolean(ColumnIndex, IsNull) then
1261 stByte: Result := GetByte(ColumnIndex, IsNull);
1262 stShort: Result := PSmallInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1263 stInteger: Result := GetInt(ColumnIndex, IsNull);
1264 stLong: Result := GetLong(ColumnIndex, IsNull);
1265 stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));
1266 stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));
1267 stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));
1268 stString, stUnicodeString: Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);
1277 Gets the value of the designated column in the current row
1278 of this <code>ResultSet</code> object as
1279 an <code>int</code> in the Java programming language.
1281 @param columnIndex the first column is 1, the second is 2, ...
1282 @return the column value; if the value is SQL <code>NULL</code>, the
1283 value returned is <code>0</code>
1285 function TZRowAccessor.GetInt(ColumnIndex: Integer; var IsNull: Boolean): Integer;
1287 {$IFNDEF DISABLE_CHECKING}
1288 CheckColumnConvertion(ColumnIndex, stInteger);
1291 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1293 case FColumnTypes[ColumnIndex - 1] of
1295 if GetBoolean(ColumnIndex, IsNull) then
1299 stByte: Result := GetByte(ColumnIndex, IsNull);
1300 stShort: Result := GetShort(ColumnIndex, IsNull);
1302 Result := PInteger(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1303 stLong: Result := GetLong(ColumnIndex, IsNull);
1304 stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));
1305 stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));
1306 stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));
1307 stString, stUnicodeString:
1308 Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);
1317 Gets the value of the designated column in the current row
1318 of this <code>ResultSet</code> object as
1319 a <code>long</code> in the Java programming language.
1321 @param columnIndex the first column is 1, the second is 2, ...
1322 @return the column value; if the value is SQL <code>NULL</code>, the
1323 value returned is <code>0</code>
1325 function TZRowAccessor.GetLong(ColumnIndex: Integer; var IsNull: Boolean): Int64;
1327 {$IFNDEF DISABLE_CHECKING}
1328 CheckColumnConvertion(ColumnIndex, stLong);
1331 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1333 case FColumnTypes[ColumnIndex - 1] of
1335 if GetBoolean(ColumnIndex, IsNull) then
1339 stByte: Result := GetByte(ColumnIndex, IsNull);
1340 stShort: Result := GetShort(ColumnIndex, IsNull);
1341 stInteger: Result := GetInt(ColumnIndex, IsNull);
1343 Result := PInt64(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1344 stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));
1345 stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));
1346 stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));
1347 stString, stUnicodeString:
1348 Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);
1357 Gets the value of the designated column in the current row
1358 of this <code>ResultSet</code> object as
1359 a <code>float</code> in the Java programming language.
1361 @param columnIndex the first column is 1, the second is 2, ...
1362 @return the column value; if the value is SQL <code>NULL</code>, the
1363 value returned is <code>0</code>
1365 function TZRowAccessor.GetFloat(ColumnIndex: Integer; var IsNull: Boolean): Single;
1367 {$IFNDEF DISABLE_CHECKING}
1368 CheckColumnConvertion(ColumnIndex, stFloat);
1371 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1373 case FColumnTypes[ColumnIndex - 1] of
1375 if GetBoolean(ColumnIndex, IsNull) then
1379 stByte: Result := GetByte(ColumnIndex, IsNull);
1380 stShort: Result := GetShort(ColumnIndex, IsNull);
1381 stInteger: Result := GetInt(ColumnIndex, IsNull);
1382 stLong: Result := GetLong(ColumnIndex, IsNull);
1384 Result := PSingle(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1385 stDouble: Result := GetDouble(ColumnIndex, IsNull);
1386 stBigDecimal: Result := GetBigDecimal(ColumnIndex, IsNull);
1387 stString, stUnicodeString:
1388 Result := SQLStrToFloatDef(AnsiString(GetString(ColumnIndex, IsNull)), 0);
1397 Gets the value of the designated column in the current row
1398 of this <code>ResultSet</code> object as
1399 a <code>double</code> in the Java programming language.
1401 @param columnIndex the first column is 1, the second is 2, ...
1402 @return the column value; if the value is SQL <code>NULL</code>, the
1403 value returned is <code>0</code>
1405 function TZRowAccessor.GetDouble(ColumnIndex: Integer; var IsNull: Boolean): Double;
1407 {$IFNDEF DISABLE_CHECKING}
1408 CheckColumnConvertion(ColumnIndex, stDouble);
1411 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1413 case FColumnTypes[ColumnIndex - 1] of
1415 if GetBoolean(ColumnIndex, IsNull) then
1419 stByte: Result := GetByte(ColumnIndex, IsNull);
1420 stShort: Result := GetShort(ColumnIndex, IsNull);
1421 stInteger: Result := GetInt(ColumnIndex, IsNull);
1422 stLong: Result := GetLong(ColumnIndex, IsNull);
1423 stFloat: Result := GetFloat(ColumnIndex, IsNull);
1425 Result := PDouble(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1426 stBigDecimal: Result := GetBigDecimal(ColumnIndex, IsNull);
1427 stString, stUnicodeString:
1428 Result := SQLStrToFloatDef(AnsiString(GetString(ColumnIndex, IsNull)), 0);
1437 Gets the value of the designated column in the current row
1438 of this <code>ResultSet</code> object as
1439 a <code>java.sql.BigDecimal</code> in the Java programming language.
1441 @param columnIndex the first column is 1, the second is 2, ...
1442 @param scale the number of digits to the right of the decimal point
1443 @return the column value; if the value is SQL <code>NULL</code>, the
1444 value returned is <code>null</code>
1446 function TZRowAccessor.GetBigDecimal(ColumnIndex: Integer; var IsNull: Boolean): Extended;
1448 {$IFNDEF DISABLE_CHECKING}
1449 CheckColumnConvertion(ColumnIndex, stBigDecimal);
1452 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1454 case FColumnTypes[ColumnIndex - 1] of
1456 if GetBoolean(ColumnIndex, IsNull) then
1460 stByte: Result := GetByte(ColumnIndex, IsNull);
1461 stShort: Result := GetShort(ColumnIndex, IsNull);
1462 stInteger: Result := GetInt(ColumnIndex, IsNull);
1463 stLong: Result := GetLong(ColumnIndex, IsNull);
1464 stFloat: Result := GetFloat(ColumnIndex, IsNull);
1465 stDouble: Result := GetDouble(ColumnIndex, IsNull);
1467 Result := PExtended(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1468 stString, stUnicodeString:
1469 Result := SQLStrToFloatDef(AnsiString(GetString(ColumnIndex, IsNull)), 0);
1478 Gets the value of the designated column in the current row
1479 of this <code>ResultSet</code> object as
1480 a <code>byte</code> array in the Java programming language.
1481 The bytes represent the raw values returned by the driver.
1483 @param columnIndex the first column is 1, the second is 2, ...
1484 @return the column value; if the value is SQL <code>NULL</code>, the
1485 value returned is <code>null</code>
1487 function TZRowAccessor.GetBytes(ColumnIndex: Integer; var IsNull: Boolean): TByteDynArray;
1489 {$IFNDEF DISABLE_CHECKING}
1490 CheckColumnConvertion(ColumnIndex, stBytes);
1493 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1495 case FColumnTypes[ColumnIndex - 1] of
1497 Result := InternalGetBytes(FBuffer, ColumnIndex);
1499 Result := GetBlob(ColumnIndex, IsNull).GetBytes;
1501 Result := StrToBytes(AnsiString(GetString(ColumnIndex, IsNull)));
1510 Gets the value of the designated column in the current row
1511 of this <code>ResultSet</code> object as
1512 a <code>java.sql.Date</code> object in the Java programming language.
1514 @param columnIndex the first column is 1, the second is 2, ...
1515 @return the column value; if the value is SQL <code>NULL</code>, the
1516 value returned is <code>null</code>
1518 function TZRowAccessor.GetDate(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;
1520 {$IFNDEF DISABLE_CHECKING}
1521 CheckColumnConvertion(ColumnIndex, stDate);
1524 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1526 case FColumnTypes[ColumnIndex - 1] of
1527 stDate, stTime, stTimestamp:
1528 Result := Int(PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^);
1529 stString, stUnicodeString:
1530 Result := Trunc(AnsiSQLDateToDateTime(GetString(ColumnIndex, IsNull)));
1539 Gets the value of the designated column in the current row
1540 of this <code>ResultSet</code> object as
1541 a <code>java.sql.Time</code> object in the Java programming language.
1543 @param columnIndex the first column is 1, the second is 2, ...
1544 @return the column value; if the value is SQL <code>NULL</code>, the
1545 value returned is <code>null</code>
1547 function TZRowAccessor.GetTime(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;
1549 {$IFNDEF DISABLE_CHECKING}
1550 CheckColumnConvertion(ColumnIndex, stTime);
1553 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1555 case FColumnTypes[ColumnIndex - 1] of
1556 stDate, stTime, stTimestamp:
1557 Result := Frac(PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^);
1558 stString, stUnicodeString:
1559 Result := Frac(AnsiSQLDateToDateTime(GetString(ColumnIndex, IsNull)));
1568 Gets the value of the designated column in the current row
1569 of this <code>ResultSet</code> object as
1570 a <code>java.sql.Timestamp</code> object in the Java programming language.
1572 @param columnIndex the first column is 1, the second is 2, ...
1573 @return the column value; if the value is SQL <code>NULL</code>, the
1574 value returned is <code>null</code>
1575 @exception SQLException if a database access error occurs
1577 function TZRowAccessor.GetTimestamp(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;
1579 {$IFNDEF DISABLE_CHECKING}
1580 CheckColumnConvertion(ColumnIndex, stTimestamp);
1583 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1585 case FColumnTypes[ColumnIndex - 1] of
1586 stDate, stTime, stTimestamp:
1587 Result := PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;
1588 stString, stUnicodeString:
1589 Result := AnsiSQLDateToDateTime(GetString(ColumnIndex, IsNull));
1598 Gets the value of the designated column in the current row
1599 of this <code>ResultSet</code> object as
1600 a stream of ASCII characters. The value can then be read in chunks from the
1601 stream. This method is particularly
1602 suitable for retrieving large <char>LONGVARCHAR</char> values.
1603 The JDBC driver will
1604 do any necessary conversion from the database format into ASCII.
1606 <P><B>Note:</B> All the data in the returned stream must be
1607 read prior to getting the value of any other column. The next
1608 call to a <code>getXXX</code> method implicitly closes the stream. Also, a
1609 stream may return <code>0</code> when the method
1610 <code>InputStream.available</code>
1611 is called whether there is data available or not.
1613 @param columnIndex the first column is 1, the second is 2, ...
1614 @return a Java input stream that delivers the database column value
1615 as a stream of one-byte ASCII characters; if the value is SQL
1616 <code>NULL</code>, the value returned is <code>null</code>
1618 function TZRowAccessor.GetAsciiStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;
1622 {$IFNDEF DISABLE_CHECKING}
1623 CheckColumnConvertion(ColumnIndex, stAsciiStream);
1625 TempBlob := GetBlobObject(FBuffer, ColumnIndex);
1626 if (TempBlob <> nil) and not TempBlob.IsEmpty then
1627 Result := TempBlob.GetStream
1630 IsNull := Result = nil;
1634 Gets the value of a column in the current row as a stream of
1635 Gets the value of the designated column in the current row
1636 of this <code>ResultSet</code> object as
1637 as a stream of Unicode characters.
1638 The value can then be read in chunks from the
1639 stream. This method is particularly
1640 suitable for retrieving large<code>LONGVARCHAR</code>values. The JDBC driver will
1641 do any necessary conversion from the database format into Unicode.
1642 The byte format of the Unicode stream must be Java UTF-8,
1643 as specified in the Java virtual machine specification.
1645 <P><B>Note:</B> All the data in the returned stream must be
1646 read prior to getting the value of any other column. The next
1647 call to a <code>getXXX</code> method implicitly closes the stream. Also, a
1648 stream may return <code>0</code> when the method
1649 <code>InputStream.available</code>
1650 is called whether there is data available or not.
1652 @param columnIndex the first column is 1, the second is 2, ...
1653 @return a Java input stream that delivers the database column value
1654 as a stream in Java UTF-8 byte format; if the value is SQL
1655 <code>NULL</code>, the value returned is <code>null</code>
1657 function TZRowAccessor.GetUnicodeStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;
1661 {$IFNDEF DISABLE_CHECKING}
1662 CheckColumnConvertion(ColumnIndex, stUnicodeStream);
1664 TempBlob := GetBlobObject(FBuffer, ColumnIndex);
1665 if (TempBlob <> nil) and not TempBlob.IsEmpty then
1666 Result := TempBlob.GetUnicodeStream
1669 IsNull := Result = nil;
1673 Gets the value of a column in the current row as a stream of
1674 Gets the value of the designated column in the current row
1675 of this <code>ResultSet</code> object as a binary stream of
1676 uninterpreted bytes. The value can then be read in chunks from the
1677 stream. This method is particularly
1678 suitable for retrieving large <code>LONGVARBINARY</code> values.
1680 <P><B>Note:</B> All the data in the returned stream must be
1681 read prior to getting the value of any other column. The next
1682 call to a <code>getXXX</code> method implicitly closes the stream. Also, a
1683 stream may return <code>0</code> when the method
1684 <code>InputStream.available</code>
1685 is called whether there is data available or not.
1687 @param columnIndex the first column is 1, the second is 2, ...
1688 @return a Java input stream that delivers the database column value
1689 as a stream of uninterpreted bytes;
1690 if the value is SQL <code>NULL</code>, the value returned is <code>null</code>
1692 function TZRowAccessor.GetBinaryStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;
1696 {$IFNDEF DISABLE_CHECKING}
1697 CheckColumnConvertion(ColumnIndex, stBinaryStream);
1699 TempBlob := GetBlobObject(FBuffer, ColumnIndex);
1700 if (TempBlob <> nil) and not TempBlob.IsEmpty then
1701 Result := TempBlob.GetStream
1704 IsNull := Result = nil;
1708 Returns the value of the designated column in the current row
1709 of this <code>ResultSet</code> object as a <code>Blob</code> object
1710 in the Java programming language.
1712 @param ColumnIndex the first column is 1, the second is 2, ...
1713 @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in
1714 the specified column
1716 function TZRowAccessor.GetBlob(ColumnIndex: Integer; var IsNull: Boolean): IZBlob;
1718 {$IFNDEF DISABLE_CHECKING}
1719 CheckColumnIndex(ColumnIndex);
1720 if not (FColumnTypes[ColumnIndex - 1] in [stAsciiStream, stBinaryStream,
1721 stUnicodeStream]) then
1723 raise EZSQLException.Create(
1724 Format(SCanNotAccessBlobRecord,
1725 [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));
1729 Result := GetBlobObject(FBuffer, ColumnIndex);
1730 IsNull := Result = nil;
1731 if Result = nil then
1733 Result := TZAbstractBlob.CreateWithStream(nil, nil);
1734 SetBlobObject(FBuffer, ColumnIndex, Result);
1739 Returns the value of the designated column in the current row
1740 of this <code>ResultSet</code> object as a <code>ResultSet</code> object
1741 in the Java programming language.
1743 @param ColumnIndex the first column is 1, the second is 2, ...
1744 @return a <code>ResultSet</code> object representing the SQL
1745 <code>ResultSet</code> value in the specified column
1747 function TZRowAccessor.GetDataSet(ColumnIndex: Integer; var IsNull: Boolean): IZDataSet;
1750 NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};
1752 {$IFNDEF DISABLE_CHECKING}
1753 CheckColumnIndex(ColumnIndex);
1754 if not (FColumnTypes[ColumnIndex - 1] = stDataSet) then
1756 raise EZSQLException.Create(
1757 Format(SCanNotAccessBlobRecord,
1758 [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));
1762 Ptr := PPointer(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
1763 NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]]);
1766 if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then
1768 if NullPtr^ = 0 then
1770 Result := IZDataSet(Ptr^)
1776 Gets the value of the designated column in the current row
1777 of this <code>ResultSet</code> object as a <code>Variant</code> value.
1779 @param columnIndex the first column is 1, the second is 2, ...
1780 @return the column value; if the value is SQL <code>NULL</code>, the
1781 value returned is <code>null</code>
1783 function TZRowAccessor.GetValue(ColumnIndex: Integer): TZVariant;
1789 if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then
1791 ValuePtr := @FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1];
1792 case FColumnTypes[ColumnIndex - 1] of
1795 Result.VType := vtInteger;
1796 Result.VInteger := PShortInt(ValuePtr)^;
1800 Result.VType := vtInteger;
1801 Result.VInteger := PSmallInt(ValuePtr)^;
1805 Result.VType := vtInteger;
1806 Result.VInteger := PInteger(ValuePtr)^;
1810 Result.VType := vtInteger;
1811 Result.VInteger := PInt64(ValuePtr)^;
1815 Result.VType := vtFloat;
1816 Result.VFloat := PSingle(ValuePtr)^;
1820 Result.VType := vtFloat;
1821 Result.VFloat := PDouble(ValuePtr)^;
1825 Result.VType := vtFloat;
1826 Result.VFloat := PExtended(ValuePtr)^;
1830 Result.VType := vtBoolean;
1831 Result.VBoolean := PWordBool(ValuePtr)^;
1833 stDate, stTime, stTimestamp:
1835 Result.VType := vtDateTime;
1836 Result.VDateTime := PDateTime(ValuePtr)^;
1840 Result.VType := vtString;
1841 Result.VString := PChar(ValuePtr);
1845 Result.VType := vtUnicodeString;
1846 Result.VUnicodeString := GetUnicodeString(ColumnIndex, IsNull);
1848 stBytes,stGUID,stAsciiStream, stBinaryStream:
1850 Result.VType := vtString;
1851 Result.VString := GetString(ColumnIndex, IsNull);
1855 Result.VType := vtUnicodeString;
1856 Result.VUnicodeString := GetUnicodeString(ColumnIndex, IsNull);
1860 Result.VType := vtInterface;
1861 Result.VInterface := GetDataSet(ColumnIndex, IsNull);
1864 Result.VType := vtNull;
1868 Result.VType := vtNull;
1871 //---------------------------------------------------------------------
1873 //---------------------------------------------------------------------
1876 Gives a not nullable column a null value.
1878 The <code>SetXXX</code> methods are used to Set column values in the
1879 current row or the insert row. The <code>SetXXX</code> methods do not
1880 Set the underlying database; instead the <code>SetRow</code>
1881 or <code>insertRow</code> methods are called to Set the database.
1883 @param columnIndex the first column is 1, the second is 2, ...
1885 procedure TZRowAccessor.SetNotNull(ColumnIndex: Integer);
1887 {$IFNDEF DISABLE_CHECKING}
1888 CheckColumnConvertion(ColumnIndex, stString);
1890 if (FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 1)
1891 and (FColumnTypes[ColumnIndex - 1] in [stAsciiStream, stBinaryStream,
1892 stUnicodeStream]) then
1894 SetBlobObject(FBuffer, ColumnIndex, nil);
1896 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
1900 Gives a nullable column a null value.
1902 The <code>SetXXX</code> methods are used to Set column values in the
1903 current row or the insert row. The <code>SetXXX</code> methods do not
1904 Set the underlying database; instead the <code>SetRow</code>
1905 or <code>insertRow</code> methods are called to Set the database.
1907 @param columnIndex the first column is 1, the second is 2, ...
1909 procedure TZRowAccessor.SetNull(ColumnIndex: Integer);
1911 {$IFNDEF DISABLE_CHECKING}
1912 CheckColumnConvertion(ColumnIndex, stString);
1914 if (FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0) then
1915 case FColumnTypes[ColumnIndex - 1] of
1916 stAsciiStream, stBinaryStream, stUnicodeStream:
1917 SetBlobObject(FBuffer, ColumnIndex, nil);
1918 stBytes,stGUID, stString, stUnicodeString:
1919 if PNativeUInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ > 0 then
1921 System.Dispose(PPointer(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^);
1922 PNativeUInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;
1925 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 1;
1929 Sets the designated column with a <code>boolean</code> value.
1930 The <code>SetXXX</code> methods are used to Set column values in the
1931 current row or the insert row. The <code>SetXXX</code> methods do not
1932 Set the underlying database; instead the <code>SetRow</code> or
1933 <code>insertRow</code> methods are called to Set the database.
1935 @param columnIndex the first column is 1, the second is 2, ...
1936 @param x the new column value
1938 procedure TZRowAccessor.SetBoolean(ColumnIndex: Integer; Value: Boolean);
1942 {$IFNDEF DISABLE_CHECKING}
1943 CheckColumnConvertion(ColumnIndex, stBoolean);
1950 case FColumnTypes[ColumnIndex - 1] of
1953 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
1954 PWordBool(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
1956 stByte: SetByte(ColumnIndex, TempInt);
1957 stShort: SetShort(ColumnIndex, TempInt);
1958 stInteger: SetInt(ColumnIndex, TempInt);
1959 stLong: SetLong(ColumnIndex, TempInt);
1960 stFloat: SetFloat(ColumnIndex, TempInt);
1961 stDouble: SetDouble(ColumnIndex, TempInt);
1962 stBigDecimal: SetBigDecimal(ColumnIndex, TempInt);
1963 stString, stUnicodeString:
1965 SetString(ColumnIndex, 'True')
1967 SetString(ColumnIndex, 'False');
1972 Sets the designated column with a <code>byte</code> value.
1973 The <code>SetXXX</code> methods are used to Set column values in the
1974 current row or the insert row. The <code>SetXXX</code> methods do not
1975 Set the underlying database; instead the <code>SetRow</code> or
1976 <code>insertRow</code> methods are called to Set the database.
1979 @param columnIndex the first column is 1, the second is 2, ...
1980 @param x the new column value
1982 procedure TZRowAccessor.SetByte(ColumnIndex: Integer;
1985 {$IFNDEF DISABLE_CHECKING}
1986 CheckColumnConvertion(ColumnIndex, stByte);
1988 case FColumnTypes[ColumnIndex - 1] of
1989 stBoolean: SetBoolean(ColumnIndex, Value <> 0);
1992 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
1993 PShortInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
1995 stShort: SetShort(ColumnIndex, Value);
1996 stInteger: SetInt(ColumnIndex, Value);
1997 stLong: SetLong(ColumnIndex, Value);
1998 stFloat: SetFloat(ColumnIndex, Value);
1999 stDouble: SetDouble(ColumnIndex, Value);
2000 stBigDecimal: SetBigDecimal(ColumnIndex, Value);
2001 stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));
2006 Sets the designated column with a <code>short</code> value.
2007 The <code>SetXXX</code> methods are used to Set column values in the
2008 current row or the insert row. The <code>SetXXX</code> methods do not
2009 Set the underlying database; instead the <code>SetRow</code> or
2010 <code>insertRow</code> methods are called to Set the database.
2012 @param columnIndex the first column is 1, the second is 2, ...
2013 @param x the new column value
2015 procedure TZRowAccessor.SetShort(ColumnIndex: Integer; Value: SmallInt);
2017 {$IFNDEF DISABLE_CHECKING}
2018 CheckColumnConvertion(ColumnIndex, stShort);
2020 case FColumnTypes[ColumnIndex - 1] of
2021 stBoolean: SetBoolean(ColumnIndex, Value <> 0);
2022 stByte: SetByte(ColumnIndex, Value);
2025 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2026 PSmallInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
2028 stInteger: SetInt(ColumnIndex, Value);
2029 stLong: SetLong(ColumnIndex, Value);
2030 stFloat: SetFloat(ColumnIndex, Value);
2031 stDouble: SetDouble(ColumnIndex, Value);
2032 stBigDecimal: SetBigDecimal(ColumnIndex, Value);
2033 stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));
2038 Sets the designated column with an <code>int</code> value.
2039 The <code>SetXXX</code> methods are used to Set column values in the
2040 current row or the insert row. The <code>SetXXX</code> methods do not
2041 Set the underlying database; instead the <code>SetRow</code> or
2042 <code>insertRow</code> methods are called to Set the database.
2044 @param columnIndex the first column is 1, the second is 2, ...
2045 @param x the new column value
2047 procedure TZRowAccessor.SetInt(ColumnIndex: Integer; Value: Integer);
2049 {$IFNDEF DISABLE_CHECKING}
2050 CheckColumnConvertion(ColumnIndex, stInteger);
2052 case FColumnTypes[ColumnIndex - 1] of
2053 stBoolean: SetBoolean(ColumnIndex, Value <> 0);
2054 stByte: SetByte(ColumnIndex, Value);
2055 stShort: SetShort(ColumnIndex, Value);
2058 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2059 PInteger(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
2061 stLong: SetLong(ColumnIndex, Value);
2062 stFloat: SetFloat(ColumnIndex, Value);
2063 stDouble: SetDouble(ColumnIndex, Value);
2064 stBigDecimal: SetBigDecimal(ColumnIndex, Value);
2065 stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));
2070 Sets the designated column with a <code>long</code> value.
2071 The <code>SetXXX</code> methods are used to Set column values in the
2072 current row or the insert row. The <code>SetXXX</code> methods do not
2073 Set the underlying database; instead the <code>SetRow</code> or
2074 <code>insertRow</code> methods are called to Set the database.
2076 @param columnIndex the first column is 1, the second is 2, ...
2077 @param x the new column value
2079 procedure TZRowAccessor.SetLong(ColumnIndex: Integer; Value: Int64);
2081 {$IFNDEF DISABLE_CHECKING}
2082 CheckColumnConvertion(ColumnIndex, stLong);
2084 case FColumnTypes[ColumnIndex - 1] of
2085 stBoolean: SetBoolean(ColumnIndex, Value <> 0);
2086 stByte: SetByte(ColumnIndex, Value);
2087 stShort: SetShort(ColumnIndex, Value);
2088 stInteger: SetInt(ColumnIndex, Value);
2091 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2092 PInt64(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
2094 stFloat: SetFloat(ColumnIndex, Value);
2095 stDouble: SetDouble(ColumnIndex, Value);
2096 stBigDecimal: SetBigDecimal(ColumnIndex, Value);
2097 stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));
2102 Sets the designated column with a <code>float</code> value.
2103 The <code>SetXXX</code> methods are used to Set column values in the
2104 current row or the insert row. The <code>SetXXX</code> methods do not
2105 Set the underlying database; instead the <code>SetRow</code> or
2106 <code>insertRow</code> methods are called to Set the database.
2108 @param columnIndex the first column is 1, the second is 2, ...
2109 @param x the new column value
2111 procedure TZRowAccessor.SetFloat(ColumnIndex: Integer; Value: Single);
2113 {$IFNDEF DISABLE_CHECKING}
2114 CheckColumnConvertion(ColumnIndex, stFloat);
2116 case FColumnTypes[ColumnIndex - 1] of
2117 stBoolean: SetBoolean(ColumnIndex, Value <> 0);
2118 stByte: SetByte(ColumnIndex, Trunc(Value));
2119 stShort: SetShort(ColumnIndex, Trunc(Value));
2120 stInteger: SetInt(ColumnIndex, Trunc(Value));
2121 stLong: SetLong(ColumnIndex, Trunc(Value));
2124 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2125 PSingle(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
2127 stDouble: SetDouble(ColumnIndex, Value);
2128 stBigDecimal: SetBigDecimal(ColumnIndex, Value);
2129 stString, stUnicodeString: SetString(ColumnIndex, FloatToSQLStr(Value));
2134 Sets the designated column with a <code>double</code> value.
2135 The <code>SetXXX</code> methods are used to Set column values in the
2136 current row or the insert row. The <code>SetXXX</code> methods do not
2137 Set the underlying database; instead the <code>SetRow</code> or
2138 <code>insertRow</code> methods are called to Set the database.
2140 @param columnIndex the first column is 1, the second is 2, ...
2141 @param x the new column value
2143 procedure TZRowAccessor.SetDouble(ColumnIndex: Integer; Value: Double);
2145 {$IFNDEF DISABLE_CHECKING}
2146 CheckColumnConvertion(ColumnIndex, stDouble);
2148 case FColumnTypes[ColumnIndex - 1] of
2149 stBoolean: SetBoolean(ColumnIndex, Value <> 0);
2150 stByte: SetByte(ColumnIndex, Trunc(Value));
2151 stShort: SetShort(ColumnIndex, Trunc(Value));
2152 stInteger: SetInt(ColumnIndex, Trunc(Value));
2153 stLong: SetLong(ColumnIndex, Trunc(Value));
2154 stFloat: SetFloat(ColumnIndex, Value);
2157 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2158 PDouble(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
2160 stBigDecimal: SetBigDecimal(ColumnIndex, Value);
2161 stString, stUnicodeString: SetString(ColumnIndex, FloatToSQLStr(Value));
2166 Sets the designated column with a <code>java.math.BigDecimal</code>
2168 The <code>SetXXX</code> methods are used to Set column values in the
2169 current row or the insert row. The <code>SetXXX</code> methods do not
2170 Set the underlying database; instead the <code>SetRow</code> or
2171 <code>insertRow</code> methods are called to Set the database.
2173 @param columnIndex the first column is 1, the second is 2, ...
2174 @param x the new column value
2176 procedure TZRowAccessor.SetBigDecimal(ColumnIndex: Integer; Value: Extended);
2178 {$IFNDEF DISABLE_CHECKING}
2179 CheckColumnConvertion(ColumnIndex, stBigDecimal);
2181 case FColumnTypes[ColumnIndex - 1] of
2182 stBoolean: SetBoolean(ColumnIndex, Value <> 0);
2183 stByte: SetByte(ColumnIndex, Trunc(Value));
2184 stShort: SetShort(ColumnIndex, Trunc(Value));
2185 stInteger: SetInt(ColumnIndex, Trunc(Value));
2186 stLong: SetLong(ColumnIndex, Trunc(Value));
2187 stFloat: SetFloat(ColumnIndex, Value);
2188 stDouble: SetDouble(ColumnIndex, Value);
2191 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2192 PExtended(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
2194 stString, stUnicodeString: SetString(ColumnIndex, FloatToSQLStr(Value));
2199 Sets the designated column with a <code>String</code> value.
2200 The <code>SetXXX</code> methods are used to Set column values in the
2201 current row or the insert row. The <code>SetXXX</code> methods do not
2202 Set the underlying database; instead the <code>SetRow</code> or
2203 <code>insertRow</code> methods are called to Set the database.
2205 @param columnIndex the first column is 1, the second is 2, ...
2206 @param x the new column value
2208 procedure TZRowAccessor.SetPChar(ColumnIndex: Integer; Value: PChar);
2210 {$IFNDEF DISABLE_CHECKING}
2211 CheckColumnConvertion(ColumnIndex, stString);
2213 case FColumnTypes[ColumnIndex - 1] of
2214 stString{$IFDEF UNICODE}, stUnicodeString{$ENDIF}:
2216 if Value <> nil then
2218 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2219 SetString(ColumnIndex, Value);
2222 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 1;
2225 SetString(ColumnIndex, Value);
2230 Sets the designated column with a <code>String</code> value.
2231 The <code>SetXXX</code> methods are used to Set column values in the
2232 current row or the insert row. The <code>SetXXX</code> methods do not
2233 Set the underlying database; instead the <code>SetRow</code> or
2234 <code>insertRow</code> methods are called to Set the database.
2236 @param columnIndex the first column is 1, the second is 2, ...
2237 @param x the new column value
2239 procedure TZRowAccessor.SetString(ColumnIndex: Integer; Value: String);
2246 {$IFNDEF DISABLE_CHECKING}
2247 CheckColumnConvertion(ColumnIndex, stString);
2250 case FColumnTypes[ColumnIndex - 1] of
2253 TempStr := UpperCase(Value);
2254 SetBoolean(ColumnIndex, (TempStr = 'Y') or (TempStr = 'T')
2255 or (TempStr = 'YES') or (TempStr = 'TRUE'));
2257 stByte: SetByte(ColumnIndex, StrToIntDef(Value, 0));
2258 stShort: SetShort(ColumnIndex, StrToIntDef(Value, 0));
2259 stInteger: SetInt(ColumnIndex, StrToIntDef(Value, 0));
2260 stLong: SetLong(ColumnIndex, StrToIntDef(Value, 0));
2261 stFloat: SetFloat(ColumnIndex, SQLStrToFloatDef(AnsiString(Value), 0));
2262 stDouble: SetDouble(ColumnIndex, SQLStrToFloatDef(AnsiString(Value), 0));
2263 stBigDecimal: SetBigDecimal(ColumnIndex, SQLStrToFloatDef(AnsiString(Value), 0));
2266 InternalSetString(FBuffer, ColumnIndex, Value);
2267 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2271 SetUnicodeString(ColumnIndex, Value);
2273 SetUnicodeString(ColumnIndex, ZDbcUnicodeString(Value, ConSettings.CTRL_CP));
2275 stBytes: SetBytes(ColumnIndex, StrToBytes(AnsiString(Value)));
2278 GUID := StringToGUID(Value);
2280 System.Move(Pointer(@GUID)^, Pointer(Bts)^, 16);
2281 SetBytes(ColumnIndex, Bts);
2283 stDate: SetDate(ColumnIndex, AnsiSQLDateToDateTime(Value));
2284 stTime: SetTime(ColumnIndex, AnsiSQLDateToDateTime(Value));
2285 stTimestamp: SetTimestamp(ColumnIndex, AnsiSQLDateToDateTime(Value));
2288 GetBlob(ColumnIndex, IsNull).SetUnicodeString(Value);
2290 GetBlob(ColumnIndex, IsNull).SetString(ZDbcUnicodeString(Value, ConSettings.CTRL_CP));
2293 GetBlob(ColumnIndex, IsNull).SetString(ZPlainString(Value, ConSettings, ConSettings.CTRL_CP));
2295 GetBlob(ColumnIndex, IsNull).SetString(RawByteString(Value));
2300 Sets the designated column with a <code>WideString</code> value.
2301 The <code>SetXXX</code> methods are used to Set column values in the
2302 current row or the insert row. The <code>SetXXX</code> methods do not
2303 Set the underlying database; instead the <code>SetRow</code> or
2304 <code>insertRow</code> methods are called to Set the database.
2306 @param columnIndex the first column is 1, the second is 2, ...
2307 @param x the new column value
2309 procedure TZRowAccessor.SetUnicodeString(ColumnIndex: Integer; Value: WideString);
2310 var IsNull: Boolean;
2312 {$IFNDEF DISABLE_CHECKING}
2313 CheckColumnConvertion(ColumnIndex, stString);
2315 case FColumnTypes[ColumnIndex - 1] of
2316 stUnicodeString{$IFDEF UNICODE},stString{$ENDIF}:
2318 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2319 InternalSetUnicodeString(FBuffer, ColumnIndex, Value);
2322 GetBlob(ColumnIndex, IsNull).SetUnicodeString(Value);
2324 SetString(ColumnIndex, ZDbcString(Value));
2329 Sets the designated column with a <code>byte</code> array value.
2330 The <code>SetXXX</code> methods are used to Set column values in the
2331 current row or the insert row. The <code>SetXXX</code> methods do not
2332 Set the underlying database; instead the <code>SetRow</code> or
2333 <code>insertRow</code> methods are called to Set the database.
2335 @param columnIndex the first column is 1, the second is 2, ...
2336 @param x the new column value
2338 procedure TZRowAccessor.SetBytes(ColumnIndex: Integer; Value: TByteDynArray);
2342 {$IFNDEF DISABLE_CHECKING}
2343 CheckColumnConvertion(ColumnIndex, stBytes);
2345 if Value <> nil then
2347 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2348 case FColumnTypes[ColumnIndex - 1] of
2349 stBytes,stGUID: InternalSetBytes(FBuffer, ColumnIndex, Value);
2350 stBinaryStream: GetBlob(ColumnIndex, IsNull).SetBytes(Value);
2352 SetString(ColumnIndex, String(BytesToStr(Value)));
2356 SetNull(ColumnIndex);
2360 Sets the designated column with a <code>java.sql.Date</code> value.
2361 The <code>SetXXX</code> methods are used to Set column values in the
2362 current row or the insert row. The <code>SetXXX</code> methods do not
2363 Set the underlying database; instead the <code>SetRow</code> or
2364 <code>insertRow</code> methods are called to Set the database.
2366 @param columnIndex the first column is 1, the second is 2, ...
2367 @param x the new column value
2369 procedure TZRowAccessor.SetDate(ColumnIndex: Integer; Value: TDateTime);
2371 {$IFNDEF DISABLE_CHECKING}
2372 CheckColumnConvertion(ColumnIndex, stTimestamp);
2374 case FColumnTypes[ColumnIndex - 1] of
2377 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2378 PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ :=
2381 stTimestamp: SetTimestamp(ColumnIndex, Trunc(Value));
2382 stString, stUnicodeString: SetString(ColumnIndex, FormatDateTime('yyyy-mm-dd', Value));
2387 Sets the designated column with a <code>java.sql.Time</code> value.
2388 The <code>SetXXX</code> methods are used to Set column values in the
2389 current row or the insert row. The <code>SetXXX</code> methods do not
2390 Set the underlying database; instead the <code>SetRow</code> or
2391 <code>insertRow</code> methods are called to Set the database.
2393 @param columnIndex the first column is 1, the second is 2, ...
2394 @param x the new column value
2396 procedure TZRowAccessor.SetTime(ColumnIndex: Integer; Value: TDateTime);
2398 {$IFNDEF DISABLE_CHECKING}
2399 CheckColumnConvertion(ColumnIndex, stTime);
2401 case FColumnTypes[ColumnIndex - 1] of
2404 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2405 PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ :=
2408 stTimestamp: SetTimestamp(ColumnIndex, Frac(Value));
2409 stString, stUnicodeString:
2410 SetString(ColumnIndex, FormatDateTime('hh:nn:ss', Value));
2415 Sets the designated column with a <code>java.sql.Timestamp</code>
2417 The <code>SetXXX</code> methods are used to Set column values in the
2418 current row or the insert row. The <code>SetXXX</code> methods do not
2419 Set the underlying database; instead the <code>SetRow</code> or
2420 <code>insertRow</code> methods are called to Set the database.
2422 @param columnIndex the first column is 1, the second is 2, ...
2423 @param x the new column value
2425 procedure TZRowAccessor.SetTimestamp(ColumnIndex: Integer; Value: TDateTime);
2427 {$IFNDEF DISABLE_CHECKING}
2428 CheckColumnConvertion(ColumnIndex, stTimestamp);
2430 case FColumnTypes[ColumnIndex - 1] of
2431 stDate: SetDate(ColumnIndex, Value);
2432 stTime: SetTime(ColumnIndex, Value);
2435 FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;
2436 PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;
2438 stString, stUnicodeString:
2439 SetString(ColumnIndex, FormatDateTime('yyyy-mm-dd hh:nn:ss', Value));
2444 Sets the designated column with an ascii stream value.
2445 The <code>SetXXX</code> methods are used to Set column values in the
2446 current row or the insert row. The <code>SetXXX</code> methods do not
2447 Set the underlying database; instead the <code>SetRow</code> or
2448 <code>insertRow</code> methods are called to Set the database.
2450 @param columnIndex the first column is 1, the second is 2, ...
2451 @param x the new column value
2453 procedure TZRowAccessor.SetAsciiStream(ColumnIndex: Integer; Value: TStream);
2457 {$IFNDEF DISABLE_CHECKING}
2458 CheckColumnConvertion(ColumnIndex, stAsciiStream);
2461 GetBlob(ColumnIndex, IsNull).SetStream(Value);
2465 Sets the designated column with a binary stream value.
2466 The <code>SetXXX</code> methods are used to Set column values in the
2467 current row or the insert row. The <code>SetXXX</code> methods do not
2468 Set the underlying database; instead the <code>SetRow</code> or
2469 <code>insertRow</code> methods are called to Set the database.
2471 @param columnIndex the first column is 1, the second is 2, ...
2472 @param x the new column value
2473 @param length the length of the stream
2475 procedure TZRowAccessor.SetBinaryStream(ColumnIndex: Integer; Value: TStream);
2479 {$IFNDEF DISABLE_CHECKING}
2480 CheckColumnConvertion(ColumnIndex, stBinaryStream);
2483 GetBlob(ColumnIndex, IsNull).SetStream(Value);
2487 Sets the designated column with a character stream value.
2488 The <code>SetXXX</code> methods are used to Set column values in the
2489 current row or the insert row. The <code>SetXXX</code> methods do not
2490 Set the underlying database; instead the <code>SetRow</code> or
2491 <code>insertRow</code> methods are called to Set the database.
2493 @param columnIndex the first column is 1, the second is 2, ...
2494 @param x the new column value
2496 procedure TZRowAccessor.SetUnicodeStream(ColumnIndex: Integer;
2502 {$IFNDEF DISABLE_CHECKING}
2503 CheckColumnConvertion(ColumnIndex, stUnicodeStream);
2505 GetBlob(ColumnIndex, IsNull).SetStream(Value, True);
2509 Sets the blob wrapper object to the specified column.
2510 @param ColumnIndex the first column is 1, the second is 2, ...
2511 @param Value a blob wrapper object to be set.
2513 procedure TZRowAccessor.SetBlob(ColumnIndex: Integer; Value: IZBlob);
2515 {$IFNDEF DISABLE_CHECKING}
2516 CheckColumnIndex(ColumnIndex);
2517 if not (FColumnTypes[ColumnIndex - 1] in [stAsciiStream, stBinaryStream,
2518 stUnicodeStream]) then
2520 raise EZSQLException.Create(
2521 Format(SCanNotAccessBlobRecord,
2522 [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));
2526 SetBlobObject(FBuffer, ColumnIndex, Value);
2530 Sets the blob wrapper object to the specified column.
2531 @param ColumnIndex the first column is 1, the second is 2, ...
2532 @param Value a ResultSet wrapper object to be set.
2534 procedure TZRowAccessor.SetDataSet(ColumnIndex: Integer; Value: IZDataSet);
2537 NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};
2539 {$IFNDEF DISABLE_CHECKING}
2540 CheckColumnIndex(ColumnIndex);
2541 if not (FColumnTypes[ColumnIndex - 1] = stDataSet) then
2543 raise EZSQLException.Create(
2544 Format(SCanNotAccessBlobRecord,
2545 [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));
2549 Ptr := PPointer(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);
2550 NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]]);
2553 if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then //M.A. if NullPtr^ = 0 then
2555 if NullPtr^ = 0 then
2557 IZDataSet(Ptr^) := nil
2561 IZDataSet(Ptr^) := Value;
2563 if Value <> nil then
2565 NullPtr^ := {$IFDEF WIN64}false{$ELSE}0{$ENDIF} //M.A. NullPtr^ := 0
2567 NullPtr^ := {$IFDEF WIN64}true{$ELSE}1{$ENDIF}; //M.A. NullPtr^ := 1;
2575 Sets the designated column with a <code>Variant</code> value.
2576 The <code>SetXXX</code> methods are used to Set column values in the
2577 current row or the insert row. The <code>SetXXX</code> methods do not
2578 Set the underlying database; instead the <code>SetRow</code> or
2579 <code>insertRow</code> methods are called to Set the database.
2581 @param columnIndex the first column is 1, the second is 2, ...
2582 @param x the new column value
2584 procedure TZRowAccessor.SetValue(ColumnIndex: Integer; Value: TZVariant);
2587 vtNull: SetNull(ColumnIndex);
2588 vtBoolean: SetBoolean(ColumnIndex, Value.VBoolean);
2589 vtInteger: SetLong(ColumnIndex, Value.VInteger);
2590 vtFloat: SetBigDecimal(ColumnIndex, Value.VFloat);
2591 vtBytes: SetBytes(ColumnIndex, Value.VBytes);
2592 vtString: SetString(ColumnIndex, Value.VString);
2593 vtUnicodeString: SetUnicodeString(ColumnIndex, Value.VUnicodeString);
2594 vtDateTime: SetTimestamp(ColumnIndex, Value.VDateTime);