Fetching Data
Suppose we want to fetch a very large image from a database. As shown in
Output Binding and Fetching Using RWDBTBuffer we would fetch the data using
RWDBOSql something like this:
RWDBOSql sql("select id, image from mytable where id = 1001");
RWDBTBuffer<long> idBuf(1);
RWDBTBuffer<RWDBBlob> buffer(1);
sql.execute(aConnection);
sql[0] >> idBuf >> buffer;
while (sql.fetch(), sql.rowsFetched() > 0) {
// process data in idBuf and buffer
}
When
RWDBOSql::execute(…) is called, the
SELECT statement is executed. On each call to
fetch(),
RWDBOSql fetches as many rows as possible from the result set and puts the data into the
RWDBTBuffer instances. Since
idBuf and
buffer can hold only one entry, at most one row is fetched on each call to
fetch(). SourcePro DB attempts to allocate enough memory to contain the entire data set. It then passes this data to the user application. If the data does not fit in the buffer provided, the data received by the application will be truncated.
The following diagram illustrates this operation:
As a way to limit the amount of memory required to handle LOBs, SourcePro DB provides an alternative API that allows callback classes to be associated with the
RWDBOSql rather than
RWDBTBuffer instances. Based the example above, the data callback class
MyDataCallback, derived from
RWDBBinaryCallback, is used in place of an
RWDBTBuffer to fetch the image data:
RWDBOSql sql("select id, image from mytable where id = 1001");
RWDBTBuffer<long> idBuf(1);
MyDataCallback buffer(1);
sql.execute(aConnection);
sql[0] >> idBuf >> buffer;
while (sql.fetch(), sql.rowsFetched() > 0) {
// process data
}
This time when RWDBOSql::fetch() is called the data set is retrieved one row at a time. The ID value is written into the idBuf in the usual manner, but the image data is fetched one piece at a time. The callback method defined by MyDataCallback is invoked repeatedly, once for each piece of data, until all of the data has been fetched. Thus, only one piece of the data needs to fit in memory at any one time.
The operation now looks like this: