OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CHROME_COMMON_SQLITE_UTILS_H_ | |
6 #define CHROME_COMMON_SQLITE_UTILS_H_ | |
7 #pragma once | |
8 | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "base/string16.h" | |
15 #include "base/utf_string_conversions.h" | |
16 #include "third_party/sqlite/sqlite3.h" | |
17 | |
18 // forward declarations of classes defined here | |
19 class FilePath; | |
20 class SQLTransaction; | |
21 class SQLNestedTransaction; | |
22 class SQLNestedTransactionSite; | |
23 class scoped_sqlite3_stmt_ptr; | |
24 class SQLStatement; | |
25 | |
26 //------------------------------------------------------------------------------ | |
27 // Interface to be implemented by objects that can handle exceptional sqlite | |
28 // conditions. This way client code can focus on handling normal condtions. | |
29 //------------------------------------------------------------------------------ | |
30 class SQLErrorHandler { | |
31 public: | |
32 virtual ~SQLErrorHandler() {} | |
33 // Handle a sqlite error. |error| is the return code an of sqlite operation | |
34 // which is considered an error. This handler is free to try repair, notify | |
35 // someone or even break into the debugger depending on the situation. | |
36 virtual int HandleError(int error, sqlite3* db) = 0; | |
37 // Returns the last value of |error| passed to HandleError. | |
38 virtual int GetLastError() const = 0; | |
39 }; | |
40 | |
41 //------------------------------------------------------------------------------ | |
42 // The factory interface is used to create the different error handling | |
43 // strategies for debug, release and for diagnostic mode. | |
44 //------------------------------------------------------------------------------ | |
45 class SQLErrorHandlerFactory { | |
46 public: | |
47 virtual ~SQLErrorHandlerFactory() {} | |
48 virtual SQLErrorHandler* Make() = 0; | |
49 }; | |
50 | |
51 //------------------------------------------------------------------------------ | |
52 // A wrapper for sqlite transactions that rollsback when the wrapper | |
53 // goes out of scope if the caller has not already called Commit or Rollback. | |
54 // Note: the constructor does NOT Begin a transaction. | |
55 //------------------------------------------------------------------------------ | |
56 class SQLTransaction { | |
57 public: | |
58 explicit SQLTransaction(sqlite3* db); | |
59 virtual ~SQLTransaction(); | |
60 | |
61 int Begin() { | |
62 // By default, we BEGIN IMMEDIATE to establish file locks at the | |
63 // onset of a transaction. This avoids SQLITE_BUSY errors, without | |
64 // waiting for the busy timeout period, which can occur when BEGIN | |
65 // DEFERRED is used. | |
66 return BeginImmediate(); | |
67 } | |
68 | |
69 int BeginExclusive() { | |
70 return BeginCommand("BEGIN EXCLUSIVE"); | |
71 } | |
72 | |
73 int BeginImmediate() { | |
74 return BeginCommand("BEGIN IMMEDIATE"); | |
75 } | |
76 | |
77 int BeginDeferred() { | |
78 return BeginCommand("BEGIN DEFERRED"); | |
79 } | |
80 | |
81 int Commit() { | |
82 return EndCommand("COMMIT"); | |
83 } | |
84 | |
85 int Rollback() { | |
86 return EndCommand("ROLLBACK"); | |
87 } | |
88 | |
89 bool HasBegun() { | |
90 return began_; | |
91 } | |
92 | |
93 protected: | |
94 virtual int BeginCommand(const char* command); | |
95 virtual int EndCommand(const char* command); | |
96 | |
97 sqlite3* db_; | |
98 bool began_; | |
99 DISALLOW_COPY_AND_ASSIGN(SQLTransaction); | |
100 }; | |
101 | |
102 | |
103 //------------------------------------------------------------------------------ | |
104 // A class for use with SQLNestedTransaction. | |
105 //------------------------------------------------------------------------------ | |
106 class SQLNestedTransactionSite { | |
107 protected: | |
108 SQLNestedTransactionSite() : db_(NULL), top_transaction_(NULL) {} | |
109 virtual ~SQLNestedTransactionSite(); | |
110 | |
111 // The following virtual methods provide notification of true transaction | |
112 // boundaries as they are crossed by a top nested transaction. | |
113 // Intended to be overriden (See WebCacheDB) | |
114 // SQLNestedTransaction calls these after the underlying database | |
115 // operation has been performed. | |
116 | |
117 virtual void OnBegin() {} | |
118 virtual void OnCommit() {} | |
119 virtual void OnRollback() {} | |
120 | |
121 // Returns the sqlite3 database connection associated with this site | |
122 // Used by SQLNestedTransaction | |
123 sqlite3* GetSqlite3DB() { return db_; } | |
124 | |
125 // Returns the current top nested transaction associated with this site | |
126 // Used by SQLNestedTransaction | |
127 SQLNestedTransaction* GetTopTransaction() { | |
128 return top_transaction_; | |
129 } | |
130 | |
131 // Sets or clears the top nested transaction associated with this site | |
132 // Used by SQLNestedTransaction | |
133 void SetTopTransaction(SQLNestedTransaction* top); | |
134 | |
135 sqlite3* db_; | |
136 SQLNestedTransaction* top_transaction_; | |
137 friend class SQLNestedTransaction; | |
138 }; | |
139 | |
140 //------------------------------------------------------------------------------ | |
141 // SQLite does not support nested transactions. This class provides a gross | |
142 // approximation of nested transactions. | |
143 // | |
144 // Really there is only one transaction, the top transaction. | |
145 // | |
146 // A nested transaction commits with respect to the top transaction. | |
147 // That is, even though the nested transaction commits, the permanence of its | |
148 // effects depends on the top transaction committing. If the top | |
149 // transaction rollsback, the results of the nested transaction are backed out. | |
150 // If any nested transaction aborts, the top transaction ultimately rollsback | |
151 // as well. | |
152 // | |
153 // Note: If a nested transaction is open for a particular db connection, an | |
154 // attempt to open a non-nested transaction (class SQLTransaction) will fail. | |
155 // And vice versa. | |
156 // | |
157 // TODO(michaeln): demonstrate usage here | |
158 // TODO(michaeln): safegaurds to prevent mis-use | |
159 //------------------------------------------------------------------------------ | |
160 class SQLNestedTransaction : public SQLTransaction { | |
161 public: | |
162 explicit SQLNestedTransaction(SQLNestedTransactionSite* site); | |
163 virtual ~SQLNestedTransaction(); | |
164 | |
165 protected: | |
166 virtual int BeginCommand(const char* command); | |
167 virtual int EndCommand(const char* command); | |
168 | |
169 private: | |
170 bool needs_rollback_; | |
171 SQLNestedTransactionSite* site_; | |
172 DISALLOW_COPY_AND_ASSIGN(SQLNestedTransaction); | |
173 }; | |
174 | |
175 //------------------------------------------------------------------------------ | |
176 // A scoped sqlite statement that finalizes when it goes out of scope. | |
177 //------------------------------------------------------------------------------ | |
178 class scoped_sqlite3_stmt_ptr { | |
179 public: | |
180 ~scoped_sqlite3_stmt_ptr() { | |
181 finalize(); | |
182 } | |
183 | |
184 scoped_sqlite3_stmt_ptr() : stmt_(NULL) { | |
185 } | |
186 | |
187 explicit scoped_sqlite3_stmt_ptr(sqlite3_stmt* stmt) | |
188 : stmt_(stmt) { | |
189 } | |
190 | |
191 sqlite3_stmt* get() const { | |
192 return stmt_; | |
193 } | |
194 | |
195 void set(sqlite3_stmt* stmt) { | |
196 finalize(); | |
197 stmt_ = stmt; | |
198 } | |
199 | |
200 sqlite3_stmt* release() { | |
201 sqlite3_stmt* tmp = stmt_; | |
202 stmt_ = NULL; | |
203 return tmp; | |
204 } | |
205 | |
206 // It is not safe to call sqlite3_finalize twice on the same stmt. | |
207 // Sqlite3's sqlite3_finalize() function should not be called directly | |
208 // without calling the release method. If sqlite3_finalize() must be | |
209 // called directly, the following usage is advised: | |
210 // scoped_sqlite3_stmt_ptr stmt; | |
211 // ... do something with stmt ... | |
212 // sqlite3_finalize(stmt.release()); | |
213 int finalize() { | |
214 int err = sqlite3_finalize(stmt_); | |
215 stmt_ = NULL; | |
216 return err; | |
217 } | |
218 | |
219 protected: | |
220 sqlite3_stmt* stmt_; | |
221 | |
222 private: | |
223 DISALLOW_COPY_AND_ASSIGN(scoped_sqlite3_stmt_ptr); | |
224 }; | |
225 | |
226 //------------------------------------------------------------------------------ | |
227 // A scoped sqlite statement with convenient C++ wrappers for sqlite3 APIs. | |
228 //------------------------------------------------------------------------------ | |
229 class SQLStatement : public scoped_sqlite3_stmt_ptr { | |
230 public: | |
231 SQLStatement() {} | |
232 | |
233 int prepare(sqlite3* db, const char* sql) { | |
234 return prepare(db, sql, -1); | |
235 } | |
236 | |
237 int prepare(sqlite3* db, const char* sql, int sql_len); | |
238 | |
239 int step(); | |
240 int reset(); | |
241 sqlite_int64 last_insert_rowid(); | |
242 int changes(); | |
243 sqlite3* db_handle(); | |
244 | |
245 // | |
246 // Parameter binding helpers (NOTE: index is 0-based) | |
247 // | |
248 | |
249 int bind_parameter_count(); | |
250 | |
251 typedef void (*Function)(void*); | |
252 | |
253 int bind_blob(int index, std::vector<unsigned char>* blob); | |
254 int bind_blob(int index, const void* value, int value_len); | |
255 int bind_blob(int index, const void* value, int value_len, Function dtor); | |
256 int bind_double(int index, double value); | |
257 int bind_bool(int index, bool value); | |
258 int bind_int(int index, int value); | |
259 int bind_int64(int index, sqlite_int64 value); | |
260 int bind_null(int index); | |
261 | |
262 int bind_string(int index, const std::string& value) { | |
263 // don't use c_str so it doesn't have to fix up the null terminator | |
264 // (sqlite just uses the length) | |
265 return bind_text(index, value.data(), | |
266 static_cast<int>(value.length()), SQLITE_TRANSIENT); | |
267 } | |
268 | |
269 int bind_string16(int index, const string16& value) { | |
270 // don't use c_str so it doesn't have to fix up the null terminator | |
271 // (sqlite just uses the length) | |
272 std::string value_utf8(UTF16ToUTF8(value)); | |
273 return bind_text(index, value_utf8.data(), | |
274 static_cast<int>(value_utf8.length()), SQLITE_TRANSIENT); | |
275 } | |
276 | |
277 int bind_wstring(int index, const std::wstring& value) { | |
278 // don't use c_str so it doesn't have to fix up the null terminator | |
279 // (sqlite just uses the length) | |
280 std::string value_utf8(WideToUTF8(value)); | |
281 return bind_text(index, value_utf8.data(), | |
282 static_cast<int>(value_utf8.length()), SQLITE_TRANSIENT); | |
283 } | |
284 | |
285 int bind_text(int index, const char* value) { | |
286 return bind_text(index, value, -1, SQLITE_TRANSIENT); | |
287 } | |
288 | |
289 // value_len is number of characters or may be negative | |
290 // a for null-terminated value string | |
291 int bind_text(int index, const char* value, int value_len) { | |
292 return bind_text(index, value, value_len, SQLITE_TRANSIENT); | |
293 } | |
294 | |
295 // value_len is number of characters or may be negative | |
296 // a for null-terminated value string | |
297 int bind_text(int index, const char* value, int value_len, | |
298 Function dtor); | |
299 | |
300 int bind_text16(int index, const char16* value) { | |
301 return bind_text16(index, value, -1, SQLITE_TRANSIENT); | |
302 } | |
303 | |
304 // value_len is number of characters or may be negative | |
305 // a for null-terminated value string | |
306 int bind_text16(int index, const char16* value, int value_len) { | |
307 return bind_text16(index, value, value_len, SQLITE_TRANSIENT); | |
308 } | |
309 | |
310 // value_len is number of characters or may be negative | |
311 // a for null-terminated value string | |
312 int bind_text16(int index, const char16* value, int value_len, | |
313 Function dtor); | |
314 | |
315 int bind_value(int index, const sqlite3_value* value); | |
316 | |
317 // | |
318 // Column helpers (NOTE: index is 0-based) | |
319 // | |
320 | |
321 int column_count(); | |
322 int column_type(int index); | |
323 const void* column_blob(int index); | |
324 bool column_blob_as_vector(int index, std::vector<unsigned char>* blob); | |
325 bool column_blob_as_string(int index, std::string* blob); | |
326 int column_bytes(int index); | |
327 int column_bytes16(int index); | |
328 double column_double(int index); | |
329 bool column_bool(int index); | |
330 int column_int(int index); | |
331 sqlite_int64 column_int64(int index); | |
332 const char* column_text(int index); | |
333 bool column_string(int index, std::string* str); | |
334 std::string column_string(int index); | |
335 const char16* column_text16(int index); | |
336 bool column_string16(int index, string16* str); | |
337 string16 column_string16(int index); | |
338 bool column_wstring(int index, std::wstring* str); | |
339 std::wstring column_wstring(int index); | |
340 | |
341 private: | |
342 DISALLOW_COPY_AND_ASSIGN(SQLStatement); | |
343 }; | |
344 | |
345 namespace sqlite_utils { | |
346 | |
347 //------------------------------------------------------------------------------ | |
348 // A scoped sqlite database that closes when it goes out of scope. | |
349 //------------------------------------------------------------------------------ | |
350 class DBClose { | |
351 public: | |
352 inline void operator()(sqlite3* x) const { | |
353 sqlite3_close(x); | |
354 } | |
355 }; | |
356 | |
357 typedef scoped_ptr_malloc<sqlite3, DBClose> scoped_sqlite_db_ptr; | |
358 | |
359 // Opens the DB in the file pointed to by |filepath|. This method forces the | |
360 // database to be in UTF-8 mode on all platforms. See | |
361 // http://www.sqlite.org/capi3ref.html#sqlite3_open for an explanation of the | |
362 // return value. | |
363 int OpenSqliteDb(const FilePath& filepath, sqlite3** database); | |
364 | |
365 // Returns true if there is a table with the given name in the database. | |
366 // For the version where a database name is specified, it may be NULL or the | |
367 // empty string if no database name is necessary. | |
368 bool DoesSqliteTableExist(sqlite3* db, | |
369 const char* db_name, | |
370 const char* table_name); | |
371 inline bool DoesSqliteTableExist(sqlite3* db, const char* table_name) { | |
372 return DoesSqliteTableExist(db, NULL, table_name); | |
373 } | |
374 | |
375 // Test whether a table has a column matching the provided name and type. | |
376 // Returns true if the column exist and false otherwise. There are two | |
377 // versions, one that takes a database name, the other that doesn't. The | |
378 // database name can be NULL or empty if no name is desired. | |
379 // | |
380 // Column type is optional, it can be NULL or empty. If specified, we the | |
381 // function will check that the column is of the correct type (case-sensetive). | |
382 bool DoesSqliteColumnExist(sqlite3* db, | |
383 const char* datbase_name, | |
384 const char* table_name, | |
385 const char* column_name, | |
386 const char* column_type); | |
387 inline bool DoesSqliteColumnExist(sqlite3* db, | |
388 const char* table_name, | |
389 const char* column_name, | |
390 const char* column_type) { | |
391 return DoesSqliteColumnExist(db, NULL, table_name, column_name, column_type); | |
392 } | |
393 | |
394 // Test whether a table has one or more rows. Returns true if the table | |
395 // has one or more rows and false if the table is empty or doesn't exist. | |
396 bool DoesSqliteTableHaveRow(sqlite3* db, const char* table_name); | |
397 | |
398 } // namespace sqlite_utils | |
399 | |
400 #endif // CHROME_COMMON_SQLITE_UTILS_H_ | |
OLD | NEW |