epoc32/include/sqldb.h
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
parent 2 2fe1408b6811
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
williamr@2
     1
// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
williamr@2
     2
// All rights reserved.
williamr@2
     3
// This component and the accompanying materials are made available
williamr@4
     4
// under the terms of "Eclipse Public License v1.0"
williamr@2
     5
// which accompanies this distribution, and is available
williamr@4
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
williamr@2
     7
//
williamr@2
     8
// Initial Contributors:
williamr@2
     9
// Nokia Corporation - initial contribution.
williamr@2
    10
//
williamr@2
    11
// Contributors:
williamr@2
    12
//
williamr@2
    13
// Description:
williamr@2
    14
// SQL Client side API header
williamr@2
    15
// 
williamr@2
    16
//
williamr@2
    17
williamr@2
    18
/**
williamr@2
    19
 @file
williamr@2
    20
 @publishedAll
williamr@2
    21
 @released
williamr@2
    22
*/
williamr@2
    23
#ifndef __SQLDB_H__
williamr@2
    24
#define __SQLDB_H__
williamr@2
    25
williamr@2
    26
#ifndef __S32STD_H__
williamr@2
    27
#include <s32std.h>	//RReadStream, RWriteStream
williamr@2
    28
#endif
williamr@2
    29
williamr@4
    30
#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS 
williamr@4
    31
	#include <sqlresourcetester.h>
williamr@4
    32
#endif
williamr@4
    33
williamr@2
    34
//Forward declarations
williamr@2
    35
class CSqlSecurityPolicy;
williamr@2
    36
class RSqlDatabase;
williamr@2
    37
class CSqlDatabaseImpl;
williamr@2
    38
class RSqlStatement;
williamr@2
    39
class CSqlStatementImpl;
williamr@2
    40
class RSqlColumnReadStream;
williamr@2
    41
class RSqlParamWriteStream;
williamr@2
    42
class TSqlScalarFullSelectQuery;
williamr@4
    43
class RSqlBlob;
williamr@4
    44
class RSqlBlobReadStream;
williamr@4
    45
class RSqlBlobWriteStream;
williamr@4
    46
class TSqlResourceProfiler;
williamr@4
    47
williamr@4
    48
/**
williamr@4
    49
Used to specify that the ROWID of the most recently inserted record
williamr@4
    50
from the specified database connection should be used as the ROWID 
williamr@4
    51
in a call to directly access a blob.
williamr@4
    52
williamr@4
    53
@see RSqlBlobReadStream
williamr@4
    54
@see RSqlBlobWriteStream
williamr@4
    55
@see TSqlBlob
williamr@4
    56
williamr@4
    57
@publishedAll
williamr@4
    58
@released
williamr@4
    59
*/
williamr@4
    60
const TInt KSqlLastInsertedRowId = -1;
williamr@2
    61
williamr@2
    62
/**
williamr@2
    63
A container for the security policies for a shared SQL database.
williamr@2
    64
williamr@2
    65
The container can contain:
williamr@2
    66
- security policies that apply to the database.
williamr@2
    67
- security policies that apply to individual database objects, i.e. database tables.
williamr@2
    68
williamr@2
    69
For the database, you use RSqlSecurityPolicy::SetDbPolicy() to apply a separate
williamr@2
    70
security policy to:
williamr@2
    71
- the database schema.
williamr@2
    72
- read activity on the database.
williamr@2
    73
- write activity on the database.
williamr@2
    74
williamr@2
    75
For database tables, you use RSqlSecurityPolicy::SetPolicy() to apply a separate
williamr@2
    76
security policy to:
williamr@2
    77
- write activity on each named database table.
williamr@2
    78
- read activity on each named database table.
williamr@2
    79
williamr@2
    80
A client uses a RSqlSecurityPolicy object to create a secure database. It does this by:
williamr@2
    81
- creating a RSqlSecurityPolicy object.
williamr@2
    82
- setting all the appropriate security policies into it.
williamr@2
    83
- passing the object as an argument to RSqlDatabase::Create().
williamr@2
    84
- closing the RSqlSecurityPolicy object on return from RSqlDatabase::Create().
williamr@2
    85
williamr@2
    86
Once a secure shared database has been created with specific security policies,
williamr@2
    87
these policies are made persistent and cannot be changed during the life of
williamr@2
    88
that database.
williamr@2
    89
williamr@2
    90
Security policies are encapsulated by TSecurityPolicy objects.
williamr@2
    91
The general usage pattern is to create the security policies container object
williamr@2
    92
(RSqlSecurityPolicy) using a default security policy (TSecurityPolicy), and then
williamr@2
    93
to assign more specific 'overriding' security policies.
williamr@2
    94
williamr@2
    95
The following code fragment shows how you do this:
williamr@2
    96
   
williamr@2
    97
@code
williamr@2
    98
TSecurityPolicy defaultPolicy;
williamr@2
    99
RSqlSecurityPolicy securityPolicy;
williamr@2
   100
RSqlDatabase database;
williamr@2
   101
TInt err;
williamr@2
   102
williamr@2
   103
// Create security policies container object using a default security policy.
williamr@2
   104
securityPolicy.Create(defaultPolicy); 
williamr@2
   105
williamr@2
   106
// Set up policy to apply to database schema
williamr@2
   107
// and assign it
williamr@2
   108
TSecurityPolicy schemaPolicy;
williamr@2
   109
...
williamr@2
   110
err = securityPolicy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, schemaPolicy);
williamr@2
   111
williamr@2
   112
// Set up policy to apply to write activity on the database
williamr@2
   113
// and assign it
williamr@2
   114
TSecurityPolicy writePolicy;
williamr@2
   115
...
williamr@2
   116
err = securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, writePolicy);
williamr@2
   117
williamr@2
   118
// Set up policy to apply to write activity to the database table named "Table1"
williamr@2
   119
// and assign it
williamr@2
   120
TSecurityPolicy tablePolicy1;
williamr@2
   121
...
williamr@2
   122
err = securityPolicy.SetPolicy(RSqlSecurityPolicy::ETable, _L("Table1"), RSqlSecurityPolicy::EWritePolicy, tablePolicy1);
williamr@2
   123
williamr@2
   124
// Set up policy to apply to read activity to the database table named "Table2"
williamr@2
   125
TSecurityPolicy tablePolicy2;
williamr@2
   126
err = securityPolicy.SetPolicy(RSqlSecurityPolicy::ETable, _L("Table2"), RSqlSecurityPolicy::EReadPolicy, tablePolicy2);
williamr@2
   127
williamr@2
   128
// Create the database, passing the security policies
williamr@2
   129
err = database.Create(KDatabaseName, securityPolicy);
williamr@2
   130
williamr@2
   131
// We can close the RSqlSecurityPolicy object.
williamr@2
   132
securityPolicy.Close();
williamr@2
   133
@endcode
williamr@2
   134
williamr@2
   135
Note that in this example code fragment, the client has not assigned specific
williamr@2
   136
overriding policies for all possible cases; for example, no overriding policy
williamr@2
   137
has been assigned to control read activity on the database, read activity
williamr@2
   138
on "Table1", nor write activity on "Table2".
williamr@2
   139
For these cases, the default security policy will apply.
williamr@2
   140
williamr@2
   141
A client can also retrieve a database's security policies by calling
williamr@2
   142
RSqlDatabase::GetSecurityPolicy(); this returns a RSqlSecurityPolicy object
williamr@2
   143
containing the security policies. Note that it is the client's responsibility
williamr@2
   144
to close the RSqlSecurityPolicy object when the client no longer needs it. The
williamr@2
   145
following code fragment suggests how you might do this:
williamr@2
   146
williamr@2
   147
@code
williamr@2
   148
RSqlDatabase database;
williamr@2
   149
RSqlSecurityPolicy securityPolicy;
williamr@2
   150
williamr@2
   151
// Retrieve the security policies; on return from the call to 
williamr@2
   152
// GetSecurityPolicy(), the RSqlSecurityPolicy object passed 
williamr@2
   153
// to this function will contain the security policies.
williamr@2
   154
database.GetSecurityPolicy(securityPolicy);
williamr@2
   155
...
williamr@2
   156
// This is the security policy that applies to database schema
williamr@2
   157
TSecurityPolicy schemaPolicy = securityPolicy.DbPolicy(RSqlSecurityPolicy::ESchemaPolicy);
williamr@2
   158
...
williamr@2
   159
// This is the security policy that applies to write activity to the database
williamr@2
   160
// table named "Table1".
williamr@2
   161
TSecurityPolicy writePolicy = securityPolicy.Policy(RSqlSecurityPolicy::ETable, _L("Table1"), RSqlSecurityPolicy::EWritePolicy);
williamr@2
   162
...
williamr@2
   163
// Close the RSqlSecurityPolicy object when no longer needed.
williamr@2
   164
securityPolicy.Close();
williamr@2
   165
@endcode
williamr@2
   166
williamr@2
   167
Note that in the cases where an 'overriding' security policy was not originally assigned,
williamr@2
   168
then the security policy returned will simply be the default security policy.
williamr@2
   169
williamr@2
   170
@see TSecurityPolicy
williamr@2
   171
@see RSqlDatabase
williamr@2
   172
@see RSqlSecurityPolicy::SetDbPolicy()
williamr@2
   173
@see RSqlSecurityPolicy::SetPolicy()
williamr@2
   174
williamr@2
   175
@publishedAll
williamr@2
   176
@released
williamr@2
   177
*/
williamr@2
   178
class RSqlSecurityPolicy
williamr@2
   179
	{
williamr@2
   180
	friend class RSqlDatabase;
williamr@2
   181
	
williamr@2
   182
public:
williamr@2
   183
	/**
williamr@2
   184
	Defines a set of values that represents the database security policy types.
williamr@2
   185
	Each database security policy type refers to a set of capabilities encapsulated in 
williamr@2
   186
	a TSecurityPolicy object. The TSecurityPolicy object defines what capabilities the calling
williamr@2
   187
	application must have in order to perform partiqular database operation.
williamr@2
   188
	@see TSecurityPolicy
williamr@2
   189
	*/
williamr@2
   190
	enum TPolicyType 
williamr@2
   191
		{
williamr@2
   192
		/**
williamr@2
   193
		Schema database security policy. An application with schema database security policy can 
williamr@2
   194
		modify the database schema, write to database, read from database.
williamr@2
   195
		*/
williamr@2
   196
		ESchemaPolicy, 
williamr@2
   197
		/**
williamr@2
   198
		Read database security policy. An application with read database security policy can 
williamr@2
   199
		read from database.
williamr@2
   200
		*/
williamr@2
   201
		EReadPolicy, 
williamr@2
   202
		/**
williamr@2
   203
		Write database security policy. An application with write database security policy can 
williamr@2
   204
		write to database.
williamr@2
   205
		*/
williamr@2
   206
		EWritePolicy
williamr@2
   207
		};
williamr@2
   208
	/**
williamr@2
   209
	Not currently supported.
williamr@2
   210
williamr@2
   211
	Defines a set of values that represents the database objects which can be protected by 
williamr@2
   212
	database security policy types.
williamr@2
   213
	*/
williamr@2
   214
	enum TObjectType 
williamr@2
   215
		{
williamr@2
   216
		ETable
williamr@2
   217
		};
williamr@2
   218
	IMPORT_C RSqlSecurityPolicy();
williamr@2
   219
	IMPORT_C TInt Create(const TSecurityPolicy& aDefaultPolicy);
williamr@2
   220
	IMPORT_C void CreateL(const TSecurityPolicy& aDefaultPolicy);
williamr@2
   221
	IMPORT_C void Close();
williamr@2
   222
	IMPORT_C TInt SetDbPolicy(TPolicyType aPolicyType, const TSecurityPolicy& aPolicy);
williamr@2
   223
	IMPORT_C TInt SetPolicy(TObjectType aObjectType, const TDesC& aObjectName, TPolicyType aPolicyType, const TSecurityPolicy& aPolicy);
williamr@2
   224
	IMPORT_C TSecurityPolicy DefaultPolicy() const;
williamr@2
   225
	IMPORT_C TSecurityPolicy DbPolicy(TPolicyType aPolicyType) const;
williamr@2
   226
	IMPORT_C TSecurityPolicy Policy(TObjectType aObjectType, const TDesC& aObjectName, TPolicyType aPolicyType) const;
williamr@2
   227
	
williamr@2
   228
	IMPORT_C void ExternalizeL(RWriteStream& aStream) const;
williamr@2
   229
	IMPORT_C void InternalizeL(RReadStream& aStream);
williamr@2
   230
		
williamr@2
   231
private:	
williamr@2
   232
	void Set(CSqlSecurityPolicy& aImpl);
williamr@2
   233
	CSqlSecurityPolicy& Impl() const;
williamr@2
   234
					
williamr@2
   235
private:
williamr@2
   236
	CSqlSecurityPolicy* iImpl;
williamr@2
   237
	};
