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