Browse Source

fcl-db: sqldb: when sqoAutoCommit is set in TSQLQuery.Options then load BLOBs as records are fetched (Do not allow deferred loading because if in mean time transaction is committed and other transaction updates blob original blob is no more available)
Also in TIBConnection check for valid transaction handle to avoid AV
Bug #29857

git-svn-id: trunk@33496 -

lacak 9 years ago
parent
commit
7de017daad

+ 9 - 3
packages/fcl-db/src/sqldb/interbase/ibconnection.pp

@@ -118,13 +118,13 @@ type
     function GetConnectionInfo(InfoType:TConnInfoType): string; override;
     procedure CreateDB; override;
     procedure DropDB; override;
-    //Segment size is not used in the code; property kept for backward compatibility
+    // Segment size is not used in the code; property kept for backward compatibility
     property BlobSegmentSize : word read FBlobSegmentSize write FBlobSegmentSize; deprecated;
     property ODSMajorVersion : integer read GetODSMajorVersion; //ODS major version number; influences database compatibility/feature level.
   published
     property DatabaseName;
     property Dialect : integer read GetDialect write FDialect stored IsDialectStored default DEFDIALECT;
-    // Set this to true to have starttransaction check transaction parameters. If False, unknown parameters are ignored.
+    // Set this to true to have StartTransaction check transaction parameters. If False, unknown parameters are ignored.
     Property CheckTransactionParams : Boolean Read FCheckTransactionParams write FCheckTransactionParams;
     property KeepConnection;
     property LoginPrompt;
@@ -193,7 +193,10 @@ end;
 
 function TIBConnection.GetTransactionHandle(trans : TSQLHandle): pointer;
 begin
-  Result := (trans as TIBtrans).TransactionHandle;
+  if Assigned(trans) then
+    Result := (trans as TIBTrans).TransactionHandle
+  else
+    Result := nil;
 end;
 
 function TIBConnection.Commit(trans : TSQLHandle) : boolean;
@@ -1616,6 +1619,9 @@ var
   blobId : PISC_QUAD;
   ptr : Pointer;
 begin
+  // A Blob ID is a unique numeric value that references Blob data. Blob ID is stored in a field in the table
+  // The first 4 bytes of Blob ID represent the relation id for the blob, the second four bytes represent the id of the blob within the table.
+  // When new blob is written new Blob ID is assigned to field
   blobId := PISC_QUAD(@(ABlobBuf^.ConnBlobBuffer));
 
   TransactionHandle := Atransaction.Handle;

+ 8 - 6
packages/fcl-db/src/sqldb/sqldb.pp

@@ -238,7 +238,7 @@ type
     function RowsAffected(cursor: TSQLCursor): TRowsCount; virtual;
     function Fetch(cursor : TSQLCursor) : boolean; virtual; abstract;
     procedure AddFieldDefs(cursor: TSQLCursor; FieldDefs : TfieldDefs); virtual; abstract;
-    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual; abstract;
+    function LoadField(cursor : TSQLCursor; FieldDef : TFieldDef; buffer : pointer; out CreateBlob : boolean) : boolean; virtual; abstract;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); virtual; abstract;
     procedure FreeFldBuffers(cursor : TSQLCursor); virtual;
 
@@ -512,7 +512,7 @@ type
     Procedure Log(EventType : TDBEventType; Const Msg : String); virtual;
     // abstract & virtual methods of TBufDataset
     function Fetch : boolean; override;
-    function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
+    function LoadField(FieldDef : TFieldDef; buffer : pointer; out CreateBlob : boolean) : boolean; override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); override;
     procedure ApplyRecUpdate(UpdateKind : TUpdateKind); override;
     procedure SetPacketRecords(aValue : integer); override;
@@ -733,7 +733,7 @@ type
     function Fetch(cursor : TSQLCursor) : boolean; override;
     procedure AddFieldDefs(cursor: TSQLCursor; FieldDefs : TfieldDefs); override;
     procedure UnPrepareStatement(cursor : TSQLCursor); override;
-    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
+    function LoadField(cursor : TSQLCursor; FieldDef : TFieldDef; buffer : pointer; out CreateBlob : boolean) : boolean; override;
     procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); override;
     procedure FreeFldBuffers(cursor : TSQLCursor); override;
 
@@ -2704,9 +2704,11 @@ begin
   Result:=FStatement.RowsAffected;
 end;
 
-function TCustomSQLQuery.LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
+function TCustomSQLQuery.LoadField(FieldDef : TFieldDef; buffer : pointer; out CreateBlob : boolean) : boolean;
 begin
-  result := SQLConnection.LoadField(Cursor,FieldDef,buffer, Createblob)
+  Result := SQLConnection.LoadField(Cursor, FieldDef, buffer, CreateBlob);
+  if Result and (FieldDef.DataType in ftBlobTypes) and (sqoAutoCommit in Options) then
+    CreateBlob:=True
 end;
 
 procedure TCustomSQLQuery.LoadBlobIntoBuffer(FieldDef: TFieldDef;
@@ -3500,7 +3502,7 @@ begin
   FProxy.FreeFldBuffers(cursor);
 end;
 
-function TSQLConnector.LoadField(cursor: TSQLCursor; FieldDef: TfieldDef;
+function TSQLConnector.LoadField(cursor: TSQLCursor; FieldDef: TFieldDef;
   buffer: pointer; out CreateBlob: boolean): boolean;
 begin
   CheckProxy;