Browse Source

* Added support for fetching BLOB-fields directly in TBufDataset

git-svn-id: trunk@6096 -
joost 18 years ago
parent
commit
1a8ff494ff

+ 14 - 5
fcl/db/bufdataset.pp

@@ -149,8 +149,9 @@ type
     procedure SetFiltered(Value: Boolean); override; {virtual;}
   {abstracts, must be overidden by descendents}
     function Fetch : boolean; virtual; abstract;
-    function LoadField(FieldDef : TFieldDef;buffer : pointer) : boolean; virtual; abstract;
+    function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual; abstract;
     procedure LoadBlobIntoStream(Field: TField;AStream: TStream); virtual; abstract;
+    procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBlobBuffer); virtual; abstract;
 
   public
     constructor Create(AOwner: TComponent); override;
@@ -487,8 +488,10 @@ end;
 
 function TBufDataset.LoadBuffer(Buffer : PChar): TGetResult;
 
-var NullMask     : pbyte;
-    x            : longint;
+var NullMask        : pbyte;
+    x               : longint;
+    CreateblobField : boolean;
+    BufBlob         : PBufBlobField;
 
 begin
   if not Fetch then
@@ -504,8 +507,14 @@ begin
 
   for x := 0 to FieldDefs.count-1 do
     begin
-    if not LoadField(FieldDefs[x],buffer) then
-      SetFieldIsNull(NullMask,x);
+    if not LoadField(FieldDefs[x],buffer,CreateblobField) then
+      SetFieldIsNull(NullMask,x)
+    else if CreateblobField then
+      begin
+      BufBlob := PBufBlobField(Buffer);
+      BufBlob^.BlobBuffer := GetNewBlobBuffer;
+      LoadBlobIntoBuffer(FieldDefs[x],BufBlob^.BlobBuffer);
+      end;
     inc(buffer,GetFieldSize(FieldDefs[x]));
     end;
   Result := grOK;

+ 3 - 2
fcl/db/sqldb/interbase/ibconnection.pp

@@ -78,7 +78,7 @@ type
     procedure Execute(cursor: TSQLCursor;atransaction:tSQLtransaction; AParams : TParams); override;
     procedure AddFieldDefs(cursor: TSQLCursor;FieldDefs : TfieldDefs); override;
     function Fetch(cursor : TSQLCursor) : boolean; override;
-    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer) : boolean; override;
+    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
     function GetTransactionHandle(trans : TSQLHandle): pointer; override;
     function Commit(trans : TSQLHandle) : boolean; override;
     function RollBack(trans : TSQLHandle) : boolean; override;
@@ -752,7 +752,7 @@ begin
 {$R+}
 end;
 
-function TIBConnection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer) : boolean;
+function TIBConnection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 
 var
   x          : integer;
@@ -761,6 +761,7 @@ var
   c            : currency;
 
 begin
+  CreateBlob := False;
   with cursor as TIBCursor do
     begin
 {$R-}

+ 3 - 2
fcl/db/sqldb/mysql/mysqlconn.inc

@@ -90,7 +90,7 @@ Type
     procedure Execute(cursor: TSQLCursor;atransaction:tSQLtransaction;AParams : TParams); override;
     procedure AddFieldDefs(cursor: TSQLCursor; FieldDefs : TfieldDefs); override;
     function Fetch(cursor : TSQLCursor) : boolean; override;
-    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer) : boolean; override;
+    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
     function GetTransactionHandle(trans : TSQLHandle): pointer; override;
     function Commit(trans : TSQLHandle) : boolean; override;
     function RollBack(trans : TSQLHandle) : boolean; override;
@@ -527,7 +527,7 @@ begin
 end;
 
 function TConnectionName.LoadField(cursor : TSQLCursor;
-  FieldDef : TfieldDef;buffer : pointer) : boolean;
+  FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 
 var
   field: PMYSQL_FIELD;
@@ -536,6 +536,7 @@ var
 
 begin
 //  Writeln('LoadFieldsFromBuffer');
+  CreateBlob := False;
   C:=Cursor as TCursorName;
   if C.Row=nil then
      begin

+ 3 - 2
fcl/db/sqldb/odbc/odbcconn.pas

@@ -89,7 +89,7 @@ type
     // - Result retrieving
     procedure AddFieldDefs(cursor:TSQLCursor; FieldDefs:TFieldDefs); override;
     function Fetch(cursor:TSQLCursor):boolean; override;
