|
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 } |