persistentstorage/sql/SRC/Server/Compact/SqlCompactConn.cpp
changeset 0 08ec8eefde2f
child 9 667e88a979d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sql/SRC/Server/Compact/SqlCompactConn.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,228 @@
+// Copyright (c) 2008-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 <f32file.h>
+#include <sqldb.h>
+#include "SqlPanic.h"
+#include "sqlite3.h"
+#include "SqliteSymbian.h"		//TSqlFreePageCallback
+#include "SqlSrvUtil.h"
+#include "SqlSrvStatementUtil.h"
+#include "SqlCompactConn.h"
+
+/**
+Creates a new CSqlCompactConn instance.
+
+@param aFullName The full database name, including the path.
+@param aFreePageCallback A reference to an object containing the free pages threshold and the callback
+					     that needs to be called when the free page count reaches ot is above the threshold.
+						 aFreePageCallback.iThreshold must be set to be in Kb. 	
+						 If the function call completes successfully and the free pages space is above the threshold,
+						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
+						 Otherwise aFreePageCallback.iThreshold will be initizized with zero.
+
+@return A pointer to the created CSqlCompactConn instance
+
+@leave KErrNoMemory, an out of memory condition has occurred,
+	   KErrArgument, invalid data in the aFreePageCallback object;
+                     Note that the function may also leave with some other database specific 
+                     errors categorised as ESqlDbError, and other system-wide error codes.
+
+@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
+@panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
+*/
+CSqlCompactConn* CSqlCompactConn::NewL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
+	{
+	__SQLASSERT(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, ESqlPanicBadArgument);
+	__SQLASSERT(aFreePageCallback.IsValid(), ESqlPanicBadArgument);
+	CSqlCompactConn* self = new (ELeave) CSqlCompactConn;
+	CleanupStack::PushL(self);
+	self->ConstructL(aFullName, aFreePageCallback);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+Destroys the CSqlCompactConn instance.
+*/
+CSqlCompactConn::~CSqlCompactConn()
+	{
+	::CloseDbHandle(iHandle);
+ 	}
+
+/**
+Implements MSqlCompactConn::Release().
+Destroys the CSqlCompactConn instance.
+*/
+void CSqlCompactConn::Release()
+	{
+	SQLCOMPACTCONN_INVARIANT();
+	delete this;	
+	}
+
+/**
+Implements MSqlCompactConn::Compact().
+
+Compacts the database making an attempt to remove the specified amount of free pages.
+
+@param aPageCount 			The amount of free pages to be removed.
+@param aProcessedPageCount	Output parameter. The actual count of the removed free pages will be stored there.
+@param aLength 				Desired length of the compaction in milliseconds.
+@return KErrNoMemory, an out of memory condition has occurred;
+                      Note that the function may also return some other database specific 
+                      errors categorised as ESqlDbError, and other system-wide error codes.
+                      
+@panic SqlDb 4 In _DEBUG mode. Negative aPageCount value.
+@panic SqlDb 4 In _DEBUG mode. Negative aLength value.
+*/
+TInt CSqlCompactConn::Compact(TInt aPageCount, TInt& aProcessedPageCount, TInt aLength)
+	{
+	__SQLASSERT(aPageCount >= 0, ESqlPanicBadArgument);
+	__SQLASSERT(aLength >= 0, ESqlPanicBadArgument);
+	SQLCOMPACTCONN_INVARIANT();
+	TInt err = ::DbCompact(iHandle, KNullDesC, aPageCount, aProcessedPageCount, aLength);
+	SQLCOMPACTCONN_INVARIANT();
+	return err;
+	}
+
+/**
+Initializes the CSqlCompactConn instance establishing a connection with the database to be compacted.
+Registers the passed "free page" callback.
+
+Note: The free page threshold data member of the callback is in Kb. 
+	  The function implementation will convert that threshold to pages and pass it to the OS porting layer.
+
+@param aFullName The full database name, including the path.
+@param aFreePageCallback Input/Output parameter. A reference to an object containing the free pages threshold and 
+						 the callback that needs to be called when the free page count reaches ot is above the threshold.
+						 aFreePageCallback.iThreshold must be set to be in Kb. 	
+						 If the function call completes successfully and the free pages space is above the threshold,
+						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
+						 Otherwise aFreePageCallback.iThreshold will be initizized with zero.
+
+@leave KErrNoMemory, an out of memory condition has occurred,
+	   KErrArgument, invalid data in the aFreePageCallback object;
+                     Note that the function may also leave with some other database specific 
+                     errors categorised as ESqlDbError, and other system-wide error codes.
+
+@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
+@panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
+@panic SqlDb 7 In _DEBUG mode. The database connection has been already established (not null db handle).
+*/
+void CSqlCompactConn::ConstructL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
+	{
+	__SQLASSERT(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, ESqlPanicBadArgument);
+	__SQLASSERT(aFreePageCallback.IsValid(), ESqlPanicBadArgument);
+	__SQLASSERT(!iHandle, ESqlPanicInternalError);
+	
+	TBuf8<KMaxFileName + 1> fname;
+	(void)::UTF16ToUTF8Z(aFullName, fname);//The file is first open by the main connection. 
+										   //The conversion here should always succeeds.
+										   //Even in a case of a conversion failure, the next line will report a failure.
+	__SQLLEAVE_IF_ERROR(::CreateDbHandle8(fname, iHandle));
+	
+	TInt pageSize = PageSizeL();
+	TInt64 freePageThersholdKb = aFreePageCallback.iThreshold;//"TInt64" because the calculation of the pages may cause an overflow on the next line
+	aFreePageCallback.iThreshold = (freePageThersholdKb * 1024) / pageSize;//the threshold can be 0
+	
+	TBuf8<sizeof(KMainDb8) + 1> dbName;
+	dbName.Copy(KMainDb8);
+	TInt err = sqlite3_file_control(iHandle, (const char *)dbName.PtrZ(), KSqlFcntlRegisterFreePageCallback, &aFreePageCallback);
+	__SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError()));
+
+	TInt64 freePageCount = FreePageCountL();//"TInt64" because the calculation of the free space may cause an overflow on the next line
+	TInt freePageSpaceKb = (freePageCount * pageSize) / 1024;
+	//Set iThreshold with the free pages count, if right now the database has free space above the threshold.
+	aFreePageCallback.iThreshold = freePageSpaceKb >= freePageThersholdKb ? freePageCount : 0;
+	}
+
+/**
+Retrieves the database free pages count.
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+                      Note that the function may also return some other database specific 
+                      errors categorised as ESqlDbError, and other system-wide error codes.
+                      
+@return Free pages count
+*/
+TInt CSqlCompactConn::FreePageCountL()
+	{
+	SQLCOMPACTCONN_INVARIANT();
+	TInt freePageCount = 0;
+	__SQLLEAVE_IF_ERROR(::DbFreePageCount(iHandle, KNullDesC, freePageCount));
+	SQLCOMPACTCONN_INVARIANT();
+	return freePageCount;
+	}
+
+/**
+Retrieves the database page size in bytes.
+
+@leave KErrNoMemory, an out of memory condition has occurred;
+                      Note that the function may also return some other database specific 
+                      errors categorised as ESqlDbError, and other system-wide error codes.
+                      
+@return Page size
+*/
+TInt CSqlCompactConn::PageSizeL()
+	{
+	SQLCOMPACTCONN_INVARIANT();
+	TInt pageSize = 0;
+	__SQLLEAVE_IF_ERROR(::DbPageSize(iHandle, KNullDesC, pageSize));
+	SQLCOMPACTCONN_INVARIANT();
+	return pageSize;
+	}
+
+#ifdef _DEBUG
+/**
+CSqlCompactConn invariant.
+*/
+void CSqlCompactConn::Invariant() const
+	{
+	__SQLASSERT_ALWAYS(iHandle != NULL, ESqlPanicInternalError);
+	}
+#endif//_DEBUG
+
+/**
+A factory function for CSqlCompactConn.
+
+@param aFullName The full name of the database to be compacted (including the path).
+@param aFreePageCallback A reference to an object containing the free pages threshold and the callback
+					     that needs to be called when the free page count reaches ot is above the threshold.
+						 aFreePageCallback.iThreshold must be set to be in Kb. 	
+						 If the function call completes successfully and the free pages space is above the threshold,
+						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
+						 Otherwise aFreePageCallback.iThreshold will be initizized with zero.
+					  
+@return A pointer to the created MSqlCompactConn interface.
+
+@leave KErrNoMemory, an out of memory condition has occurred,
+	   KErrArgument, invalid data in the aFreePageCallback object;
+                     Note that the function may also leave with some other database specific 
+                     errors categorised as ESqlDbError, and other system-wide error codes.
+
+@see MSqlCompactConn
+@see CSqlCompactConn
+
+@internalComponent
+
+@panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
+@panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
+*/
+MSqlCompactConn* SqlCreateCompactConnL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
+	{
+	__SQLASSERT(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, ESqlPanicBadArgument);
+	__SQLASSERT(aFreePageCallback.IsValid(), ESqlPanicBadArgument);
+	return CSqlCompactConn::NewL(aFullName, aFreePageCallback);
+	}