williamr@2
   238
	
williamr@2
   239
/**
williamr@2
   240
A handle to a SQL database.
williamr@2
   241
williamr@2
   242
A RSqlDatabase object is, in effect, a handle to the SQL database. A client can:
williamr@2
   243
- create a SQL database by calling RSqlDatabase::Create().
williamr@2
   244
- open an existing SQL database by calling RSqlDatabase::Open().
williamr@2
   245
- close a SQL database by calling RSqlDatabase::Close().
williamr@2
   246
- copy a SQL database by calling RSqlDatabase::Copy().
williamr@2
   247
- delete a SQL database by calling RSqlDatabase::Delete().
williamr@2
   248
- attach a SQL database to current database connection by calling RSqlDatabase::Attach().
williamr@2
   249
- detach a SQL database from current database connection by calling RSqlDatabase::Detach().
williamr@2
   250
williamr@4
   251
The RSqlDatabase handles are not thread-safe.
williamr@4
   252
williamr@2
   253
A client can create either a non-secure database or a secure database,
williamr@2
   254
depending on the variant of RSqlDatabase::Create() that is used.
williamr@2
   255
- a non-secure database is created if the RSqlDatabase::Create(const TDesC&) variant is used.
williamr@2
   256
- a secure database is created if the RSqlDatabase::Create(const TDesC&, const RSqlSecurityPolicy&)
williamr@2
   257
variant is used. In this case, a container containing a collection of security
williamr@2
   258
policies needs to be set up first and passed to this Create() function.
williamr@2
   259
See references to RSqlSecurityPolicy for more information on security policies.
williamr@2
   260
williamr@2
   261
A client can also specify how it wants a transaction to interact with
williamr@2
   262
other transactions that may be running concurrently. The various ways in which
williamr@2
   263
transactions can interact (i.e. how one transaction can affect another) are
williamr@2
   264
referred to as "transaction isolation levels", and are defined by the values
williamr@2
   265
of the TIsolationLevel enum. A client specifies this by calling RSqlDatabase::SetIsolationLevel().
williamr@2
   266
williamr@2
   267
Each of the various flavours of Open and Create allows the optional provision of a
williamr@2
   268
configuration string. It is acceptable for this string to be missing.
williamr@2
   269
In the case where the string is missing, the config in the SqlServer.sql file
williamr@2
   270
will be used. If that does not exist then the MMH macro definitions will be used.
williamr@2
   271
williamr@2
   272
The config string is in the format PARAM=VALUE; PARAM=VALUE;...
williamr@2
   273
williamr@2
   274
Allowed parameters are:
williamr@2
   275
	cache_size=nnnn
williamr@2
   276
	page_size=nnnn
williamr@2
   277
	encoding=UTF8|UTF16
williamr@2
   278
williamr@2
   279
Badly formed config strings are reported as KErrArgument
williamr@2
   280
williamr@2
   281
The string may not exceed 255 characters.
williamr@2
   282
williamr@2
   283
Please note that a database can only be accessed within the thread where it has been created. It is then not possible
williamr@2
   284
to create a database from thread1 and access it from thread2.
williamr@2
   285
williamr@2
   286
A client calls RSqlDatabase::Exec() to execute SQL statements.
williamr@2
   287
@see RSqlDatabase::Create()
williamr@2
   288
@see RSqlDatabase::Open()
williamr@2
   289
@see RSqlDatabase::Close()
williamr@2
   290
@see RSqlDatabase::Copy()
williamr@2
   291
@see RSqlDatabase::Delete()
williamr@2
   292
@see RSqlDatabase::Attach()
williamr@2
   293
@see RSqlDatabase::Detach()
williamr@2
   294
@see RSqlDatabase::SetIsolationLevel()
williamr@2
   295
@see RSqlDatabase::Exec()
williamr@2
   296
@see TIsolationLevel
williamr@2
   297
@see RSqlSecurityPolicy
williamr@2
   298
williamr@2
   299
@publishedAll
williamr@2
   300
@released
williamr@2
   301
*/
williamr@2
   302
class RSqlDatabase
williamr@2
   303
	{
williamr@2
   304
	friend class RSqlStatement;
williamr@2
   305
	friend class TSqlScalarFullSelectQuery;
williamr@4
   306
	friend class RSqlBlob;
williamr@4
   307
	friend class RSqlBlobReadStream;
williamr@4
   308
	friend class RSqlBlobWriteStream;
williamr@4
   309
	friend class TSqlResourceProfiler;
williamr@2
   310
	
williamr@2
   311
public:
williamr@2
   312
	/**
williamr@2
   313
	Defines a set of values that represents the transaction isolation level.
williamr@2
   314
	
williamr@2
   315
	A transaction isolation level defines the way in which a transaction
williamr@2
   316
	interacts with other transactions that may be in progress concurrently.
williamr@2
   317
	
williamr@2
   318
	A client sets the transaction isolation level by calling SetIsolationLevel()
williamr@2
   319
	
williamr@2
   320
	@see RSqlDatabase::SetIsolationLevel()
williamr@2
   321
	*/
williamr@2
   322
	enum TIsolationLevel 
williamr@2
   323
		{
williamr@2
   324
		/**
williamr@2
   325
		A transaction can read uncommitted data, i.e. data that is being changed
williamr@2
   326
		by another transaction, which is still in progress.
williamr@2
   327
		
williamr@2
   328
		This means that
williamr@2
   329
		- a 'database read' transaction will not block 'database write' transactions
williamr@2
   330
		being performed by different database connections on the same shared database.
williamr@2
   331
		- a 'database read' transaction will not be blocked by 'database write'
williamr@2
   332
		transactions performed by the same database connection.
williamr@2
   333
		- concurrent 'database write' transactions are prevented.
williamr@2
   334
		
williamr@2
   335
		This transaction isolation level can be set at any time during
williamr@2
   336
		the lifetime of the database.
williamr@2
   337
		
williamr@2
   338
		@see TIsolationLevel
williamr@2
   339
		@see RSqlDatabase::SetIsolationLevel()
williamr@2
   340
		*/
williamr@2
   341
		EReadUncommitted, 
williamr@2
   342
williamr@2
   343
		/**
williamr@2
   344
		Not currently supported.
williamr@2
   345
		
williamr@2
   346
		A transaction cannot read uncommitted data. "Dirty reads" are prevented.
williamr@2
   347
		
williamr@2
   348
		"Dirty read" is a data inconsistency type which can be described with the following example:
williamr@2
   349
		- Transaction A updates TableA.Column1 value from 1 to 2;
williamr@2
   350
		- Transaction B reads TableA.Column1 value;
williamr@2
   351
		- Transaction A rolls back and restores the original value of TableA.Column1 (1);
williamr@2
   352
		- Transaction B ends showing that TableA.Column1 value is 2, even though, logically and transactionally, 
williamr@2
   353
		  this data never really even existed in the database because Transaction A never committed that change 
williamr@2
   354
		  to the database;
williamr@2
   355
		
williamr@2
   356
		@see TIsolationLevel
williamr@2
   357
		@see RSqlDatabase::SetIsolationLevel()
williamr@2
   358
		*/
williamr@2
   359
		EReadCommitted, 
williamr@2
   360
		
williamr@2
   361
		/**
williamr@2
   362
		Not currently supported.
williamr@2
   363
		
williamr@2
   364
		A transaction cannot change data that is being read by a different transaction. 
williamr@2
   365
		"Dirty reads" and "non-repeatable reads" are prevented.
williamr@2
   366
williamr@2
   367
		"Non-repeatable reads" is a data inconsistency type which can be described with the following example:
williamr@2
   368
		- Transaction A reads TableA.Column1 value which is 1;
williamr@2
   369
		- Transaction B updates TableA.Column1 value from 1 to 2;
williamr@2
   370
		- Transaction B commits the chages;
williamr@2
   371
		- Transaction A reads TableA.Column1 value again. Transaction A has inconsistent data because TableA.Column1 
williamr@2
   372
		  value now is 2 instead of 1, all within the scope of the same Transaction A;
williamr@2
   373
		
williamr@2
   374
		@see TIsolationLevel
williamr@2
   375
		@see RSqlDatabase::SetIsolationLevel()
williamr@2
   376
		*/
williamr@2
   377
		ERepeatableRead, 
williamr@2
   378
		
williamr@2
   379
		/**
williamr@2
   380
		Any number of 'database read' transactions can be performed concurrently
williamr@2
   381
		by different database connections on the same shared database.
williamr@2
   382
		
williamr@2
   383
		Only one 'database write' transaction can be performed at any one time. If a
williamr@2
   384
		'database write' transaction is in progress, then any attempt to start
williamr@2
   385
		another 'database read' or 'database write' transaction will be blocked
williamr@2
   386
		until the first 'database write' transaction has completed.
williamr@2
   387
		
williamr@2
   388
		This is the default isolation level, if no isolation level is
williamr@2
   389
		explicitly set.
williamr@2
   390
		
williamr@2
   391
		"Dirty reads", "non-repeatable" reads and "phantom reads" are prevented.
williamr@2
   392
		
williamr@2
   393
		"Phantom reads" is a data inconsistency type which can be described with the following example:
williamr@2
   394
		- Transaction A reads all rows that have Column1 = 1;
williamr@2
   395
		- Transaction B inserts a new row which has Column1 = 1;
williamr@2
   396
		- Transaction B commits;
williamr@2
   397
		- Transaction A updates all rows that have Column1 = 1. This will also update the row that 
williamr@2
   398
		  Transaction B inserted, because Transaction A must read the data again in order to update it.
williamr@2
   399
		- Transaction A commits;
williamr@2
   400
		
williamr@2
   401
		@see TIsolationLevel
williamr@2
   402
		@see RSqlDatabase::SetIsolationLevel()
williamr@2
   403
		*/
williamr@2
   404
		ESerializable
williamr@2
   405
		};
williamr@4
   406
	/**
williamr@4
   407
	This structure is used for retrieving the database size and database free space.
williamr@4
   408
	@see RSqlDatabase::Size(TSize&)
williamr@4
   409
	*/
williamr@4
   410
	struct TSize
williamr@4
   411
		{
williamr@4
   412
		/** The database size in bytes*/
williamr@4
   413
		TInt64	iSize;
williamr@4
   414
		/** The database free space in bytes*/
williamr@4
   415
		TInt64	iFree;
williamr@4
   416
		};
williamr@4
   417
williamr@4
   418
	/** If this value is used as an argument of RSqlDatabase::Compact() (aSize argument), then all free space will be removed */
williamr@4
   419
	enum {EMaxCompaction = -1};
williamr@2
   420
		
williamr@2
   421
	IMPORT_C RSqlDatabase();
williamr@2
   422
	
williamr@2
   423
	IMPORT_C TInt Create(const TDesC& aDbFileName, const TDesC8* aConfig=NULL);
williamr@2
   424
	IMPORT_C TInt Create(const TDesC& aDbFileName,
williamr@2
   425
			const RSqlSecurityPolicy& aSecurityPolicy, const TDesC8* aConfig=NULL);
williamr@2
   426
	IMPORT_C TInt Open(const TDesC& aDbFileName, const TDesC8* aConfig=NULL);
williamr@2
   427
	IMPORT_C void CreateL(const TDesC& aDbFileName, const TDesC8* aConfig=NULL);
williamr@2
   428
	IMPORT_C void CreateL(const TDesC& aDbFileName,
williamr@2
   429
			const RSqlSecurityPolicy& aSecurityPolicy, const TDesC8* aConfig=NULL);
williamr@2
   430
	IMPORT_C void OpenL(const TDesC& aDbFileName, const TDesC8* aConfig=NULL);
williamr@2
   431
	
williamr@2
   432
	IMPORT_C void Close();
williamr@2
   433
	
williamr@2
   434
	IMPORT_C TInt Attach(const TDesC& aDbFileName, const TDesC& aDbName);
williamr@2
   435
	IMPORT_C TInt Detach(const TDesC& aDbName);
williamr@2
   436
	
williamr@2
   437
	IMPORT_C static TInt Copy(const TDesC& aSrcDbFileName, const TDesC& aDestDbFileName);
williamr@2
   438
	IMPORT_C static TInt Delete(const TDesC& aDbFileName);
williamr@2
   439
	
williamr@2
   440
	IMPORT_C TInt GetSecurityPolicy(RSqlSecurityPolicy& aSecurityPolicy) const;
williamr@2
   441
	IMPORT_C void GetSecurityPolicyL(RSqlSecurityPolicy& aSecurityPolicy) const;
williamr@2
   442
	
williamr@2
   443
	IMPORT_C TInt SetIsolationLevel(TIsolationLevel aIsolationLevel);
williamr@2
   444
	
williamr@2
   445
	IMPORT_C TInt Exec(const TDesC& aSqlStmt);
williamr@2
   446
	IMPORT_C TInt Exec(const TDesC8& aSqlStmt);
williamr@2
   447
	
williamr@2
   448
	IMPORT_C void Exec(const TDesC& aSqlStmt, TRequestStatus& aStatus);
williamr@2
   449
	IMPORT_C void Exec(const TDesC8& aSqlStmt, TRequestStatus& aStatus);
williamr@2
   450
	
williamr@2
   451
	IMPORT_C TPtrC LastErrorMessage() const;
williamr@4
   452
	IMPORT_C TInt64 LastInsertedRowId() const; 
williamr@2
   453
	
williamr@2
   454
	IMPORT_C TBool InTransaction() const;
williamr@2
   455
	IMPORT_C TInt Size() const;
williamr@4
   456
	IMPORT_C TInt Size(TSize& aSize, const TDesC& aDbName = KNullDesC) const;
williamr@4
   457
williamr@4
   458
	IMPORT_C TInt Compact(TInt64 aSize, const TDesC& aDbName = KNullDesC);
williamr@4
   459
	IMPORT_C void Compact(TInt64 aSize, TRequestStatus& aStatus, const TDesC& aDbName = KNullDesC);
williamr@2
   460
	
williamr@2
   461
	IMPORT_C TInt ReserveDriveSpace(TInt aSize);
williamr@2
   462
	IMPORT_C void FreeReservedSpace();
williamr@2
   463
	IMPORT_C TInt GetReserveAccess();
williamr@2
   464
	IMPORT_C void ReleaseReserveAccess();
williamr@2
   465
	
williamr@2
   466
private:
williamr@2
   467
	CSqlDatabaseImpl& Impl() const;
williamr@2
   468
williamr@2
   469
private:
williamr@2
   470
	CSqlDatabaseImpl* iImpl;
williamr@2
   471
	};
