Accessing BLOB values
BLOB values are large binary data blocks, which may contain values up to 2 GB. BLOB values may contain any kind of data. BLOB values require specific actions (Value::read()) in order to load the stored value into a binary buffer area (Binary). Updating or creating BLOB values is possible by calling the Value::write() function. BLOB values may be accessed /read or write) partially. The size for the currently selected BLOB value may be obtained by calling Value::size().
BLOB values have to be defined as reference values. The property size may be defined but will be ignored, i.e. in contrast to MEMO values, BLOB values are not limited in size until the exceed 2 GB.
In order to manipulate binary data, ODABA provides the Binary class.
Since BLOB values are stored as references, they might be accessed by Value functions as well as by Property functions.
In order to access BLOB values, Value::read() and Value::write() should be used rather than Property::get() and Property::save(). BLOB values are automatically selected or created whenever required, but the parent property handle has to be selected.
In order to handle large BLOB values properly without wasting memory, one may access BLOB values partially by passing position (and size) to read() and write() functions. Nevertheless, a database entry containing the complete BLOB data area will be allocated, i.e. accessing a large BLOB value always require sufficient storage for loading the complete BLOB value into memory. Typically, BLOB values are used for storing images or executables, but one might get into trouble when trying to store long movies into BLOB areas. In such cases, file references might be used, instead, referring to the file stored outside the database.
Since the content of a BLOB area is under control of the application, BLOB values are not converted when running the data base in platform independent mode (PIF). In order to guarantee platform independence, BLOB data has to be stored in pltform independent formats or the application has to care about proper conversion to the desired platform format.
Since BLOB values are not limited in size, BLOB values are not copied to an internal instance area when calling Property::get(). Instead, they may be read into an internal user area provided with the Binary data block. By default, BLOB values may always be accessed, but might be empty, when not yet being written. Hence, accessing a BLOB value by calling Value::read() will always return a binary data block (which might be empty). In order to check, whether a data has already been stored for the value, Property::instanceLoid() may be called, which returns 0 in case that no instance had been created.
// copy BLOB data - C++
... fragment (const Value &source, Value &target) {
int len;
int bufsize = 8000;
int pos;
Binary buffer;
for ( pos=0, len = source.size();
len > 0;
pos+=bufsize, len -= bufsize ) {
target.write(source.read(pos,MIN(bufsize,len),pos,MIN(bufsize,len));
}
In order to manipulate BLOB values, binary data has to be provided in a binary data block (Binary). Communication between database and application always goes through a Binary object instance. The Binary class provides several functions for manipulating binary data.
The class allows updating single bytes or sections within a binary data block (update()), extending data in a data block (append()) or inserting (insert()) and removing (remove()) data. Moreover, one may convert binary data into string data (base 64, hexadecimal - base 16 or quoted printable) and reverse (to...() and from...() functions).
Finally, the class supports reading and writing binary data from and to files (loadFile(), storeFile()).
Manipulated binary data may be stored to the database by passing the binary data block to Value::write().
// update BLOB
... fragment ( Value &myBlob ) {
Binary bin_area;
int len;
bin_area = myBlob.read();
for ( len = bin_area.length(); len > 0; len-- )
if ( bin_are.index(len-1) == 10 )
bin_area.erase(len-1,1);
myBlob.write(bin_area);
}