1 {*********************************************************}
3 { Zeos Database Objects }
4 { Interbase Database Connectivity Classes }
6 { Originally written by Sergey Merkuriev }
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 {********************************************************@}
52 unit ZDbcASAResultSet;
59 {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},
60 Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}
61 ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZDbcASA, ZPlainASADriver, ZCompatibility,
62 ZDbcResultSetMetadata, ZDbcASAUtils, ZMessages, ZVariant;
66 {** Implements ASA ResultSet. }
67 TZASAResultSet = class(TZAbstractResultSet)
71 FCursorName: AnsiString;
74 FParamsSqlData: IZASASQLDA;
75 FUpdateSqlData: IZASASQLDA;
76 FASAConnection: IZASAConnection;
81 procedure Open; override;
82 procedure PrepareUpdateSQLData; virtual;
83 function GetFieldValue(ColumnIndex: Integer): Variant;
84 function InternalGetString(ColumnIndex: Integer): RawByteString; override;
86 constructor Create(Statement: IZStatement; SQL: string;
87 var StmtNum: SmallInt; CursorName: AnsiString;
88 SqlData: IZASASQLDA; ParamsSqlData: IZASASQLDA;
91 function GetCursorName: AnsiString; override;
92 procedure Close; override;
94 function IsNull(ColumnIndex: Integer): Boolean; override;
95 function GetBoolean(ColumnIndex: Integer): Boolean; override;
96 function GetByte(ColumnIndex: Integer): Byte; override;
97 function GetShort(ColumnIndex: Integer): SmallInt; override;
98 function GetInt(ColumnIndex: Integer): Integer; override;
99 function GetLong(ColumnIndex: Integer): Int64; override;
100 function GetFloat(ColumnIndex: Integer): Single; override;
101 function GetDouble(ColumnIndex: Integer): Double; override;
102 function GetBigDecimal(ColumnIndex: Integer): Extended; override;
103 function GetBytes(ColumnIndex: Integer): TByteDynArray; override;
104 function GetDate(ColumnIndex: Integer): TDateTime; override;
105 function GetTime(ColumnIndex: Integer): TDateTime; override;
106 function GetTimestamp(ColumnIndex: Integer): TDateTime; override;
107 function GetBlob(ColumnIndex: Integer): IZBlob; override;
109 function Last: Boolean; override;
110 function MoveAbsolute(Row: Integer): Boolean; override;
111 function MoveRelative(Rows: Integer): Boolean; override;
112 function Previous: Boolean; override;
113 function Next: Boolean; override;
115 function RowUpdated: Boolean; override;
116 function RowInserted: Boolean; override;
117 function RowDeleted: Boolean; override;
119 procedure UpdateNull(ColumnIndex: Integer); override;
120 procedure UpdateBoolean(ColumnIndex: Integer; Value: Boolean); override;
121 procedure UpdateByte(ColumnIndex: Integer; Value: ShortInt); override;
122 procedure UpdateShort(ColumnIndex: Integer; Value: SmallInt); override;
123 procedure UpdateInt(ColumnIndex: Integer; Value: Integer); override;
124 procedure UpdateLong(ColumnIndex: Integer; Value: Int64); override;
125 procedure UpdateFloat(ColumnIndex: Integer; Value: Single); override;
126 procedure UpdateDouble(ColumnIndex: Integer; Value: Double); override;
127 procedure UpdateBigDecimal(ColumnIndex: Integer; Value: Extended); override;
128 procedure UpdatePChar(ColumnIndex: Integer; Value: PChar); override;
129 procedure UpdateString(ColumnIndex: Integer; const Value: String); override;
130 procedure UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString); override;
131 procedure UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray); override;
132 procedure UpdateDate(ColumnIndex: Integer; Value: TDateTime); override;
133 procedure UpdateTime(ColumnIndex: Integer; Value: TDateTime); override;
134 procedure UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime); override;
135 procedure UpdateAsciiStream(ColumnIndex: Integer; Value: TStream); override;
136 procedure UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream); override;
137 procedure UpdateBinaryStream(ColumnIndex: Integer; Value: TStream); override;
138 procedure UpdateValue(ColumnIndex: Integer; const Value: TZVariant); override;
140 procedure InsertRow; override;
141 procedure UpdateRow; override;
142 procedure DeleteRow; override;
143 procedure RefreshRow; override;
144 procedure CancelRowUpdates; override;
145 procedure MoveToInsertRow; override;
146 procedure MoveToCurrentRow; override;
148 property SQLData: IZASASQLDA read FSQLData;
151 IZASABlob = interface(IZBlob)
152 ['{1E043426-5856-4953-88B8-F6FB276B7B61}']
156 {** Implements external blob wrapper object for PostgreSQL. }
157 TZASABlob = class(TZAbstractBlob, IZASABlob)
160 FResultSet: TZASAResultSet;
165 constructor Create( ResultSet: TZASAResultSet; ColID: Integer);
166 constructor CreateWithStream(Stream: TStream; Connection: IZConnection);
167 constructor CreateWithData(Data: Pointer; Size: Integer; Connection: IZConnection);
169 function IsEmpty: Boolean; override;
170 function Clone: IZBlob; override;
171 function GetStream: TStream; override;
172 function GetString: RawByteString; override;
173 function GetUnicodeString: WideString; override;
174 function GetBytes: TByteDynArray; override;
185 SysUtils, Math, ZdbcLogging, ZPlainASAConstants, ZDbcUtils, ZEncoding;
190 Constructs this object, assignes main properties and
191 opens the record set.
192 @param Statement a related SQL statement object.
193 @param handle a Interbase6 database connect handle.
194 @param the statement previously prepared
195 @param the sql out data previously allocated
196 @param the Interbase sql dialect
198 constructor TZASAResultSet.Create(Statement: IZStatement; SQL: string;
199 var StmtNum: SmallInt; CursorName: AnsiString;
200 SqlData: IZASASQLDA; ParamsSqlData: IZASASQLDA;
201 CachedBlob: boolean);
203 inherited Create( Statement, SQL, nil,Statement.GetConnection.GetConSettings);
207 FCursorName := CursorName;
208 FCachedBlob := CachedBlob;
209 FASAConnection := Statement.GetConnection as IZASAConnection;
214 FParamsSqlData := ParamsSqlData;
216 ResultSetType := rtScrollSensitive;
217 ResultSetConcurrency := rcUpdatable;
223 Return field value by it index
224 @param the index column 0 first, 1 second ...
225 @return the field value as variant type
227 function TZASAResultSet.GetFieldValue(ColumnIndex: Integer): Variant;
230 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
231 Result := FUpdateSqlData.GetValue( ColumnIndex - 1)
233 Result := FSqlData.GetValue( ColumnIndex - 1);
234 LastWasNull := IsNull( ColumnIndex);
238 Gets the value of the designated column in the current row
239 of this <code>ResultSet</code> object as
240 a <code>java.sql.BigDecimal</code> in the Java programming language.
242 @param columnIndex the first column is 1, the second is 2, ...
243 @param scale the number of digits to the right of the decimal point
244 @return the column value; if the value is SQL <code>NULL</code>, the
245 value returned is <code>null</code>
247 function TZASAResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;
250 CheckColumnConvertion(ColumnIndex, stBigDecimal);
251 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
252 Result := FUpdateSqlData.GetBigDecimal( ColumnIndex - 1)
254 Result := FSqlData.GetBigDecimal( ColumnIndex - 1);
255 LastWasNull := IsNull( ColumnIndex);
259 Returns the value of the designated column in the current row
260 of this <code>ResultSet</code> object as a <code>Blob</code> object
261 in the Java programming language.
263 @param ColumnIndex the first column is 1, the second is 2, ...
264 @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in
267 function TZASAResultSet.GetBlob(ColumnIndex: Integer): IZBlob;
274 CheckBlobColumn(ColumnIndex);
276 LastWasNull := IsNull(ColumnIndex);
280 Blob := TZASABlob.Create( Self, ColumnIndex - 1);
283 if ( GetMetadata.GetColumnType(ColumnIndex) in [stUnicodeStream, stAsciiStream] ) then
285 case GetMetaData.GetColumnType(ColumnIndex) of
287 Blob.SetString(GetValidatedAnsiString(Blob.GetString, ConSettings, True));
290 TempStream := GetValidatedUnicodeStream(Blob.GetBuffer, Blob.Length, ConSettings, True);
291 Blob.SetStream(TempStream, True);
300 Gets the value of the designated column in the current row
301 of this <code>ResultSet</code> object as
302 a <code>boolean</code> in the Java programming language.
304 @param columnIndex the first column is 1, the second is 2, ...
305 @return the column value; if the value is SQL <code>NULL</code>, the
306 value returned is <code>false</code>
308 function TZASAResultSet.GetBoolean(ColumnIndex: Integer): Boolean;
311 CheckColumnConvertion(ColumnIndex, stBoolean);
312 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
313 Result := FUpdateSqlData.GetBoolean( ColumnIndex - 1)
315 Result := FSqlData.GetBoolean( ColumnIndex - 1);
316 LastWasNull := IsNull( ColumnIndex);
320 Gets the value of the designated column in the current row
321 of this <code>ResultSet</code> object as
322 a <code>byte</code> in the Java programming language.
324 @param columnIndex the first column is 1, the second is 2, ...
325 @return the column value; if the value is SQL <code>NULL</code>, the
326 value returned is <code>0</code>
328 function TZASAResultSet.GetByte(ColumnIndex: Integer): Byte;
331 CheckColumnConvertion(ColumnIndex, stByte);
332 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
333 Result := FUpdateSqlData.GetByte( ColumnIndex - 1)
335 Result := FSqlData.GetByte( ColumnIndex - 1);
336 LastWasNull := IsNull( ColumnIndex);
340 Gets the value of the designated column in the current row
341 of this <code>ResultSet</code> object as
342 a <code>byte</code> array in the Java programming language.
343 The bytes represent the raw values returned by the driver.
345 @param columnIndex the first column is 1, the second is 2, ...
346 @return the column value; if the value is SQL <code>NULL</code>, the
347 value returned is <code>null</code>
349 function TZASAResultSet.GetBytes(
350 ColumnIndex: Integer): TByteDynArray;
353 CheckColumnConvertion(ColumnIndex, stBytes);
354 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
355 Result := FUpdateSqlData.GetBytes( ColumnIndex - 1)
357 Result := FSqlData.GetBytes( ColumnIndex - 1);
358 LastWasNull := IsNull( ColumnIndex);
362 Gets the value of the designated column in the current row
363 of this <code>ResultSet</code> object as
364 a <code>java.sql.Date</code> object in the Java programming language.
366 @param columnIndex the first column is 1, the second is 2, ...
367 @return the column value; if the value is SQL <code>NULL</code>, the
368 value returned is <code>null</code>
370 function TZASAResultSet.GetDate(ColumnIndex: Integer): TDateTime;
373 CheckColumnConvertion(ColumnIndex, stDate);
374 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
375 Result := FUpdateSqlData.GetDate( ColumnIndex - 1)
377 Result := FSqlData.GetDate( ColumnIndex - 1);
378 LastWasNull := IsNull( ColumnIndex);
382 Gets the value of the designated column in the current row
383 of this <code>ResultSet</code> object as
384 a <code>double</code> in the Java programming language.
386 @param columnIndex the first column is 1, the second is 2, ...
387 @return the column value; if the value is SQL <code>NULL</code>, the
388 value returned is <code>0</code>
390 function TZASAResultSet.GetDouble(ColumnIndex: Integer): Double;
393 CheckColumnConvertion(ColumnIndex, stDouble);
394 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
395 Result := FUpdateSqlData.GetDouble( ColumnIndex - 1)
397 Result := FSqlData.GetDouble( ColumnIndex - 1);
398 LastWasNull := IsNull( ColumnIndex);
402 Gets the value of the designated column in the current row
403 of this <code>ResultSet</code> object as
404 a <code>float</code> in the Java programming language.
406 @param columnIndex the first column is 1, the second is 2, ...
407 @return the column value; if the value is SQL <code>NULL</code>, the
408 value returned is <code>0</code>
410 function TZASAResultSet.GetFloat(ColumnIndex: Integer): Single;
413 CheckColumnConvertion(ColumnIndex, stFloat);
414 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
415 Result := FUpdateSqlData.GetFloat( ColumnIndex - 1)
417 Result := FSqlData.GetFloat( ColumnIndex - 1);
418 LastWasNull := IsNull( ColumnIndex);
422 Gets the value of the designated column in the current row
423 of this <code>ResultSet</code> object as
424 an <code>int</code> in the Java programming language.
426 @param columnIndex the first column is 1, the second is 2, ...
427 @return the column value; if the value is SQL <code>NULL</code>, the
428 value returned is <code>0</code>
430 function TZASAResultSet.GetInt(ColumnIndex: Integer): Integer;
433 CheckColumnConvertion(ColumnIndex, stInteger);
434 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
435 Result := FUpdateSqlData.GetInt( ColumnIndex - 1)
437 Result := FSqlData.GetInt( ColumnIndex - 1);
438 LastWasNull := IsNull( ColumnIndex);
442 Gets the value of the designated column in the current row
443 of this <code>ResultSet</code> object as
444 a <code>long</code> in the Java programming language.
446 @param columnIndex the first column is 1, the second is 2, ...
447 @return the column value; if the value is SQL <code>NULL</code>, the
448 value returned is <code>0</code>
450 function TZASAResultSet.GetLong(ColumnIndex: Integer): Int64;
453 CheckColumnConvertion(ColumnIndex, stLong);
454 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
455 Result := FUpdateSqlData.GetLong( ColumnIndex - 1)
457 Result := FSqlData.GetLong( ColumnIndex - 1);
458 LastWasNull := IsNull( ColumnIndex);
462 Gets the value of the designated column in the current row
463 of this <code>ResultSet</code> object as
464 a <code>short</code> in the Java programming language.
466 @param columnIndex the first column is 1, the second is 2, ...
467 @return the column value; if the value is SQL <code>NULL</code>, the
468 value returned is <code>0</code>
470 function TZASAResultSet.GetShort(ColumnIndex: Integer): SmallInt;
473 CheckColumnConvertion(ColumnIndex, stShort);
474 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
475 Result := FUpdateSqlData.GetShort( ColumnIndex - 1)
477 Result := FSqlData.GetShort( ColumnIndex - 1);
478 LastWasNull := IsNull( ColumnIndex);
482 Gets the value of the designated column in the current row
483 of this <code>ResultSet</code> object as
484 a <code>String</code> in the Java programming language.
486 @param columnIndex the first column is 1, the second is 2, ...
487 @return the column value; if the value is SQL <code>NULL</code>, the
488 value returned is <code>null</code>
490 function TZASAResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;
493 CheckColumnConvertion( ColumnIndex, stString);
494 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
495 Result := FUpdateSqlData.GetString( ColumnIndex - 1)
497 Result := FSqlData.GetString( ColumnIndex - 1);
498 LastWasNull := IsNull( ColumnIndex);
502 Gets the value of the designated column in the current row
503 of this <code>ResultSet</code> object as
504 a <code>java.sql.Time</code> object in the Java programming language.
506 @param columnIndex the first column is 1, the second is 2, ...
507 @return the column value; if the value is SQL <code>NULL</code>, the
508 value returned is <code>null</code>
510 function TZASAResultSet.GetTime(ColumnIndex: Integer): TDateTime;
513 CheckColumnConvertion(ColumnIndex, stTime);
514 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
515 Result := FUpdateSqlData.GetTime( ColumnIndex - 1)
517 Result := FSqlData.GetTime( ColumnIndex - 1);
518 LastWasNull := IsNull( ColumnIndex);
522 Gets the value of the designated column in the current row
523 of this <code>ResultSet</code> object as
524 a <code>java.sql.Timestamp</code> object in the Java programming language.
526 @param columnIndex the first column is 1, the second is 2, ...
527 @return the column value; if the value is SQL <code>NULL</code>, the
528 value returned is <code>null</code>
529 @exception SQLException if a database access error occurs
531 function TZASAResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;
534 CheckColumnConvertion(ColumnIndex, stTimestamp);
535 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
536 Result := FUpdateSqlData.GetTimestamp( ColumnIndex - 1)
538 Result := FSqlData.GetTimestamp( ColumnIndex - 1);
539 LastWasNull := IsNull( ColumnIndex);
543 Indicates if the value of the designated column in the current row
544 of this <code>ResultSet</code> object is Null.
546 @param columnIndex the first column is 1, the second is 2, ...
547 @return if the value is SQL <code>NULL</code>, the
548 value returned is <code>true</code>. <code>false</code> otherwise.
550 function TZASAResultSet.IsNull(ColumnIndex: Integer): Boolean;
553 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
554 Result := FUpdateSqlData.IsNull( ColumnIndex - 1)
556 Result := FSqlData.IsNull(ColumnIndex - 1);
559 function TZASAResultSet.Last: Boolean;
561 if LastRowNo <> MaxInt then
562 Result := MoveAbsolute( LastRowNo)
564 Result := MoveAbsolute( -1);
568 Moves the cursor to the given row number in
569 this <code>ResultSet</code> object.
571 <p>If the row number is positive, the cursor moves to
572 the given row number with respect to the
573 beginning of the result set. The first row is row 1, the second
576 <p>If the given row number is negative, the cursor moves to
577 an absolute row position with respect to
578 the end of the result set. For example, calling the method
579 <code>absolute(-1)</code> positions the
580 cursor on the last row; calling the method <code>absolute(-2)</code>
581 moves the cursor to the next-to-last row, and so on.
583 <p>An attempt to position the cursor beyond the first/last row in
584 the result set leaves the cursor before the first row or after
587 <p><B>Note:</B> Calling <code>absolute(1)</code> is the same
588 as calling <code>first()</code>. Calling <code>absolute(-1)</code>
589 is the same as calling <code>last()</code>.
591 @return <code>true</code> if the cursor is on the result set;
592 <code>false</code> otherwise
594 function TZASAResultSet.MoveAbsolute(Row: Integer): Boolean;
597 if (MaxRows > 0) and (Row >= MaxRows) then
600 FASAConnection.GetPlainDriver.db_fetch( FASAConnection.GetDBHandle,
601 PAnsiChar(FCursorName), CUR_ABSOLUTE, Row, FSqlData.GetData, BlockSize, CUR_FORREGULAR);
602 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
603 FASAConnection.GetDBHandle, lcOther);
605 if FASAConnection.GetDBHandle.sqlCode <> SQLE_NOTFOUND then
616 FFetchStat := FASAConnection.GetDBHandle.sqlerrd[2];
617 if FFetchStat > 0 then
618 LastRowNo := Max( Row - FFetchStat, 0);
622 function TZASAResultSet.MoveRelative(Rows: Integer): Boolean;
625 if (RowNo > LastRowNo) or ((MaxRows > 0) and (RowNo >= MaxRows)) then
627 FASAConnection.GetPlainDriver.db_fetch( FASAConnection.GetDBHandle,
628 PAnsiChar( FCursorName), CUR_RELATIVE, Rows, FSqlData.GetData, BlockSize, CUR_FORREGULAR);
629 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
630 FASAConnection.GetDBHandle, lcOther, '', SQLE_CURSOR_NOT_OPEN); //handle a known null resultset issue (cursor not open)
631 if FASAConnection.GetDBHandle.sqlCode = SQLE_CURSOR_NOT_OPEN then Exit;
632 if FASAConnection.GetDBHandle.sqlCode <> SQLE_NOTFOUND then
634 if ( RowNo > 0) or ( RowNo + Rows < 0) then
635 RowNo := RowNo + Rows;
644 FFetchStat := FASAConnection.GetDBHandle.sqlerrd[2];
645 if ( FFetchStat > 0) and ( RowNo > 0) then
646 LastRowNo := Max( RowNo + Rows - FFetchStat, 0);
650 function TZASAResultSet.Previous: Boolean;
652 Result := MoveRelative( -1);
656 Moves the cursor down one row from its current position.
657 A <code>ResultSet</code> cursor is initially positioned
658 before the first row; the first call to the method
659 <code>next</code> makes the first row the current row; the
660 second call makes the second row the current row, and so on.
662 <P>If an input stream is open for the current row, a call
663 to the method <code>next</code> will
664 implicitly close it. A <code>ResultSet</code> object's
665 warning chain is cleared when a new row is read.
667 @return <code>true</code> if the new current row is valid;
668 <code>false</code> if there are no more rows
670 function TZASAResultSet.Next: Boolean;
672 Result := MoveRelative( 1);
676 Opens this recordset.
678 procedure TZASAResultSet.Open;
681 FieldSqlType: TZSQLType;
682 ColumnInfo: TZColumnInfo;
685 raise EZSQLException.Create(SCanNotRetrieveResultSetData);
688 for i := 0 to FSqlData.GetFieldCount - 1 do
690 ColumnInfo := TZColumnInfo.Create;
691 with ColumnInfo, FSqlData do
693 FieldSqlType := GetFieldSqlType(I);
694 ColumnName := GetFieldName(I);
695 // TableName := GetFieldRelationName(I);
696 ColumnLabel := ColumnName;
697 ColumnType := FieldSqlType;
701 stUnicodeString: Precision := GetFieldSize(FieldSqlType, ConSettings,
702 GetFieldLength(I)-4, ConSettings.ClientCodePage.CharWidth, @ColumnDisplaySize, True);
707 if IsNullable(I) then
708 Nullable := ntNullable
710 Nullable := ntNoNulls;
711 Nullable := ntNullable;
713 Scale := GetFieldScale(I);
714 AutoIncrement := False;
716 CaseSensitive := False;
718 ColumnsInfo.Add(ColumnInfo);
724 procedure TZASAResultSet.Close;
727 FParamsSqlData := nil;
728 FUpdateSqlData := nil;
729 if FCursorName <> '' then
731 FASAConnection.GetPlainDriver.db_close(FASAConnection.GetDBHandle, PAnsiChar(FCursorName));
737 function TZASAResultSet.GetCursorName: AnsiString;
739 Result := FCursorName;
742 function TZASAResultSet.RowUpdated: Boolean;
747 function TZASAResultSet.RowInserted: Boolean;
752 function TZASAResultSet.RowDeleted: Boolean;
757 procedure TZASAResultSet.PrepareUpdateSQLData;
759 FUpdate := not FInsert;
760 if not Assigned( FUpdateSQLData) then
762 FUpdateSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,
763 FASAConnection.GetDBHandle, FCursorName, ConSettings, FSQLData.GetFieldCount);
765 else if FUpdateSQLData.GetFieldCount = 0 then
766 FUpdateSQLData.AllocateSQLDA( FSQLData.GetFieldCount);
769 procedure TZASAResultSet.UpdateNull(ColumnIndex: Integer);
771 PrepareUpdateSQLData;
772 FUpdateSqlData.UpdateNull( ColumnIndex, True);
775 procedure TZASAResultSet.UpdateBoolean(ColumnIndex: Integer; Value: Boolean);
777 PrepareUpdateSQLData;
778 FUpdateSqlData.UpdateBoolean( ColumnIndex, Value);
781 procedure TZASAResultSet.UpdateByte(ColumnIndex: Integer; Value: ShortInt);
783 PrepareUpdateSQLData;
784 FUpdateSqlData.UpdateByte( ColumnIndex, Value);
787 procedure TZASAResultSet.UpdateShort(ColumnIndex: Integer; Value: SmallInt);
789 PrepareUpdateSQLData;
790 FUpdateSqlData.UpdateShort( ColumnIndex, Value);
793 procedure TZASAResultSet.UpdateInt(ColumnIndex: Integer; Value: Integer);
795 PrepareUpdateSQLData;
796 FUpdateSqlData.UpdateInt( ColumnIndex, Value);
799 procedure TZASAResultSet.UpdateLong(ColumnIndex: Integer; Value: Int64);
801 PrepareUpdateSQLData;
802 FUpdateSqlData.UpdateLong( ColumnIndex, Value);
805 procedure TZASAResultSet.UpdateFloat(ColumnIndex: Integer; Value: Single);
807 PrepareUpdateSQLData;
808 FUpdateSqlData.UpdateFloat( ColumnIndex, Value);
811 procedure TZASAResultSet.UpdateDouble(ColumnIndex: Integer; Value: Double);
813 PrepareUpdateSQLData;
814 FUpdateSqlData.UpdateDouble( ColumnIndex, Value);
817 procedure TZASAResultSet.UpdateBigDecimal(ColumnIndex: Integer; Value: Extended);
819 PrepareUpdateSQLData;
820 FUpdateSqlData.UpdateBigDecimal( ColumnIndex, Value);
823 procedure TZASAResultSet.UpdatePChar(ColumnIndex: Integer; Value: PChar);
825 PrepareUpdateSQLData;
826 FUpdateSqlData.UpdatePChar( ColumnIndex, Value);
829 procedure TZASAResultSet.UpdateString(ColumnIndex: Integer; const Value: String);
831 PrepareUpdateSQLData;
832 FUpdateSqlData.UpdateString(ColumnIndex, ZPlainString(Value));
835 procedure TZASAResultSet.UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString);
837 PrepareUpdateSQLData;
838 FUpdateSqlData.UpdateString(ColumnIndex, ZPlainString(Value));
841 procedure TZASAResultSet.UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray);
843 PrepareUpdateSQLData;
844 FUpdateSqlData.UpdateBytes( ColumnIndex, Value);
847 procedure TZASAResultSet.UpdateDate(ColumnIndex: Integer; Value: TDateTime);
849 PrepareUpdateSQLData;
850 FUpdateSqlData.UpdateDate( ColumnIndex, Value);
853 procedure TZASAResultSet.UpdateTime(ColumnIndex: Integer; Value: TDateTime);
855 PrepareUpdateSQLData;
856 FUpdateSqlData.UpdateTime( ColumnIndex, Value);
859 procedure TZASAResultSet.UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime);
861 PrepareUpdateSQLData;
862 FUpdateSqlData.UpdateTimestamp( ColumnIndex, Value);
865 procedure TZASAResultSet.UpdateAsciiStream(ColumnIndex: Integer; Value: TStream);
867 PrepareUpdateSQLData;
868 FUpdateSqlData.WriteBlob( ColumnIndex, Value, stAsciiStream);
871 procedure TZASAResultSet.UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream);
873 PrepareUpdateSQLData;
874 FUpdateSqlData.WriteBlob( ColumnIndex, Value, stUnicodeStream);
877 procedure TZASAResultSet.UpdateBinaryStream(ColumnIndex: Integer; Value: TStream);
879 PrepareUpdateSQLData;
880 FUpdateSqlData.WriteBlob( ColumnIndex, Value, stBinaryStream);
883 procedure TZASAResultSet.UpdateValue(ColumnIndex: Integer; const Value: TZVariant);
885 PrepareUpdateSQLData;
886 FUpdateSqlData.UpdateValue( ColumnIndex, EncodeVariant( Value));
889 procedure TZASAResultSet.InsertRow;
891 if Assigned( FUpdateSQLData) and FInsert then
893 FASAConnection.GetPlainDriver.db_put_into( FASAConnection.GetDBHandle,
894 PAnsiChar(FCursorName), FUpdateSQLData.GetData, FSQLData.GetData);
895 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
896 FASAConnection.GetDBHandle, lcOther, 'Insert row');
899 FUpdateSQLData.FreeSQLDA;
903 procedure TZASAResultSet.UpdateRow;
905 if Assigned( FUpdateSQLData) and FUpdate then
907 FASAConnection.GetPlainDriver.db_update( FASAConnection.GetDBHandle,
908 PAnsiChar(FCursorName), FUpdateSQLData.GetData);
909 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
910 FASAConnection.GetDBHandle, lcOther, 'Update row:' + IntToStr( RowNo));
913 FUpdateSQLData.FreeSQLDA;
917 procedure TZASAResultSet.DeleteRow;
919 FASAConnection.GetPlainDriver.db_delete( FASAConnection.GetDBHandle,
920 PAnsiChar(FCursorName));
921 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
922 FASAConnection.GetDBHandle, lcOther, 'Delete row:' + IntToStr( RowNo));
925 if LastRowNo <> MaxInt then
926 LastRowNo := LastRowNo - FASAConnection.GetDBHandle.sqlerrd[2];
929 procedure TZASAResultSet.RefreshRow;
934 procedure TZASAResultSet.CancelRowUpdates;
937 if Assigned( FUpdateSQLData) then
938 FUpdateSQLData.FreeSQLDA;
941 procedure TZASAResultSet.MoveToInsertRow;
946 procedure TZASAResultSet.MoveToCurrentRow;
949 if Assigned( FUpdateSQLData) then
950 FUpdateSQLData.FreeSQLDA;
955 function TZASABlob.Clone: IZBlob;
962 GetMem( Dt, BlobSize);
963 System.Move( BlobData^, Dt^, BlobSize);
965 Result := TZASABlob.CreateWithData( Dt, BlobSize, FConnection);
969 Reads the blob information by blob handle.
970 @param handle a Interbase6 database connect handle.
971 @param the statement previously prepared
973 constructor TZASABlob.Create( ResultSet: TZASAResultSet; ColID: Integer);
976 FConnection := ResultSet.GetStatement.GetConnection;
978 FResultSet := ResultSet;
982 constructor TZASABlob.CreateWithStream(Stream: TStream; Connection: IZConnection);
984 inherited CreateWithStream(Stream, Connection);
988 constructor TZASABlob.CreateWithData(Data: Pointer; Size: Integer;
989 Connection: IZConnection);
992 FConnection := Connection;
999 function TZASABlob.GetBytes: TByteDynArray;
1002 Result := inherited GetBytes;
1005 function TZASABlob.GetStream: TStream;
1008 Result := inherited GetStream;
1011 function TZASABlob.GetString: RawByteString;
1014 Result := inherited GetString;
1017 function TZASABlob.GetUnicodeString: WideString;
1019 Result := inherited GetUnicodeString;
1022 function TZASABlob.IsEmpty: Boolean;
1025 Result := inherited IsEmpty;
1028 procedure TZASABlob.ReadBlob;
1035 if Assigned(BlobData) then
1038 if FResultSet.FInsert or ( FResultSet.FUpdate and FResultSet.FUpdateSQLData.IsAssigned( FColID)) then
1039 FResultSet.FUpdateSQLData.ReadBlobToMem( FColID, Buffer, Size)
1041 FResultSet.FSQLData.ReadBlobToMem( FColID, Buffer, Size);