williamr@2
   472
williamr@2
   473
/**
williamr@2
   474
TSqlScalarFullSelectQuery interface is used for executing SELECT sql queries, which 
williamr@2
   475
return a single row consisting of a single column value.
williamr@2
   476
williamr@2
   477
Examples.
williamr@2
   478
williamr@2
   479
CASE 1 - retrieving records count of a table:
williamr@2
   480
@code
williamr@2
   481
RSqlDatabase db;
williamr@2
   482
//initialize db object....
williamr@2
   483
.......
williamr@2
   484
TSqlScalarFullSelectQuery fullSelectQuery(db);
williamr@2
   485
TInt recCnt = fullSelectQuery.SelectIntL(_L("SELECT COUNT(*) FROM PersonTbl"));
williamr@2
   486
@endcode
williamr@2
   487
williamr@2
   488
CASE 2 - retrieving specific column value using a condition in the SELECT statement:
williamr@2
   489
@code
williamr@2
   490
RSqlDatabase db;
williamr@2
   491
//initialize db object....
williamr@2
   492
.......
williamr@2
   493
TSqlScalarFullSelectQuery fullSelectQuery(db);
williamr@2
   494
TInt personId = fullSelectQuery.SelectIntL(_L("SELECT ID FROM PersonTbl WHERE Name = 'John'"));
williamr@2
   495
@endcode
williamr@2
   496
williamr@2
   497
CASE 3 - retrieving a text column value, the receiving buffer is not big enough:
williamr@2
   498
@code
williamr@2
   499
RSqlDatabase db;
williamr@2
   500
//initialize db object....
williamr@2
   501
.......
williamr@2
   502
TSqlScalarFullSelectQuery fullSelectQuery(db);
williamr@2
   503
HBufC* buf = HBufC::NewLC(20);
williamr@2
   504
TPtr name = buf->Des();
williamr@2
   505
TInt rc = fullSelectQuery.SelectTextL(_L("SELECT Name FROM PersonTbl WHERE Id = 1"), name);
williamr@2
   506
TEST(rc >= 0); //the function may return only non-negative values
williamr@2
   507
if(rc > 0)
williamr@2
   508
	{
williamr@2
   509
	buf = buf->ReAllocL(rc);
williamr@2
   510
	CleanupStack::Pop();	
williamr@2
   511
	CleanupStack::PushL(buf);
williamr@2
   512
	name.Set(buf->Des());
williamr@2
   513
	rc = fullSelectQuery.SelectTextL(_L("SELECT Name FROM PersonTbl WHERE Id = 1"), name);
williamr@2
   514
	TEST(rc == 0);
williamr@2
   515
	}
williamr@2
   516
CleanupStack::PopAndDestroy();//buf
williamr@2
   517
@endcode
williamr@2
   518
williamr@2
   519
@see RSqlDatabase
williamr@2
   520
williamr@2
   521
@publishedAll
williamr@2
   522
@released
williamr@2
   523
*/
williamr@2
   524
class TSqlScalarFullSelectQuery
williamr@2
   525
	{
williamr@2
   526
public:
williamr@2
   527
	IMPORT_C TSqlScalarFullSelectQuery();
williamr@2
   528
	IMPORT_C TSqlScalarFullSelectQuery(RSqlDatabase& aDatabase);
williamr@2
   529
	IMPORT_C void SetDatabase(RSqlDatabase& aDatabase);
williamr@2
   530
williamr@2
   531
	IMPORT_C TInt SelectIntL(const TDesC& aSqlStmt);
williamr@2
   532
	IMPORT_C TInt64 SelectInt64L(const TDesC& aSqlStmt);
williamr@2
   533
	IMPORT_C TReal SelectRealL(const TDesC& aSqlStmt);
williamr@2
   534
	IMPORT_C TInt SelectTextL(const TDesC& aSqlStmt, TDes& aDest);
williamr@2
   535
	IMPORT_C TInt SelectBinaryL(const TDesC& aSqlStmt, TDes8& aDest);
williamr@2
   536
williamr@2
   537
	IMPORT_C TInt SelectIntL(const TDesC8& aSqlStmt);
williamr@2
   538
	IMPORT_C TInt64 SelectInt64L(const TDesC8& aSqlStmt);
williamr@2
   539
	IMPORT_C TReal SelectRealL(const TDesC8& aSqlStmt);
williamr@2
   540
	IMPORT_C TInt SelectTextL(const TDesC8& aSqlStmt, TDes& aDest);
williamr@2
   541
	IMPORT_C TInt SelectBinaryL(const TDesC8& aSqlStmt, TDes8& aDest);
williamr@2
   542
	
williamr@2
   543
private:
williamr@2
   544
	inline CSqlDatabaseImpl& Impl() const;
williamr@2
   545
	
williamr@2
   546
private:	
williamr@2
   547
	CSqlDatabaseImpl* iDatabaseImpl;
williamr@2
   548
	};
williamr@2
   549
williamr@2
   550
/**
williamr@2
   551
An enumeration whose values represent the supported database column types.
williamr@2
   552
williamr@2
   553
williamr@2
   554
@see RSqlStatement::ColumnType()
williamr@2
   555
williamr@2
   556
@publishedAll
williamr@2
   557
@released
williamr@2
   558
*/
williamr@2
   559
enum TSqlColumnType 
williamr@2
   560
	{
williamr@2
   561
	/**
williamr@2
   562
	Null column value.
williamr@2
   563
	*/
williamr@2
   564
	ESqlNull,
williamr@2
   565
	
williamr@2
   566
 	/**
williamr@2
   567
 	32-bit integer column value.
williamr@2
   568
 	*/  
williamr@2
   569
	ESqlInt, 
williamr@2
   570
	
williamr@2
   571
 	/**
williamr@2
   572
 	64-bit integer column value.
williamr@2
   573
 	*/
williamr@2
   574
	ESqlInt64, 
williamr@2
   575
	
williamr@2
   576
	/**
williamr@2
   577
	64-bit floating point column value.
williamr@2
   578
	*/
williamr@2
   579
	ESqlReal, 
williamr@2
   580
	
williamr@2
   581
	/**
williamr@2
   582
	Unicode text, a sequence of 16-bit character codes.
williamr@2
   583
	*/
williamr@2
   584
	ESqlText, 
williamr@2
   585
	
williamr@2
   586
	/**
williamr@2
   587
	Binary data, a sequence of bytes.
williamr@2
   588
	*/
williamr@4
   589
	ESqlBinary
williamr@2
   590
	};
williamr@2
   591
williamr@2
   592
