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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
18 #include "SqlAssert.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"
28 #include "SqlTraceDef.h"
31 Creates a new CSqlCompactConn instance.
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.
41 @return A pointer to the created CSqlCompactConn instance
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.
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.
51 CSqlCompactConn* CSqlCompactConn::NewL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
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)));
65 Destroys the CSqlCompactConn instance.
67 CSqlCompactConn::~CSqlCompactConn()
69 SQL_TRACE_COMPACT(OstTrace1(TRACE_INTERNALS, CSQLCOMPACTCONN_CSQLCOMPACTCONN2, "0x%X;CSqlCompactConn::~CSqlCompactConn", (TUint)this));
70 ::CloseDbHandle(iHandle);
74 Implements MSqlCompactConn::Release().
75 Destroys the CSqlCompactConn instance.
77 void CSqlCompactConn::Release()
79 SQLCOMPACTCONN_INVARIANT();
84 Implements MSqlCompactConn::Compact().
86 Compacts the database making an attempt to remove the specified amount of free pages.
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.
95 @panic SqlDb 4 In _DEBUG mode. Negative aPageCount value.
96 @panic SqlDb 4 In _DEBUG mode. Negative aLength value.
98 TInt CSqlCompactConn::Compact(TInt aPageCount, TInt& aProcessedPageCount, TInt aLength)
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();
109 Initializes the CSqlCompactConn instance establishing a connection with the database to be compacted.
110 Registers the passed "free page" callback.
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.
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.
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.
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).
132 void CSqlCompactConn::ConstructL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
134 __ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC(ESqlPanicBadArgument));
135 __ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC(ESqlPanicBadArgument));
136 __ASSERT_DEBUG(!iHandle, __SQLPANIC(ESqlPanicInternalError));
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));
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
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()));
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;
160 Retrieves the database free pages count.
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.
166 @return Free pages count
168 TInt CSqlCompactConn::FreePageCountL()
170 SQLCOMPACTCONN_INVARIANT();
171 TInt freePageCount = 0;
172 __SQLLEAVE_IF_ERROR(::DbFreePageCount(iHandle, KNullDesC, freePageCount));
173 SQLCOMPACTCONN_INVARIANT();
174 return freePageCount;
178 Retrieves the database page size in bytes.
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.
186 TInt CSqlCompactConn::PageSizeL()
188 SQLCOMPACTCONN_INVARIANT();
190 __SQLLEAVE_IF_ERROR(::DbPageSize(iHandle, KNullDesC, pageSize));
191 SQLCOMPACTCONN_INVARIANT();
197 CSqlCompactConn invariant.
199 void CSqlCompactConn::Invariant() const
201 __ASSERT_ALWAYS(iHandle != NULL, __SQLPANIC(ESqlPanicInternalError));
206 A factory function for CSqlCompactConn.
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.
216 @return A pointer to the created MSqlCompactConn interface.
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.
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.
231 MSqlCompactConn* SqlCreateCompactConnL(const TDesC& aFullName, TSqlFreePageCallback& aFreePageCallback)
233 __ASSERT_DEBUG(aFullName.Length() > 0 && aFullName.Length() <= KMaxFileName, __SQLPANIC2(ESqlPanicBadArgument));
234 __ASSERT_DEBUG(aFreePageCallback.IsValid(), __SQLPANIC2(ESqlPanicBadArgument));
235 return CSqlCompactConn::NewL(aFullName, aFreePageCallback);