Browse Source

+ Patch from Bram Kuijvenhoven: optimised storage of zero-length BLOBS

git-svn-id: trunk@3469 -
michael 19 years ago
parent
commit
32e0de3ba7
1 changed files with 16 additions and 11 deletions
  1. 16 11
      fcl/db/sqldb/odbc/odbcconn.pas

+ 16 - 11
fcl/db/sqldb/odbc/odbcconn.pas

@@ -102,8 +102,8 @@ type
   public
   public
     property Environment:TODBCEnvironment read FEnvironment;
     property Environment:TODBCEnvironment read FEnvironment;
   published
   published
-    property Driver:string read FDriver write FDriver;                         // will be passed as DRIVER connection parameter
-    property FileDSN:string read FFileDSN write FFileDSN;                      // will be passed as FILEDSN parameter
+    property Driver:string read FDriver write FDriver;    // will be passed as DRIVER connection parameter
+    property FileDSN:string read FFileDSN write FFileDSN; // will be passed as FILEDSN parameter
     // Redeclare properties from TSQLConnection
     // Redeclare properties from TSQLConnection
     property Password;     // will be passed as PWD connection parameter
     property Password;     // will be passed as PWD connection parameter
     property Transaction;
     property Transaction;
@@ -599,11 +599,14 @@ begin
         else
         else
           BlobBufferSize:=DEFAULT_BLOB_BUFFER_SIZE;
           BlobBufferSize:=DEFAULT_BLOB_BUFFER_SIZE;
         try
         try
-          // Allocate the buffer and memorystream
-          BlobBuffer:=GetMem(BlobBufferSize);
-          BlobMemoryStream:=TMemoryStream.Create;
-          if BlobBufferSize>0 then
+          // init BlobBuffer and BlobMemoryStream to nil pointers
+          BlobBuffer:=nil;
+          BlobMemoryStream:=nil;
+          if BlobBufferSize>0 then // Note: zero-length BLOB is represented as nil pointer in the field buffer to save memory usage
           begin
           begin
+            // Allocate the buffer and memorystream
+            BlobBuffer:=GetMem(BlobBufferSize);
+            BlobMemoryStream:=TMemoryStream.Create;
             // Retrieve data in parts (or effectively in one part if StrLenOrInd<>SQL_NO_TOTAL above)
             // Retrieve data in parts (or effectively in one part if StrLenOrInd<>SQL_NO_TOTAL above)
             repeat
             repeat
               Res:=SQLGetData(ODBCCursor.FSTMTHandle, FieldDef.Index+1, SQL_C_BINARY, BlobBuffer, BlobBufferSize, @StrLenOrInd);
               Res:=SQLGetData(ODBCCursor.FSTMTHandle, FieldDef.Index+1, SQL_C_BINARY, BlobBuffer, BlobBufferSize, @StrLenOrInd);
@@ -618,12 +621,14 @@ begin
           end;
           end;
           // Store memorystream pointer in Field buffer and in the cursor's FBlobStreams list
           // Store memorystream pointer in Field buffer and in the cursor's FBlobStreams list
           TObject(buffer^):=BlobMemoryStream;
           TObject(buffer^):=BlobMemoryStream;
-          ODBCCursor.FBlobStreams.Add(BlobMemoryStream);
+          if BlobMemoryStream<>nil then
+            ODBCCursor.FBlobStreams.Add(BlobMemoryStream);
           // Set BlobMemoryStream to nil, so it won't get freed in the finally block below
           // Set BlobMemoryStream to nil, so it won't get freed in the finally block below
           BlobMemoryStream:=nil;
           BlobMemoryStream:=nil;
         finally
         finally
           BlobMemoryStream.Free;
           BlobMemoryStream.Free;
-          Freemem(BlobBuffer,BlobBufferSize);
+          if BlobBuffer<>nil then
+            Freemem(BlobBuffer,BlobBufferSize);
         end;
         end;
       end;
       end;
     end;
     end;
@@ -642,12 +647,12 @@ var
   ODBCCursor: TODBCCursor;
   ODBCCursor: TODBCCursor;
   BlobMemoryStream, BlobMemoryStreamCopy: TMemoryStream;
   BlobMemoryStream, BlobMemoryStreamCopy: TMemoryStream;
 begin
 begin
-  // TODO: implement TODBCConnection.CreateBlobStream
-  if Mode=bmRead then
+  if (Mode=bmRead) and not Field.IsNull then
   begin
   begin
     Field.GetData(@BlobMemoryStream);
     Field.GetData(@BlobMemoryStream);
     BlobMemoryStreamCopy:=TMemoryStream.Create;
     BlobMemoryStreamCopy:=TMemoryStream.Create;
-    BlobMemoryStreamCopy.LoadFromStream(BlobMemoryStream);
+    if BlobMemoryStream<>nil then
+      BlobMemoryStreamCopy.LoadFromStream(BlobMemoryStream);
     Result:=BlobMemoryStreamCopy;
     Result:=BlobMemoryStreamCopy;
   end
   end
   else
   else