persistentstorage/sql/SRC/Client/SqlDatabaseImpl.cpp
changeset 0 08ec8eefde2f
child 11 667e88a979d7
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "SqlSecurityImpl.h"	//CSqlSecurityPolicy
       
    17 #include "SqlDatabaseImpl.h"	//CSqlDatabaseImpl
       
    18 #include <e32debug.h>
       
    19 
       
    20 /**
       
    21 Manual compaction - max compacton step execution time in microseconds.
       
    22 
       
    23 @internalComponent
       
    24 */
       
    25 static const TInt KCompactMaxStepTimeUs = 100000;
       
    26 
       
    27 /**
       
    28 Minimal amount of free database space to be removed by the compaction steps.
       
    29 
       
    30 @internalComponent
       
    31 */
       
    32 static const TInt KCompactMinStepSize =  2 * 1024;
       
    33 
       
    34 /**
       
    35 The amount of free database space to be removed by the first compaction step.
       
    36 
       
    37 @internalComponent
       
    38 */
       
    39 static const TInt KCompactStartStepSize = 32 * 1024;
       
    40 
       
    41 /**
       
    42 Calculates the amount of space that has to be removed from the database.
       
    43 The decision is based on the time spent on the pervious compaction step.
       
    44 If the time is bigger than KCompactMaxStepTimeUs then the space will be reduced by factor of 2 (slow media),
       
    45 bet will never be less than KCompactMinStepSize.
       
    46 If the time is less than the KCompactMaxStepTimeUs/2 then the space will be increased by factor of 2 (fast media).
       
    47 
       
    48 @param aRemaining The remaining free database space.
       
    49 @param aStep The size of the space removed by the previous compaction step.
       
    50 @param aTime The execution time of the previous compaction step.
       
    51 
       
    52 @return The size in bytes if the next comaction step - the amount of space to be removed.
       
    53 
       
    54 @see KMaxStepTimeUs
       
    55 @see KMinStepSize
       
    56 @see KStartStepSize
       
    57 
       
    58 @internalComponent
       
    59 */
       
    60 static TInt CalcCompactionStep(TInt aRemaining, TInt aStep, TInt aTime)
       
    61 	{
       
    62 	if(aTime > KCompactMaxStepTimeUs)
       
    63 		{
       
    64 		aStep /= 2;
       
    65 		if(aStep < KCompactMinStepSize)
       
    66 			{
       
    67 			aStep = KCompactMinStepSize; 
       
    68 			}
       
    69 		}
       
    70 	else if(aTime <= (KCompactMaxStepTimeUs / 2))
       
    71 		{
       
    72 		aStep *= 2;
       
    73 		}
       
    74 	if(aRemaining < aStep)
       
    75 		{
       
    76 		aStep = aRemaining;
       
    77 		}
       
    78 	return aStep;
       
    79 	}
       
    80  
       
    81 /**
       
    82 Creates a new CSqlDatabaseImpl instance.
       
    83 
       
    84 CSqlDatabaseImpl implements RSqlDatabase, which means that CSqlDatabaseImpl instance will be created from 
       
    85 RSqlDatabase functions doing RSqlDatabase instance initialization - Create() and Open().
       
    86 
       
    87 @param aFunction It may have one of the following values: 																																																																																																																																																																																																																																																																																																																																																																																																							
       
    88  ESqlSrvDbCreate       - Create a shared non-secure or private secure database;
       
    89  ESqlSrvDbCreateSecure - Create a shared secure database;
       
    90  ESqlSrvDbOpen         - Open a shared non-secure, shared secure or private secure database;
       
    91 	
       
    92 @param aDbFileName The name of the file that is to host the database.
       
    93 				   If it is a secure database, then the format of the name is 
       
    94 				   \<drive\>:\<[SID]database file name excluding the path\>. "[SID]" refers to the application SID.
       
    95 				   If it is a non-secure database then aDbFileName should contain the full path name of the file 
       
    96 				   that is to host the database.
       
    97 @param aSecurityPolicy The container for the security policies. 
       
    98 				   aSecurityPolicy is NULL if aDbFileName refers to a non-secure database.
       
    99 @param aConfig the configuration string "PARAM=VALUE;...."
       
   100 
       
   101 @return A pointer to the created CSqlDatabaseImpl instance.
       
   102 
       
   103 @leave KErrNoMemory, an out of memory condition has occurred;
       
   104        KErrBadName, the file name is invalid - it has either a zero length or it is the name of a directory;
       
   105        KErrArgument, system table name found in the security policies (aSecurityPolicy);
       
   106        KErrAlreadyExists, the file already exists;
       
   107        KErrNotReady, the drive does not exist or is not ready;
       
   108        KErrInUse, the file is already open;
       
   109        KErrNotFound, database file not found;
       
   110        KErrGeneral, missing or invalid security policies (if the database to be opened is a secure database);
       
   111        KErrNotSupported, incompatible SQL security version (if the database to be opened is a secure database).
       
   112        KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
       
   113                       Note that the function may leave with database specific errors categorised as ESqlDbError and
       
   114                       other system-wide error codes.
       
   115                       
       
   116 @see RSqlDatabase
       
   117 @see RSqlDatabase::Create()
       
   118 @see RSqlDatabase::Open()
       
   119 @see TSqlSrvFunction
       
   120 @see CSqlSecurityPolicy
       
   121 */
       
   122 CSqlDatabaseImpl* CSqlDatabaseImpl::NewL(TSqlSrvFunction aFunction, const TDesC& aDbFileName, 
       
   123 										 const CSqlSecurityPolicy* aSecurityPolicy,
       
   124 										 const TDesC8* aConfig)
       
   125 	{
       
   126 	CSqlDatabaseImpl* self = new (ELeave) CSqlDatabaseImpl;
       
   127 	CleanupStack::PushL(self);
       
   128 	self->ConstructL(aFunction, aDbFileName, aSecurityPolicy, aConfig);
       
   129 	CleanupStack::Pop(self);
       
   130 	return self;
       
   131 	}
       
   132 
       
   133 /**
       
   134 Initializes the created CSqlDatabaseImpl instance.
       
   135 
       
   136 @param aFunction It may have one of the following values:
       
   137   ESqlSrvDbCreate       - Create a shared non-secure or private secure database;
       
   138   ESqlSrvDbCreateSecure - Create a shared secure database;
       
   139   ESqlSrvDbOpen         - Open a shared non-secure, shared secure or private secure database;
       
   140 
       
   141 @param aDbFileName The name of the file that is to host the database.
       
   142 				   If it is a secure database, then the format of the name is 
       
   143 				   \<drive\>:\<[SID]database file name excluding the path\>. "[SID]" refers to the application SID.
       
   144 				   If it is a non-secure database then aDbFileName should contain the full path name of the file 
       
   145 				   that is to host the database.
       
   146 @param aSecurityPolicy The container for the security policies. 
       
   147 				   aSecurityPolicy is NULL if aDbFileName refers to a non-secure database.
       
   148 @param aConfig the configuration string "PARAM=VALUE;...."
       
   149 
       
   150 @leave KErrNoMemory, an out of memory condition has occurred;
       
   151        KErrBadName, the file name is invalid - it has either a zero length or it is the name of a directory;
       
   152        KErrArgument, system table name found in the security policies (aSecurityPolicy);
       
   153        KErrAlreadyExists, the file already exists;
       
   154        KErrNotReady, the drive does not exist or is not ready;
       
   155        KErrInUse, the file is already open;
       
   156        KErrNotFound, database file not found;
       
   157        KErrGeneral, missing or invalid security policies (if the database to be opened is a secure database);
       
   158        KErrNotSupported, incompatible SQL security version (if the database to be opened is a secure database).
       
   159        KErrPermissionDenied, the caller does not satisfy the relevant database security policies.
       
   160                       Note that the function may leave with database specific errors categorised as ESqlDbError and
       
   161                       other system-wide error codes.
       
   162 
       
   163 @see CSqlDatabaseImpl::NewL()
       
   164 
       
   165 @panic SqlDb 4 In _DEBUG mode. aSecurityPolicy is NULL, but the request is for opening/creating a secure database.
       
   166 */
       
   167 void CSqlDatabaseImpl::ConstructL(TSqlSrvFunction aFunction, const TDesC& aDbFileName, 
       
   168 								  const CSqlSecurityPolicy* aSecurityPolicy, const TDesC8* aConfig)
       
   169 	{
       
   170 	TPtrC8 securityPolicyData;
       
   171 	if(aFunction == ESqlSrvDbCreateSecure)	
       
   172 		{
       
   173 		__SQLASSERT(aSecurityPolicy != NULL, ESqlPanicBadArgument);
       
   174 		const RSqlBufFlat& bufFlat = aSecurityPolicy->BufFlat();
       
   175 		securityPolicyData.Set(bufFlat.BufDes());
       
   176 		}
       
   177 	__SQLLEAVE_IF_ERROR(Session().Connect(aFunction, aDbFileName, securityPolicyData, aConfig));
       
   178 	}
       
   179 
       
   180 /**
       
   181 Frees the allocated by CSqlDatabaseImpl instance memory and other resources.
       
   182 */
       
   183 CSqlDatabaseImpl::~CSqlDatabaseImpl()
       
   184 	{
       
   185 	Session().Close();
       
   186 	}
       
   187 
       
   188 /**
       
   189 Creates and returns a copy of the database security policies object.
       
   190 The caller is responsible for destroying the returned CSqlSecurityPolicy instance.
       
   191 
       
   192 Implements RSqlDatabase::GetSecurityPolicyL().
       
   193 
       
   194 @return A copy of the database security policies object. 
       
   195         The returned copy must be destroyed by the caller.
       
   196         
       
   197 @leave KErrNotSupported, the current database is not a secure database;
       
   198        KErrNoMemory, an out of memory condition has occurred;
       
   199 
       
   200 @see RSqlDatabase
       
   201 @see RSqlDatabase::GetSecurityPolicyL()
       
   202 */
       
   203 CSqlSecurityPolicy* CSqlDatabaseImpl::CloneSecurityPolicyL()
       
   204 	{
       
   205 	TSecurityPolicy defaultPolicy(TSecurityPolicy::EAlwaysFail);
       
   206 	CSqlSecurityPolicy* dbPolicy = CSqlSecurityPolicy::NewLC(defaultPolicy);
       
   207 	__SQLLEAVE_IF_ERROR(Session().GetSecurityPolicy(dbPolicy->BufFlat()));
       
   208 	CleanupStack::Pop(dbPolicy);
       
   209 	return dbPolicy;
       
   210 	}
       
   211 
       
   212 /**
       
   213 Implements RSqlDatabase::Compact().
       
   214 
       
   215 @param aSize Can be one of:
       
   216 				 RSqlDatabase::EMaxCompaction - requests a full database compaction. All free pages
       
   217 				  (if any exists) will be removed;
       
   218 				 Positive integer value - the server will attempt to compact the database removing 
       
   219 				  at most aSize bytes from the database file, rounded up to the nearest page count, 
       
   220 				  e.g. request for removing 1 byte will remove one free page from the database;
       
   221 @param aDbName The attached database name or KNullDesC for the main database
       
   222 
       
   223 @return Zero or positive integer - the operation has completed succesfully, the return value is the
       
   224          						   size of the removed free space in bytes,
       
   225 		KErrArgument, Invalid aSize value;
       
   226         KErrBadName, Invalid (too long) attached database name;
       
   227         KSqlErrReadOnly, Read-only database;
       
   228         KSqlErrGeneral, There is no an attached database with aDbName name;
       
   229                   Note that database specific errors categorised as ESqlDbError, and
       
   230                   other system-wide error codes may also be returned.
       
   231 
       
   232 Usage of the IPC call arguments:
       
   233 Arg 0: [out]	How much space in bytes should be compacted, all free pages should be removed if the
       
   234 				parameter value is RSqlDatabase::EMaxCompaction.
       
   235 Arg 1: [out]	The database name length in characters
       
   236 Arg 2: [out]	The attached database name or KNullDesC for the main database
       
   237 */
       
   238 TInt CSqlDatabaseImpl::Compact(TInt aSize, const TDesC& aDbName)
       
   239 	{
       
   240 	if(aSize < 0)
       
   241 		{
       
   242 		if(aSize != RSqlDatabase::EMaxCompaction)
       
   243 			{
       
   244 			return KErrArgument;
       
   245 			}
       
   246 		aSize = KMaxTInt;
       
   247 		}
       
   248 	TInt remaining = aSize;
       
   249 	TInt compacted = 0;
       
   250 	TInt step = KCompactStartStepSize;
       
   251 	TInt rc = 0;
       
   252 	TTimeIntervalMicroSeconds interval(0);
       
   253 	while(remaining > 0)
       
   254 		{
       
   255 		step = ::CalcCompactionStep(remaining, step, interval.Int64());
       
   256 		TTime start;
       
   257 		start.HomeTime();
       
   258 		rc = Session().SendReceive(ESqlSrvDbCompact, TIpcArgs(step, aDbName.Length(), &aDbName));
       
   259 		if(rc <= 0)
       
   260 			{
       
   261 			break;	
       
   262 			}
       
   263 		TTime end;
       
   264 		end.HomeTime();
       
   265 		interval = end.MicroSecondsFrom(start);
       
   266 		remaining -= rc;				
       
   267 		compacted += rc;
       
   268 		}
       
   269 	return rc < 0 ? rc : compacted;
       
   270 	}
       
   271 
       
   272 /**
       
   273 Usage of the IPC call arguments:
       
   274 Arg 0: [out]	How much space in bytes should be compacted, all free pages should be removed if the
       
   275 				parameter value is RSqlDatabase::EMaxCompaction.
       
   276 Arg 1: [out]	The database name length in characters
       
   277 Arg 2: [out]	The attached database name or KNullDesC for the main database
       
   278 */
       
   279 void CSqlDatabaseImpl::Compact(TInt aSize, const TDesC& aDbName, TRequestStatus& aStatus)
       
   280 	{
       
   281 	if(aSize == 0)
       
   282 		{
       
   283 		TRequestStatus* stat = &aStatus;
       
   284 		User::RequestComplete(stat, 0);
       
   285 		return;
       
   286 		}
       
   287 	Session().SendReceive(ESqlSrvDbCompact, TIpcArgs(aSize, aDbName.Length(), &aDbName), aStatus);
       
   288 	}