RSqlBlobWriteStream Class Reference

#include <sqldb.h>

Link against: sqldb.lib

class RSqlBlobWriteStream : public RWriteStream

Inherits from

  • RSqlBlobWriteStream

    Detailed Description

    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);

    See also: RSqlBlobReadStream RSqlDatabase::LastInsertedRowId() RSqlStatement::BindZeroBlob()

    Member Function Documentation

    OpenL ( RSqlDatabase &, const TDesC &, const TDesC &, TInt64, const TDesC & )

    IMPORT_C voidOpenL(RSqlDatabase &aDb,
    const TDesC &aTableName,
    const TDesC &aColumnName,
    TInt64aRowId =  KSqlLastInsertedRowId ,
    const TDesC &aDbName =  KNullDesC
    )

    Gives access to a blob as a writeable stream of bytes.

    leave
    KSqlErrGeneral, Invalid database connection or table name or column name or column type or ROWID or database name, or the specified column is indexed; KErrNoMemory, An out of memory condition occurred; KErrArgument, The ROWID is zero or negative or a UTF-16 to UTF-8 string conversion failed; KErrBadName, The table name, column name or database name has an invalid length; KErrPermissionDenied, The client does not have the required security capabilites for this operation; Note that the function may also leave with some other system wide errors or database specific errors categorised as ESqlDbError.
    panic
    SqlDb 2 The database object is not yet created
    panic
    SqlDb 3 Server failed to create a handle to the blob
    panic
    SqlDb 4 In _DEBUG mode. Bad parameter value
    panic
    SqlDb 7 In _DEBUG mode. NULL blob handle
    capability
    None, if the aDb parameter represents a handle which operates on a non-secure database; RSqlSecurityPolicy::EWritePolicy or RSqlSecurityPolicy::ESchemaPolicy database policy type, if the blob belongs to a secure database;
    ParameterDescription
    aDbA connection to the database that contains the blob
    aTableNameThe name of the table that contains the blob
    aColumnNameThe name of the column that contains the blob
    aRowIdThe ROWID of the record that contains the blob, or KSqlLastInsertedRowId if the last inserted ROWID of the specified database connection is to be used
    aDbNameThe name of the attached database if the blob is contained in an attached database

    SizeL ( )

    IMPORT_C TIntSizeL()

    Returns the size of the blob object, in bytes.

    leave
    One of the system-wide error codes
    panic
    SqlDb 2 The stream buffer is NULL
    capability
    None

    Returns: The size of the blob object, in bytes