epoc32/include/sqldb.h
branchSymbian3
changeset 4 837f303aceeb
parent 2 2fe1408b6811
     1.1 --- a/epoc32/include/sqldb.h	Wed Mar 31 12:27:01 2010 +0100
     1.2 +++ b/epoc32/include/sqldb.h	Wed Mar 31 12:33:34 2010 +0100
     1.3 @@ -1,9 +1,9 @@
     1.4  // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5  // All rights reserved.
     1.6  // This component and the accompanying materials are made available
     1.7 -// under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
     1.8 +// under the terms of "Eclipse Public License v1.0"
     1.9  // which accompanies this distribution, and is available
    1.10 -// at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
    1.11 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.12  //
    1.13  // Initial Contributors:
    1.14  // Nokia Corporation - initial contribution.
    1.15 @@ -15,8 +15,6 @@
    1.16  // 
    1.17  //
    1.18  
    1.19 -
    1.20 -
    1.21  /**
    1.22   @file
    1.23   @publishedAll
    1.24 @@ -29,6 +27,10 @@
    1.25  #include <s32std.h>	//RReadStream, RWriteStream
    1.26  #endif
    1.27  
    1.28 +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS 
    1.29 +	#include <sqlresourcetester.h>
    1.30 +#endif
    1.31 +
    1.32  //Forward declarations
    1.33  class CSqlSecurityPolicy;
    1.34  class RSqlDatabase;
    1.35 @@ -38,6 +40,24 @@
    1.36  class RSqlColumnReadStream;
    1.37  class RSqlParamWriteStream;
    1.38  class TSqlScalarFullSelectQuery;
    1.39 +class RSqlBlob;
    1.40 +class RSqlBlobReadStream;
    1.41 +class RSqlBlobWriteStream;
    1.42 +class TSqlResourceProfiler;
    1.43 +
    1.44 +/**
    1.45 +Used to specify that the ROWID of the most recently inserted record
    1.46 +from the specified database connection should be used as the ROWID 
    1.47 +in a call to directly access a blob.
    1.48 +
    1.49 +@see RSqlBlobReadStream
    1.50 +@see RSqlBlobWriteStream
    1.51 +@see TSqlBlob
    1.52 +
    1.53 +@publishedAll
    1.54 +@released
    1.55 +*/
    1.56 +const TInt KSqlLastInsertedRowId = -1;
    1.57  
    1.58  /**
    1.59  A container for the security policies for a shared SQL database.
    1.60 @@ -228,6 +248,8 @@
    1.61  - attach a SQL database to current database connection by calling RSqlDatabase::Attach().
    1.62  - detach a SQL database from current database connection by calling RSqlDatabase::Detach().
    1.63  
    1.64 +The RSqlDatabase handles are not thread-safe.
    1.65 +
    1.66  A client can create either a non-secure database or a secure database,
    1.67  depending on the variant of RSqlDatabase::Create() that is used.
    1.68  - a non-secure database is created if the RSqlDatabase::Create(const TDesC&) variant is used.
    1.69 @@ -281,6 +303,10 @@
    1.70  	{
    1.71  	friend class RSqlStatement;
    1.72  	friend class TSqlScalarFullSelectQuery;
    1.73 +	friend class RSqlBlob;
    1.74 +	friend class RSqlBlobReadStream;
    1.75 +	friend class RSqlBlobWriteStream;
    1.76 +	friend class TSqlResourceProfiler;
    1.77  	
    1.78  public:
    1.79  	/**
    1.80 @@ -377,6 +403,20 @@
    1.81  		*/
    1.82  		ESerializable
    1.83  		};
    1.84 +	/**
    1.85 +	This structure is used for retrieving the database size and database free space.
    1.86 +	@see RSqlDatabase::Size(TSize&)
    1.87 +	*/
    1.88 +	struct TSize
    1.89 +		{
    1.90 +		/** The database size in bytes*/
    1.91 +		TInt64	iSize;
    1.92 +		/** The database free space in bytes*/
    1.93 +		TInt64	iFree;
    1.94 +		};
    1.95 +
    1.96 +	/** If this value is used as an argument of RSqlDatabase::Compact() (aSize argument), then all free space will be removed */
    1.97 +	enum {EMaxCompaction = -1};
    1.98  		
    1.99  	IMPORT_C RSqlDatabase();
   1.100  	
   1.101 @@ -409,9 +449,14 @@
   1.102  	IMPORT_C void Exec(const TDesC8& aSqlStmt, TRequestStatus& aStatus);
   1.103  	
   1.104  	IMPORT_C TPtrC LastErrorMessage() const;
   1.105 +	IMPORT_C TInt64 LastInsertedRowId() const; 
   1.106  	
   1.107  	IMPORT_C TBool InTransaction() const;
   1.108  	IMPORT_C TInt Size() const;
   1.109 +	IMPORT_C TInt Size(TSize& aSize, const TDesC& aDbName = KNullDesC) const;
   1.110 +
   1.111 +	IMPORT_C TInt Compact(TInt64 aSize, const TDesC& aDbName = KNullDesC);
   1.112 +	IMPORT_C void Compact(TInt64 aSize, TRequestStatus& aStatus, const TDesC& aDbName = KNullDesC);
   1.113  	
   1.114  	IMPORT_C TInt ReserveDriveSpace(TInt aSize);
   1.115  	IMPORT_C void FreeReservedSpace();
   1.116 @@ -541,7 +586,7 @@
   1.117  	/**
   1.118  	Binary data, a sequence of bytes.
   1.119  	*/
   1.120 -	ESqlBinary 
   1.121 +	ESqlBinary
   1.122  	};
   1.123  
   1.124  /**
   1.125 @@ -761,10 +806,18 @@
   1.126  If the result is outside the range that can be represented by the type returned
   1.127  by the accessor function, then it will be clamped.
   1.128  
   1.129 +Note that when handling blob and text data over 2Mb in size it is recommended that the 
   1.130 +RSqlBlobReadStream and RSqlBlobWriteStream classes or the TSqlBlob class is used instead. 
   1.131 +These classes provide a more RAM-efficient way of reading and writing large amounts of 
   1.132 +blob or text data from a database.
   1.133 +
   1.134  @see KMinTInt
   1.135  @see KMaxTInt
   1.136  @see KNullDesC
   1.137  @see KNullDesC8
   1.138 +@see RSqlBlobReadStream
   1.139 +@see RSqlBlobWriteStream
   1.140 +@see TSqlBlob
   1.141  
   1.142  @publishedAll
   1.143  @released
   1.144 @@ -800,6 +853,7 @@
   1.145  	IMPORT_C TInt BindReal(TInt aParameterIndex, TReal aParameterValue);
   1.146  	IMPORT_C TInt BindText(TInt aParameterIndex, const TDesC& aParameterText);
   1.147  	IMPORT_C TInt BindBinary(TInt aParameterIndex, const TDesC8& aParameterData);
   1.148 +	IMPORT_C TInt BindZeroBlob(TInt aParameterIndex, TInt aBlobSize);
   1.149  	
   1.150  	IMPORT_C TBool IsNull(TInt aColumnIndex) const;
   1.151  	IMPORT_C TInt ColumnInt(TInt aColumnIndex) const;
   1.152 @@ -814,6 +868,9 @@
   1.153  	IMPORT_C TInt ColumnBinary(TInt aColumnIndex, TPtrC8& aPtr) const;
   1.154  	IMPORT_C TInt ColumnBinary(TInt aColumnIndex, TDes8& aDest) const;
   1.155  	
   1.156 +	IMPORT_C TInt ColumnName(TInt aColumnIndex, TPtrC& aNameDest);
   1.157 +	IMPORT_C TInt ParameterName(TInt aParameterIndex, TPtrC& aNameDest);
   1.158 +	IMPORT_C TInt ParamName(TInt aParameterIndex, TPtrC& aNameDest);
   1.159  private:
   1.160  	CSqlStatementImpl& Impl() const;
   1.161  	
   1.162 @@ -825,13 +882,18 @@
   1.163  /**
   1.164  The read stream interface.
   1.165  
   1.166 -The class is used for reading the content of a column containing a large
   1.167 -amount of either binary data or text data.
   1.168 +The class is used for reading the content of a column containing either 
   1.169 +binary data or text data.
   1.170  
   1.171  The class derives from RReadStream, which means that all RReadStream public
   1.172  member functions and predefined stream operators \>\> can be used to deal
   1.173  with column data.
   1.174  
   1.175 +If the blob or text data is over 2Mb in size then it is recommended that the 
   1.176 +RSqlBlobReadStream or TSqlBlob class is used instead. These classes provide 
   1.177 +a more RAM-efficient way of reading large amounts of blob or text data from
   1.178 +a database.
   1.179 +
   1.180  The following two cases are typical:
   1.181  
   1.182  CASE 1 - processing large binary column data.
   1.183 @@ -886,6 +948,9 @@
   1.184  	}
   1.185  @endcode
   1.186  
   1.187 +@see RSqlBlobReadStream
   1.188 +@see TSqlBlob
   1.189 +
   1.190  @publishedAll
   1.191  @released
   1.192  */
   1.193 @@ -902,13 +967,18 @@
   1.194  /**
   1.195  The write stream interface.
   1.196  
   1.197 -The class is used to set a large amount of either binary data or text data
   1.198 -into a parameter. This is a also known as binding a parameter.
   1.199 +The class is used to set binary data or text data into a parameter. 
   1.200 +This is a also known as binding a parameter.
   1.201  
   1.202  The class derives from RWriteStream, which means that all RWriteStream public
   1.203  member functions and predefined stream operators \<\< can be used to deal with
   1.204  the parameter data.
   1.205  
   1.206 +If the blob or text data is over 2Mb in size then it is recommended that the 
   1.207 +RSqlBlobWriteStream or TSqlBlob class is used instead. These classes provide 
   1.208 +a more RAM-efficient way of writing large amounts of blob or text data to
   1.209 +a database.
   1.210 +
   1.211  The following two cases are typical:
   1.212  
   1.213  CASE 1 - binding a large binary parameter.
   1.214 @@ -955,6 +1025,9 @@
   1.215  CleanupStack::PopAndDestroy(&paramStream);
   1.216  @endcode
   1.217  
   1.218 +@see RSqlBlobWriteStream
   1.219 +@see TSqlBlob
   1.220 +
   1.221  @publishedAll
   1.222  @released
   1.223  */
   1.224 @@ -969,22 +1042,312 @@
   1.225  	};
   1.226  
   1.227  /**
   1.228 -TSqlResourceTester class is used internally by the SQL server out of memory and resource leaking
   1.229 -tests. 
   1.230 -It provides methods for heap allocation failure simulation and resource checking and counting.
   1.231 +A direct handle to a blob, used for reading the content of the blob via a streaming interface.
   1.232  
   1.233 -@internalAll
   1.234 +The target blob is identified using the relevant database connection, table name, 
   1.235 +column name and ROWID of the record to which the blob belongs (also the attached
   1.236 +database name if the blob is contained in an attached database).
   1.237 +
   1.238 +A blob in this context refers to the content of a BLOB or TEXT column, 
   1.239 +and a read handle can be opened on both types of column.
   1.240 +For TEXT columns it is important to note that no conversions are performed on 
   1.241 +data retrieved using this class - the data is returned as a stream of bytes.
   1.242 +
   1.243 +The class derives from RReadStream and provides all of its streaming methods.
   1.244 +The SizeL() method can be used to check the total size of the blob, in bytes.
   1.245 +
   1.246 +It is strongly recommended to use this class for reading the content of large blobs 
   1.247 +because it significantly reduces the amount of RAM that is used when compared to using the 
   1.248 +RSqlColumnReadStream, RSqlStatement::ColumnBinary(L) or RSqlStatement::ColumnText(L) APIs.
   1.249 +
   1.250 +Specifically, it is recommended to use this class for blobs over 2Mb in size.
   1.251 +Indeed, in some circumstances where very large blobs are in use it may be impossible
   1.252 +to read the blob content using the legacy APIs (due to the server's finite RAM capacity), 
   1.253 +and this class may provide the only way to access the data.
   1.254 +
   1.255 +The following code illustrates typical use cases of this class:
   1.256 +
   1.257 +CASE 1 - reading large blob data from the last inserted record.
   1.258 +
   1.259 +@code
   1.260 +RSqlDatabase db;
   1.261 +CleanupClosePushL(db);
   1.262 +<open/create "db" object>;
   1.263 +RSqlBlobReadStream rdStrm;
   1.264 +CleanupClosePushL(rdStrm);
   1.265 +rdStrm.OpenL(db, <table_name>, <column_name>);
   1.266 +HBufC8* buffer = HBufC8::NewLC(KBlockSize);
   1.267 +TPtr8 bufPtr(buffer->Des());
   1.268 +TInt size = rdStrm.SizeL();
   1.269 +while(size)
   1.270 +	{
   1.271 +	TInt bytesToRead = (size >= KBlockSize) ? KBlockSize : size ;
   1.272 +	rdStrm.ReadL(bufPtr, bytesToRead); // read the next block of data		
   1.273 +	<do something with the block of data>
   1.274 +	size =- bytesToRead;
   1.275 +	}
   1.276 +CleanupStack::PopAndDestroy(3); // buffer, rdStrm, db
   1.277 +@endcode
   1.278 +
   1.279 +CASE 2 - reading large blob data from a selection of records.
   1.280 +
   1.281 +@code
   1.282 +RSqlDatabase db;
   1.283 +CleanupClosePushL(db);
   1.284 +<open/create "db" object>;
   1.285 +RSqlStatement stmt;
   1.286 +CleanupClosePushL(stmt);
   1.287 +<prepare "stmt" object to SELECT the ROWIDs of a collection of blob objects>;
   1.288 +TInt rc = 0;
   1.289 +while((rc = stmt.Next()) == KSqlAtRow)
   1.290 +	{
   1.291 +	TInt64 rowid = stmt.ColumnInt64(0);	
   1.292 +	RSqlBlobReadStream rdStrm;
   1.293 +	CleanupClosePushL(rdStrm);
   1.294 +	rdStrm.OpenL(db, <table_name>, <column_name>, rowid);
   1.295 +	
   1.296 +	HBufC8* buffer = HBufC8::NewLC(KBlockSize);
   1.297 +	TPtr8 bufPtr(buffer->Des());
   1.298 +	TInt size = rdStrm.SizeL();
   1.299 +	while(size)
   1.300 +		{
   1.301 +		TInt bytesToRead = (size >= KBlockSize) ? KBlockSize : size ;
   1.302 +		rdStrm.ReadL(bufPtr, bytesToRead); // read the next block of data		
   1.303 +		<do something with the block of data>
   1.304 +		size =- bytesToRead;
   1.305 +		}
   1.306 +	CleanupStack::PopAndDestroy(2); // buffer, rdStrm
   1.307 +	}
   1.308 +CleanupStack::PopAndDestroy(2); // stmt, db
   1.309 +@endcode
   1.310 +
   1.311 +@see RSqlBlobWriteStream
   1.312 +@see RSqlDatabase::LastInsertedRowId()
   1.313 +
   1.314 +@publishedAll
   1.315  @released
   1.316  */
   1.317 -class TSqlResourceTester
   1.318 +class RSqlBlobReadStream : public RReadStream
   1.319  	{
   1.320 -public:	
   1.321 -	IMPORT_C static void Mark();
   1.322 -	IMPORT_C static void Check();
   1.323 -	IMPORT_C static TInt Count();
   1.324 -	IMPORT_C static void SetDbHeapFailure(TInt aAllocFailType,TInt aRate);
   1.325 -	IMPORT_C static void SetHeapFailure(TInt aAllocFailType,TInt aRate);
   1.326 +public:						
   1.327 +	IMPORT_C void OpenL(RSqlDatabase& aDb, const TDesC& aTableName, const TDesC& aColumnName, 
   1.328 +						TInt64 aRowId = KSqlLastInsertedRowId, const TDesC& aDbName = KNullDesC);
   1.329 +	IMPORT_C TInt SizeL();
   1.330 +	};
   1.331  
   1.332 +/**
   1.333 +A direct handle to a blob, used for writing the content of the blob via a streaming interface.
   1.334 +
   1.335 +The target blob is identified using the relevant database connection, table name, 
   1.336 +column name and ROWID of the record to which the blob belongs (also the attached
   1.337 +database name if the blob is contained in an attached database).
   1.338 +
   1.339 +A blob in this context refers to the content of a BLOB or TEXT column, 
   1.340 +and a write handle can be opened on both types of column, except if the
   1.341 +column is indexed, in which case the open call will fail with KSqlErrGeneral.
   1.342 +For TEXT columns it is important to note that no conversions are performed on data 
   1.343 +that is stored using this class - the data is simply stored as a stream of bytes.
   1.344 +
   1.345 +The class derives from RWriteStream and provides all of its streaming methods.
   1.346 +The SizeL() method can be used to check the total size of the blob, in bytes.
   1.347 +Note that this class cannot be used to increase the size of a blob, only to modify 
   1.348 +the existing contents of a blob. An attempt to write beyond the end of a blob will
   1.349 +fail with KErrEof.
   1.350 +
   1.351 +It is strongly recommended to use this class for writing the content of large blobs 
   1.352 +because it significantly reduces the amount of RAM that is used when compared to using 
   1.353 +the RSqlParamWriteStream, RSqlStatement::BindBinary or RSqlStatement::BindText APIs.
   1.354 +
   1.355 +Specifically, it is recommended to use this class for blobs over 2Mb in size.
   1.356 +Indeed, in some circumstances where very large blobs are required it may be impossible
   1.357 +to create a blob or update its content using the legacy APIs (due to the server's finite 
   1.358 +RAM capacity), and this class may provide the only way to achieve this.
   1.359 +
   1.360 +Using this class in combination with zeroblobs it is possible to create and manipulate 
   1.361 +blobs that are gigabytes in size. A zeroblob acts as a place-holder for a blob whose 
   1.362 +content is later written using this class and one can be created using an INSERT 
   1.363 +statement that either contains the SQLite 'zeroblob()' function or on which 
   1.364 +RSqlStatement::BindZeroBlob() has been executed.
   1.365 +Note that a zeroblob should be created in a column after which there are no columns 
   1.366 +that contain anything other than zeroblobs or NULLs, otherwise the zeroblob must be 
   1.367 +allocated in full in RAM.
   1.368 +
   1.369 +When creating a zeroblob it is recommended, where possible, to create the zeroblob and
   1.370 +then write the blob content within the same transaction. Otherwise the zeroblob will 
   1.371 +have to be journalled before being written to.
   1.372 +
   1.373 +It is also strongly recommended to execute calls to WriteL() within a transaction. 
   1.374 +If a leave occurs during a call to WriteL() then the current state of the blob object is
   1.375 +undefined and a ROLLBACK should be executed to return the blob object to its previous state.
   1.376 +Note that in order for a ROLLBACK to execute successfully all open RSqlBlobReadStream 
   1.377 +and RSqlBlobWriteStream handles and all open RSqlStatement objects must be closed 
   1.378 +before the ROLLBACK is executed.
   1.379 +
   1.380 +The following code illustrates typical use cases of this class:
   1.381 +
   1.382 +CASE 1 - creating a 5Mb blob.
   1.383 +
   1.384 +@code
   1.385 +RSqlDatabase db;
   1.386 +CleanupClosePushL(db);
   1.387 +<open/create "db" object>;
   1.388 +CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function
   1.389 +TInt err = db.Exec(_L("BEGIN"));
   1.390 +<check err>
   1.391 +err = db.Exec(_L("INSERT INTO table1 VALUES(35, zeroblob(5242880))"));
   1.392 +<check err>
   1.393 +RSqlBlobWriteStream wrStrm;
   1.394 +CleanupClosePushL(wrStrm);
   1.395 +wrStrm.OpenL(db, <table_name>, <column_name>);
   1.396 +TInt size = wrStrm.SizeL();
   1.397 +while(size)
   1.398 +	{
   1.399 +	TInt bytesToWrite = (size >= KBlockSize) ? KBlockSize : size ;
   1.400 +	<fill a buffer 'buf' with this amount of the blob data>
   1.401 +	wrStrm.WriteL(buf); // write the next block of data		
   1.402 +	size =- bytesToWrite;
   1.403 +	}
   1.404 +CleanupStack::PopAndDestroy(&wrStrm);
   1.405 +CleanupStack::Pop(); // TCleanupItem
   1.406 +err = db.Exec(_L("COMMIT")); // blob data committed to disk
   1.407 +<check err>
   1.408 +CleanupStack::PopAndDestroy(&db);
   1.409 +@endcode
   1.410 +
   1.411 +CASE 2 - updating a large blob in the last inserted record.
   1.412 +
   1.413 +@code
   1.414 +RSqlDatabase db;
   1.415 +CleanupClosePushL(db);
   1.416 +<open/create "db" object>;
   1.417 +CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function
   1.418 +TInt err = db.Exec(_L("BEGIN"));
   1.419 +<check err>
   1.420 +RSqlBlobWriteStream wrStrm;
   1.421 +CleanupClosePushL(wrStrm);
   1.422 +wrStrm.OpenL(db, <table_name>, <column_name>);
   1.423 +<fill a buffer 'buf' with the changed blob data>
   1.424 +wrStrm.WriteL(buf); // update the blob
   1.425 +CleanupStack::PopAndDestroy(&wrStrm);
   1.426 +CleanupStack::Pop(); // TCleanupItem
   1.427 +err = db.Exec(_L("COMMIT")); // blob data committed to disk
   1.428 +<check err>
   1.429 +CleanupStack::PopAndDestroy(&db);
   1.430 +@endcode
   1.431 +
   1.432 +@see RSqlBlobReadStream
   1.433 +@see RSqlDatabase::LastInsertedRowId()
   1.434 +@see RSqlStatement::BindZeroBlob()
   1.435 +
   1.436 +@publishedAll
   1.437 +@released
   1.438 +*/
   1.439 +class RSqlBlobWriteStream : public RWriteStream
   1.440 +	{
   1.441 +public:
   1.442 +	IMPORT_C void OpenL(RSqlDatabase& aDb, const TDesC& aTableName, const TDesC& aColumnName, 
   1.443 +						TInt64 aRowId = KSqlLastInsertedRowId, const TDesC& aDbName = KNullDesC);
   1.444 +	IMPORT_C TInt SizeL();
   1.445 +	};
   1.446 +
   1.447 +/**
   1.448 +Utility class that provides methods for reading and writing the entire content of 
   1.449 +a blob in a single call.
   1.450 +
   1.451 +The target blob is identified using the relevant database connection, table name, 
   1.452 +column name and ROWID of the record to which the blob belongs (also the attached
   1.453 +database name if the blob is contained in an attached database).
   1.454 +
   1.455 +The behaviour of the RSqlBlobReadStream class and the recommendations for using
   1.456 +it exist for the Get() and GetLC() methods of this class. Similarly, the behaviour 
   1.457 +of the RSqlBlobWriteStream class and the recommendations for using it exist for the 
   1.458 +SetL() method of this class.
   1.459 +
   1.460 +In particular, it is strongly recommended to use this class or the RSqlBlobReadStream
   1.461 +and RSqlBlobWriteStream classes for reading and writing the content of large blobs 
   1.462 +because it significantly reduces the amount of RAM that is used when compared to using 
   1.463 +the legacy streaming and RSqlStatement APIs.
   1.464 +
   1.465 +Specifically, it is recommended to use this class for blobs over 2Mb in size.
   1.466 +Indeed, in some circumstances where very large blobs are in use it may be impossible
   1.467 +to read or write to a blob using the legacy APIs (due to the server's finite 
   1.468 +RAM capacity), and this class or the RSqlBlobReadStream and RSqlBlobWriteStream classes 
   1.469 +may provide the only way to achieve this.
   1.470 +
   1.471 +It is strongly recommended to execute calls to the SetL() method within a transaction. 
   1.472 +If a leave occurs during a call to SetL() then the current state of the blob object is 
   1.473 +undefined and a ROLLBACK should be executed to return the blob object to its previous state.
   1.474 +Note that in order for a ROLLBACK to execute successfully all open RSqlBlobReadStream 
   1.475 +and RSqlBlobWriteStream handles and all open RSqlStatement objects must be closed 
   1.476 +before the ROLLBACK is executed.
   1.477 +
   1.478 +When using SetL() to update the content of a zeroblob it is recommended, where possible, 
   1.479 +to create the zeroblob and then call SetL() within the same transaction. 
   1.480 +Otherwise the zeroblob will have to be journalled before being written to.
   1.481 +
   1.482 +The following code illustrates typical use cases of this class:
   1.483 +
   1.484 +CASE 1 - retrieving the entire content of a large blob.
   1.485 +
   1.486 +@code
   1.487 +RSqlDatabase db;
   1.488 +CleanupClosePushL(db);
   1.489 +<open/create "db" object>;
   1.490 +HBufC8* wholeBlob = TSqlBlob::GetLC(db, <table_name>, <column_name>, <rowid>);
   1.491 +<do something with the blob data>
   1.492 +CleanupStack::PopAndDestroy(2); // wholeBlob, db
   1.493 +@endcode
   1.494 +
   1.495 +
   1.496 +CASE 2 - creating a 4Mb blob.
   1.497 +
   1.498 +@code
   1.499 +RSqlDatabase db;
   1.500 +CleanupClosePushL(db);
   1.501 +<open/create "db" object>;
   1.502 +CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function
   1.503 +TInt err = db.Exec(_L("BEGIN"));
   1.504 +<check err>
   1.505 +err = db.Exec(_L("INSERT INTO table1 VALUES(99, zeroblob(4194304))"));
   1.506 +<check err>
   1.507 +<fill a buffer 'buf' with 4Mb of blob data>
   1.508 +TSqlBlob::SetL(db, <table_name>, <column_name>, buf);
   1.509 +CleanupStack::Pop(); // TCleanupItem
   1.510 +err = db.Exec(_L("COMMIT")); // blob data committed to disk
   1.511 +<check err>
   1.512 +CleanupStack::PopAndDestroy(&db);
   1.513 +@endcode
   1.514 +
   1.515 +@see RSqlBlobReadStream
   1.516 +@see RSqlBlobWriteStream
   1.517 +@see RSqlDatabase::LastInsertedRowId()
   1.518 +@see RSqlStatement::BindZeroBlob()
   1.519 +
   1.520 +@publishedAll
   1.521 +@released
   1.522 +*/
   1.523 +class TSqlBlob
   1.524 +	{
   1.525 +public:					  		  	  
   1.526 +	IMPORT_C static HBufC8* GetLC(RSqlDatabase& aDb, 	
   1.527 +					     		  const TDesC& aTableName, 
   1.528 +					     		  const TDesC& aColumnName, 	
   1.529 +					     		  TInt64 aRowId = KSqlLastInsertedRowId,
   1.530 +					     		  const TDesC& aDbName = KNullDesC);
   1.531 +								  		  	  
   1.532 +	IMPORT_C static TInt Get(RSqlDatabase& aDb, 	
   1.533 +					 		 const TDesC& aTableName, 
   1.534 +					 		 const TDesC& aColumnName, 	
   1.535 +					 		 TDes8& aBuffer,
   1.536 +					 		 TInt64 aRowId = KSqlLastInsertedRowId,
   1.537 +					 		 const TDesC& aDbName = KNullDesC);			 		 
   1.538 +
   1.539 +	IMPORT_C static void SetL(RSqlDatabase& aDb, 	
   1.540 +					  		  const TDesC& aTableName, 
   1.541 +					  		  const TDesC& aColumnName,
   1.542 +					  		  const TDesC8& aData,	
   1.543 +					  		  TInt64 aRowId = KSqlLastInsertedRowId,
   1.544 +					  		  const TDesC& aDbName = KNullDesC);				  
   1.545  	};
   1.546  
   1.547  /**