os/persistentdata/persistentstorage/sql/SRC/Server/Compact/SqlCompactConn.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2008-2010 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 <f32file.h>
    17 #include <sqldb.h>
    18 #include "SqlAssert.h"
    19 #include "sqlite3.h"
    20 #include "SqliteSymbian.h"		//TSqlFreePageCallback
    21 #include "SqlSrvUtil.h"
    22 #include "SqlSrvStatementUtil.h"
    23 #include "SqlCompactConn.h"
    24 #include "OstTraceDefinitions.h"
    25 #ifdef OST_TRACE_COMPILER_IN_USE
    26 #include "SqlCompactConnTraces.h"
    27 #endif
    28 #include "SqlTraceDef.h"
    29 
    30 /**
    31 Creates a new CSqlCompactConn instance.
    32 
    33 @param aFullName The full database name, including the path.
    34 @param aFreePageCallback A reference to an object containing the free pages threshold and the callback
    35 					     that needs to be called when the free page count reaches or is above the threshold.
    36 						 aFreePageCallback.iThreshold must be set to be in Kb. 	
    37 						 If the function call completes successfully and the free pages space is above the threshold,
    38 						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
    39 						 Otherwise aFreePageCallback.iThreshold will be initialized with zero.
    40 
    41 @return A pointer to the created CSqlCompactConn instance
    42 
    43 @leave KErrNoMemory, an out of memory condition has occurred,
    44 	   KErrArgument, invalid data in the aFreePageCallback object;
    45                      Note that the function may also leave with some other database specific 
    46                      errors categorised as ESqlDbError, and other system-wide error codes.
    47 
    48 @panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
    49 @panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
    50 */
    51 CSqlCompactConn* CSqlCompactConn::NewL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
    52 	{
    53 	SQL_TRACE_COMPACT(OstTraceExt1(TRACE_INTERNALS, CSQLCOMPACTCONN_NEWLC_ENTRY, "Entry;0;CSqlCompactConn::NewL;aFullName=%S", __SQLPRNSTR(aFullName)));
    54 	__ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicBadArgument));
    55 	__ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC2(ESqlPanicBadArgument));
    56 	CSqlCompactConn* self = new (ELeave) CSqlCompactConn;
    57 	CleanupStack::PushL(self);
    58 	self->ConstructL(aFullName, aFreePageCallback);
    59 	CleanupStack::Pop(self);
    60 	SQL_TRACE_COMPACT(OstTraceExt2(TRACE_INTERNALS, CSQLCOMPACTCONN_NEWLC_EXIT, "Exit;0x%X;CSqlCompactConn::NewL;aFullName=%S", (TUint)self, __SQLPRNSTR(aFullName)));
    61 	return self;
    62 	}
    63 
    64 /**
    65 Destroys the CSqlCompactConn instance.
    66 */
    67 CSqlCompactConn::~CSqlCompactConn()
    68 	{
    69 	SQL_TRACE_COMPACT(OstTrace1(TRACE_INTERNALS, CSQLCOMPACTCONN_CSQLCOMPACTCONN2, "0x%X;CSqlCompactConn::~CSqlCompactConn", (TUint)this));
    70 	::CloseDbHandle(iHandle);
    71  	}
    72 
    73 /**
    74 Implements MSqlCompactConn::Release().
    75 Destroys the CSqlCompactConn instance.
    76 */
    77 void CSqlCompactConn::Release()
    78 	{
    79 	SQLCOMPACTCONN_INVARIANT();
    80 	delete this;	
    81 	}
    82 
    83 /**
    84 Implements MSqlCompactConn::Compact().
    85 
    86 Compacts the database making an attempt to remove the specified amount of free pages.
    87 
    88 @param aPageCount 			The amount of free pages to be removed.
    89 @param aProcessedPageCount	Output parameter. The actual count of the removed free pages will be stored there.
    90 @param aLength 				Desired length of the compaction in milliseconds.
    91 @return KErrNoMemory, an out of memory condition has occurred;
    92                       Note that the function may also return some other database specific 
    93                       errors categorised as ESqlDbError, and other system-wide error codes.
    94                       
    95 @panic SqlDb 4 In _DEBUG mode. Negative aPageCount value.
    96 @panic SqlDb 4 In _DEBUG mode. Negative aLength value.
    97 */
    98 TInt CSqlCompactConn::Compact(TInt aPageCount, TInt& aProcessedPageCount, TInt aLength)
    99 	{
   100 	__ASSERT_DEBUG(aPageCount >= 0, __SQLPANIC(ESqlPanicBadArgument));
   101 	__ASSERT_DEBUG(aLength >= 0, __SQLPANIC(ESqlPanicBadArgument));
   102 	SQLCOMPACTCONN_INVARIANT();
   103 	TInt err = ::DbCompact(iHandle, KNullDesC, aPageCount, aProcessedPageCount, aLength);
   104 	SQLCOMPACTCONN_INVARIANT();
   105 	return err;
   106 	}
   107 
   108 /**
   109 Initializes the CSqlCompactConn instance establishing a connection with the database to be compacted.
   110 Registers the passed "free page" callback.
   111 
   112 Note: The free page threshold data member of the callback is in Kb. 
   113 	  The function implementation will convert that threshold to pages and pass it to the OS porting layer.
   114 
   115 @param aFullName The full database name, including the path.
   116 @param aFreePageCallback Input/Output parameter. A reference to an object containing the free pages threshold and 
   117 						 the callback that needs to be called when the free page count reaches or is above the threshold.
   118 						 aFreePageCallback.iThreshold must be set to be in Kb. 	
   119 						 If the function call completes successfully and the free pages space is above the threshold,
   120 						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
   121 						 Otherwise aFreePageCallback.iThreshold will be initialized with zero.
   122 
   123 @leave KErrNoMemory, an out of memory condition has occurred,
   124 	   KErrArgument, invalid data in the aFreePageCallback object;
   125                      Note that the function may also leave with some other database specific 
   126                      errors categorised as ESqlDbError, and other system-wide error codes.
   127 
   128 @panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
   129 @panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
   130 @panic SqlDb 7 In _DEBUG mode. The database connection has been already established (not null db handle).
   131 */
   132 void CSqlCompactConn::ConstructL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
   133 	{
   134 	__ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC(ESqlPanicBadArgument));
   135 	__ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC(ESqlPanicBadArgument));
   136 	__ASSERT_DEBUG(!iHandle, __SQLPANIC(ESqlPanicInternalError));
   137 	
   138 	TBuf8<KMaxFileName + 1> fname;
   139 	(void)::UTF16ToUTF8Z(aFullName, fname);//The file is first open by the main connection. 
   140 										   //The conversion here should always succeed.
   141 										   //Even in a case of a conversion failure, the next line will report a failure.
   142 	__SQLLEAVE_IF_ERROR(::CreateDbHandle8(fname, iHandle));
   143 	
   144 	TInt pageSize = PageSizeL();
   145 	TInt64 freePageThresholdKb = aFreePageCallback.iThreshold;//"TInt64" because the calculation of the pages may cause an overflow on the next line
   146 	aFreePageCallback.iThreshold = (freePageThresholdKb * 1024) / pageSize;//the threshold can be 0
   147 	
   148 	TBuf8<sizeof(KMainDb8) + 1> dbName;
   149 	dbName.Copy(KMainDb8);
   150 	TInt err = sqlite3_file_control(iHandle, (const char *)dbName.PtrZ(), KSqlFcntlRegisterFreePageCallback, &aFreePageCallback);
   151 	__SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError()));
   152 
   153 	TInt64 freePageCount = FreePageCountL();//"TInt64" because the calculation of the free space may cause an overflow on the next line
   154 	TInt freePageSpaceKb = (freePageCount * pageSize) / 1024;
   155 	//Set iThreshold with the free pages count, if right now the database has free space above the threshold.
   156 	aFreePageCallback.iThreshold = freePageSpaceKb >= freePageThresholdKb ? freePageCount : 0;
   157 	}
   158 
   159 /**
   160 Retrieves the database free pages count.
   161 
   162 @leave KErrNoMemory, an out of memory condition has occurred;
   163                       Note that the function may also return some other database specific 
   164                       errors categorised as ESqlDbError, and other system-wide error codes.
   165                       
   166 @return Free pages count
   167 */
   168 TInt CSqlCompactConn::FreePageCountL()
   169 	{
   170 	SQLCOMPACTCONN_INVARIANT();
   171 	TInt freePageCount = 0;
   172 	__SQLLEAVE_IF_ERROR(::DbFreePageCount(iHandle, KNullDesC, freePageCount));
   173 	SQLCOMPACTCONN_INVARIANT();
   174 	return freePageCount;
   175 	}
   176 
   177 /**
   178 Retrieves the database page size in bytes.
   179 
   180 @leave KErrNoMemory, an out of memory condition has occurred;
   181                       Note that the function may also return some other database specific 
   182                       errors categorised as ESqlDbError, and other system-wide error codes.
   183                       
   184 @return Page size
   185 */
   186 TInt CSqlCompactConn::PageSizeL()
   187 	{
   188 	SQLCOMPACTCONN_INVARIANT();
   189 	TInt pageSize = 0;
   190 	__SQLLEAVE_IF_ERROR(::DbPageSize(iHandle, KNullDesC, pageSize));
   191 	SQLCOMPACTCONN_INVARIANT();
   192 	return pageSize;
   193 	}
   194 
   195 #ifdef _DEBUG
   196 /**
   197 CSqlCompactConn invariant.
   198 */
   199 void CSqlCompactConn::Invariant() const
   200 	{
   201 	__ASSERT_ALWAYS(iHandle != NULL, __SQLPANIC(ESqlPanicInternalError));
   202 	}
   203 #endif//_DEBUG
   204 
   205 /**
   206 A factory function for CSqlCompactConn.
   207 
   208 @param aFullName The full name of the database to be compacted (including the path).
   209 @param aFreePageCallback A reference to an object containing the free pages threshold and the callback
   210 					     that needs to be called when the free page count reaches or is above the threshold.
   211 						 aFreePageCallback.iThreshold must be set to be in Kb. 	
   212 						 If the function call completes successfully and the free pages space is above the threshold,
   213 						 the aFreePageCallback.iThreshold will be set to contain the free pages count.
   214 						 Otherwise aFreePageCallback.iThreshold will be initialized with zero.
   215 					  
   216 @return A pointer to the created MSqlCompactConn interface.
   217 
   218 @leave KErrNoMemory, an out of memory condition has occurred,
   219 	   KErrArgument, invalid data in the aFreePageCallback object;
   220                      Note that the function may also leave with some other database specific 
   221                      errors categorised as ESqlDbError, and other system-wide error codes.
   222 
   223 @see MSqlCompactConn
   224 @see CSqlCompactConn
   225 
   226 @internalComponent
   227 
   228 @panic SqlDb 4 In _DEBUG mode. Too short or too long database name (aFullName parameter)
   229 @panic SqlDb 4 In _DEBUG mode. Invalid aFreePageCallback content.
   230 */
   231 MSqlCompactConn* SqlCreateCompactConnL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
   232 	{
   233 	__ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicBadArgument));
   234 	__ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC2(ESqlPanicBadArgument));
   235 	return CSqlCompactConn::NewL(aFullName, aFreePageCallback);
   236 	}