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