/**
williamr@2
   593
Represents an SQL statement.
williamr@2
   594
williamr@2
   595
An object of this type can be used to execute all types of SQL statements; this
williamr@2
   596
includes SQL statements with parameters.
williamr@2
   597
williamr@2
   598
If a SELECT statament is passed to RSqlStatement::Prepare(), then the returned record set 
williamr@2
   599
is forward only, non-updateable.
williamr@2
   600
williamr@2
   601
There are a number of ways that this object is used; here are some examples.
williamr@2
   602
williamr@2
   603
CASE 1 - the execution of a SQL statement, which does not return record set:
williamr@2
   604
williamr@2
   605
@code
williamr@2
   606
RSqlDatabase database;
williamr@2
   607
.........
williamr@2
   608
RSqlStatement stmt;
williamr@2
   609
TInt err = stmt.Prepare(database, _L("INSERT INTO Tbl1(Fld1) VALUES(:Val)"));
williamr@2
   610
TInt paramIndex = stmt.ParameterIndex(_L(":Val"));
williamr@2
   611
for(TInt i=1;i<=10;++i)
williamr@2
   612
	{
williamr@2
   613
	err = stmt.BindInt(paramIndex, i);
williamr@2
   614
	err = stmt.Exec();
williamr@2
   615
	err = stmt.Reset();
williamr@2
   616
	}
williamr@2
   617
stmt.Close();
williamr@2
   618
@endcode
williamr@2
   619
williamr@2
   620
The following pseudo code shows the general pattern:
williamr@2
   621
williamr@2
   622
@code
williamr@2
   623
<RSqlStatement::Prepare()>
williamr@2
   624
[begin:]
williamr@2
   625
<RSqlStatement::Bind<param_type>()>
williamr@2
   626
<RSqlStatement::Exec()>
williamr@2
   627
[<RSqlStatement::Reset()>]
williamr@2
   628
[<RSqlStatement::Bind<param_type>()>]
williamr@2
   629
[<Goto :begin>]
williamr@2
   630
@endcode
williamr@2
   631
williamr@2
   632
CASE 2 - the execution of a SQL statement, which returns a record set:
williamr@2
   633
williamr@2
   634
@code
williamr@2
   635
RSqlDatabase database;
williamr@2
   636
.........
williamr@2
   637
RSqlStatement stmt;
williamr@2
   638
TInt err = stmt.Prepare(database, _L("SELECT Fld1 FROM Tbl1 WHERE Fld1 > :Val"));
williamr@2
   639
TInt paramIndex = stmt.ParameterIndex(_L(":Val"));
williamr@2
   640
err = stmt.BindInt(paramIndex, 5);
williamr@2
   641
TInt columnIndex = stmt.ColumnIndex(_L("Fld1"));
williamr@2
   642
while((err = stmt.Next()) == KSqlAtRow)
williamr@2
   643
	{
williamr@2
   644
	TInt val = stmt.ColumnInt(columnIndex);
williamr@2
   645
	RDebug::Print(_L("val=%d\n"), val);
williamr@2
   646
	}
williamr@2
   647
if(err == KSqlAtEnd)
williamr@2
   648
	<OK - no more records>;
williamr@2
   649
else
williamr@2
   650
	<process the error>;
williamr@2
   651
stmt.Close();
williamr@2
   652
@endcode
williamr@2
   653
williamr@2
   654
The following pseudo code shows the general pattern:
williamr@2
   655
williamr@2
   656
@code
williamr@2
   657
<RSqlStatement::Prepare()>
williamr@2
   658
[begin:]
williamr@2
   659
<while (RSqlStatement::Next() == KSqlAtRow)>
williamr@2
   660
	<do something with the records>
williamr@2
   661
if(err == KSqlAtEnd)
williamr@2
   662
	<OK - no more records>;
williamr@2
   663
else
williamr@2
   664
	<process the error>;
williamr@2
   665
[<RSqlStatement::Reset()>]
williamr@2
   666
[<RSqlStatement::Bind<param_type>()>]
williamr@2
   667
[<Goto begin>]
williamr@2
   668
@endcode
williamr@2
   669
williamr@2
   670
CASE 3.1 - SELECT statements: large column data processing, where the data is
williamr@2
   671
copied into a buffer supplied by the client:
williamr@2
   672
williamr@2
   673
@code
williamr@2
   674
RSqlDatabase database;
williamr@2
   675
.........
williamr@2
   676
RSqlStatement stmt;
williamr@2
   677
TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1"));
williamr@2
   678
TInt columnIndex = stmt.ColumnIndex(_L("BinaryField"));
williamr@2
   679
while((err = stmt.Next()) == KSqlAtRow)
williamr@2
   680
	{
williamr@2
   681
	TInt size = stmt. ColumnSize(columnIndex);
williamr@2
   682
	HBufC8* buf = HBufC8::NewL(size);
williamr@2
   683
	err = stmt.ColumnBinary(columnIndex, buf->Ptr());
williamr@2
   684
	<do something with the data>;
williamr@2
   685
	delete buf;
williamr@2
   686
	}
williamr@2
   687
if(err == KSqlAtEnd)
williamr@2
   688
	<OK - no more records>;
williamr@2
   689
else
williamr@2
   690
	<process the error>;
williamr@2
   691
stmt.Close();
williamr@2
   692
@endcode
williamr@2
   693
williamr@2
   694
CASE 3.2 - SELECT statements: large column data processing, where the data is
williamr@2
   695
accessed by the client without copying:
williamr@2
   696
williamr@2
   697
@code
williamr@2
   698
RSqlDatabase database;
williamr@2
   699
.........
williamr@2
   700
RSqlStatement stmt;
williamr@2
   701
TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1"));
williamr@2
   702
TInt columnIndex = stmt.ColumnIndex(_L("BinaryField"));
williamr@2
   703
while((err = stmt.Next()) == KSqlAtRow)
williamr@2
   704
	{
williamr@2
   705
	TPtrC8 data = stmt.ColumnBinaryL(columnIndex);
williamr@2
   706
	<do something with the data>;
williamr@2
   707
	}
williamr@2
   708
if(err == KSqlAtEnd)
williamr@2
   709
	<OK - no more records>;
williamr@2
   710
else
williamr@2
   711
	<process the error>;
williamr@2
   712
stmt.Close();
williamr@2
   713
@endcode
williamr@2
   714
williamr@2
   715
CASE 3.3 - SELECT statements, large column data processing (the data is accessed by 
williamr@2
   716
the client without copying), leaving-safe processing:
williamr@2
   717
williamr@2
   718
@code
williamr@2
   719
RSqlDatabase database;
williamr@2
   720
.........
williamr@2
   721
RSqlStatement stmt;
williamr@2
   722
TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1"));
williamr@2
   723
TInt columnIndex = stmt.ColumnIndex(_L("BinaryField"));
williamr@2
   724
while((err = stmt.Next()) == KSqlAtRow)
williamr@2
   725
	{
williamr@2
   726
	TPtrC8 data;
williamr@2
   727
	TInt err = stmt.ColumnBinary(columnIndex, data);
williamr@2
   728
	if(err == KErrNone)
williamr@2
   729
		{
williamr@2
   730
		<do something with the data>;
williamr@2
   731
		}
williamr@2
   732
	}
williamr@2
   733
if(err == KSqlAtEnd)
williamr@2
   734
	<OK - no more records>;
williamr@2
   735
else
williamr@2
   736
	<process the error>;
williamr@2
   737
stmt.Close();
williamr@2
   738
@endcode
williamr@2
   739
williamr@2
   740
CASE 3.4 - SELECT statements: large column data processing, where the data is
williamr@2
   741
accessed by the client using a stream:
williamr@2
   742
williamr@2
   743
@code
williamr@2
   744
RSqlDatabase database;
williamr@2
   745
.........
williamr@2
   746
RSqlStatement stmt;
williamr@2
   747
TInt err = stmt.Prepare(database, _L("SELECT BinaryField FROM Tbl1"));
williamr@2
   748
TInt columnIndex = stmt.ColumnIndex(_L("BinaryField"));
williamr@2
   749
while((err = stmt.Next()) == KSqlAtRow)
williamr@2
   750
	{
williamr@2
   751
	RSqlColumnReadStream stream;
williamr@2
   752
	err = stream.ColumnBinary(stmt, columnIndex);
williamr@2
   753
	<do something with the data in the stream>;
williamr@2
   754
	stream.Close();
williamr@2
   755
	}
williamr@2
   756
if(err == KSqlAtEnd)
williamr@2
   757
	<OK - no more records>;
williamr@2
   758
else
williamr@2
   759
	<process the error>;
williamr@2
   760
stmt.Close();
williamr@2
   761
@endcode
williamr@2
   762
williamr@2
   763
CASE 4 - the execution of a SQL statement with parameter(s), some of which may
williamr@2
   764
be large text or binary values:
williamr@2
   765
williamr@2
   766
@code
williamr@2
   767
RSqlDatabase database;
williamr@2
   768
.........
williamr@2
   769
RSqlStatement stmt;
williamr@2
   770
TInt err = 
williamr@2
   771
	stmt.Prepare(database, _L("UPDATE Tbl1 SET LargeTextField = :LargeTextVal WHERE IdxField = :KeyVal"));
williamr@2
   772
TInt paramIndex1 = stmt.ParameterIndex(_L(":LargeTextVal"));
williamr@2
   773
TInt paramIndex2 = stmt.ParameterIndex(_L(":KeyVal"));
williamr@2
   774
for(TInt i=1;i<=10;++i)
williamr@2
   775
	{
williamr@2
   776
	RSqlParamWriteStream stream;
williamr@2
   777
	err = stream.BindText(stmt, paramIndex1);
williamr@2
   778
	<insert large text data into the stream>;
williamr@2
   779
	stream.Close();
williamr@2
   780
	err = stmt.BindInt(paramIndex2, i);
williamr@2
   781
	err = stmt.Exec();
williamr@2
   782
	stmt.Reset();
williamr@2
   783
	}
williamr@2
   784
stmt.Close();
williamr@2
   785
@endcode
williamr@2
   786
williamr@2
   787
The following table shows what is returned when the caller uses a specific
williamr@2
   788
column data retrieving function on a specific column type.
williamr@2
   789
williamr@2
   790
@code
williamr@2
   791
--------------------------------------------------------------------------------
williamr@2
   792
Column type | ColumnInt() ColumnInt64() ColumnReal() ColumnText() ColumnBinary()
williamr@2
   793
--------------------------------------------------------------------------------
williamr@2
   794
Null........|.0...........0.............0.0..........KNullDesC....KNullDesC8
williamr@2
   795
Int.........|.Int.........Int64.........Real.........KNullDesC....KNullDesC8 
williamr@2
   796
Int64.......|.clamp.......Int64.........Real.........KNullDesC....KNullDesC8 
williamr@2
   797
Real........|.round.......round.........Real.........KNullDesC....KNullDesC8 
williamr@2
   798
Text........|.0...........0.............0.0..........Text.........KNullDesC8   
williamr@2
   799
Binary......|.0...........0.............0.0..........KNullDesC....Binary
williamr@2
   800
--------------------------------------------------------------------------------
williamr@2
   801
@endcode
williamr@2
   802
Note the following definitions:
williamr@2
   803
- "clamp": return KMinTInt or KMaxTInt if the value is outside the range that can be 
williamr@2
   804
represented by the type returned by the accessor function.
williamr@2
   805
- "round": the floating point value will be rounded up to the nearest integer.
williamr@2
   806
If the result is outside the range that can be represented by the type returned
williamr@2
   807
by the accessor function, then it will be clamped.
williamr@2
   808
williamr@4
   809
Note that when handling blob and text data over 2Mb in size it is recommended that the 
williamr@4
   810
RSqlBlobReadStream and RSqlBlobWriteStream classes or the TSqlBlob class is used instead. 
williamr@4
   811
These classes provide a more RAM-efficient way of reading and writing large amounts of 
williamr@4
   812
blob or text data from a database.
williamr@4
   813
williamr@2
   814
@see KMinTInt
williamr@2
   815
@see KMaxTInt
williamr@2
   816
@see KNullDesC
williamr@2
   817
@see KNullDesC8
williamr@4
   818
@see RSqlBlobReadStream
williamr@4
   819
@see RSqlBlobWriteStream
williamr@4
   820
@see TSqlBlob
williamr@2
   821
williamr@2
   822
@publishedAll
williamr@2
   823
@released
williamr@2
   824
*/
williamr@2
   825