-    function LoadField(cursor:TSQLCursor; FieldDef:TFieldDef; buffer:pointer):boolean; override;
+    function LoadField(cursor:TSQLCursor; FieldDef:TFieldDef; buffer:pointer; out CreateBlob : boolean):boolean; override;
     procedure LoadBlobIntoStream(Field: TField;AStream: TStream;cursor: TSQLCursor;ATransaction : TSQLTransaction); override;
     procedure FreeFldBuffers(cursor:TSQLCursor); override;
     // - UpdateIndexDefs
@@ -528,7 +528,7 @@ begin
   Result:=Res<>SQL_NO_DATA;
 end;
 
-function TODBCConnection.LoadField(cursor: TSQLCursor; FieldDef: TFieldDef; buffer: pointer): boolean;
+function TODBCConnection.LoadField(cursor: TSQLCursor; FieldDef: TFieldDef; buffer: pointer; out CreateBlob : boolean): boolean;
 const
   DEFAULT_BLOB_BUFFER_SIZE = 1024;
 var
@@ -543,6 +543,7 @@ var
   BlobMemoryStream:TMemoryStream;
   Res:SQLRETURN;
 begin
+  CreateBlob := False;
   ODBCCursor:=cursor as TODBCCursor;
 
   // load the field using SQLGetData

+ 3 - 2
fcl/db/sqldb/oracle/oracleconnection.pp

@@ -65,7 +65,7 @@ type
     // - Result retrieving
     procedure AddFieldDefs(cursor:TSQLCursor; FieldDefs:TFieldDefs); override;
     function Fetch(cursor:TSQLCursor):boolean; override;
-    function LoadField(cursor:TSQLCursor; FieldDef:TFieldDef; buffer:pointer):boolean; override;
+    function LoadField(cursor:TSQLCursor; FieldDef:TFieldDef; buffer:pointer; out CreateBlob : boolean):boolean; override;
 //    function CreateBlobStream(Field:TField; Mode:TBlobStreamMode):TStream; override;
     procedure FreeFldBuffers(cursor:TSQLCursor); override;
 
@@ -414,7 +414,7 @@ begin
   end; {case}
 end;
 
-function TOracleConnection.LoadField(cursor: TSQLCursor; FieldDef: TFieldDef; buffer: pointer): boolean;
+function TOracleConnection.LoadField(cursor: TSQLCursor; FieldDef: TFieldDef; buffer: pointer; out CreateBlob : boolean): boolean;
 
 var dt        : TDateTime;
     b         : pbyte;
@@ -424,6 +424,7 @@ var dt        : TDateTime;
     odt       : POCIdateTime;
 
 begin
+  CreateBlob := False;
   with cursor as TOracleCursor do if fieldbuffers[FieldDef.FieldNo-1].ind = -1 then
     Result := False
   else

+ 21 - 11
fcl/db/sqldb/postgres/pqconnection.pp

@@ -7,7 +7,7 @@ unit pqconnection;
 interface
 
 uses
-  Classes, SysUtils, sqldb, db, dbconst,
+  Classes, SysUtils, sqldb, db, dbconst,bufdataset,
 {$IfDef LinkDynamically}
   postgres3dyn;
 {$Else}
@@ -55,7 +55,7 @@ type
     procedure AddFieldDefs(cursor: TSQLCursor; FieldDefs : TfieldDefs); override;
     function Fetch(cursor : TSQLCursor) : boolean; override;
     procedure UnPrepareStatement(cursor : TSQLCursor); override;
-    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer) : boolean; override;
+    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
     function GetTransactionHandle(trans : TSQLHandle): pointer; override;
     function RollBack(trans : TSQLHandle) : boolean; override;
     function Commit(trans : TSQLHandle) : boolean; override;
@@ -64,6 +64,7 @@ type
     procedure RollBackRetaining(trans : TSQLHandle); override;
     procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); override;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; override;
+    procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBlobBuffer; cursor: TSQLCursor;ATransaction : TSQLTransaction); override;
   public
     constructor Create(AOwner : TComponent); override;
     procedure CreateDB; override;
@@ -626,7 +627,7 @@ begin
     end;
 end;
 
-function TPQConnection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer) : boolean;
+function TPQConnection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 
 type TNumericRecord = record
        Digits : SmallInt;
@@ -646,6 +647,7 @@ var
   s             : string;
 
 begin
+  Createblob := False;
   with cursor as TPQCursor do
     begin
     x := FieldBinding[FieldDef.FieldNo-1];
