On 19-11-2011 23:36, Michael Van Canneyt wrote:
> On Sat, 19 Nov 2011, Reinier Olislagers wrote:
>> On 19-11-2011 13:28, Reinier Olislagers wrote: I wonder
>> whether/what changes are required for reading blobs...
> 
> The following function needs adapting:
> 
> function TIBConnection.getMaxBlobSize(blobHandle : TIsc_Blob_Handle)
> : longInt; var iscInfoBlobMaxSegment : byte =
> isc_info_blob_max_segment; blobInfo : array[0..50] of byte;
> 
> begin if isc_blob_info(@Fstatus[0], @blobHandle, 
> sizeof(iscInfoBlobMaxSegment), pchar(@iscInfoBlobMaxSegment), 
> sizeof(blobInfo) CheckError('isc_blob_info', FStatus); if blobInfo[0]
> = isc_info_blob_max_segment then begin result :=
> isc_vax_integer(pchar(@blobInfo[3]), 
> isc_vax_integer(pchar(@blobInfo[1]), 2)); end else 
> CheckError('isc_blob_info', FStatus); end;
> 
> You should first check what it returns. I suspect the declared blob 
> segment size.
> 
> Michael.
getMaxBlobSize does indeed return the segment size used when writing
(i.e. 80 by default on pre 2.7.1, 65535 with my patch).

Changed ibconnection.pp:
- remove getMaxBlobSize function
- use MAXBLOBSEGMENTSIZE (65535) when reading

Tested it with existing blobs written in 80 byte and 65535 byte
segments. Works; the returned value matches what was written in the
first place:
  while FQuery.EOF=false do
  begin
    if FQuery.FieldByName('BLOBCOL').AsString <> RecordText then writeln
('Error reading record');;
    FQuery.Next;
  end;

Patch attached; it applies against 2.7.1.
Please let me know if you want me to open a bug for this...

Thanks,
Reinier
--- d:/cop/t/ibconnection.pp    Sun Nov 20 10:20:53 2011
+++ 
C:/Development/Fpc/Source/packages/fcl-db/src/sqldb/interbase/ibconnection.pp   
    Sun Nov 20 10:23:10 2011
@@ -65,7 +65,6 @@
     procedure GetFloat(CurrBuff, Buffer : pointer; Size : Byte);
     procedure SetFloat(CurrBuff: pointer; Dbl: Double; Size: integer);
     procedure CheckError(ProcName : string; Status : PISC_STATUS);
-    function getMaxBlobSize(blobHandle : TIsc_Blob_Handle) : longInt;
     procedure SetParameters(cursor : TSQLCursor; aTransation : 
TSQLTransaction; AParams : TParams);
     procedure FreeSQLDABuffer(var aSQLDA : PXSQLDA);
     function  IsDialectStored: boolean;
@@ -1249,22 +1248,6 @@
 end;
 
 
-function TIBConnection.getMaxBlobSize(blobHandle : TIsc_Blob_Handle) : longInt;
-var
-  iscInfoBlobMaxSegment : byte = isc_info_blob_max_segment;
-  blobInfo : array[0..50] of byte;
-
-begin
-  if isc_blob_info(@Fstatus[0], @blobHandle, sizeof(iscInfoBlobMaxSegment), 
pchar(@iscInfoBlobMaxSegment), sizeof(blobInfo) - 2, pchar(@blobInfo[0])) <> 0 
then
-    CheckError('isc_blob_info', FStatus);
-  if blobInfo[0]  = isc_info_blob_max_segment then
-    begin
-      result :=  isc_vax_integer(pchar(@blobInfo[3]), 
isc_vax_integer(pchar(@blobInfo[1]), 2));
-    end
-  else
-     CheckError('isc_blob_info', FStatus);
-end;
-
 procedure TIBConnection.LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: 
PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction);
 const
   isc_segstr_eof = 335544367; // It's not defined in ibase60 but in ibase40. 
Would it be better to define in ibase60?
@@ -1273,7 +1256,6 @@
   blobHandle : Isc_blob_Handle;
   blobSegment : pointer;
   blobSegLen : word;
-  maxBlobSize : longInt;
   TransactionHandle : pointer;
   blobId : PISC_QUAD;
   ptr : Pointer;
@@ -1286,14 +1268,13 @@
   if isc_open_blob(@FStatus[0], @FSQLDatabaseHandle, @TransactionHandle, 
@blobHandle, blobId) <> 0 then
     CheckError('TIBConnection.CreateBlobStream', FStatus);
 
-  maxBlobSize := getMaxBlobSize(blobHandle);
-
-  blobSegment := AllocMem(maxBlobSize);
+  //For performance, read as much as we can, regardless of any segment size 
set in database.
+  blobSegment := AllocMem(MAXBLOBSEGMENTSIZE);
 
   with ABlobBuf^.BlobBuffer^ do
     begin
     Size := 0;
-    while (isc_get_segment(@FStatus[0], @blobHandle, @blobSegLen, maxBlobSize, 
blobSegment) = 0) do
+    while (isc_get_segment(@FStatus[0], @blobHandle, @blobSegLen, 
MAXBLOBSEGMENTSIZE, blobSegment) = 0) do
       begin
       ReAllocMem(Buffer,Size+blobSegLen);
       ptr := Buffer+Size;
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to