OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_SYNC_UTIL_SQLITE_UTILS_H_ | 5 #ifndef CHROME_BROWSER_SYNC_UTIL_SQLITE_UTILS_H_ |
6 #define CHROME_BROWSER_SYNC_UTIL_SQLITE_UTILS_H_ | 6 #define CHROME_BROWSER_SYNC_UTIL_SQLITE_UTILS_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/string16.h" | 14 #include "base/string16.h" |
15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
16 #include "third_party/sqlite/sqlite3.h" | 16 #include "third_party/sqlite/sqlite3.h" |
17 | 17 |
18 // forward declarations of classes defined here | |
19 class FilePath; | 18 class FilePath; |
| 19 |
| 20 namespace sqlite_utils { |
| 21 |
20 class SQLTransaction; | 22 class SQLTransaction; |
21 class SQLNestedTransaction; | 23 class SQLNestedTransaction; |
22 class SQLNestedTransactionSite; | 24 class SQLNestedTransactionSite; |
23 class scoped_sqlite3_stmt_ptr; | 25 class scoped_sqlite3_stmt_ptr; |
24 class SQLStatement; | 26 class SQLStatement; |
25 | 27 |
26 //------------------------------------------------------------------------------ | |
27 // Interface to be implemented by objects that can handle exceptional sqlite | 28 // Interface to be implemented by objects that can handle exceptional sqlite |
28 // conditions. This way client code can focus on handling normal condtions. | 29 // conditions. This way client code can focus on handling normal condtions. |
29 //------------------------------------------------------------------------------ | |
30 class SQLErrorHandler { | 30 class SQLErrorHandler { |
31 public: | 31 public: |
32 virtual ~SQLErrorHandler() {} | 32 virtual ~SQLErrorHandler() {} |
33 // Handle a sqlite error. |error| is the return code an of sqlite operation | 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 | 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. | 35 // someone or even break into the debugger depending on the situation. |
36 virtual int HandleError(int error, sqlite3* db) = 0; | 36 virtual int HandleError(int error, sqlite3* db) = 0; |
37 // Returns the last value of |error| passed to HandleError. | 37 // Returns the last value of |error| passed to HandleError. |
38 virtual int GetLastError() const = 0; | 38 virtual int GetLastError() const = 0; |
39 }; | 39 }; |
40 | 40 |
41 //------------------------------------------------------------------------------ | |
42 // The factory interface is used to create the different error handling | 41 // The factory interface is used to create the different error handling |
43 // strategies for debug, release and for diagnostic mode. | 42 // strategies for debug, release and for diagnostic mode. |
44 //------------------------------------------------------------------------------ | |
45 class SQLErrorHandlerFactory { | 43 class SQLErrorHandlerFactory { |
46 public: | 44 public: |
47 virtual ~SQLErrorHandlerFactory() {} | 45 virtual ~SQLErrorHandlerFactory() {} |
48 virtual SQLErrorHandler* Make() = 0; | 46 virtual SQLErrorHandler* Make() = 0; |
49 }; | 47 }; |
50 | 48 |
51 //------------------------------------------------------------------------------ | 49 // A wrapper for sqlite transactions that rollsback when the wrapper goes out of |
52 // A wrapper for sqlite transactions that rollsback when the wrapper | 50 // scope if the caller has not already called Commit or Rollback. |
53 // goes out of scope if the caller has not already called Commit or Rollback. | |
54 // Note: the constructor does NOT Begin a transaction. | 51 // Note: the constructor does NOT Begin a transaction. |
55 //------------------------------------------------------------------------------ | |
56 class SQLTransaction { | 52 class SQLTransaction { |
57 public: | 53 public: |
58 explicit SQLTransaction(sqlite3* db); | 54 explicit SQLTransaction(sqlite3* db); |
59 virtual ~SQLTransaction(); | 55 virtual ~SQLTransaction(); |
60 | 56 |
61 int Begin() { | 57 int Begin() { |
62 // By default, we BEGIN IMMEDIATE to establish file locks at the | 58 // By default, we BEGIN IMMEDIATE to establish file locks at the |
63 // onset of a transaction. This avoids SQLITE_BUSY errors, without | 59 // onset of a transaction. This avoids SQLITE_BUSY errors, without |
64 // waiting for the busy timeout period, which can occur when BEGIN | 60 // waiting for the busy timeout period, which can occur when BEGIN |
65 // DEFERRED is used. | 61 // DEFERRED is used. |
(...skipping 26 matching lines...) Expand all Loading... |
92 | 88 |
93 protected: | 89 protected: |
94 virtual int BeginCommand(const char* command); | 90 virtual int BeginCommand(const char* command); |
95 virtual int EndCommand(const char* command); | 91 virtual int EndCommand(const char* command); |
96 | 92 |
97 sqlite3* db_; | 93 sqlite3* db_; |
98 bool began_; | 94 bool began_; |
99 DISALLOW_COPY_AND_ASSIGN(SQLTransaction); | 95 DISALLOW_COPY_AND_ASSIGN(SQLTransaction); |
100 }; | 96 }; |
101 | 97 |
102 | |
103 //------------------------------------------------------------------------------ | |
104 // A class for use with SQLNestedTransaction. | 98 // A class for use with SQLNestedTransaction. |
105 //------------------------------------------------------------------------------ | |
106 class SQLNestedTransactionSite { | 99 class SQLNestedTransactionSite { |
107 protected: | 100 protected: |
108 SQLNestedTransactionSite() : db_(NULL), top_transaction_(NULL) {} | 101 SQLNestedTransactionSite() : db_(NULL), top_transaction_(NULL) {} |
109 virtual ~SQLNestedTransactionSite(); | 102 virtual ~SQLNestedTransactionSite(); |
110 | 103 |
111 // The following virtual methods provide notification of true transaction | 104 // The following virtual methods provide notification of true transaction |
112 // boundaries as they are crossed by a top nested transaction. | 105 // boundaries as they are crossed by a top nested transaction. |
113 // Intended to be overriden (See WebCacheDB) | 106 // Intended to be overriden (See WebCacheDB) |
114 // SQLNestedTransaction calls these after the underlying database | 107 // SQLNestedTransaction calls these after the underlying database |
115 // operation has been performed. | 108 // operation has been performed. |
(...skipping 14 matching lines...) Expand all Loading... |
130 | 123 |
131 // Sets or clears the top nested transaction associated with this site | 124 // Sets or clears the top nested transaction associated with this site |
132 // Used by SQLNestedTransaction | 125 // Used by SQLNestedTransaction |
133 void SetTopTransaction(SQLNestedTransaction* top); | 126 void SetTopTransaction(SQLNestedTransaction* top); |
134 | 127 |
135 sqlite3* db_; | 128 sqlite3* db_; |
136 SQLNestedTransaction* top_transaction_; | 129 SQLNestedTransaction* top_transaction_; |
137 friend class SQLNestedTransaction; | 130 friend class SQLNestedTransaction; |
138 }; | 131 }; |
139 | 132 |
140 //------------------------------------------------------------------------------ | |
141 // SQLite does not support nested transactions. This class provides a gross | 133 // SQLite does not support nested transactions. This class provides a gross |
142 // approximation of nested transactions. | 134 // approximation of nested transactions. |
143 // | 135 // |
144 // Really there is only one transaction, the top transaction. | 136 // Really there is only one transaction, the top transaction. |
145 // | 137 // |
146 // A nested transaction commits with respect to the top transaction. | 138 // A nested transaction commits with respect to the top transaction. |
147 // That is, even though the nested transaction commits, the permanence of its | 139 // That is, even though the nested transaction commits, the permanence of its |
148 // effects depends on the top transaction committing. If the top | 140 // effects depends on the top transaction committing. If the top |
149 // transaction rollsback, the results of the nested transaction are backed out. | 141 // transaction rollsback, the results of the nested transaction are backed out. |
150 // If any nested transaction aborts, the top transaction ultimately rollsback | 142 // If any nested transaction aborts, the top transaction ultimately rollsback |
151 // as well. | 143 // as well. |
152 // | 144 // |
153 // Note: If a nested transaction is open for a particular db connection, an | 145 // 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. | 146 // attempt to open a non-nested transaction (class SQLTransaction) will fail. |
155 // And vice versa. | 147 // And vice versa. |
156 // | 148 // |
157 // TODO(michaeln): demonstrate usage here | 149 // TODO(michaeln): demonstrate usage here |
158 // TODO(michaeln): safegaurds to prevent mis-use | 150 // TODO(michaeln): safegaurds to prevent mis-use |
159 //------------------------------------------------------------------------------ | |
160 class SQLNestedTransaction : public SQLTransaction { | 151 class SQLNestedTransaction : public SQLTransaction { |
161 public: | 152 public: |
162 explicit SQLNestedTransaction(SQLNestedTransactionSite* site); | 153 explicit SQLNestedTransaction(SQLNestedTransactionSite* site); |
163 virtual ~SQLNestedTransaction(); | 154 virtual ~SQLNestedTransaction(); |
164 | 155 |
165 protected: | 156 protected: |
166 virtual int BeginCommand(const char* command); | 157 virtual int BeginCommand(const char* command); |
167 virtual int EndCommand(const char* command); | 158 virtual int EndCommand(const char* command); |
168 | 159 |
169 private: | 160 private: |
170 bool needs_rollback_; | 161 bool needs_rollback_; |
171 SQLNestedTransactionSite* site_; | 162 SQLNestedTransactionSite* site_; |
172 DISALLOW_COPY_AND_ASSIGN(SQLNestedTransaction); | 163 DISALLOW_COPY_AND_ASSIGN(SQLNestedTransaction); |
173 }; | 164 }; |
174 | 165 |
175 //------------------------------------------------------------------------------ | |
176 // A scoped sqlite statement that finalizes when it goes out of scope. | 166 // A scoped sqlite statement that finalizes when it goes out of scope. |
177 //------------------------------------------------------------------------------ | |
178 class scoped_sqlite3_stmt_ptr { | 167 class scoped_sqlite3_stmt_ptr { |
179 public: | 168 public: |
180 ~scoped_sqlite3_stmt_ptr() { | 169 ~scoped_sqlite3_stmt_ptr() { |
181 finalize(); | 170 finalize(); |
182 } | 171 } |
183 | 172 |
184 scoped_sqlite3_stmt_ptr() : stmt_(NULL) { | 173 scoped_sqlite3_stmt_ptr() : stmt_(NULL) { |
185 } | 174 } |
186 | 175 |
187 explicit scoped_sqlite3_stmt_ptr(sqlite3_stmt* stmt) | 176 explicit scoped_sqlite3_stmt_ptr(sqlite3_stmt* stmt) |
(...skipping 28 matching lines...) Expand all Loading... |
216 return err; | 205 return err; |
217 } | 206 } |
218 | 207 |
219 protected: | 208 protected: |
220 sqlite3_stmt* stmt_; | 209 sqlite3_stmt* stmt_; |
221 | 210 |
222 private: | 211 private: |
223 DISALLOW_COPY_AND_ASSIGN(scoped_sqlite3_stmt_ptr); | 212 DISALLOW_COPY_AND_ASSIGN(scoped_sqlite3_stmt_ptr); |
224 }; | 213 }; |
225 | 214 |
226 //------------------------------------------------------------------------------ | |
227 // A scoped sqlite statement with convenient C++ wrappers for sqlite3 APIs. | 215 // A scoped sqlite statement with convenient C++ wrappers for sqlite3 APIs. |
228 //------------------------------------------------------------------------------ | |
229 class SQLStatement : public scoped_sqlite3_stmt_ptr { | 216 class SQLStatement : public scoped_sqlite3_stmt_ptr { |
230 public: | 217 public: |
231 SQLStatement() {} | 218 SQLStatement() {} |
232 | 219 |
233 int prepare(sqlite3* db, const char* sql) { | 220 int prepare(sqlite3* db, const char* sql) { |
234 return prepare(db, sql, -1); | 221 return prepare(db, sql, -1); |
235 } | 222 } |
236 | 223 |
237 int prepare(sqlite3* db, const char* sql, int sql_len); | 224 int prepare(sqlite3* db, const char* sql, int sql_len); |
238 | 225 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 } | 295 } |
309 | 296 |
310 // value_len is number of characters or may be negative | 297 // value_len is number of characters or may be negative |
311 // a for null-terminated value string | 298 // a for null-terminated value string |
312 int bind_text16(int index, const char16* value, int value_len, | 299 int bind_text16(int index, const char16* value, int value_len, |
313 Function dtor); | 300 Function dtor); |
314 | 301 |
315 int bind_value(int index, const sqlite3_value* value); | 302 int bind_value(int index, const sqlite3_value* value); |
316 | 303 |
317 // | 304 // |
318 // Column helpers (NOTE: index is 0-based) | 305 // Column helpers (NOTE: index is 0-based). |
319 // | 306 // |
320 | |
321 int column_count(); | 307 int column_count(); |
322 int column_type(int index); | 308 int column_type(int index); |
323 const void* column_blob(int index); | 309 const void* column_blob(int index); |
324 bool column_blob_as_vector(int index, std::vector<unsigned char>* blob); | 310 bool column_blob_as_vector(int index, std::vector<unsigned char>* blob); |
325 bool column_blob_as_string(int index, std::string* blob); | 311 bool column_blob_as_string(int index, std::string* blob); |
326 int column_bytes(int index); | 312 int column_bytes(int index); |
327 int column_bytes16(int index); | 313 int column_bytes16(int index); |
328 double column_double(int index); | 314 double column_double(int index); |
329 bool column_bool(int index); | 315 bool column_bool(int index); |
330 int column_int(int index); | 316 int column_int(int index); |
331 sqlite_int64 column_int64(int index); | 317 sqlite_int64 column_int64(int index); |
332 const char* column_text(int index); | 318 const char* column_text(int index); |
333 bool column_string(int index, std::string* str); | 319 bool column_string(int index, std::string* str); |
334 std::string column_string(int index); | 320 std::string column_string(int index); |
335 const char16* column_text16(int index); | 321 const char16* column_text16(int index); |
336 bool column_string16(int index, string16* str); | 322 bool column_string16(int index, string16* str); |
337 string16 column_string16(int index); | 323 string16 column_string16(int index); |
338 bool column_wstring(int index, std::wstring* str); | 324 bool column_wstring(int index, std::wstring* str); |
339 std::wstring column_wstring(int index); | 325 std::wstring column_wstring(int index); |
340 | 326 |
341 private: | 327 private: |
342 DISALLOW_COPY_AND_ASSIGN(SQLStatement); | 328 DISALLOW_COPY_AND_ASSIGN(SQLStatement); |
343 }; | 329 }; |
344 | 330 |
345 namespace sqlite_utils { | |
346 | |
347 //------------------------------------------------------------------------------ | |
348 // A scoped sqlite database that closes when it goes out of scope. | 331 // A scoped sqlite database that closes when it goes out of scope. |
349 //------------------------------------------------------------------------------ | |
350 class DBClose { | 332 class DBClose { |
351 public: | 333 public: |
352 inline void operator()(sqlite3* x) const { | 334 inline void operator()(sqlite3* x) const { |
353 sqlite3_close(x); | 335 sqlite3_close(x); |
354 } | 336 } |
355 }; | 337 }; |
356 | 338 |
357 typedef scoped_ptr_malloc<sqlite3, DBClose> scoped_sqlite_db_ptr; | 339 typedef scoped_ptr_malloc<sqlite3, DBClose> scoped_sqlite_db_ptr; |
358 | 340 |
359 // Opens the DB in the file pointed to by |filepath|. This method forces the | 341 // Opens the DB in the file pointed to by |filepath|. This method forces the |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 return DoesSqliteColumnExist(db, NULL, table_name, column_name, column_type); | 373 return DoesSqliteColumnExist(db, NULL, table_name, column_name, column_type); |
392 } | 374 } |
393 | 375 |
394 // Test whether a table has one or more rows. Returns true if the table | 376 // 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. | 377 // 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); | 378 bool DoesSqliteTableHaveRow(sqlite3* db, const char* table_name); |
397 | 379 |
398 } // namespace sqlite_utils | 380 } // namespace sqlite_utils |
399 | 381 |
400 #endif // CHROME_BROWSER_SYNC_UTIL_SQLITE_UTILS_H_ | 382 #endif // CHROME_BROWSER_SYNC_UTIL_SQLITE_UTILS_H_ |
OLD | NEW |