@@ -685,14 +687,7 @@ begin
           pchar(Buffer + li)^ := #0;
           i := pqfmod(res,x)-3;
           end;
-        ftBlob  :
-          begin
-          li := pqgetlength(res,curtuple,x);
-          setlength(s,li);
-          Move(CurrBuff^, s[1], li);
-          i := fBlobStrings.Add(S);
-          Move(I, Buffer^, SizeOf(Integer));
-          end;
+        ftBlob : Createblob := True;
         ftdate :
           begin
           dbl := pointer(buffer);
@@ -833,5 +828,20 @@ begin
   result := s;
 end;
 
+procedure TPQConnection.LoadBlobIntoBuffer(FieldDef: TFieldDef;
+  ABlobBuf: PBlobBuffer; cursor: TSQLCursor; ATransaction: TSQLTransaction);
+var
+  x             : integer;
+  li            : Longint;
+begin
+  with cursor as TPQCursor do
+    begin
+    x := FieldBinding[FieldDef.FieldNo-1];
+    li := pqgetlength(res,curtuple,x);
+    ReAllocMem(ABlobBuf^.Buffer,li);
+    Move(pqgetvalue(res,CurTuple,x)^, ABlobBuf^.Buffer^, li);
+    ABlobBuf^.Size := li;
+    end;
+end;
 
 end.

+ 12 - 4
fcl/db/sqldb/sqldb.pp

@@ -99,7 +99,7 @@ type
     procedure UnPrepareStatement(cursor : TSQLCursor); virtual; abstract;
 
     procedure FreeFldBuffers(cursor : TSQLCursor); virtual;
-    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer) : boolean; virtual; abstract;
+    function LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; virtual; abstract;
     function GetTransactionHandle(trans : TSQLHandle): pointer; virtual; abstract;
     function Commit(trans : TSQLHandle) : boolean; virtual; abstract;
     function RollBack(trans : TSQLHandle) : boolean; virtual; abstract;
@@ -109,6 +109,7 @@ type
     procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); virtual;
     function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; virtual;
     procedure LoadBlobIntoStream(Field: TField;AStream: TStream;cursor: TSQLCursor;ATransaction : TSQLTransaction); virtual;
+    procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBlobBuffer; cursor: TSQLCursor; ATransaction : TSQLTransaction); virtual; abstract;
   public
     property Handle: Pointer read GetHandle;
     destructor Destroy; override;
@@ -218,7 +219,7 @@ type
   protected
     // abstract & virtual methods of TBufDataset
     function Fetch : boolean; override;
-    function LoadField(FieldDef : TFieldDef;buffer : pointer) : boolean; override;
+    function LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean; override;
     // abstract & virtual methods of TDataset
     procedure UpdateIndexDefs; override;
     procedure SetDatabase(Value : TDatabase); override;
@@ -236,6 +237,7 @@ type
     Function GetDataSource : TDatasource; override;
     Procedure SetDataSource(AValue : TDatasource); 
     procedure LoadBlobIntoStream(Field: TField;AStream: TStream); override;
+    procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBlobBuffer); override;
   public
     procedure Prepare; virtual;
     procedure UnPrepare; virtual;
@@ -814,10 +816,10 @@ begin
   (Database as tsqlconnection).execute(Fcursor,Transaction as tsqltransaction, FParams);
 end;
 
-function TSQLQuery.LoadField(FieldDef : TFieldDef;buffer : pointer) : boolean;
+function TSQLQuery.LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 
 begin
-  result := (Database as tSQLConnection).LoadField(FCursor,FieldDef,buffer)
+  result := (Database as tSQLConnection).LoadField(FCursor,FieldDef,buffer, Createblob)
 end;
 
 procedure TSQLQuery.InternalAddRecord(Buffer: Pointer; AAppend: Boolean);
@@ -1323,6 +1325,12 @@ begin
   (DataBase as tsqlconnection).LoadBlobIntoStream(Field, AStream, FCursor,(Transaction as tsqltransaction));
 end;
 
+procedure TSQLQuery.LoadBlobIntoBuffer(FieldDef: TFieldDef;
+  ABlobBuf: PBlobBuffer);
+begin
+  (DataBase as tsqlconnection).LoadBlobIntoBuffer(FieldDef, ABlobBuf, FCursor,(Transaction as tsqltransaction));
+end;
+
 function TSQLQuery.GetStatementType : TStatementType;
 
 begin