00001 {*********************************************************}
00002 { }
00003 { Zeos Database Objects }
00004 { Interbase Database Connectivity Classes }
00005 { }
00006 { Originally written by Sergey Merkuriev }
00007 { }
00008 {*********************************************************}
00009
00010 {@********************************************************}
00011 { Copyright (c) 1999-2006 Zeos Development Group }
00012 { }
00013 { License Agreement: }
00014 { }
00015 { This library is distributed in the hope that it will be }
00016 { useful, but WITHOUT ANY WARRANTY; without even the }
00017 { implied warranty of MERCHANTABILITY or FITNESS FOR }
00018 { A PARTICULAR PURPOSE. See the GNU Lesser General }
00019 { Public License for more details. }
00020 { }
00021 { The source code of the ZEOS Libraries and packages are }
00022 { distributed under the Library GNU General Public }
00023 { License (see the file COPYING / COPYING.ZEOS) }
00024 { with the following modification: }
00025 { As a special exception, the copyright holders of this }
00026 { library give you permission to link this library with }
00027 { independent modules to produce an executable, }
00028 { regardless of the license terms of these independent }
00029 { modules, and to copy and distribute the resulting }
00030 { executable under terms of your choice, provided that }
00031 { you also meet, for each linked independent module, }
00032 { the terms and conditions of the license of that module. }
00033 { An independent module is a module which is not derived }
00034 { from or based on this library. If you modify this }
00035 { library, you may extend this exception to your version }
00036 { of the library, but you are not obligated to do so. }
00037 { If you do not wish to do so, delete this exception }
00038 { statement from your version. }
00039 { }
00040 { }
00041 { The project web site is located on: }
00042 { http:
00043 { http:
00044 { svn:
00045 { }
00046 { http:
00047 { http:
00048 { }
00049 { }
00050 { }
00051 { Zeos Development Group. }
00052 {********************************************************@}
00053
00054 unit ZDbcASAResultSet;
00055
00056 interface
00057
00058 {$I ZDbc.inc}
00059
00060 uses
00061 Classes, ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZDbcASA,
00062 ZPlainASADriver, ZCompatibility, ZDbcResultSetMetadata,
00063 ZDbcASAUtils, ZMessages, ZVariant;
00064
00065 type
00066
00067 {** Implements ASA ResultSet. }
00068 TZASAResultSet = class(TZAbstractResultSet)
00069 private
00070 FCachedBlob: boolean;
00071 FFetchStat: Integer;
00072 FCursorName: string;
00073 FStmtNum: SmallInt;
00074 FSqlData: IZASASQLDA;
00075 FParamsSqlData: IZASASQLDA;
00076 FUpdateSqlData: IZASASQLDA;
00077 FASAConnection: IZASAConnection;
00078 FInsert: Boolean;
00079 FUpdate: Boolean;
00080 FDelete: Boolean;
00081 protected
00082 procedure Open; override;
00083 procedure PrepareUpdateSQLData; virtual;
00084 function GetFieldValue(ColumnIndex: Integer): Variant;
00085 public
00086 constructor Create(Statement: IZStatement; SQL: string;
00087 var StmtNum: SmallInt; CursorName: string;
00088 SqlData: IZASASQLDA; ParamsSqlData: IZASASQLDA;
00089 CachedBlob: boolean);
00090
00091 function GetCursorName: string; override;
00092
00093 function IsNull(ColumnIndex: Integer): Boolean; override;
00094 function GetString(ColumnIndex: Integer): string; override;
00095 function GetBoolean(ColumnIndex: Integer): Boolean; override;
00096 function GetByte(ColumnIndex: Integer): ShortInt; override;
00097 function GetShort(ColumnIndex: Integer): SmallInt; override;
00098 function GetInt(ColumnIndex: Integer): Integer; override;
00099 function GetLong(ColumnIndex: Integer): Int64; override;
00100 function GetFloat(ColumnIndex: Integer): Single; override;
00101 function GetDouble(ColumnIndex: Integer): Double; override;
00102 function GetBigDecimal(ColumnIndex: Integer): Extended; override;
00103 function GetBytes(ColumnIndex: Integer): TByteDynArray; override;
00104 function GetDate(ColumnIndex: Integer): TDateTime; override;
00105 function GetTime(ColumnIndex: Integer): TDateTime; override;
00106 function GetTimestamp(ColumnIndex: Integer): TDateTime; override;
00107 function GetBlob(ColumnIndex: Integer): IZBlob; override;
00108
00109 function Last: Boolean; override;
00110 function MoveAbsolute(Row: Integer): Boolean; override;
00111 function MoveRelative(Rows: Integer): Boolean; override;
00112 function Previous: Boolean; override;
00113 function Next: Boolean; override;
00114
00115 function RowUpdated: Boolean; override;
00116 function RowInserted: Boolean; override;
00117 function RowDeleted: Boolean; override;
00118
00119 procedure UpdateNull(ColumnIndex: Integer); override;
00120 procedure UpdateBoolean(ColumnIndex: Integer; Value: Boolean); override;
00121 procedure UpdateByte(ColumnIndex: Integer; Value: ShortInt); override;
00122 procedure UpdateShort(ColumnIndex: Integer; Value: SmallInt); override;
00123 procedure UpdateInt(ColumnIndex: Integer; Value: Integer); override;
00124 procedure UpdateLong(ColumnIndex: Integer; Value: Int64); override;
00125 procedure UpdateFloat(ColumnIndex: Integer; Value: Single); override;
00126 procedure UpdateDouble(ColumnIndex: Integer; Value: Double); override;
00127 procedure UpdateBigDecimal(ColumnIndex: Integer; Value: Extended); override;
00128 procedure UpdatePChar(ColumnIndex: Integer; Value: PChar); override;
00129 procedure UpdateString(ColumnIndex: Integer; const Value: string); override;
00130 procedure UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString);
00131 override;
00132 procedure UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray); override;
00133 procedure UpdateDate(ColumnIndex: Integer; Value: TDateTime); override;
00134 procedure UpdateTime(ColumnIndex: Integer; Value: TDateTime); override;
00135 procedure UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime); override;
00136 procedure UpdateAsciiStream(ColumnIndex: Integer; Value: TStream); override;
00137 procedure UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream); override;
00138 procedure UpdateBinaryStream(ColumnIndex: Integer; Value: TStream); override;
00139 procedure UpdateValue(ColumnIndex: Integer; const Value: TZVariant); override;
00140
00141 procedure InsertRow; override;
00142 procedure UpdateRow; override;
00143 procedure DeleteRow; override;
00144 procedure RefreshRow; override;
00145 procedure CancelRowUpdates; override;
00146 procedure MoveToInsertRow; override;
00147 procedure MoveToCurrentRow; override;
00148
00149 property SQLData: IZASASQLDA read FSQLData;
00150 end;
00151
00152 {** Implements external blob wrapper object for PostgreSQL. }
00153 TZASABlob = class(TZAbstractBlob)
00154 private
00155 FBlobRead: Boolean;
00156 FResultSet: TZASAResultSet;
00157 FColID: Integer;
00158 protected
00159 procedure ReadBlob;
00160 public
00161 constructor Create( ResultSet: TZASAResultSet; ColID: Integer);
00162 constructor CreateWithStream(Stream: TStream);
00163 constructor CreateWithData(Data: Pointer; Size: Integer);
00164
00165 function IsEmpty: Boolean; override;
00166 function Clone: IZBlob; override;
00167 function GetStream: TStream; override;
00168 function GetString: string; override;
00169 function GetUnicodeString: WideString; override;
00170 function GetBytes: TByteDynArray; override;
00171 property BlobSize;
00172 property BlobData;
00173 end;
00174
00175 implementation
00176
00177 uses
00178 {$IFNDEF VER130BELOW}
00179 Variants,
00180 {$ENDIF}
00181 SysUtils, Math, ZdbcLogging;
00182
00183 { TZASAResultSet }
00184
00185 {**
00186 Constructs this object, assignes main properties and
00187 opens the record set.
00188 @param Statement a related SQL statement object.
00189 @param handle a Interbase6 database connect handle.
00190 @param the statement previously prepared
00191 @param the sql out data previously allocated
00192 @param the Interbase sql dialect
00193 }
00194 constructor TZASAResultSet.Create(Statement: IZStatement; SQL: string;
00195 var StmtNum: SmallInt; CursorName: string;
00196 SqlData: IZASASQLDA; ParamsSqlData: IZASASQLDA;
00197 CachedBlob: boolean);
00198 begin
00199 inherited Create( Statement, SQL, nil);
00200
00201 FFetchStat := 0;
00202 FSqlData := SqlData;
00203 FCursorName := CursorName;
00204 FCachedBlob := CachedBlob;
00205 FASAConnection := Statement.GetConnection as IZASAConnection;
00206 FDelete := False;
00207 FInsert := False;
00208 FUpdate := False;
00209
00210 FParamsSqlData := ParamsSqlData;
00211 FStmtNum := StmtNum;
00212 ResultSetType := rtScrollSensitive;
00213 ResultSetConcurrency := rcUpdatable;
00214
00215 Open;
00216 end;
00217
00218 {**
00219 Return field value by it index
00220 @param the index column 0 first, 1 second ...
00221 @return the field value as variant type
00222 }
00223 function TZASAResultSet.GetFieldValue(ColumnIndex: Integer): Variant;
00224 begin
00225 CheckClosed;
00226 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00227 Result := FUpdateSqlData.GetValue( ColumnIndex - 1)
00228 else
00229 Result := FSqlData.GetValue( ColumnIndex - 1);
00230 LastWasNull := IsNull( ColumnIndex);
00231 end;
00232
00233 {**
00234 Gets the value of the designated column in the current row
00235 of this <code>ResultSet</code> object as
00236 a <code>java.sql.BigDecimal</code> in the Java programming language.
00237
00238 @param columnIndex the first column is 1, the second is 2, ...
00239 @param scale the number of digits to the right of the decimal point
00240 @return the column value; if the value is SQL <code>NULL</code>, the
00241 value returned is <code>null</code>
00242 }
00243 function TZASAResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;
00244 begin
00245 CheckClosed;
00246 CheckColumnConvertion(ColumnIndex, stBigDecimal);
00247 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00248 Result := FUpdateSqlData.GetBigDecimal( ColumnIndex - 1)
00249 else
00250 Result := FSqlData.GetBigDecimal( ColumnIndex - 1);
00251 LastWasNull := IsNull( ColumnIndex);
00252 end;
00253
00254 {**
00255 Returns the value of the designated column in the current row
00256 of this <code>ResultSet</code> object as a <code>Blob</code> object
00257 in the Java programming language.
00258
00259 @param ColumnIndex the first column is 1, the second is 2, ...
00260 @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in
00261 the specified column
00262 }
00263 function TZASAResultSet.GetBlob(ColumnIndex: Integer): IZBlob;
00264 var
00265 Blob: TZASABlob;
00266 begin
00267 Result := nil;
00268 CheckClosed;
00269 CheckBlobColumn(ColumnIndex);
00270
00271 LastWasNull := IsNull(ColumnIndex);
00272 if LastWasNull then Exit;
00273
00274 Blob := TZASABlob.Create( Self, ColumnIndex - 1);
00275 if FCachedBlob then
00276 Blob.ReadBlob;
00277 Result := Blob;
00278 end;
00279
00280 {**
00281 Gets the value of the designated column in the current row
00282 of this <code>ResultSet</code> object as
00283 a <code>boolean</code> in the Java programming language.
00284
00285 @param columnIndex the first column is 1, the second is 2, ...
00286 @return the column value; if the value is SQL <code>NULL</code>, the
00287 value returned is <code>false</code>
00288 }
00289 function TZASAResultSet.GetBoolean(ColumnIndex: Integer): Boolean;
00290 begin
00291 CheckClosed;
00292 CheckColumnConvertion(ColumnIndex, stBoolean);
00293 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00294 Result := FUpdateSqlData.GetBoolean( ColumnIndex - 1)
00295 else
00296 Result := FSqlData.GetBoolean( ColumnIndex - 1);
00297 LastWasNull := IsNull( ColumnIndex);
00298 end;
00299
00300 {**
00301 Gets the value of the designated column in the current row
00302 of this <code>ResultSet</code> object as
00303 a <code>byte</code> in the Java programming language.
00304
00305 @param columnIndex the first column is 1, the second is 2, ...
00306 @return the column value; if the value is SQL <code>NULL</code>, the
00307 value returned is <code>0</code>
00308 }
00309 function TZASAResultSet.GetByte(ColumnIndex: Integer): ShortInt;
00310 begin
00311 CheckClosed;
00312 CheckColumnConvertion(ColumnIndex, stByte);
00313 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00314 Result := FUpdateSqlData.GetByte( ColumnIndex - 1)
00315 else
00316 Result := FSqlData.GetByte( ColumnIndex - 1);
00317 LastWasNull := IsNull( ColumnIndex);
00318 end;
00319
00320 {**
00321 Gets the value of the designated column in the current row
00322 of this <code>ResultSet</code> object as
00323 a <code>byte</code> array in the Java programming language.
00324 The bytes represent the raw values returned by the driver.
00325
00326 @param columnIndex the first column is 1, the second is 2, ...
00327 @return the column value; if the value is SQL <code>NULL</code>, the
00328 value returned is <code>null</code>
00329 }
00330 function TZASAResultSet.GetBytes(
00331 ColumnIndex: Integer): TByteDynArray;
00332 begin
00333 CheckClosed;
00334 CheckColumnConvertion(ColumnIndex, stBytes);
00335 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00336 Result := FUpdateSqlData.GetBytes( ColumnIndex - 1)
00337 else
00338 Result := FSqlData.GetBytes( ColumnIndex - 1);
00339 LastWasNull := IsNull( ColumnIndex);
00340 end;
00341
00342 {**
00343 Gets the value of the designated column in the current row
00344 of this <code>ResultSet</code> object as
00345 a <code>java.sql.Date</code> object in the Java programming language.
00346
00347 @param columnIndex the first column is 1, the second is 2, ...
00348 @return the column value; if the value is SQL <code>NULL</code>, the
00349 value returned is <code>null</code>
00350 }
00351 function TZASAResultSet.GetDate(ColumnIndex: Integer): TDateTime;
00352 begin
00353 CheckClosed;
00354 CheckColumnConvertion(ColumnIndex, stDate);
00355 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00356 Result := FUpdateSqlData.GetDate( ColumnIndex - 1)
00357 else
00358 Result := FSqlData.GetDate( ColumnIndex - 1);
00359 LastWasNull := IsNull( ColumnIndex);
00360 end;
00361
00362 {**
00363 Gets the value of the designated column in the current row
00364 of this <code>ResultSet</code> object as
00365 a <code>double</code> in the Java programming language.
00366
00367 @param columnIndex the first column is 1, the second is 2, ...
00368 @return the column value; if the value is SQL <code>NULL</code>, the
00369 value returned is <code>0</code>
00370 }
00371 function TZASAResultSet.GetDouble(ColumnIndex: Integer): Double;
00372 begin
00373 CheckClosed;
00374 CheckColumnConvertion(ColumnIndex, stDouble);
00375 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00376 Result := FUpdateSqlData.GetDouble( ColumnIndex - 1)
00377 else
00378 Result := FSqlData.GetDouble( ColumnIndex - 1);
00379 LastWasNull := IsNull( ColumnIndex);
00380 end;
00381
00382 {**
00383 Gets the value of the designated column in the current row
00384 of this <code>ResultSet</code> object as
00385 a <code>float</code> in the Java programming language.
00386
00387 @param columnIndex the first column is 1, the second is 2, ...
00388 @return the column value; if the value is SQL <code>NULL</code>, the
00389 value returned is <code>0</code>
00390 }
00391 function TZASAResultSet.GetFloat(ColumnIndex: Integer): Single;
00392 begin
00393 CheckClosed;
00394 CheckColumnConvertion(ColumnIndex, stFloat);
00395 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00396 Result := FUpdateSqlData.GetFloat( ColumnIndex - 1)
00397 else
00398 Result := FSqlData.GetFloat( ColumnIndex - 1);
00399 LastWasNull := IsNull( ColumnIndex);
00400 end;
00401
00402 {**
00403 Gets the value of the designated column in the current row
00404 of this <code>ResultSet</code> object as
00405 an <code>int</code> in the Java programming language.
00406
00407 @param columnIndex the first column is 1, the second is 2, ...
00408 @return the column value; if the value is SQL <code>NULL</code>, the
00409 value returned is <code>0</code>
00410 }
00411 function TZASAResultSet.GetInt(ColumnIndex: Integer): Integer;
00412 begin
00413 CheckClosed;
00414 CheckColumnConvertion(ColumnIndex, stInteger);
00415 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00416 Result := FUpdateSqlData.GetInt( ColumnIndex - 1)
00417 else
00418 Result := FSqlData.GetInt( ColumnIndex - 1);
00419 LastWasNull := IsNull( ColumnIndex);
00420 end;
00421
00422 {**
00423 Gets the value of the designated column in the current row
00424 of this <code>ResultSet</code> object as
00425 a <code>long</code> in the Java programming language.
00426
00427 @param columnIndex the first column is 1, the second is 2, ...
00428 @return the column value; if the value is SQL <code>NULL</code>, the
00429 value returned is <code>0</code>
00430 }
00431 function TZASAResultSet.GetLong(ColumnIndex: Integer): Int64;
00432 begin
00433 CheckClosed;
00434 CheckColumnConvertion(ColumnIndex, stLong);
00435 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00436 Result := FUpdateSqlData.GetLong( ColumnIndex - 1)
00437 else
00438 Result := FSqlData.GetLong( ColumnIndex - 1);
00439 LastWasNull := IsNull( ColumnIndex);
00440 end;
00441
00442 {**
00443 Gets the value of the designated column in the current row
00444 of this <code>ResultSet</code> object as
00445 a <code>short</code> in the Java programming language.
00446
00447 @param columnIndex the first column is 1, the second is 2, ...
00448 @return the column value; if the value is SQL <code>NULL</code>, the
00449 value returned is <code>0</code>
00450 }
00451 function TZASAResultSet.GetShort(ColumnIndex: Integer): SmallInt;
00452 begin
00453 CheckClosed;
00454 CheckColumnConvertion(ColumnIndex, stShort);
00455 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00456 Result := FUpdateSqlData.GetShort( ColumnIndex - 1)
00457 else
00458 Result := FSqlData.GetShort( ColumnIndex - 1);
00459 LastWasNull := IsNull( ColumnIndex);
00460 end;
00461
00462 {**
00463 Gets the value of the designated column in the current row
00464 of this <code>ResultSet</code> object as
00465 a <code>String</code> in the Java programming language.
00466
00467 @param columnIndex the first column is 1, the second is 2, ...
00468 @return the column value; if the value is SQL <code>NULL</code>, the
00469 value returned is <code>null</code>
00470 }
00471 function TZASAResultSet.GetString(ColumnIndex: Integer): string;
00472 begin
00473 CheckClosed;
00474 CheckColumnConvertion( ColumnIndex, stString);
00475 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00476 Result := FUpdateSqlData.GetString( ColumnIndex - 1)
00477 else
00478 Result := FSqlData.GetString( ColumnIndex - 1);
00479 LastWasNull := IsNull( ColumnIndex);
00480 end;
00481
00482 {**
00483 Gets the value of the designated column in the current row
00484 of this <code>ResultSet</code> object as
00485 a <code>java.sql.Time</code> object in the Java programming language.
00486
00487 @param columnIndex the first column is 1, the second is 2, ...
00488 @return the column value; if the value is SQL <code>NULL</code>, the
00489 value returned is <code>null</code>
00490 }
00491 function TZASAResultSet.GetTime(ColumnIndex: Integer): TDateTime;
00492 begin
00493 CheckClosed;
00494 CheckColumnConvertion(ColumnIndex, stTime);
00495 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00496 Result := FUpdateSqlData.GetTime( ColumnIndex - 1)
00497 else
00498 Result := FSqlData.GetTime( ColumnIndex - 1);
00499 LastWasNull := IsNull( ColumnIndex);
00500 end;
00501
00502 {**
00503 Gets the value of the designated column in the current row
00504 of this <code>ResultSet</code> object as
00505 a <code>java.sql.Timestamp</code> object in the Java programming language.
00506
00507 @param columnIndex the first column is 1, the second is 2, ...
00508 @return the column value; if the value is SQL <code>NULL</code>, the
00509 value returned is <code>null</code>
00510 @exception SQLException if a database access error occurs
00511 }
00512 function TZASAResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;
00513 begin
00514 CheckClosed;
00515 CheckColumnConvertion(ColumnIndex, stTimestamp);
00516 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00517 Result := FUpdateSqlData.GetTimestamp( ColumnIndex - 1)
00518 else
00519 Result := FSqlData.GetTimestamp( ColumnIndex - 1);
00520 LastWasNull := IsNull( ColumnIndex);
00521 end;
00522
00523 {**
00524 Indicates if the value of the designated column in the current row
00525 of this <code>ResultSet</code> object is Null.
00526
00527 @param columnIndex the first column is 1, the second is 2, ...
00528 @return if the value is SQL <code>NULL</code>, the
00529 value returned is <code>true</code>. <code>false</code> otherwise.
00530 }
00531 function TZASAResultSet.IsNull(ColumnIndex: Integer): Boolean;
00532 begin
00533 CheckClosed;
00534 if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then
00535 Result := FUpdateSqlData.IsNull( ColumnIndex - 1)
00536 else
00537 Result := FSqlData.IsNull(ColumnIndex - 1);
00538 end;
00539
00540 function TZASAResultSet.Last: Boolean;
00541 begin
00542 if LastRowNo <> MaxInt then
00543 Result := MoveAbsolute( LastRowNo)
00544 else
00545 Result := MoveAbsolute( -1);
00546 end;
00547
00548 {**
00549 Moves the cursor to the given row number in
00550 this <code>ResultSet</code> object.
00551
00552 <p>If the row number is positive, the cursor moves to
00553 the given row number with respect to the
00554 beginning of the result set. The first row is row 1, the second
00555 is row 2, and so on.
00556
00557 <p>If the given row number is negative, the cursor moves to
00558 an absolute row position with respect to
00559 the end of the result set. For example, calling the method
00560 <code>absolute(-1)</code> positions the
00561 cursor on the last row; calling the method <code>absolute(-2)</code>
00562 moves the cursor to the next-to-last row, and so on.
00563
00564 <p>An attempt to position the cursor beyond the first/last row in
00565 the result set leaves the cursor before the first row or after
00566 the last row.
00567
00568 <p><B>Note:</B> Calling <code>absolute(1)</code> is the same
00569 as calling <code>first()</code>. Calling <code>absolute(-1)</code>
00570 is the same as calling <code>last()</code>.
00571
00572 @return <code>true</code> if the cursor is on the result set;
00573 <code>false</code> otherwise
00574 }
00575 function TZASAResultSet.MoveAbsolute(Row: Integer): Boolean;
00576 begin
00577 Result := False;
00578 if (MaxRows > 0) and (Row >= MaxRows) then
00579 Exit;
00580
00581 FASAConnection.GetPlainDriver.db_fetch( FASAConnection.GetDBHandle,
00582 PChar( FCursorName), CUR_ABSOLUTE, Row, FSqlData.GetData, BlockSize, CUR_FORREGULAR);
00583 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
00584 FASAConnection.GetDBHandle, lcOther);
00585
00586 if FASAConnection.GetDBHandle.sqlCode <> SQLE_NOTFOUND then
00587 begin
00588 RowNo := Row;
00589 Result := True;
00590 FFetchStat := 0;
00591 FDelete := False;
00592 FInsert := False;
00593 FUpdate := False;
00594 end else begin
00595 FFetchStat := FASAConnection.GetDBHandle.sqlerrd[2];
00596 if FFetchStat > 0 then
00597 LastRowNo := Max( Row - FFetchStat, 0);
00598 end;
00599 end;
00600
00601 function TZASAResultSet.MoveRelative(Rows: Integer): Boolean;
00602 begin
00603 Result := False;
00604 if (MaxRows > 0) and ( Abs( RowNo) + Rows >= MaxRows) then
00605 Exit;
00606
00607 FASAConnection.GetPlainDriver.db_fetch( FASAConnection.GetDBHandle,
00608 PChar( FCursorName), CUR_RELATIVE, Rows, FSqlData.GetData, BlockSize, CUR_FORREGULAR);
00609 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
00610 FASAConnection.GetDBHandle, lcOther);
00611
00612 if FASAConnection.GetDBHandle.sqlCode <> SQLE_NOTFOUND then
00613 begin
00614 if ( RowNo > 0) or ( RowNo + Rows < 0) then
00615 RowNo := RowNo + Rows;
00616 Result := True;
00617 FFetchStat := 0;
00618 FDelete := False;
00619 FInsert := False;
00620 FUpdate := False;
00621 end else begin
00622 FFetchStat := FASAConnection.GetDBHandle.sqlerrd[2];
00623 if ( FFetchStat > 0) and ( RowNo > 0) then
00624 LastRowNo := Max( RowNo + Rows - FFetchStat, 0);
00625 end;
00626 end;
00627
00628 function TZASAResultSet.Previous: Boolean;
00629 begin
00630 Result := MoveRelative( -1);
00631 end;
00632
00633 {**
00634 Moves the cursor down one row from its current position.
00635 A <code>ResultSet</code> cursor is initially positioned
00636 before the first row; the first call to the method
00637 <code>next</code> makes the first row the current row; the
00638 second call makes the second row the current row, and so on.
00639
00640 <P>If an input stream is open for the current row, a call
00641 to the method <code>next</code> will
00642 implicitly close it. A <code>ResultSet</code> object's
00643 warning chain is cleared when a new row is read.
00644
00645 @return <code>true</code> if the new current row is valid;
00646 <code>false</code> if there are no more rows
00647 }
00648 function TZASAResultSet.Next: Boolean;
00649 begin
00650 Result := MoveRelative( 1);
00651 end;
00652
00653 {**
00654 Opens this recordset.
00655 }
00656 procedure TZASAResultSet.Open;
00657 var
00658 i: Integer;
00659 FieldSqlType: TZSQLType;
00660 ColumnInfo: TZColumnInfo;
00661 begin
00662 if FStmtNum = 0 then
00663 raise EZSQLException.Create(SCanNotRetrieveResultSetData);
00664
00665 ColumnsInfo.Clear;
00666 for i := 0 to FSqlData.GetFieldCount - 1 do
00667 begin
00668 ColumnInfo := TZColumnInfo.Create;
00669 with ColumnInfo, FSqlData do
00670 begin
00671 FieldSqlType := GetFieldSqlType(I);
00672 ColumnName := GetFieldName(I);
00673 // TableName := GetFieldRelationName(I);
00674 ColumnLabel := ColumnName;
00675 ColumnType := FieldSqlType;
00676
00677 case FieldSqlType of
00678 stString,
00679 stUnicodeString: Precision := GetFieldLength(I);
00680 end;
00681
00682 ReadOnly := False;
00683
00684 if IsNullable(I) then
00685 Nullable := ntNullable
00686 else
00687 Nullable := ntNoNulls;
00688 Nullable := ntNullable;
00689
00690 Scale := GetFieldScale(I);
00691 AutoIncrement := False;
00692 //Signed := False;
00693 CaseSensitive := False;
00694 end;
00695 ColumnsInfo.Add(ColumnInfo);
00696 end;
00697 LastRowNo := MaxInt;
00698 inherited Open;
00699 end;
00700
00701 function TZASAResultSet.GetCursorName: string;
00702 begin
00703 Result := FCursorName;
00704 end;
00705
00706 function TZASAResultSet.RowUpdated: Boolean;
00707 begin
00708 Result := FUpdate;
00709 end;
00710
00711 function TZASAResultSet.RowInserted: Boolean;
00712 begin
00713 Result := FInsert;
00714 end;
00715
00716 function TZASAResultSet.RowDeleted: Boolean;
00717 begin
00718 Result := FDelete;
00719 end;
00720
00721 procedure TZASAResultSet.PrepareUpdateSQLData;
00722 begin
00723 FUpdate := not FInsert;
00724 if not Assigned( FUpdateSQLData) then
00725 begin
00726 FUpdateSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,
00727 FASAConnection.GetDBHandle, FCursorName, FSQLData.GetFieldCount);
00728 end else if FUpdateSQLData.GetFieldCount = 0 then
00729 FUpdateSQLData.AllocateSQLDA( FSQLData.GetFieldCount);
00730 end;
00731
00732 procedure TZASAResultSet.UpdateNull(ColumnIndex: Integer);
00733 begin
00734 PrepareUpdateSQLData;
00735 FUpdateSqlData.UpdateNull( ColumnIndex, True);
00736 end;
00737
00738 procedure TZASAResultSet.UpdateBoolean(ColumnIndex: Integer; Value: Boolean);
00739 begin
00740 PrepareUpdateSQLData;
00741 FUpdateSqlData.UpdateBoolean( ColumnIndex, Value);
00742 end;
00743
00744 procedure TZASAResultSet.UpdateByte(ColumnIndex: Integer; Value: ShortInt);
00745 begin
00746 PrepareUpdateSQLData;
00747 FUpdateSqlData.UpdateByte( ColumnIndex, Value);
00748 end;
00749
00750 procedure TZASAResultSet.UpdateShort(ColumnIndex: Integer; Value: SmallInt);
00751 begin
00752 PrepareUpdateSQLData;
00753 FUpdateSqlData.UpdateShort( ColumnIndex, Value);
00754 end;
00755
00756 procedure TZASAResultSet.UpdateInt(ColumnIndex: Integer; Value: Integer);
00757 begin
00758 PrepareUpdateSQLData;
00759 FUpdateSqlData.UpdateInt( ColumnIndex, Value);
00760 end;
00761
00762 procedure TZASAResultSet.UpdateLong(ColumnIndex: Integer; Value: Int64);
00763 begin
00764 PrepareUpdateSQLData;
00765 FUpdateSqlData.UpdateLong( ColumnIndex, Value);
00766 end;
00767
00768 procedure TZASAResultSet.UpdateFloat(ColumnIndex: Integer; Value: Single);
00769 begin
00770 PrepareUpdateSQLData;
00771 FUpdateSqlData.UpdateFloat( ColumnIndex, Value);
00772 end;
00773
00774 procedure TZASAResultSet.UpdateDouble(ColumnIndex: Integer; Value: Double);
00775 begin
00776 PrepareUpdateSQLData;
00777 FUpdateSqlData.UpdateDouble( ColumnIndex, Value);
00778 end;
00779
00780 procedure TZASAResultSet.UpdateBigDecimal(ColumnIndex: Integer; Value: Extended);
00781 begin
00782 PrepareUpdateSQLData;
00783 FUpdateSqlData.UpdateBigDecimal( ColumnIndex, Value);
00784 end;
00785
00786 procedure TZASAResultSet.UpdatePChar(ColumnIndex: Integer; Value: PChar);
00787 begin
00788 PrepareUpdateSQLData;
00789 FUpdateSqlData.UpdatePChar( ColumnIndex, Value);
00790 end;
00791
00792 procedure TZASAResultSet.UpdateString(ColumnIndex: Integer; const Value: string);
00793 begin
00794 PrepareUpdateSQLData;
00795 FUpdateSqlData.UpdateString( ColumnIndex, Value);
00796 end;
00797
00798 procedure TZASAResultSet.UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString);
00799 begin
00800 PrepareUpdateSQLData;
00801 FUpdateSqlData.UpdatePChar( ColumnIndex, PChar( Value));
00802 end;
00803
00804 procedure TZASAResultSet.UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray);
00805 begin
00806 PrepareUpdateSQLData;
00807 FUpdateSqlData.UpdateBytes( ColumnIndex, Value);
00808 end;
00809
00810 procedure TZASAResultSet.UpdateDate(ColumnIndex: Integer; Value: TDateTime);
00811 begin
00812 PrepareUpdateSQLData;
00813 FUpdateSqlData.UpdateDate( ColumnIndex, Value);
00814 end;
00815
00816 procedure TZASAResultSet.UpdateTime(ColumnIndex: Integer; Value: TDateTime);
00817 begin
00818 PrepareUpdateSQLData;
00819 FUpdateSqlData.UpdateTime( ColumnIndex, Value);
00820 end;
00821
00822 procedure TZASAResultSet.UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime);
00823 begin
00824 PrepareUpdateSQLData;
00825 FUpdateSqlData.UpdateTimestamp( ColumnIndex, Value);
00826 end;
00827
00828 procedure TZASAResultSet.UpdateAsciiStream(ColumnIndex: Integer; Value: TStream);
00829 begin
00830 PrepareUpdateSQLData;
00831 FUpdateSqlData.WriteBlob( ColumnIndex, Value);
00832 end;
00833
00834 procedure TZASAResultSet.UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream);
00835 begin
00836 PrepareUpdateSQLData;
00837 FUpdateSqlData.WriteBlob( ColumnIndex, Value);
00838 end;
00839
00840 procedure TZASAResultSet.UpdateBinaryStream(ColumnIndex: Integer; Value: TStream);
00841 begin
00842 PrepareUpdateSQLData;
00843 FUpdateSqlData.WriteBlob( ColumnIndex, Value);
00844 end;
00845
00846 procedure TZASAResultSet.UpdateValue(ColumnIndex: Integer; const Value: TZVariant);
00847 begin
00848 PrepareUpdateSQLData;
00849 FUpdateSqlData.UpdateValue( ColumnIndex, EncodeVariant( Value));
00850 end;
00851
00852 procedure TZASAResultSet.InsertRow;
00853 begin
00854 if Assigned( FUpdateSQLData) and FInsert then
00855 begin
00856 FASAConnection.GetPlainDriver.db_put_into( FASAConnection.GetDBHandle,
00857 PChar( FCursorName), FUpdateSQLData.GetData, FSQLData.GetData);
00858 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
00859 FASAConnection.GetDBHandle, lcOther, 'Insert row');
00860
00861 FInsert := false;
00862 FUpdateSQLData.FreeSQLDA;
00863 end;
00864 end;
00865
00866 procedure TZASAResultSet.UpdateRow;
00867 begin
00868 if Assigned( FUpdateSQLData) and FUpdate then
00869 begin
00870 FASAConnection.GetPlainDriver.db_update( FASAConnection.GetDBHandle,
00871 PChar( FCursorName), FUpdateSQLData.GetData);
00872 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
00873 FASAConnection.GetDBHandle, lcOther, 'Update row:' + IntToStr( RowNo));
00874
00875 FUpdate := false;
00876 FUpdateSQLData.FreeSQLDA;
00877 end;
00878 end;
00879
00880 procedure TZASAResultSet.DeleteRow;
00881 begin
00882 FASAConnection.GetPlainDriver.db_delete( FASAConnection.GetDBHandle,
00883 PChar( FCursorName));
00884 ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,
00885 FASAConnection.GetDBHandle, lcOther, 'Delete row:' + IntToStr( RowNo));
00886
00887 FDelete := True;
00888 if LastRowNo <> MaxInt then
00889 LastRowNo := LastRowNo - FASAConnection.GetDBHandle.sqlerrd[2];
00890 end;
00891
00892 procedure TZASAResultSet.RefreshRow;
00893 begin
00894 MoveRelative( 0);
00895 end;
00896
00897 procedure TZASAResultSet.CancelRowUpdates;
00898 begin
00899 FUpdate := false;
00900 if Assigned( FUpdateSQLData) then
00901 FUpdateSQLData.FreeSQLDA;
00902 end;
00903
00904 procedure TZASAResultSet.MoveToInsertRow;
00905 begin
00906 FInsert := true;
00907 end;
00908
00909 procedure TZASAResultSet.MoveToCurrentRow;
00910 begin
00911 FInsert := false;
00912 if Assigned( FUpdateSQLData) then
00913 FUpdateSQLData.FreeSQLDA;
00914 end;
00915
00916 { TZASABlob }
00917
00918 function TZASABlob.Clone: IZBlob;
00919 var
00920 Dt: Pointer;
00921 begin
00922 Dt := nil;
00923 if BlobSize > 0 then
00924 begin
00925 GetMem( Dt, BlobSize);
00926 System.Move( BlobData^, Dt^, BlobSize);
00927 end;
00928 Result := TZASABlob.CreateWithData( Dt, BlobSize);
00929 end;
00930
00931 {**
00932 Reads the blob information by blob handle.
00933 @param handle a Interbase6 database connect handle.
00934 @param the statement previously prepared
00935 }
00936 constructor TZASABlob.Create( ResultSet: TZASAResultSet; ColID: Integer);
00937 begin
00938 inherited Create;
00939 FBlobRead := False;
00940 FResultSet := ResultSet;
00941 FColID := ColID;
00942 end;
00943
00944 constructor TZASABlob.CreateWithStream(Stream: TStream);
00945 begin
00946 inherited CreateWithStream( Stream);
00947 FBlobRead := true;
00948 end;
00949
00950 constructor TZASABlob.CreateWithData(Data: Pointer; Size: Integer);
00951 begin
00952 inherited Create;
00953 BlobData := Data;
00954 BlobSize := Size;
00955 Updated := False;
00956 FBlobRead := true;
00957 end;
00958
00959 function TZASABlob.GetBytes: TByteDynArray;
00960 begin
00961 ReadBlob;
00962 Result := inherited GetBytes;
00963 end;
00964
00965 function TZASABlob.GetStream: TStream;
00966 begin
00967 ReadBlob;
00968 Result := inherited GetStream;
00969 end;
00970
00971 function TZASABlob.GetString: string;
00972 begin
00973 ReadBlob;
00974 Result := inherited GetString;
00975 end;
00976
00977 function TZASABlob.GetUnicodeString: WideString;
00978 begin
00979 ReadBlob;
00980 Result := inherited GetUnicodeString;
00981 end;
00982
00983 function TZASABlob.IsEmpty: Boolean;
00984 begin
00985 ReadBlob;
00986 Result := inherited IsEmpty;
00987 end;
00988
00989 procedure TZASABlob.ReadBlob;
00990 var
00991 Size: LongWord;
00992 Buffer: Pointer;
00993 begin
00994 if FBlobRead then
00995 Exit;
00996
00997 if FResultSet.FInsert or ( FResultSet.FUpdate and FResultSet.FUpdateSQLData.IsAssigned( FColID)) then
00998 FResultSet.FUpdateSQLData.ReadBlobToMem( FColID, Buffer, Size)
00999 else
01000 FResultSet.FSQLData.ReadBlobToMem( FColID, Buffer, Size);
01001 BlobSize := Size;
01002 BlobData := Buffer;
01003 FBlobRead := True;
01004 end;
01005
01006 end.