--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/dbms/udbms/UD_DBS.CPP Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,573 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "UD_STD.H"
+
+// Class RDbDatabase
+
+/**
+Closes a database. Commits any pending transaction. Frees the allocated resources.
+*/
+EXPORT_C void RDbDatabase::Close()
+ {
+ CDbDatabase* db=iDatabase();
+ if (db && InTransaction())
+ Commit(); // attempt to commit
+ iDatabase.Close();
+ }
+
+//
+// Runs the incremental DDL object to completion.
+//
+LOCAL_C void CompleteDDLL(CDbIncremental* aIncremental,TInt& aStep)
+ {
+ __ASSERT((aIncremental==0)==(aStep==0));
+ if (!aIncremental)
+ return;
+ aIncremental->PushL();
+ do aIncremental->NextL(aStep);
+ while (aStep!=0);
+ CleanupStack::PopAndDestroy(); // aIncrmental
+ }
+
+//
+// Runs the DML incremental object to completion.
+//
+LOCAL_C void CompleteDMLL(CDbIncremental* aIncremental,TInt& aRows)
+ {
+ __ASSERT((aIncremental==0)!=(aRows==0));
+ if (!aIncremental)
+ return;
+ aIncremental->PushL();
+ while (aIncremental->NextL(aRows))
+ ;
+ CleanupStack::PopAndDestroy(); // aIncremental
+ }
+
+LOCAL_C TInt Property(const RDbHandle<CDbDatabase>& aDb,CDbDatabase::TProperty aProperty)
+ {
+ return aDb->Property(aProperty);
+ }
+
+LOCAL_C TInt Utility(RDbHandle<CDbDatabase>& aDb,CDbDatabase::TUtility aType)
+ {
+ TInt step;
+ TRAPD(r,CompleteDDLL(aDb->UtilityL(aType,step),step));
+ return r;
+ }
+
+/**
+Reports the damage status of the database.
+The function checks database indexes and returs true if some of them are broken.
+
+@return True if the database is damaged, false otherwise.
+*/
+EXPORT_C TBool RDbDatabase::IsDamaged() const
+ {
+ return Property(iDatabase,CDbDatabase::EIsDamaged);
+ }
+
+/**
+Synchronous database recovery.
+Recover() will try to rebuild database indexes if they are broken.
+If the database data is corrupted, it cannot be recovered.
+
+@return KErrNone The operation has completed successfully;
+ KErrNoMemory, an out of memory condition has occurred;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::Recover()
+ {
+ return Utility(iDatabase,CDbDatabase::ERecover);
+ }
+
+/**
+Returns the currently available size information for the database.
+This comprises a size in bytes for the database objects and a percentage used value which indicates
+how much of that size is live data-the remainder may be available for compaction.
+Some types of database may not be able to report this information, e.g. a RDbStoreDatabase,
+and others may need to have UpdateStats() in order to provide valid data.
+In these cases, the values in the RDbDatabase::TSize structure will contain an error value to indicate this.
+
+@return RDbDatabase::TSize object, containing the database size and the percentage used value.
+*/
+EXPORT_C RDbDatabase::TSize RDbDatabase::Size() const
+ {
+ TSize size;
+ size.iSize=Property(iDatabase,CDbDatabase::ESize);
+ size.iUsage=Property(iDatabase,CDbDatabase::EUsage);
+ return size;
+ }
+
+/**
+Update any calculated statistics for the database.
+Note that this can take an extended time to complete,
+so an incremental form is also provided - RDbIncremental::UpdateStats().
+
+@return KErrNone The operation has completed successfully;
+ KErrNoMemory, an out of memory condition has occurred;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the database.
+
+@see RDbIncremental::UpdateStats()
+*/
+EXPORT_C TInt RDbDatabase::UpdateStats()
+ {
+ return Utility(iDatabase,CDbDatabase::EStats);
+ }
+
+/**
+Synchronous database compaction.
+Compacts the database and returns when complete.
+Note that this can take an extended time to complete, so an incremental form is also provided.
+There is a complementary interface to calculate and report database size and usage information, which
+can be used by the clients to determine when it may be appropriate to compact the database.
+
+@see RDbIncremental::Compact()
+@see RDbDatabase::UpdateStats()
+@see RDbDatabase::Size()
+
+@return KErrNone The operation has completed successfully;
+ KErrNoMemory, an out of memory condition has occurred;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the write
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::Compact()
+ {
+ return Utility(iDatabase,CDbDatabase::ECompact);
+ }
+
+
+/**
+Drops the tables and destroys the database.
+This handle is closed on successful destruction.
+
+@return KErrNone The operation has completed successfully;
+ KErrNoMemory, an out of memory condition has occurred;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the schema
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::Destroy()
+ {
+ CDbTableNames* t=NULL;
+ TRAPD(r,t=TableNamesL());
+ if (r!=KErrNone)
+ return r;
+ TInt ii=t->Count();
+ do
+ {
+ if (--ii<0)
+ {
+ r=iDatabase->Destroy();
+ if (r==KErrNone)
+ iDatabase.Close();
+ break;
+ }
+ r=DropTable((*t)[ii]);
+ } while (r==KErrNone);
+ delete t;
+ return r;
+ }
+
+/**
+Begins a transaction.
+
+DBMS server only supports one 'granularity' of transaction lock: the whole database.
+Beginning a transaction locks the database, and this can fail if another client has already got a lock which
+excludes this client.
+If the same client has already locked the database it will be panic'd.
+The function is guaranteed to return KErrNone for client-side access.
+
+DBMS transactions do not provide any form of isolation between the clients:
+while one client is updating a table within a transaction, other clients will be able to see the changes as
+they are made. As a result, if a client retrieves two separate rows from a database there is no automatic
+guarantee that the data being retrieved has not been changed between the reads - this can lead to
+an 'inconsistent read'. A client can prevent an update while retrieving related rows by enclosing the individual
+reads within a transaction. Such a transaction will not modify the database and only operates as a read-lock:
+releasing such a lock using Commit() or Rollback() will not affect the database in any way.
+
+How RDbDatabase::Begin() works:
+ - on a shared database Begin() will attempt to get a shared read-lock on the database, and will fail with
+ KErrLocked if anyone has an exclusive write-lock. Other clients with read-locks will not cause this operation
+ to fail.
+ - any operation which will modify the database attempts to gain an exclusive write-lock on the database,
+ and will fail with KErrLocked if anyone else has any lock on the database. If the current client already has
+ a read-lock as a result of calling Begin(), then it will be upgraded to an exclusive write-lock.
+ - Commit() or Rollback() after a read-lock has been acquired (but not a write-lock) will release that client's
+ lock. The database will only be considered to be unlocked when all such locks are removed by all clients,
+ when it will report a EUnlock event to any notifiers.
+ - Commit() or Rollback() after a write-lock has been acquired will release the lock, and report the ECommit or
+ ERollback event to any notifiers.
+ - automatic transactions will be used as at present if updates are made outside of explicit transactions,
+ and such updates will also be able to fail with KErrLocked if an exclusive lock cannot be acquired.
+
+Allowing read-locks to be shared enables greater concurrency at the same time as providing some safe guard
+against inconsistent reads. It does, however, lead to the possibility of deadlock: two clients wanting to update
+the database can reach deadlock if they both Begin() a transaction before either of them starts an update,
+then one client's read-lock will prevent the other from upgrading to a write lock and vice versa. The only way out
+of this is to code the clients in such a way as to back out of such a deadlock situation, rather than retry
+forever without releasing the locks.
+
+A client will be able to change the database schema while other clients are using the database,
+as long as the other clients have no locks on it. As described above, other clients may find that their
+rowsets are then invalidated asynchronously as a result of this.
+
+@return KErrNone The operation has completed successfully;
+ KErrLocked, the database is locked by another client;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy either the read, write
+ or the schema access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::Begin()
+ {
+ return iDatabase->Begin();
+ }
+
+/**
+Commits the current transaction.
+
+@return KErrNone The operation has completed successfully;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy either the read, write
+ or the schema access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::Commit()
+ {
+ return iDatabase->Commit();
+ }
+
+/**
+Rollbacks the current transaction.
+
+@capability Note For a secure shared database, the caller must satisfy either the read, write
+ or the schema access policy for the database.
+*/
+EXPORT_C void RDbDatabase::Rollback()
+ {
+ iDatabase->Rollback();
+ }
+
+/**
+@return True if the database is in a transaction, false otherwise.
+*/
+EXPORT_C TBool RDbDatabase::InTransaction() const
+ {
+ return Property(iDatabase,CDbDatabase::EInTransaction);
+ }
+
+/**
+Creates a table on the database.
+
+@param aName Table name.
+@param aColSet A set of column definitions which describe the table structure.
+@param aPrimaryKey Primary key definition. If it is NULL, no primary key will be created for the new table.
+
+@return KErrNone The operation has completed successfully;
+ KErrNoMemory, an out of memory condition has occurred;
+ KErrAlreadyExists, a table with that name already exists;
+ KErrArgument, empty column set, duplicated column name, invalid column length;
+ KErrBadName, invalid table name, invalid column name (containing spaces for example);
+ KErrNotSupported, unknown column type, unknown column attributes;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the schema
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::CreateTable(const TDesC& aName,const CDbColSet& aColSet,const CDbKey* aPrimaryKey)
+ {
+ TRAPD(r,iDatabase->CreateTableL(aName,aColSet,aPrimaryKey));
+ return r;
+ }
+
+/**
+Drops a table synchronously.
+
+@param aName Table name.
+
+@return KErrNone The operation has completed successfully;
+ KErrNotFound, there is no table with the supplied name;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the schema
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::DropTable(const TDesC& aName)
+ {
+ TInt step;
+ TRAPD(r,CompleteDDLL(iDatabase->DropTableL(aName,step),step));
+ return r;
+ }
+
+/**
+Alters a table synchronously.
+
+@param aName Table name.
+@param aColSet A new set of column definitions which describe the table structure.
+
+@return KErrNone The operation has completed successfully;
+ KErrNoMemory, an out of memory condition has occurred;
+ KErrArgument, empty column set, duplicated column name, invalid column length;
+ KErrNotFound, there is no table with the supplied name;
+ KErrNotSupported, unknown column type, unknown column attributes;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the schema
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::AlterTable(const TDesC& aName,const CDbColSet& aColSet)
+ {
+ TInt step;
+ TRAPD(r,CompleteDDLL(iDatabase->AlterTableL(aName,aColSet,step),step));
+ return r;
+ }
+
+/**
+Creates an index synchronously.
+
+@param aName Index name.
+@param aTableName Table name.
+@param aKey Index definition
+
+@return KErrNone The operation has completed successfully;
+ KErrNoMemory, an out of memory condition has occurred;
+ KErrBadName, invalid index name (containing spaces for example);
+ KErrAlreadyExists, an index with that name already exists;
+ KErrNotFound, there is no table with that name;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the schema
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::CreateIndex(const TDesC& aName,const TDesC& aTableName,const CDbKey& aKey)
+ {
+ TInt step;
+ TRAPD(r,CompleteDDLL(iDatabase->CreateIndexL(aName,aTableName,aKey,step),step));
+ return r;
+ }
+
+/**
+Drops an index synchronously.
+
+@param aName Index name.
+@param aTableName Table name.
+
+@return KErrNone The operation has completed successfully;
+ KErrNotFound, there is no table or index with that name;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy the schema
+ access policy for the database.
+*/
+EXPORT_C TInt RDbDatabase::DropIndex(const TDesC& aName,const TDesC& aTableName)
+ {
+ TInt step;
+ TRAPD(r,CompleteDDLL(iDatabase->DropIndexL(aName,aTableName,step),step));
+ return r;
+ }
+
+/**
+Executes a SQL statement on the database, and returns when it is complete.
+The aComp parameter is used in the execution of some SQL statements:
+ - in CREATE INDEX statements it specifies the comparison operation used for text columns in the index key;
+ - in UPDATE and DELETE statements it specifies the comparison operation used to evaluate the WHERE clause;
+Other statements ignore the value of aComp.
+A negative return value indicates an error. A successful DDL operation always returns KErrNone (zero),
+a successful DML operation returns the number of rows that were inserted, updated or deleted by the operation.
+
+@param aSql A string of 16-bit wide characters containing one SQL statement.
+@param aComparison Tells the DBMS how to compare text and long text columns.
+
+@return Zero or positive value, the number of rows that were inserted, updated or deleted by the operation;
+ KErrLocked, the database is locked by another client;
+ KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
+ Note that other system-wide error codes may also be returned.
+
+@capability Note For a secure shared database, the caller must satisfy:
+ - the schema access policy for the database, if the SQL statement is
+ CREATE/DROP/ALTER;
+ - the write access policy for the table in the SQL, if the SQL statement is
+ INSERT/UPDATE/DELETE;
+*/
+EXPORT_C TInt RDbDatabase::Execute(const TDesC& aSql,TDbTextComparison aComparison)
+ {
+ TInt ret;
+ TRAP(ret, \
+ CDbIncremental* inc=iDatabase->ExecuteL(aSql,aComparison,ret); \
+ if (inc) \
+ ret ? CompleteDDLL(inc,ret) : CompleteDMLL(inc,ret); \
+ )
+ return ret;
+ }
+
+/**
+Lists the tables on the database.
+
+@return A pointer to a CDbTableNames container with table names. The caller is responsible for destroying
+ the returned CDbTableNames instance.
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+ Note that the function may leave with other system-wide error codes.
+*/
+EXPORT_C CDbTableNames* RDbDatabase::TableNamesL() const
+ {
+ CDbTableNames* names=CDbTableNames::NewLC();
+ iDatabase->TablesL(*names);
+ CleanupStack::Pop();
+ return names;
+ }
+
+/**
+Returns the table definition.
+
+@param aName Table name.
+
+@return A pointer to a CDbColSet container with column definitions . The caller is responsible for destroying
+ the returned CDbColSet instance.
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+ KErrNotFound, no table with that name exists;
+ Note that the function may leave with other system-wide error codes.
+*/
+EXPORT_C CDbColSet* RDbDatabase::ColSetL(const TDesC& aName) const
+ {
+ CDbColSet* set=CDbColSet::NewLC();
+ iDatabase->ColumnsL(*set,aName);
+ CleanupStack::Pop();
+ return set;
+ }
+
+/**
+Lists the indexes on a table.
+
+@param aTable Table name.
+
+@return A pointer to a CDbIndexNames container with column definitions . The caller is responsible for destroying
+ the returned CDbIndexNames instance.
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+ KErrNotFound, no table with that name exists;
+ Note that the function may leave with other system-wide error codes.
+*/
+EXPORT_C CDbIndexNames* RDbDatabase::IndexNamesL(const TDesC& aTable) const
+ {
+ CDbIndexNames* names=CDbIndexNames::NewLC();
+ iDatabase->IndexesL(*names,aTable);
+ CleanupStack::Pop();
+ return names;
+ }
+
+/**
+Returns the index key.
+
+@param aName Index name.
+@param aTable Table name.
+
+@return A pointer to a CDbKey object containing the index definition. The caller is responsible for destroying
+ the returned CDbKey instance.
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+ KErrNotFound, no index or table with that name exists;
+ Note that the function may leave with other system-wide error codes.
+*/
+EXPORT_C CDbKey* RDbDatabase::KeyL(const TDesC& aName,const TDesC& aTable) const
+ {
+ CDbKey* key=CDbKey::NewLC();
+ iDatabase->KeysL(*key,aName,aTable);
+ CleanupStack::Pop();
+ return key;
+ }
+
+// class CDbDatabase
+
+CDbNotifier* CDbDatabase::NotifierL()
+ {
+ return AttachContext(this,OpenNotifierL());
+ }
+
+CDbIncremental* CDbDatabase::UtilityL(CDbDatabase::TUtility aType,TInt& aStep)
+ {
+ return AttachContext(this,OpenUtilityL(aType,aStep));
+ }
+
+CDbIncremental* CDbDatabase::DropTableL(const TDesC& aTable,TInt& aStep)
+ {
+ return AttachContext(this,OpenDropTableL(aTable,aStep));
+ }
+
+CDbIncremental* CDbDatabase::AlterTableL(const TDesC& aTable,const CDbColSet& aNewDef,TInt& aStep)
+ {
+ return AttachContext(this,OpenAlterTableL(aTable,aNewDef,aStep));
+ }
+
+CDbIncremental* CDbDatabase::CreateIndexL(const TDesC& aName,const TDesC& aTable,const CDbKey& aKey,TInt& aStep)
+ {
+ return AttachContext(this,OpenCreateIndexL(aName,aTable,aKey,aStep));
+ }
+
+CDbIncremental* CDbDatabase::DropIndexL(const TDesC& aName,const TDesC& aTable,TInt& aStep)
+ {
+ return AttachContext(this,OpenDropIndexL(aName,aTable,aStep));
+ }
+
+CDbIncremental* CDbDatabase::ExecuteL(const TDesC& aSql,TDbTextComparison aComparison,TInt& aInit)
+ {
+ return AttachContext(this,OpenExecuteL(aSql,aComparison,aInit));
+ }
+
+CDbCursor* CDbDatabase::ViewL(const TDbQuery& aQuery,const TDbWindow& aWindow,RDbRowSet::TAccess anAccess)
+ {
+ return AttachContext(this,PrepareViewL(aQuery,aWindow,anAccess));
+ }
+
+CDbCursor* CDbDatabase::TableL(const TDesC &aName,RDbRowSet::TAccess anAccess)
+ {
+ return AttachContext(this,OpenTableL(aName,anAccess));
+ }
+
+//
+// Reserved for future development
+//
+EXPORT_C void CDbDatabase::Reserved_1()
+ {
+ }
+
+//
+// Reserved for future development
+//
+EXPORT_C void CDbDatabase::Reserved_2()
+ {
+ }