class RSqlStatement
williamr@2
   826
	{
williamr@2
   827
	friend class RSqlColumnReadStream;
williamr@2
   828
	friend class RSqlParamWriteStream;
williamr@2
   829
williamr@2
   830
public:
williamr@2
   831
	IMPORT_C RSqlStatement();
williamr@2
   832
	IMPORT_C TInt Prepare(RSqlDatabase& aDatabase, const TDesC& aSqlStmt);
williamr@2
   833
	IMPORT_C TInt Prepare(RSqlDatabase& aDatabase, const TDesC8& aSqlStmt);
williamr@2
   834
	IMPORT_C void PrepareL(RSqlDatabase& aDatabase, const TDesC& aSqlStmt);
williamr@2
   835
	IMPORT_C void PrepareL(RSqlDatabase& aDatabase, const TDesC8& aSqlStmt);
williamr@2
   836
	IMPORT_C void Close();
williamr@2
   837
	IMPORT_C TBool AtRow() const;
williamr@2
   838
	IMPORT_C TInt Reset();
williamr@2
   839
	IMPORT_C TInt Exec();
williamr@2
   840
	IMPORT_C void Exec(TRequestStatus& aStatus);
williamr@2
   841
	IMPORT_C TInt Next();
williamr@2
   842
	
williamr@2
   843
	IMPORT_C TInt ParameterIndex(const TDesC& aParameterName) const;
williamr@2
   844
	IMPORT_C TInt ColumnCount() const;
williamr@2
   845
	IMPORT_C TInt ColumnIndex(const TDesC& aColumnName) const;
williamr@2
   846
	IMPORT_C TSqlColumnType ColumnType(TInt aColumnIndex) const;
williamr@2
   847
	IMPORT_C TInt DeclaredColumnType(TInt aColumnIndex, TSqlColumnType& aColumnType) const;
williamr@2
   848
	IMPORT_C TInt ColumnSize(TInt aColumnIndex) const;
williamr@2
   849
	
williamr@2
   850
	IMPORT_C TInt BindNull(TInt aParameterIndex);
williamr@2
   851
	IMPORT_C TInt BindInt(TInt aParameterIndex, TInt aParameterValue);
williamr@2
   852
	IMPORT_C TInt BindInt64(TInt aParameterIndex, TInt64 aParameterValue);
williamr@2
   853
	IMPORT_C TInt BindReal(TInt aParameterIndex, TReal aParameterValue);
williamr@2
   854
	IMPORT_C TInt BindText(TInt aParameterIndex, const TDesC& aParameterText);
williamr@2
   855
	IMPORT_C TInt BindBinary(TInt aParameterIndex, const TDesC8& aParameterData);
williamr@4
   856
	IMPORT_C TInt BindZeroBlob(TInt aParameterIndex, TInt aBlobSize);
williamr@2
   857
	
williamr@2
   858
	IMPORT_C TBool IsNull(TInt aColumnIndex) const;
williamr@2
   859
	IMPORT_C TInt ColumnInt(TInt aColumnIndex) const;
williamr@2
   860
	IMPORT_C TInt64 ColumnInt64(TInt aColumnIndex) const;
williamr@2
   861
	IMPORT_C TReal ColumnReal(TInt aColumnIndex) const;
williamr@2
   862
	
williamr@2
   863
	IMPORT_C TPtrC ColumnTextL(TInt aColumnIndex) const;
williamr@2
   864
	IMPORT_C TInt ColumnText(TInt aColumnIndex, TPtrC& aPtr) const;
williamr@2
   865
	IMPORT_C TInt ColumnText(TInt aColumnIndex, TDes& aDest) const;
williamr@2
   866
	
williamr@2
   867
	IMPORT_C TPtrC8 ColumnBinaryL(TInt aColumnIndex) const;
williamr@2
   868
	IMPORT_C TInt ColumnBinary(TInt aColumnIndex, TPtrC8& aPtr) const;
williamr@2
   869
	IMPORT_C TInt ColumnBinary(TInt aColumnIndex, TDes8& aDest) const;
williamr@2
   870
	
williamr@4
   871
	IMPORT_C TInt ColumnName(TInt aColumnIndex, TPtrC& aNameDest);
williamr@4
   872
	IMPORT_C TInt ParameterName(TInt aParameterIndex, TPtrC& aNameDest);
williamr@4
   873
	IMPORT_C TInt ParamName(TInt aParameterIndex, TPtrC& aNameDest);
williamr@2
   874
private:
williamr@2
   875
	CSqlStatementImpl& Impl() const;
williamr@2
   876
	
williamr@2
   877
private:
williamr@2
   878
	CSqlStatementImpl* 	iImpl;
williamr@2
   879
	
williamr@2
   880
	};
williamr@2
   881
williamr@2
   882
/**
williamr@2
   883
The read stream interface.
williamr@2
   884
williamr@4
   885
The class is used for reading the content of a column containing either 
williamr@4
   886
binary data or text data.
williamr@2
   887
williamr@2
   888
The class derives from RReadStream, which means that all RReadStream public
williamr@2
   889
member functions and predefined stream operators \>\> can be used to deal
williamr@2
   890
with column data.
williamr@2
   891
williamr@4
   892
If the blob or text data is over 2Mb in size then it is recommended that the 
williamr@4
   893
RSqlBlobReadStream or TSqlBlob class is used instead. These classes provide 
williamr@4
   894
a more RAM-efficient way of reading large amounts of blob or text data from
williamr@4
   895
a database.
williamr@4
   896
williamr@2
   897
The following two cases are typical:
williamr@2
   898
williamr@2
   899
CASE 1 - processing large binary column data.
williamr@2
   900
williamr@2
   901
@code
williamr@2
   902
RSqlDatabase db;
williamr@2
   903
<open/create "db" object>;
williamr@2
   904
RSqlStatement stmt;
williamr@2
   905
<prepare "stmt" object>;
williamr@2
   906
TInt rc = stmt.Next();
williamr@2
   907
if(rc == KSqlAtRow)
williamr@2
   908
	{
williamr@2
   909
	RSqlColumnReadStream colStream;
williamr@2
   910
	CleanupClosePushL(colStream);
williamr@2
   911
	User::LeaveIfError(colStream.ColumnBinary(stmt, <column_number>));
williamr@2
   912
	TInt size = stmt.ColumnSize(<column_number>);
williamr@2
   913
	//read the column data in a buffer ("buf" variable).
williamr@2
   914
	//(or the column data can be retrieved in a smaller portions)
williamr@2
   915
	colStream.ReadL(buf, size);
williamr@2
   916
	//Close the stream
williamr@2
   917
	CleanupStack::PopAndDestroy(&colStream);
williamr@2
   918
	}
williamr@2
   919
else
williamr@2
   920
	{
williamr@2
   921
	...
williamr@2
   922
	}
williamr@2
   923
@endcode
williamr@2
   924
williamr@2
   925
CASE 2 - processing large text column data.
williamr@2
   926
williamr@2
   927
@code
williamr@2
   928
RSqlDatabase db;
williamr@2
   929
<open/create "db" object>;
williamr@2
   930
RSqlStatement stmt;
williamr@2
   931
<prepare "stmt" object>;
williamr@2
   932
TInt rc = stmt.Next();
williamr@2
   933
if(rc == KSqlAtRow)
williamr@2
   934
	{
williamr@2
   935
	RSqlColumnReadStream colStream;
williamr@2
   936
	CleanupClosePushL(colStream);
williamr@2
   937
	User::LeaveIfError(colStream.ColumnText(stmt, <column_number>));
williamr@2
   938
	TInt size = stmt.ColumnSize(<column_number>);
williamr@2
   939
	//read the column data in a buffer ("buf" variable).
williamr@2
   940
	//(or the column data can be retrieved in a smaller portions)
williamr@2
   941
	colStream.ReadL(buf, size);
williamr@2
   942
	//Close the stream
williamr@2
   943
	CleanupStack::PopAndDestroy(&colStream);
williamr@2
   944
	}
williamr@2
   945
else
williamr@2
   946
	{
williamr@2
   947
	...
williamr@2
   948
	}
williamr@2
   949
@endcode
williamr@2
   950
williamr@4
   951
@see RSqlBlobReadStream
williamr@4
   952
@see TSqlBlob
williamr@4
   953
williamr@2
   954
@publishedAll
williamr@2
   955
@released
williamr@2
   956
*/
williamr@2
   957
class RSqlColumnReadStream : public RReadStream
williamr@2
   958
	{
williamr@2
   959
public:	
williamr@2
   960
	IMPORT_C TInt ColumnText(RSqlStatement& aStmt, TInt aColumnIndex);
williamr@2
   961
	IMPORT_C TInt ColumnBinary(RSqlStatement& aStmt, TInt aColumnIndex);
williamr@2
   962
	IMPORT_C void ColumnTextL(RSqlStatement& aStmt, TInt aColumnIndex);
williamr@2
   963
	IMPORT_C void ColumnBinaryL(RSqlStatement& aStmt, TInt aColumnIndex);
williamr@2
   964
williamr@2
   965
	};
williamr@2
   966
williamr@2
   967
/**
williamr@2
   968
The write stream interface.
williamr@2
   969
williamr@4
   970
The class is used to set binary data or text data into a parameter. 
williamr@4
   971
This is a also known as binding a parameter.
williamr@2
   972
williamr@2
   973
The class derives from RWriteStream, which means that all RWriteStream public
williamr@2
   974
member functions and predefined stream operators \<\< can be used to deal with
williamr@2
   975
the parameter data.
williamr@2
   976
williamr@4
   977
If the blob or text data is over 2Mb in size then it is recommended that the 
williamr@4
   978
RSqlBlobWriteStream or TSqlBlob class is used instead. These classes provide 
williamr@4
   979
a more RAM-efficient way of writing large amounts of blob or text data to
williamr@4
   980
a database.
williamr@4
   981
williamr@2
   982
The following two cases are typical:
williamr@2
   983
williamr@2
   984
CASE 1 - binding a large binary parameter.
williamr@2
   985
williamr@2
   986
@code
williamr@2
   987
RSqlDatabase db;
williamr@2
   988
<open/create "db" object>;
williamr@2
   989
RSqlStatement stmt;
williamr@2
   990
<prepare "stmt" object>;//The SQL statement references large binary parameter
williamr@2
   991
RSqlParamWriteStream paramStream;
williamr@2
   992
CleanupClosePushL(paramStream);
williamr@2
   993
User::LeaveIfError(paramStream.BindBinary(stmt, <parameter_number>));
williamr@2
   994
//Write out the parameter data
williamr@2
   995
paramStream.WriteL(..);
williamr@2
   996
paramStream << <data>;
williamr@2
   997
...
williamr@2
   998
//Commit the stream
williamr@2
   999
paramStream.CommitL();
williamr@2
  1000
//Continue with the statement processing issuing Next() or Exec().
williamr@2
  1001
TInt rc = stmt.Next();//rc = stmt.Exec()
williamr@2
  1002
//Close the stream
williamr@2
  1003
CleanupStack::PopAndDestroy(&paramStream);
williamr@2
  1004
@endcode
williamr@2
  1005
williamr@2
  1006
CASE 2 - binding a large text parameter.
williamr@2
  1007
williamr@2
  1008
@code
williamr@2
  1009
RSqlDatabase db;
williamr@2
  1010
<open/create "db" object>;
williamr@2
  1011
RSqlStatement stmt;
williamr@2
  1012
<prepare "stmt" object>;//The SQL statement references large text parameter
williamr@2
  1013
RSqlParamWriteStream paramStream;
williamr@2
  1014
CleanupClosePushL(paramStream);
williamr@2
  1015
User::LeaveIfError(paramStream.BindText(stmt, <parameter_number>));
williamr@2
  1016
//Write out the parameter data
williamr@2
  1017
paramStream.WriteL(..);
williamr@2
  1018
paramStream << <data>;
williamr@2
  1019
...
williamr@2
  1020
//Commit the stream
williamr@2
  1021
paramStream.CommitL();
williamr@2
  1022
//Continue with the statement processing issuing Next() or Exec().
williamr@2
  1023
TInt rc = stmt.Next();//rc = stmt.Exec()
williamr@2
  1024
//Close the stream
williamr@2
  1025
CleanupStack::PopAndDestroy(&paramStream);
williamr@2
  1026
@endcode
williamr@2
  1027
williamr@4
  1028
@see RSqlBlobWriteStream
williamr@4
  1029
@see TSqlBlob
williamr@4
  1030
williamr@2
  1031
@publishedAll
williamr@2
  1032
@released
williamr@2
  1033
*/
williamr@2
  1034
class RSqlParamWriteStream : public RWriteStream
williamr@2
  1035
	{
williamr@2
  1036
public:	
williamr@2
  1037
	IMPORT_C TInt BindText(RSqlStatement& aStmt, TInt aParameterIndex);
williamr@2
  1038
	IMPORT_C TInt BindBinary(RSqlStatement& aStmt, TInt aParameterIndex);
williamr@2
  1039
	IMPORT_C void BindTextL(RSqlStatement& aStmt, TInt aParameterIndex);
williamr@2
  1040
	IMPORT_C void BindBinaryL(RSqlStatement& aStmt, TInt aParameterIndex);
williamr@2
  1041
williamr@2
  1042
	};
williamr@2
  1043
williamr@2
  1044
