User Tools

Site Tools


blob_declare_a_variable_length_field_.htm
Navigation:  Language Reference > 4 - Entity Declarations > File Structures >====== BLOB (declare a variable-length field) ====== Previous pageReturn to chapter overviewNext page
label BLOB [,BINARY] [,NAME( )]

blk2blue.jpg

Label The label of the BLOB (PROP:Label).
BLOB Declares a variable-length string stored on disk per record which may be greater than 64K
BINARY Declares the BLOB a storage area for binary data (PROP:BINARY).
NAME Specifies the disk filename for the BLOB field (PROP:NAME).

BLOB (Binary Large Object) declares a string field which is completely variable-length and may be greater than 64K in size. A BLOB must be declared before the RECORD structure. Generally, up to 255 BLOB fields may be declared in a FILE structure (the exact number and their manner of storage on disk is file driver dependent).

A BLOB may not be used as a variable–you may not name a BLOB as a control's USE attribute, or directly assign data to or from the BLOB.

You can use PROP:Handle to get the Windows handle to the BLOB entity and assign one BLOB to another: get the handle of both BLOB entities and then assign one BLOB's handle to the other BLOB's handle. A BLOB may not be accessed “as a whole;” you must either use Clarion's string slicing syntax to access the data (unlimited in 32-bit), or PROP:ImageBlob. The individual bytes of data in the BLOB are numbered starting with zero (0), not one (1). PROP:Handle when used with BLOB returns a Windows Global Memory Object Handle for use with low-level Windows GlobalXxxx() API calls that require it.

The SIZE procedure returns the number of bytes contained in the BLOB field for the current record in memory. You can also get (and set) the size of a BLOB using PROP:Size. You may set the size of the BLOB before assigning data to a new BLOB using string slicing, but it is not necessary as the size is automatically set by the string slice operation. You can also use PROP:ImageBlob to store and retrieve graphic images without first setting PROP:Size. It is a good idea to first set PROP:Size to zero (0) before assigning data to a BLOB that has not previously contained data, to eliminate any “junk” leftover from any previously accessed BLOB. When assigning from one BLOB to another using PROP:Handle, you may need to use PROP:Size to adjust the size of the destination BLOB to the size of the source BLOB. PROP:Touched can be used to determine if the contents of the BLOB has changed since it was retrieved from disk.

BLOB fields are not in the RECORD structure, and should not be listed in a PROP:SQL.  If you need to retrieve an image field from an SQL backend, use SET/NEXT and BLOB syntax to retrieve the blob data.

Example:

ArchiveFile PROCEDURE

Names   FILE,DRIVER('TopSpeed')

NaneKey  KEY(Name)

Notes    BLOB        !Can be larger than 64K

Rec      RECORD

Name      STRING(20)

        END

       END

ArcNames FILE,DRIVER('TopSpeed')

Notes    BLOB        

Rec       RECORD

Name       STRING(20)

         END

        END

CODE

SET(Names)

LOOP

 NEXT(Names)

 IF ERRORCODE() THEN BREAK.

 ArcNames.Rec = Names.Rec                               !Assign rec data to Archive

 ArcNames.Notes{PROP:Handle} = Names.Notes{PROP:Handle} !Assign BLOB to Archive

 IF ERRORCODE() = 80

  MESSAGE('BLOB size is too large')

  BREAK

 END

 ArcNames.Notes{PROP:Size} = Names.Notes{PROP:Size}     ! and adjust the size

 ADD(ArcNames)

END

StoreFileInBlob PROCEDURE                                !Stores any disk file into a BLOB

DosFileName STRING(260),STATIC

LastRec     LONG

SavPtr      LONG(1)                                      !Start at 1

FileSize    LONG

DosFile    FILE,DRIVER('DOS'),PRE(DOS),NAME(DosFileName)

Record      RECORD

F1           STRING(2000)

           END

          END

BlobStorage  FILE,DRIVER('TopSpeed'),PRE(STO)

File         BLOB,BINARY

Record        RECORD

FileName       STRING(64)

             END

            END

CODE

IF NOT FILEDIALOG('Choose File to Store',DosFileName,,0010b) THEN RETURN.

OPEN(BlobStorage)                     !Open the BLOB file

STO:FileName = DosFileName            ! and store the filename

OPEN(DosFile)                         !Open the file

FileSize = BYTES(DosFile)             !Get size of file

STO:File{PROP:Size} = FileSize        ! and set the BLOB to store the file

LastRec = FileSize % SIZE(DOS:Record) !Check for short record at end of file

LOOP INT(FileSize/SIZE(DOS:Record)) TIMES

 GET(DosFile,SavPtr)                  !Get each record

 ASSERT(NOT ERRORCODE())

 STO:File[SavPtr - 1 : SavPtr + SIZE(DOS:Record) - 2] = DOS:Record

                                      !String slice data into BLOB

 SavPtr += SIZE(DOS:Record)           !Compute next record pointer

END

IF LastRec                            !If short record at end of file

 GET(DosFile,SavPtr)                  !Get last record

 ASSERT(BYTES(DosFile) = LastRec)     ! size read should match computed size

 STO:File[SavPtr - 1 : SavPtr + LastRec - 2] = DOS:Record

END

ADD(BlobStorage)

ASSERT(NOT ERRORCODE())

CLOSE(DosFile);CLOSE(BlobStorage)

See Also:

PROP:ImageBlob

PROP:Size

Implicit String Arrays and String Slicing

BLOBtoFILE

FILEtoBLOB

PROP:Handle

PROP:ClientHandle

blob_declare_a_variable_length_field_.htm.txt · Last modified: 2021/04/15 15:57 (external edit)