os/persistentdata/persistentstorage/sql/SRC/Server/Compact/SqlCompactConn.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sql/SRC/Server/Compact/SqlCompactConn.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,236 @@
     1.4 +// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include <f32file.h>
    1.20 +#include <sqldb.h>
    1.21 +#include "SqlAssert.h"
    1.22 +#include "sqlite3.h"
    1.23 +#include "SqliteSymbian.h"		//TSqlFreePageCallback
    1.24 +#include "SqlSrvUtil.h"
    1.25 +#include "SqlSrvStatementUtil.h"
    1.26 +#include "SqlCompactConn.h"
    1.27 +#include "OstTraceDefinitions.h"
    1.28 +#ifdef OST_TRACE_COMPILER_IN_USE
    1.29 +#include "SqlCompactConnTraces.h"
    1.30 +#endif
    1.31 +#include "SqlTraceDef.h"
    1.32 +
    1.33 +/**
    1.34 +Creates a new CSqlCompactConn instance.
    1.35 +
    1.36 +@param aFullName The full database name, including the path.
    1.37 +@param aFreePageCallback A reference to an object containing the free pages threshold and the callback
    1.38 +					     that needs to be called when the free page count reaches or is above the threshold.
    1.39 +						 aFreePageCallback.iThreshold must be set to be in Kb. 	
    1.40 +						 If the function call completes successfully and the free pages space is above the threshold,
    1.41 +						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
    1.42 +						 Otherwise aFreePageCallback.iThreshold will be initialized with zero.
    1.43 +
    1.44 +@return A pointer to the created CSqlCompactConn instance
    1.45 +
    1.46 +@leave KErrNoMemory, an out of memory condition has occurred,
    1.47 +	   KErrArgument, invalid data in the aFreePageCallback object;
    1.48 +                     Note that the function may also leave with some other database specific 
    1.49 +                     errors categorised as ESqlDbError, and other system-wide error codes.
    1.50 +
    1.51 +@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
    1.52 +@panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
    1.53 +*/
    1.54 +CSqlCompactConn* CSqlCompactConn::NewL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
    1.55 +	{
    1.56 +	SQL_TRACE_COMPACT(OstTraceExt1(TRACE_INTERNALS, CSQLCOMPACTCONN_NEWLC_ENTRY, "Entry;0;CSqlCompactConn::NewL;aFullName=%S", __SQLPRNSTR(aFullName)));
    1.57 +	__ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicBadArgument));
    1.58 +	__ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC2(ESqlPanicBadArgument));
    1.59 +	CSqlCompactConn* self = new (ELeave) CSqlCompactConn;
    1.60 +	CleanupStack::PushL(self);
    1.61 +	self->ConstructL(aFullName, aFreePageCallback);
    1.62 +	CleanupStack::Pop(self);
    1.63 +	SQL_TRACE_COMPACT(OstTraceExt2(TRACE_INTERNALS, CSQLCOMPACTCONN_NEWLC_EXIT, "Exit;0x%X;CSqlCompactConn::NewL;aFullName=%S", (TUint)self, __SQLPRNSTR(aFullName)));
    1.64 +	return self;
    1.65 +	}
    1.66 +
    1.67 +/**
    1.68 +Destroys the CSqlCompactConn instance.
    1.69 +*/
    1.70 +CSqlCompactConn::~CSqlCompactConn()
    1.71 +	{
    1.72 +	SQL_TRACE_COMPACT(OstTrace1(TRACE_INTERNALS, CSQLCOMPACTCONN_CSQLCOMPACTCONN2, "0x%X;CSqlCompactConn::~CSqlCompactConn", (TUint)this));
    1.73 +	::CloseDbHandle(iHandle);
    1.74 + 	}
    1.75 +
    1.76 +/**
    1.77 +Implements MSqlCompactConn::Release().
    1.78 +Destroys the CSqlCompactConn instance.
    1.79 +*/
    1.80 +void CSqlCompactConn::Release()
    1.81 +	{
    1.82 +	SQLCOMPACTCONN_INVARIANT();
    1.83 +	delete this;	
    1.84 +	}
    1.85 +
    1.86 +/**
    1.87 +Implements MSqlCompactConn::Compact().
    1.88 +
    1.89 +Compacts the database making an attempt to remove the specified amount of free pages.
    1.90 +
    1.91 +@param aPageCount 			The amount of free pages to be removed.
    1.92 +@param aProcessedPageCount	Output parameter. The actual count of the removed free pages will be stored there.
    1.93 +@param aLength 				Desired length of the compaction in milliseconds.
    1.94 +@return KErrNoMemory, an out of memory condition has occurred;
    1.95 +                      Note that the function may also return some other database specific 
    1.96 +                      errors categorised as ESqlDbError, and other system-wide error codes.
    1.97 +                      
    1.98 +@panic SqlDb 4 In _DEBUG mode. Negative aPageCount value.
    1.99 +@panic SqlDb 4 In _DEBUG mode. Negative aLength value.
   1.100 +*/
   1.101 +TInt CSqlCompactConn::Compact(TInt aPageCount, TInt& aProcessedPageCount, TInt aLength)
   1.102 +	{
   1.103 +	__ASSERT_DEBUG(aPageCount >= 0, __SQLPANIC(ESqlPanicBadArgument));
   1.104 +	__ASSERT_DEBUG(aLength >= 0, __SQLPANIC(ESqlPanicBadArgument));
   1.105 +	SQLCOMPACTCONN_INVARIANT();
   1.106 +	TInt err = ::DbCompact(iHandle, KNullDesC, aPageCount, aProcessedPageCount, aLength);
   1.107 +	SQLCOMPACTCONN_INVARIANT();
   1.108 +	return err;
   1.109 +	}
   1.110 +
   1.111 +/**
   1.112 +Initializes the CSqlCompactConn instance establishing a connection with the database to be compacted.
   1.113 +Registers the passed "free page" callback.
   1.114 +
   1.115 +Note: The free page threshold data member of the callback is in Kb. 
   1.116 +	  The function implementation will convert that threshold to pages and pass it to the OS porting layer.
   1.117 +
   1.118 +@param aFullName The full database name, including the path.
   1.119 +@param aFreePageCallback Input/Output parameter. A reference to an object containing the free pages threshold and 
   1.120 +						 the callback that needs to be called when the free page count reaches or is above the threshold.
   1.121 +						 aFreePageCallback.iThreshold must be set to be in Kb. 	
   1.122 +						 If the function call completes successfully and the free pages space is above the threshold,
   1.123 +						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
   1.124 +						 Otherwise aFreePageCallback.iThreshold will be initialized with zero.
   1.125 +
   1.126 +@leave KErrNoMemory, an out of memory condition has occurred,
   1.127 +	   KErrArgument, invalid data in the aFreePageCallback object;
   1.128 +                     Note that the function may also leave with some other database specific 
   1.129 +                     errors categorised as ESqlDbError, and other system-wide error codes.
   1.130 +
   1.131 +@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
   1.132 +@panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
   1.133 +@panic SqlDb 7 In _DEBUG mode. The database connection has been already established (not null db handle).
   1.134 +*/
   1.135 +void CSqlCompactConn::ConstructL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
   1.136 +	{
   1.137 +	__ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC(ESqlPanicBadArgument));
   1.138 +	__ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC(ESqlPanicBadArgument));
   1.139 +	__ASSERT_DEBUG(!iHandle, __SQLPANIC(ESqlPanicInternalError));
   1.140 +	
   1.141 +	TBuf8<KMaxFileName + 1> fname;
   1.142 +	(void)::UTF16ToUTF8Z(aFullName, fname);//The file is first open by the main connection. 
   1.143 +										   //The conversion here should always succeed.
   1.144 +										   //Even in a case of a conversion failure, the next line will report a failure.
   1.145 +	__SQLLEAVE_IF_ERROR(::CreateDbHandle8(fname, iHandle));
   1.146 +	
   1.147 +	TInt pageSize = PageSizeL();
   1.148 +	TInt64 freePageThresholdKb = aFreePageCallback.iThreshold;//"TInt64" because the calculation of the pages may cause an overflow on the next line
   1.149 +	aFreePageCallback.iThreshold = (freePageThresholdKb * 1024) / pageSize;//the threshold can be 0
   1.150 +	
   1.151 +	TBuf8<sizeof(KMainDb8) + 1> dbName;
   1.152 +	dbName.Copy(KMainDb8);
   1.153 +	TInt err = sqlite3_file_control(iHandle, (const char *)dbName.PtrZ(), KSqlFcntlRegisterFreePageCallback, &aFreePageCallback);
   1.154 +	__SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError()));
   1.155 +
   1.156 +	TInt64 freePageCount = FreePageCountL();//"TInt64" because the calculation of the free space may cause an overflow on the next line
   1.157 +	TInt freePageSpaceKb = (freePageCount * pageSize) / 1024;
   1.158 +	//Set iThreshold with the free pages count, if right now the database has free space above the threshold.
   1.159 +	aFreePageCallback.iThreshold = freePageSpaceKb >= freePageThresholdKb ? freePageCount : 0;
   1.160 +	}
   1.161 +
   1.162 +/**
   1.163 +Retrieves the database free pages count.
   1.164 +
   1.165 +@leave KErrNoMemory, an out of memory condition has occurred;
   1.166 +                      Note that the function may also return some other database specific 
   1.167 +                      errors categorised as ESqlDbError, and other system-wide error codes.
   1.168 +                      
   1.169 +@return Free pages count
   1.170 +*/
   1.171 +TInt CSqlCompactConn::FreePageCountL()
   1.172 +	{
   1.173 +	SQLCOMPACTCONN_INVARIANT();
   1.174 +	TInt freePageCount = 0;
   1.175 +	__SQLLEAVE_IF_ERROR(::DbFreePageCount(iHandle, KNullDesC, freePageCount));
   1.176 +	SQLCOMPACTCONN_INVARIANT();
   1.177 +	return freePageCount;
   1.178 +	}
   1.179 +
   1.180 +/**
   1.181 +Retrieves the database page size in bytes.
   1.182 +
   1.183 +@leave KErrNoMemory, an out of memory condition has occurred;
   1.184 +                      Note that the function may also return some other database specific 
   1.185 +                      errors categorised as ESqlDbError, and other system-wide error codes.
   1.186 +                      
   1.187 +@return Page size
   1.188 +*/
   1.189 +TInt CSqlCompactConn::PageSizeL()
   1.190 +	{
   1.191 +	SQLCOMPACTCONN_INVARIANT();
   1.192 +	TInt pageSize = 0;
   1.193 +	__SQLLEAVE_IF_ERROR(::DbPageSize(iHandle, KNullDesC, pageSize));
   1.194 +	SQLCOMPACTCONN_INVARIANT();
   1.195 +	return pageSize;
   1.196 +	}
   1.197 +
   1.198 +#ifdef _DEBUG
   1.199 +/**
   1.200 +CSqlCompactConn invariant.
   1.201 +*/
   1.202 +void CSqlCompactConn::Invariant() const
   1.203 +	{
   1.204 +	__ASSERT_ALWAYS(iHandle != NULL, __SQLPANIC(ESqlPanicInternalError));
   1.205 +	}
   1.206 +#endif//_DEBUG
   1.207 +
   1.208 +/**
   1.209 +A factory function for CSqlCompactConn.
   1.210 +
   1.211 +@param aFullName The full name of the database to be compacted (including the path).
   1.212 +@param aFreePageCallback A reference to an object containing the free pages threshold and the callback
   1.213 +					     that needs to be called when the free page count reaches or is above the threshold.
   1.214 +						 aFreePageCallback.iThreshold must be set to be in Kb. 	
   1.215 +						 If the function call completes successfully and the free pages space is above the threshold,
   1.216 +						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
   1.217 +						 Otherwise aFreePageCallback.iThreshold will be initialized with zero.
   1.218 +					  
   1.219 +@return A pointer to the created MSqlCompactConn interface.
   1.220 +
   1.221 +@leave KErrNoMemory, an out of memory condition has occurred,
   1.222 +	   KErrArgument, invalid data in the aFreePageCallback object;
   1.223 +                     Note that the function may also leave with some other database specific 
   1.224 +                     errors categorised as ESqlDbError, and other system-wide error codes.
   1.225 +
   1.226 +@see MSqlCompactConn
   1.227 +@see CSqlCompactConn
   1.228 +
   1.229 +@internalComponent
   1.230 +
   1.231 +@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
   1.232 +@panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
   1.233 +*/
   1.234 +MSqlCompactConn* SqlCreateCompactConnL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
   1.235 +	{
   1.236 +	__ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicBadArgument));
   1.237 +	__ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC2(ESqlPanicBadArgument));
   1.238 +	return CSqlCompactConn::NewL(aFullName, aFreePageCallback);
   1.239 +	}