/**
williamr@4
  1045
A direct handle to a blob, used for reading the content of the blob via a streaming interface.
williamr@2
  1046
williamr@4
  1047
The target blob is identified using the relevant database connection, table name, 
williamr@4
  1048
column name and ROWID of the record to which the blob belongs (also the attached
williamr@4
  1049
database name if the blob is contained in an attached database).
williamr@4
  1050
williamr@4
  1051
A blob in this context refers to the content of a BLOB or TEXT column, 
williamr@4
  1052
and a read handle can be opened on both types of column.
williamr@4
  1053
For TEXT columns it is important to note that no conversions are performed on 
williamr@4
  1054
data retrieved using this class - the data is returned as a stream of bytes.
williamr@4
  1055
williamr@4
  1056
The class derives from RReadStream and provides all of its streaming methods.
williamr@4
  1057
The SizeL() method can be used to check the total size of the blob, in bytes.
williamr@4
  1058
williamr@4
  1059
It is strongly recommended to use this class for reading the content of large blobs 
williamr@4
  1060
because it significantly reduces the amount of RAM that is used when compared to using the 
williamr@4
  1061
RSqlColumnReadStream, RSqlStatement::ColumnBinary(L) or RSqlStatement::ColumnText(L) APIs.
williamr@4
  1062
williamr@4
  1063
Specifically, it is recommended to use this class for blobs over 2Mb in size.
williamr@4
  1064
Indeed, in some circumstances where very large blobs are in use it may be impossible
williamr@4
  1065
to read the blob content using the legacy APIs (due to the server's finite RAM capacity), 
williamr@4
  1066
and this class may provide the only way to access the data.
williamr@4
  1067
williamr@4
  1068
The following code illustrates typical use cases of this class:
williamr@4
  1069
williamr@4
  1070
CASE 1 - reading large blob data from the last inserted record.
williamr@4
  1071
williamr@4
  1072
@code
williamr@4
  1073
RSqlDatabase db;
williamr@4
  1074
CleanupClosePushL(db);
williamr@4
  1075
<open/create "db" object>;
williamr@4
  1076
RSqlBlobReadStream rdStrm;
williamr@4
  1077
CleanupClosePushL(rdStrm);
williamr@4
  1078
rdStrm.OpenL(db, <table_name>, <column_name>);
williamr@4
  1079
HBufC8* buffer = HBufC8::NewLC(KBlockSize);
williamr@4
  1080
TPtr8 bufPtr(buffer->Des());
williamr@4
  1081
TInt size = rdStrm.SizeL();
williamr@4
  1082
while(size)
williamr@4
  1083
	{
williamr@4
  1084
	TInt bytesToRead = (size >= KBlockSize) ? KBlockSize : size ;
williamr@4
  1085
	rdStrm.ReadL(bufPtr, bytesToRead); // read the next block of data		
williamr@4
  1086
	<do something with the block of data>
williamr@4
  1087
	size =- bytesToRead;
williamr@4
  1088
	}
williamr@4
  1089
CleanupStack::PopAndDestroy(3); // buffer, rdStrm, db
williamr@4
  1090
@endcode
williamr@4
  1091
williamr@4
  1092
CASE 2 - reading large blob data from a selection of records.
williamr@4
  1093
williamr@4
  1094
@code
williamr@4
  1095
RSqlDatabase db;
williamr@4
  1096
CleanupClosePushL(db);
williamr@4
  1097
<open/create "db" object>;
williamr@4
  1098
RSqlStatement stmt;
williamr@4
  1099
CleanupClosePushL(stmt);
williamr@4
  1100
<prepare "stmt" object to SELECT the ROWIDs of a collection of blob objects>;
williamr@4
  1101
TInt rc = 0;
williamr@4
  1102
while((rc = stmt.Next()) == KSqlAtRow)
williamr@4
  1103
	{
williamr@4
  1104
	TInt64 rowid = stmt.ColumnInt64(0);	
williamr@4
  1105
	RSqlBlobReadStream rdStrm;
williamr@4
  1106
	CleanupClosePushL(rdStrm);
williamr@4
  1107
	rdStrm.OpenL(db, <table_name>, <column_name>, rowid);
williamr@4
  1108
	
williamr@4
  1109
	HBufC8* buffer = HBufC8::NewLC(KBlockSize);
williamr@4
  1110
	TPtr8 bufPtr(buffer->Des());
williamr@4
  1111
	TInt size = rdStrm.SizeL();
williamr@4
  1112
	while(size)
williamr@4
  1113
		{
williamr@4
  1114
		TInt bytesToRead = (size >= KBlockSize) ? KBlockSize : size ;
williamr@4
  1115
		rdStrm.ReadL(bufPtr, bytesToRead); // read the next block of data		
williamr@4
  1116
		<do something with the block of data>
williamr@4
  1117
		size =- bytesToRead;
williamr@4
  1118
		}
williamr@4
  1119
	CleanupStack::PopAndDestroy(2); // buffer, rdStrm
williamr@4
  1120
	}
williamr@4
  1121
CleanupStack::PopAndDestroy(2); // stmt, db
williamr@4
  1122
@endcode
williamr@4
  1123
williamr@4
  1124
@see RSqlBlobWriteStream
williamr@4
  1125
@see RSqlDatabase::LastInsertedRowId()
williamr@4
  1126
williamr@4
  1127
@publishedAll
williamr@2
  1128
@released
williamr@2
  1129
*/
williamr@4
  1130
class RSqlBlobReadStream : public RReadStream
williamr@2
  1131
	{
williamr@4
  1132
public:						
williamr@4
  1133
	IMPORT_C void OpenL(RSqlDatabase& aDb, const TDesC& aTableName, const TDesC& aColumnName, 
williamr@4
  1134
						TInt64 aRowId = KSqlLastInsertedRowId, const TDesC& aDbName = KNullDesC);
williamr@4
  1135
	IMPORT_C TInt SizeL();
williamr@4
  1136
	};
williamr@2
  1137
williamr@4
  1138
/**
williamr@4
  1139
A direct handle to a blob, used for writing the content of the blob via a streaming interface.
williamr@4
  1140
williamr@4
  1141
The target blob is identified using the relevant database connection, table name, 
williamr@4
  1142
column name and ROWID of the record to which the blob belongs (also the attached
williamr@4
  1143
database name if the blob is contained in an attached database).
williamr@4
  1144
williamr@4
  1145
A blob in this context refers to the content of a BLOB or TEXT column, 
williamr@4
  1146
and a write handle can be opened on both types of column, except if the
williamr@4
  1147
column is indexed, in which case the open call will fail with KSqlErrGeneral.
williamr@4
  1148
For TEXT columns it is important to note that no conversions are performed on data 
williamr@4
  1149
that is stored using this class - the data is simply stored as a stream of bytes.
williamr@4
  1150
williamr@4
  1151
The class derives from RWriteStream and provides all of its streaming methods.
williamr@4
  1152
The SizeL() method can be used to check the total size of the blob, in bytes.
williamr@4
  1153
Note that this class cannot be used to increase the size of a blob, only to modify 
williamr@4
  1154
the existing contents of a blob. An attempt to write beyond the end of a blob will
williamr@4
  1155
fail with KErrEof.
williamr@4
  1156
williamr@4
  1157
It is strongly recommended to use this class for writing the content of large blobs 
williamr@4
  1158
because it significantly reduces the amount of RAM that is used when compared to using 
williamr@4
  1159
the RSqlParamWriteStream, RSqlStatement::BindBinary or RSqlStatement::BindText APIs.
williamr@4
  1160
williamr@4
  1161
Specifically, it is recommended to use this class for blobs over 2Mb in size.
williamr@4
  1162
Indeed, in some circumstances where very large blobs are required it may be impossible
williamr@4
  1163
to create a blob or update its content using the legacy APIs (due to the server's finite 
williamr@4
  1164
RAM capacity), and this class may provide the only way to achieve this.
williamr@4
  1165
williamr@4
  1166
Using this class in combination with zeroblobs it is possible to create and manipulate 
williamr@4
  1167
blobs that are gigabytes in size. A zeroblob acts as a place-holder for a blob whose 
williamr@4
  1168
content is later written using this class and one can be created using an INSERT 
williamr@4
  1169
statement that either contains the SQLite 'zeroblob()' function or on which 
williamr@4
  1170
RSqlStatement::BindZeroBlob() has been executed.
williamr@4
  1171
Note that a zeroblob should be created in a column after which there are no columns 
williamr@4
  1172
that contain anything other than zeroblobs or NULLs, otherwise the zeroblob must be 
williamr@4
  1173
allocated in full in RAM.
williamr@4
  1174
williamr@4
  1175
When creating a zeroblob it is recommended, where possible, to create the zeroblob and
williamr@4
  1176
then write the blob content within the same transaction. Otherwise the zeroblob will 
williamr@4
  1177
have to be journalled before being written to.
williamr@4
  1178
williamr@4
  1179
It is also strongly recommended to execute calls to WriteL() within a transaction. 
williamr@4
  1180
If a leave occurs during a call to WriteL() then the current state of the blob object is
williamr@4
  1181
undefined and a ROLLBACK should be executed to return the blob object to its previous state.
williamr@4
  1182
Note that in order for a ROLLBACK to execute successfully all open RSqlBlobReadStream 
williamr@4
  1183
and RSqlBlobWriteStream handles and all open RSqlStatement objects must be closed 
williamr@4
  1184
before the ROLLBACK is executed.
williamr@4
  1185
williamr@4
  1186
The following code illustrates typical use cases of this class:
williamr@4
  1187
williamr@4
  1188
CASE 1 - creating a 5Mb blob.
williamr@4
  1189
williamr@4
  1190
@code
williamr@4
  1191
RSqlDatabase db;
williamr@4
  1192
CleanupClosePushL(db);
williamr@4
  1193
<open/create "db" object>;
williamr@4
  1194
CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function
williamr@4
  1195
TInt err = db.Exec(_L("BEGIN"));
williamr@4
  1196
<check err>
williamr@4
  1197
err = db.Exec(_L("INSERT INTO table1 VALUES(35, zeroblob(5242880))"));
williamr@4
  1198
<check err>
williamr@4
  1199
RSqlBlobWriteStream wrStrm;
williamr@4
  1200
CleanupClosePushL(wrStrm);
williamr@4
  1201
wrStrm.OpenL(db, <table_name>, <column_name>);
williamr@4
  1202
TInt size = wrStrm.SizeL();
williamr@4
  1203
while(size)
williamr@4
  1204
	{
williamr@4
  1205
	TInt bytesToWrite = (size >= KBlockSize) ? KBlockSize : size ;
williamr@4
  1206
	<fill a buffer 'buf' with this amount of the blob data>
williamr@4
  1207
	wrStrm.WriteL(buf); // write the next block of data		
williamr@4
  1208
	size =- bytesToWrite;
williamr@4
  1209
	}
williamr@4
  1210
CleanupStack::PopAndDestroy(&wrStrm);
williamr@4
  1211
CleanupStack::Pop(); // TCleanupItem
williamr@4
  1212
err = db.Exec(_L("COMMIT")); // blob data committed to disk
williamr@4
  1213
<check err>
williamr@4
  1214
CleanupStack::PopAndDestroy(&db);
williamr@4
  1215
@endcode
williamr@4
  1216
williamr@4
  1217
CASE 2 - updating a large blob in the last inserted record.
williamr@4
  1218
williamr@4
  1219
@code
williamr@4
  1220
RSqlDatabase db;
williamr@4
  1221
CleanupClosePushL(db);
williamr@4
  1222
<open/create "db" object>;
williamr@4
  1223
CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function
williamr@4
  1224
TInt err = db.Exec(_L("BEGIN"));
williamr@4
  1225
<check err>
williamr@4
  1226
RSqlBlobWriteStream wrStrm;
williamr@4
  1227
CleanupClosePushL(wrStrm);
williamr@4
  1228
wrStrm.OpenL(db, <table_name>, <column_name>);
williamr@4
  1229
<fill a buffer 'buf' with the changed blob data>
williamr@4
  1230
wrStrm.WriteL(buf); // update the blob
williamr@4
  1231
CleanupStack::PopAndDestroy(&wrStrm);
williamr@4
  1232
CleanupStack::Pop(); // TCleanupItem
williamr@4
  1233
err = db.Exec(_L("COMMIT")); // blob data committed to disk
williamr@4
  1234
<check err>
williamr@4
  1235
CleanupStack::PopAndDestroy(&db);
williamr@4
  1236
@endcode
williamr@4
  1237
williamr@4
  1238
@see RSqlBlobReadStream
williamr@4
  1239
@see RSqlDatabase::LastInsertedRowId()
williamr@4
  1240
@see RSqlStatement::BindZeroBlob()
williamr@4
  1241
williamr@4
  1242
@publishedAll
williamr@4
  1243
@released
williamr@4
  1244
*/
williamr@4
  1245
