class RSqlBlobWriteStream : public RWriteStream |
A direct handle to a blob, used for writing the content of the blob via a streaming interface.
The target blob is identified using the relevant database connection, table name, column name and ROWID of the record to which the blob belongs (also the attached database name if the blob is contained in an attached database).
A blob in this context refers to the content of a BLOB or TEXT column, and a write handle can be opened on both types of column, except if the column is indexed, in which case the open call will fail with KSqlErrGeneral. For TEXT columns it is important to note that no conversions are performed on data that is stored using this class - the data is simply stored as a stream of bytes.
The class derives from RWriteStream and provides all of its streaming methods. The SizeL() method can be used to check the total size of the blob, in bytes. Note that this class cannot be used to increase the size of a blob, only to modify the existing contents of a blob. An attempt to write beyond the end of a blob will fail with KErrEof.
It is strongly recommended to use this class for writing the content of large blobs because it significantly reduces the amount of RAM that is used when compared to using the RSqlParamWriteStream, RSqlStatement::BindBinary or RSqlStatement::BindText APIs.
Specifically, it is recommended to use this class for blobs over 2Mb in size. Indeed, in some circumstances where very large blobs are required it may be impossible to create a blob or update its content using the legacy APIs (due to the server's finite RAM capacity), and this class may provide the only way to achieve this.
Using this class in combination with zeroblobs it is possible to create and manipulate blobs that are gigabytes in size. A zeroblob acts as a place-holder for a blob whose content is later written using this class and one can be created using an INSERT statement that either contains the SQLite 'zeroblob()' function or on which RSqlStatement::BindZeroBlob() has been executed. Note that a zeroblob should be created in a column after which there are no columns that contain anything other than zeroblobs or NULLs, otherwise the zeroblob must be allocated in full in RAM.
When creating a zeroblob it is recommended, where possible, to create the zeroblob and then write the blob content within the same transaction. Otherwise the zeroblob will have to be journalled before being written to.
It is also strongly recommended to execute calls to WriteL() within a transaction. If a leave occurs during a call to WriteL() then the current state of the blob object is undefined and a ROLLBACK should be executed to return the blob object to its previous state. Note that in order for a ROLLBACK to execute successfully all open RSqlBlobReadStream and RSqlBlobWriteStream handles and all open RSqlStatement objects must be closed before the ROLLBACK is executed.
The following code illustrates typical use cases of this class:
CASE 1 - creating a 5Mb blob.
RSqlDatabase db; CleanupClosePushL(db); <open/create "db" object>; CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function TInt err = db.Exec(_L("BEGIN")); <check err> err = db.Exec(_L("INSERT INTO table1 VALUES(35, zeroblob(5242880))")); <check err> RSqlBlobWriteStream wrStrm; CleanupClosePushL(wrStrm); wrStrm.OpenL(db, <table_name>, <column_name>); TInt size = wrStrm.SizeL(); while(size) { TInt bytesToWrite = (size >= KBlockSize) ? KBlockSize : size ; <fill a buffer 'buf' with this amount of the blob data> wrStrm.WriteL(buf); // write the next block of data size =- bytesToWrite; } CleanupStack::PopAndDestroy(&wrStrm); CleanupStack::Pop(); // TCleanupItem err = db.Exec(_L("COMMIT")); // blob data committed to disk <check err> CleanupStack::PopAndDestroy(&db);
CASE 2 - updating a large blob in the last inserted record.
RSqlDatabase db; CleanupClosePushL(db); <open/create "db" object>; CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function TInt err = db.Exec(_L("BEGIN")); <check err> RSqlBlobWriteStream wrStrm; CleanupClosePushL(wrStrm); wrStrm.OpenL(db, <table_name>, <column_name>); <fill a buffer 'buf' with the changed blob data> wrStrm.WriteL(buf); // update the blob CleanupStack::PopAndDestroy(&wrStrm); CleanupStack::Pop(); // TCleanupItem err = db.Exec(_L("COMMIT")); // blob data committed to disk <check err> CleanupStack::PopAndDestroy(&db);
Public Member Functions | |
---|---|
IMPORT_C void | OpenL(RSqlDatabase &, const TDesC &, const TDesC &, TInt64, const TDesC &) |
IMPORT_C TInt | SizeL() |
IMPORT_C void | OpenL | ( | RSqlDatabase & | aDb, |
const TDesC & | aTableName, | |||
const TDesC & | aColumnName, | |||
TInt64 | aRowId = KSqlLastInsertedRowId , | |||
const TDesC & | aDbName = KNullDesC | |||
) |
RSqlDatabase & aDb | |
const TDesC & aTableName | |
const TDesC & aColumnName | |
TInt64 aRowId = KSqlLastInsertedRowId | |
const TDesC & aDbName = KNullDesC |