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