class RSqlBlobWriteStream : public RWriteStream
williamr@4
  1246
	{
williamr@4
  1247
public:
williamr@4
  1248
	IMPORT_C void OpenL(RSqlDatabase& aDb, const TDesC& aTableName, const TDesC& aColumnName, 
williamr@4
  1249
						TInt64 aRowId = KSqlLastInsertedRowId, const TDesC& aDbName = KNullDesC);
williamr@4
  1250
	IMPORT_C TInt SizeL();
williamr@4
  1251
	};
williamr@4
  1252
williamr@4
  1253
/**
williamr@4
  1254
Utility class that provides methods for reading and writing the entire content of 
williamr@4
  1255
a blob in a single call.
williamr@4
  1256
williamr@4
  1257
The target blob is identified using the relevant database connection, table name, 
williamr@4
  1258
column name and ROWID of the record to which the blob belongs (also the attached
williamr@4
  1259
database name if the blob is contained in an attached database).
williamr@4
  1260
williamr@4
  1261
The behaviour of the RSqlBlobReadStream class and the recommendations for using
williamr@4
  1262
it exist for the Get() and GetLC() methods of this class. Similarly, the behaviour 
williamr@4
  1263
of the RSqlBlobWriteStream class and the recommendations for using it exist for the 
williamr@4
  1264
SetL() method of this class.
williamr@4
  1265
williamr@4
  1266
In particular, it is strongly recommended to use this class or the RSqlBlobReadStream
williamr@4
  1267
and RSqlBlobWriteStream classes for reading and writing the content of large blobs 
williamr@4
  1268
because it significantly reduces the amount of RAM that is used when compared to using 
williamr@4
  1269
the legacy streaming and RSqlStatement APIs.
williamr@4
  1270
williamr@4
  1271
Specifically, it is recommended to use this class for blobs over 2Mb in size.
williamr@4
  1272
Indeed, in some circumstances where very large blobs are in use it may be impossible
williamr@4
  1273
to read or write to a blob using the legacy APIs (due to the server's finite 
williamr@4
  1274
RAM capacity), and this class or the RSqlBlobReadStream and RSqlBlobWriteStream classes 
williamr@4
  1275
may provide the only way to achieve this.
williamr@4
  1276
williamr@4
  1277
It is strongly recommended to execute calls to the SetL() method within a transaction. 
williamr@4
  1278
If a leave occurs during a call to SetL() then the current state of the blob object is 
williamr@4
  1279
undefined and a ROLLBACK should be executed to return the blob object to its previous state.
williamr@4
  1280
Note that in order for a ROLLBACK to execute successfully all open RSqlBlobReadStream 
williamr@4
  1281
and RSqlBlobWriteStream handles and all open RSqlStatement objects must be closed 
williamr@4
  1282
before the ROLLBACK is executed.
williamr@4
  1283
williamr@4
  1284
When using SetL() to update the content of a zeroblob it is recommended, where possible, 
williamr@4
  1285
to create the zeroblob and then call SetL() within the same transaction. 
williamr@4
  1286
Otherwise the zeroblob will have to be journalled before being written to.
williamr@4
  1287
williamr@4
  1288
The following code illustrates typical use cases of this class:
williamr@4
  1289
williamr@4
  1290
CASE 1 - retrieving the entire content of a large blob.
williamr@4
  1291
williamr@4
  1292
@code
williamr@4
  1293
RSqlDatabase db;
williamr@4
  1294
CleanupClosePushL(db);
williamr@4
  1295
<open/create "db" object>;
williamr@4
  1296
HBufC8* wholeBlob = TSqlBlob::GetLC(db, <table_name>, <column_name>, <rowid>);
williamr@4
  1297
<do something with the blob data>
williamr@4
  1298
CleanupStack::PopAndDestroy(2); // wholeBlob, db
williamr@4
  1299
@endcode
williamr@4
  1300
williamr@4
  1301
williamr@4
  1302
CASE 2 - creating a 4Mb blob.
williamr@4
  1303
williamr@4
  1304
@code
williamr@4
  1305
RSqlDatabase db;
williamr@4
  1306
CleanupClosePushL(db);
williamr@4
  1307
<open/create "db" object>;
williamr@4
  1308
CleanupStack::PushL(TCleanupItem(&DoRollback, &db)); // rollback function
williamr@4
  1309
TInt err = db.Exec(_L("BEGIN"));
williamr@4
  1310
<check err>
williamr@4
  1311
err = db.Exec(_L("INSERT INTO table1 VALUES(99, zeroblob(4194304))"));
williamr@4
  1312
<check err>
williamr@4
  1313
<fill a buffer 'buf' with 4Mb of blob data>
williamr@4
  1314
TSqlBlob::SetL(db, <table_name>, <column_name>, buf);
williamr@4
  1315
CleanupStack::Pop(); // TCleanupItem
williamr@4
  1316
err = db.Exec(_L("COMMIT")); // blob data committed to disk
williamr@4
  1317
<check err>
williamr@4
  1318
CleanupStack::PopAndDestroy(&db);
williamr@4
  1319
@endcode
williamr@4
  1320
williamr@4
  1321
@see RSqlBlobReadStream
williamr@4
  1322
@see RSqlBlobWriteStream
williamr@4
  1323
@see RSqlDatabase::LastInsertedRowId()
williamr@4
  1324
@see RSqlStatement::BindZeroBlob()
williamr@4
  1325
williamr@4
  1326
@publishedAll
williamr@4
  1327
@released
williamr@4
  1328
*/
williamr@4
  1329
class TSqlBlob
williamr@4
  1330
	{
williamr@4
  1331
public:					  		  	  
williamr@4
  1332
	IMPORT_C static HBufC8* GetLC(RSqlDatabase& aDb, 	
williamr@4
  1333
					     		  const TDesC& aTableName, 
williamr@4
  1334
					     		  const TDesC& aColumnName, 	
williamr@4
  1335
					     		  TInt64 aRowId = KSqlLastInsertedRowId,
williamr@4
  1336
					     		  const TDesC& aDbName = KNullDesC);
williamr@4
  1337
								  		  	  
williamr@4
  1338
	IMPORT_C static TInt Get(RSqlDatabase& aDb, 	
williamr@4
  1339
					 		 const TDesC& aTableName, 
williamr@4
  1340
					 		 const TDesC& aColumnName, 	
williamr@4
  1341
					 		 TDes8& aBuffer,
williamr@4
  1342
					 		 TInt64 aRowId = KSqlLastInsertedRowId,
williamr@4
  1343
					 		 const TDesC& aDbName = KNullDesC);			 		 
williamr@4
  1344
williamr@4
  1345
	IMPORT_C static void SetL(RSqlDatabase& aDb, 	
williamr@4
  1346
					  		  const TDesC& aTableName, 
williamr@4
  1347
					  		  const TDesC& aColumnName,
williamr@4
  1348
					  		  const TDesC8& aData,	
williamr@4
  1349
					  		  TInt64 aRowId = KSqlLastInsertedRowId,
williamr@4
  1350
					  		  const TDesC& aDbName = KNullDesC);				  
williamr@2
  1351
	};
williamr@2
  1352
williamr@2
  1353
/**
williamr@2
  1354
Defines a set of categories for the values returned by the SQL API.
williamr@2
  1355
williamr@2
  1356
A call to an SQL API may complete with a non-zero return code indicating that some
williamr@2
  1357
unexpected behaviour has occurred. This can be categorised in a number of ways,
williamr@2
  1358
for example, as a Symbian OS error, or as a database error etc. 
williamr@2
  1359
williamr@2
  1360
Callers to the SQL API may not want to be concerned with the detailed meaning of
williamr@2
  1361
a specific return code value, and may find it sufficient just to know the category
williamr@2
  1362
of the error.
williamr@2
  1363
williamr@2
  1364
The category associated with a specific return code can be found by passing the 
williamr@2
  1365
return code value to the function SqlRetCodeClass().
williamr@2
  1366
williamr@2
  1367
@publishedAll
williamr@2
  1368
@released
williamr@2
  1369
*/
williamr@2
  1370
enum TSqlRetCodeClass 
williamr@2
  1371
	{
williamr@2
  1372
	/**
williamr@2
  1373
	Indicates that a return code is just for information.
williamr@2
  1374
	
williamr@2
  1375
	This category corresponds to the SQL API return codes: KSqlAtRow and KSqlAtEnd. 
williamr@2
  1376
	
williamr@2
  1377
	@see SqlRetCodeClass()
williamr@2
  1378
	@see TSqlRetCodeClass
williamr@2
  1379
	@see KSqlAtRow 
williamr@2
  1380
	@see KSqlAtEnd
williamr@2
  1381
	*/
williamr@2
  1382
	ESqlInformation, 
williamr@2
  1383
	
williamr@2
  1384
	/**
williamr@2
  1385
	Indicates that a return code represents a database-specific error.
williamr@2
  1386
	
williamr@2
  1387
	This category corresponds to SQL API return codes in the range KSqlErrGeneral to KSqlErrStmtExpired.
williamr@2
  1388
	
williamr@2
  1389
	@see SqlRetCodeClass()
williamr@2
  1390
	@see TSqlRetCodeClass
williamr@2
  1391
	@see KSqlErrGeneral
williamr@2
  1392
	@see KSqlErrStmtExpired
williamr@2
  1393
	*/
williamr@2
  1394
	ESqlDbError,
williamr@2
  1395
	
williamr@2
  1396
	/**
williamr@2
  1397
	Indicates that a return code represents a Symbian OS error.
williamr@2
  1398
	
williamr@2
  1399
	This category corresponds to SQL API return codes in the range KErrPermissionDenied to KErrNone,
williamr@2
  1400
	
williamr@2
  1401
	@see SqlRetCodeClass()
williamr@2
  1402
	@see TSqlRetCodeClass
williamr@2
  1403
	@see KErrPermissionDenied
williamr@2
  1404
	@see KErrNone
williamr@2
  1405
	*/
williamr@2
  1406
	ESqlOsError 
williamr@2
  1407
	};
williamr@2
  1408
williamr@2
  1409
/**
williamr@2
  1410
An information type return code from a call to RSqlStatement::Next().
williamr@2
  1411
williamr@2
  1412
It means that the RSqlStatement object points to a valid row, and that
williamr@2
  1413
the user can access the column data using the appropriate RSqlStatement
williamr@2
  1414
member functions.
williamr@2
  1415
williamr@2
  1416
@see RSqlStatement::Next()
williamr@2
  1417
@see RSqlStatement
williamr@2
  1418
@see ESqlInformation
williamr@2
  1419
@see TSqlRetCodeClass
williamr@2
  1420
williamr@2
  1421
@publishedAll
williamr@2
  1422
@released
williamr@2
  1423
*/
williamr@2
  1424
const TInt KSqlAtRow = 1;
williamr@2
  1425
williamr@2
  1426
/**
williamr@2
  1427
An information type return code from a call to RSqlStatement::Next().
williamr@2
  1428
williamr@2
  1429
It means that the RSqlStatement object does not point to a valid row,
williamr@2
  1430
and that column data accessors cannot be used.
williamr@2
  1431
williamr@2
  1432
@see RSqlStatement::Next()
williamr@2
  1433
@see RSqlStatement
williamr@2
  1434
@see ESqlInformation
williamr@2
  1435
@see TSqlRetCodeClass
williamr@2
  1436
williamr@2
  1437
@publishedAll
williamr@2
  1438
@released
williamr@2
  1439
*/
williamr@2
  1440
const TInt KSqlAtEnd = 2;
williamr@2
  1441
williamr@2
  1442
/**
williamr@2
  1443
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1444
williamr@2
  1445
It indicates a general SQL error or a missing database.
williamr@2
  1446
williamr@2
  1447
@see RSqlStatement
williamr@2
  1448
@see ESqlDbError
williamr@2
  1449
@see TSqlRetCodeClass
williamr@2
  1450
williamr@2
  1451
@publishedAll
williamr@2
  1452
@released
williamr@2
  1453
*/
williamr@2
  1454
const TInt KSqlErrGeneral		= -311;
williamr@2
  1455
williamr@2
  1456
