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