/**
williamr@2
  1457
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1458
williamr@2
  1459
It indicates an internal logic error in the SQL database engine, and specifically
williamr@2
  1460
that an internal consistency check within the SQL database engine has failed.
williamr@2
  1461
williamr@2
  1462
@see RSqlStatement
williamr@2
  1463
@see ESqlDbError
williamr@2
  1464
@see TSqlRetCodeClass
williamr@2
  1465
williamr@2
  1466
@publishedAll
williamr@2
  1467
@released
williamr@2
  1468
*/
williamr@2
  1469
const TInt KSqlErrInternal		= -312;
williamr@2
  1470
williamr@2
  1471
/**
williamr@2
  1472
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1473
williamr@2
  1474
It indicates that access permission has been denied.
williamr@2
  1475
williamr@2
  1476
@see RSqlStatement
williamr@2
  1477
@see ESqlDbError
williamr@2
  1478
@see TSqlRetCodeClass
williamr@2
  1479
williamr@2
  1480
@publishedAll
williamr@2
  1481
@released
williamr@2
  1482
*/
williamr@2
  1483
const TInt KSqlErrPermission	= -313;
williamr@2
  1484
williamr@2
  1485
/**
williamr@2
  1486
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1487
williamr@2
  1488
It indicates an internal logic error in the SQL database engine, and specifically
williamr@2
  1489
that a callback routine requested an abort.
williamr@2
  1490
williamr@2
  1491
@publishedAll
williamr@2
  1492
@released
williamr@2
  1493
*/
williamr@2
  1494
const TInt KSqlErrAbort			= -314;
williamr@2
  1495
williamr@2
  1496
/**
williamr@2
  1497
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1498
williamr@2
  1499
It indicates that the database file is locked.
williamr@2
  1500
williamr@2
  1501
@see RSqlStatement
williamr@2
  1502
@see ESqlDbError
williamr@2
  1503
@see TSqlRetCodeClass
williamr@2
  1504
williamr@2
  1505
@publishedAll
williamr@2
  1506
@released
williamr@2
  1507
*/
williamr@2
  1508
const TInt KSqlErrBusy			= -315;
williamr@2
  1509
williamr@2
  1510
/**
williamr@2
  1511
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1512
williamr@2
  1513
It indicates that a table in the database is locked.
williamr@2
  1514
williamr@2
  1515
@see RSqlStatement
williamr@2
  1516
@see ESqlDbError
williamr@2
  1517
@see TSqlRetCodeClass
williamr@2
  1518
williamr@2
  1519
@publishedAll
williamr@2
  1520
@released
williamr@2
  1521
*/
williamr@2
  1522
const TInt KSqlErrLocked		= -316;
williamr@2
  1523
williamr@2
  1524
/**
williamr@2
  1525
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1526
williamr@2
  1527
It indicates an attempt to write to a database that is read-only.
williamr@2
  1528
williamr@2
  1529
@see RSqlStatement
williamr@2
  1530
@see ESqlDbError
williamr@2
  1531
@see TSqlRetCodeClass
williamr@2
  1532
williamr@2
  1533
@publishedAll
williamr@2
  1534
@released
williamr@2
  1535
*/
williamr@2
  1536
const TInt KSqlErrReadOnly		= -318;
williamr@2
  1537
williamr@2
  1538
/**
williamr@2
  1539
SQL database-specific error type. Operation terminated.
williamr@2
  1540
williamr@2
  1541
@publishedAll
williamr@2
  1542
@released
williamr@2
  1543
*/
williamr@2
  1544
const TInt KSqlErrInterrupt		= -319;
williamr@2
  1545
williamr@2
  1546
/**
williamr@2
  1547
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1548
williamr@2
  1549
It indicates that a disk I/O error has occurred.
williamr@2
  1550
williamr@2
  1551
@see RSqlStatement
williamr@2
  1552
@see ESqlDbError
williamr@2
  1553
@see TSqlRetCodeClass
williamr@2
  1554
williamr@2
  1555
@publishedAll
williamr@2
  1556
@released
williamr@2
  1557
*/
williamr@2
  1558
const TInt KSqlErrIO			= -320;
williamr@2
  1559
williamr@2
  1560
/**
williamr@2
  1561
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1562
williamr@2
  1563
It indicates that the database disk image is malformed.
williamr@2
  1564
williamr@2
  1565
@see RSqlStatement
williamr@2
  1566
@see ESqlDbError
williamr@2
  1567
@see TSqlRetCodeClass
williamr@2
  1568
williamr@2
  1569
@publishedAll
williamr@2
  1570
@released
williamr@2
  1571
*/
williamr@2
  1572
const TInt KSqlErrCorrupt		= -321;
williamr@2
  1573
williamr@2
  1574
/**
williamr@2
  1575
SQL database-specific error type. Table or record not found.
williamr@2
  1576
williamr@2
  1577
@publishedAll
williamr@2
  1578
@released
williamr@2
  1579
*/
williamr@2
  1580
const TInt KSqlErrNotFound		= -322;
williamr@2
  1581
williamr@2
  1582
/**
williamr@2
  1583
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1584
williamr@2
  1585
It indicates that an insertion operation has failed because an autoincrement column used up 
williamr@2
  1586
all awailable rowids.
williamr@2
  1587
williamr@2
  1588
@see RSqlStatement
williamr@2
  1589
@see ESqlDbError
williamr@2
  1590
@see TSqlRetCodeClass
williamr@2
  1591
williamr@2
  1592
@publishedAll
williamr@2
  1593
@released
williamr@2
  1594
*/
williamr@2
  1595
const TInt KSqlErrFull			= -323;
williamr@2
  1596
williamr@2
  1597
/**
williamr@2
  1598
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1599
williamr@2
  1600
It indicates a failure to open the database file.
williamr@2
  1601
williamr@2
  1602
@see RSqlStatement
williamr@2
  1603
@see ESqlDbError
williamr@2
  1604
@see TSqlRetCodeClass
williamr@2
  1605
williamr@2
  1606
@publishedAll
williamr@2
  1607
@released
williamr@2
  1608
*/
williamr@2
  1609
const TInt KSqlErrCantOpen		= -324;
williamr@2
  1610
williamr@2
  1611
/**
williamr@2
  1612
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1613
williamr@2
  1614
It indicates a database lock protocol error.
williamr@2
  1615
williamr@2
  1616
@see RSqlStatement
williamr@2
  1617
@see ESqlDbError
williamr@2
  1618
@see TSqlRetCodeClass
williamr@2
  1619
williamr@2
  1620
@publishedAll
williamr@2
  1621
@released
williamr@2
  1622
*/
williamr@2
  1623
const TInt KSqlErrProtocol		= -325;
williamr@2
  1624
williamr@2
  1625
/**
williamr@2
  1626
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1627
williamr@2
  1628
It indicates that the database is empty.
williamr@2
  1629
williamr@2
  1630
@see RSqlStatement
williamr@2
  1631
@see ESqlDbError
williamr@2
  1632
@see TSqlRetCodeClass
williamr@2
  1633
williamr@2
  1634
@publishedAll
williamr@2
  1635
@released
williamr@2
  1636
*/
williamr@2
  1637
const TInt KSqlErrEmpty			= -326;
williamr@2
  1638
williamr@2
  1639
/**
williamr@2
  1640
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1641
williamr@2
  1642
It indicates that a prepared SQL statement is no longer valid 
williamr@2
  1643
and cannot be executed.
williamr@2
  1644
williamr@2
  1645
The most common reason for this return code is that the database schema was modified after
williamr@2
  1646
the SQL statement was prepared. The SQL statement must be prepared again
williamr@2
  1647
using the RSqlStatement::Prepare() member functions.
williamr@2
  1648
williamr@2
  1649
Another possible reason for this return code is a detached database.
williamr@2
  1650
williamr@2
  1651
@see RSqlStatement
williamr@2
  1652
@see ESqlDbError
williamr@2
  1653
@see TSqlRetCodeClass
williamr@2
  1654
williamr@2
  1655
@publishedAll
williamr@2
  1656
@released
williamr@2
  1657
*/
williamr@2
  1658
const TInt KSqlErrSchema		= -327;
williamr@2
  1659
williamr@2
  1660
/**
williamr@2
  1661
SQL database-specific error type. Too much data for one row.
williamr@2
  1662
williamr@2
  1663
@publishedAll
williamr@2
  1664
@released
williamr@2
  1665
*/
williamr@2
  1666
const TInt KSqlErrTooBig		= -328;
williamr@2
  1667
williamr@2
  1668
/**
williamr@2
  1669
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1670
williamr@2
  1671
It indicates an abort due to constraint violation.
williamr@2
  1672
williamr@2
  1673
"Constraint violation" means violation of one or more column constraints ("NOT NULL", "PRIMARY KEY",
williamr@2
  1674
"UNIQUE", "CHECK", "DEFAULT", "COLLATE" SQL keywords) or table constraints ("PRIMARY KEY", "UNIQUE", 
williamr@2
  1675
"CHECK" SQL keywords).
williamr@2
  1676
williamr@2
  1677
@see RSqlStatement
williamr@2
  1678
@see ESqlDbError
williamr@2
  1679
@see TSqlRetCodeClass
williamr@2
  1680
williamr@2
  1681
@publishedAll
williamr@2
  1682
@released
williamr@2
  1683
*/
williamr@2
  1684
const TInt KSqlErrConstraint	= -329;
williamr@2
  1685
williamr@2
  1686
/**
williamr@2
  1687
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1688
williamr@2
  1689
It indicates a data type mismatch.
williamr@2
  1690
williamr@2
  1691
@see RSqlStatement
williamr@2
  1692
@see ESqlDbError
williamr@2
  1693
@see TSqlRetCodeClass
williamr@2
  1694
williamr@2
  1695
@publishedAll
williamr@2
  1696
@released
williamr@2
  1697
*/
williamr@2
  1698
const TInt KSqlErrMismatch		= -330;
williamr@2
  1699
williamr@2
  1700
/**
williamr@2
  1701
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1702
williamr@2
  1703
It indicates an internal logic error in the SQL database engine.
williamr@2
  1704
williamr@2
  1705
@see RSqlStatement
williamr@2
  1706
@see ESqlDbError
williamr@2
  1707
@see TSqlRetCodeClass
williamr@2
  1708
williamr@2
  1709
@publishedAll
williamr@2
  1710
@released
williamr@2
  1711
*/
williamr@2
  1712
const TInt KSqlErrMisuse		= -331;
williamr@2
  1713
williamr@2
  1714
/**
williamr@2
  1715
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1716
williamr@2
  1717
It indicates that a parameter index value is out of range.
williamr@2
  1718
williamr@2
  1719
@see RSqlStatement
williamr@2
  1720
@see ESqlDbError
williamr@2
  1721
@see TSqlRetCodeClass
williamr@2
  1722
williamr@2
  1723
@publishedAll
williamr@2
  1724
@released
williamr@2
  1725
*/
williamr@2
  1726
const TInt KSqlErrRange			= -335;
williamr@2
  1727
williamr@2
  1728
/**
williamr@2
  1729
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1730
williamr@2
  1731
It indicates that the file that has been opened is not a database file.
williamr@2
  1732
williamr@2
  1733
@see RSqlStatement
williamr@2
  1734
@see ESqlDbError
williamr@2
  1735
@see TSqlRetCodeClass
williamr@2
  1736
williamr@2
  1737
@publishedAll
williamr@2
  1738
@released
williamr@2
  1739
*/
williamr@2
  1740
const TInt KSqlErrNotDb			= -336;
williamr@2
  1741
williamr@2
  1742
/**
williamr@2
  1743
An SQL database-specific error type return code from a call to the SQL API.
williamr@2
  1744
williamr@2
  1745
It indicates that an SQL statement has expired, and needs to be prepared again.
williamr@2
  1746
williamr@2
  1747
@see RSqlStatement
williamr@2
  1748
@see ESqlDbError
williamr@2
  1749
@see TSqlRetCodeClass
williamr@2
  1750
williamr@2
  1751
@publishedAll
williamr@2
  1752
@released
williamr@2
  1753
*/
williamr@2
  1754
const TInt KSqlErrStmtExpired	= -360;
williamr@2
  1755
williamr@2
  1756
IMPORT_C TSqlRetCodeClass SqlRetCodeClass(TInt aSqlRetCode);
williamr@2
  1757
williamr@2
  1758
#endif //__SQLDB_H__