| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "sql/connection.h" | 5 #include "sql/connection.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 connection_->StatementRefCreated(this); | 68 connection_->StatementRefCreated(this); |
| 69 } | 69 } |
| 70 | 70 |
| 71 Connection::StatementRef::~StatementRef() { | 71 Connection::StatementRef::~StatementRef() { |
| 72 if (connection_) | 72 if (connection_) |
| 73 connection_->StatementRefDeleted(this); | 73 connection_->StatementRefDeleted(this); |
| 74 Close(); | 74 Close(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void Connection::StatementRef::Close() { | 77 void Connection::StatementRef::Close() { |
| 78 AssertIOAllowed(); |
| 78 if (stmt_) { | 79 if (stmt_) { |
| 79 sqlite3_finalize(stmt_); | 80 sqlite3_finalize(stmt_); |
| 80 stmt_ = NULL; | 81 stmt_ = NULL; |
| 81 } | 82 } |
| 82 connection_ = NULL; // The connection may be getting deleted. | 83 connection_ = NULL; // The connection may be getting deleted. |
| 83 } | 84 } |
| 84 | 85 |
| 85 Connection::Connection() | 86 Connection::Connection() |
| 86 : db_(NULL), | 87 : db_(NULL), |
| 87 page_size_(0), | 88 page_size_(0), |
| 88 cache_size_(0), | 89 cache_size_(0), |
| 89 exclusive_locking_(false), | 90 exclusive_locking_(false), |
| 90 transaction_nesting_(0), | 91 transaction_nesting_(0), |
| 91 needs_rollback_(false) { | 92 needs_rollback_(false), |
| 93 in_memory_(false) { |
| 92 } | 94 } |
| 93 | 95 |
| 94 Connection::~Connection() { | 96 Connection::~Connection() { |
| 95 Close(); | 97 Close(); |
| 96 } | 98 } |
| 97 | 99 |
| 98 bool Connection::Open(const FilePath& path) { | 100 bool Connection::Open(const FilePath& path) { |
| 99 #if defined(OS_WIN) | 101 #if defined(OS_WIN) |
| 100 return OpenInternal(WideToUTF8(path.value())); | 102 return OpenInternal(WideToUTF8(path.value())); |
| 101 #elif defined(OS_POSIX) | 103 #elif defined(OS_POSIX) |
| 102 return OpenInternal(path.value()); | 104 return OpenInternal(path.value()); |
| 103 #endif | 105 #endif |
| 104 } | 106 } |
| 105 | 107 |
| 106 bool Connection::OpenInMemory() { | 108 bool Connection::OpenInMemory() { |
| 109 in_memory_ = true; |
| 107 return OpenInternal(":memory:"); | 110 return OpenInternal(":memory:"); |
| 108 } | 111 } |
| 109 | 112 |
| 110 void Connection::Close() { | 113 void Connection::Close() { |
| 114 AssertIOAllowed(); |
| 115 |
| 111 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point | 116 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point |
| 112 // will delete the -journal file. For ChromiumOS or other more | 117 // will delete the -journal file. For ChromiumOS or other more |
| 113 // embedded systems, this is probably not appropriate, whereas on | 118 // embedded systems, this is probably not appropriate, whereas on |
| 114 // desktop it might make some sense. | 119 // desktop it might make some sense. |
| 115 | 120 |
| 116 // sqlite3_close() needs all prepared statements to be finalized. | 121 // sqlite3_close() needs all prepared statements to be finalized. |
| 117 // Release all cached statements, then assert that the client has | 122 // Release all cached statements, then assert that the client has |
| 118 // released all statements. | 123 // released all statements. |
| 119 statement_cache_.clear(); | 124 statement_cache_.clear(); |
| 120 DCHECK(open_statements_.empty()); | 125 DCHECK(open_statements_.empty()); |
| 121 | 126 |
| 122 // Additionally clear the prepared statements, because they contain | 127 // Additionally clear the prepared statements, because they contain |
| 123 // weak references to this connection. This case has come up when | 128 // weak references to this connection. This case has come up when |
| 124 // error-handling code is hit in production. | 129 // error-handling code is hit in production. |
| 125 ClearCache(); | 130 ClearCache(); |
| 126 | 131 |
| 127 if (db_) { | 132 if (db_) { |
| 128 // TODO(shess): Histogram for failure. | 133 // TODO(shess): Histogram for failure. |
| 129 sqlite3_close(db_); | 134 sqlite3_close(db_); |
| 130 db_ = NULL; | 135 db_ = NULL; |
| 131 } | 136 } |
| 132 } | 137 } |
| 133 | 138 |
| 134 void Connection::Preload() { | 139 void Connection::Preload() { |
| 140 AssertIOAllowed(); |
| 141 |
| 135 if (!db_) { | 142 if (!db_) { |
| 136 DLOG(FATAL) << "Cannot preload null db"; | 143 DLOG(FATAL) << "Cannot preload null db"; |
| 137 return; | 144 return; |
| 138 } | 145 } |
| 139 | 146 |
| 140 // A statement must be open for the preload command to work. If the meta | 147 // A statement must be open for the preload command to work. If the meta |
| 141 // table doesn't exist, it probably means this is a new database and there | 148 // table doesn't exist, it probably means this is a new database and there |
| 142 // is nothing to preload (so it's OK we do nothing). | 149 // is nothing to preload (so it's OK we do nothing). |
| 143 if (!DoesTableExist("meta")) | 150 if (!DoesTableExist("meta")) |
| 144 return; | 151 return; |
| 145 Statement dummy(GetUniqueStatement("SELECT * FROM meta")); | 152 Statement dummy(GetUniqueStatement("SELECT * FROM meta")); |
| 146 if (!dummy.Step()) | 153 if (!dummy.Step()) |
| 147 return; | 154 return; |
| 148 | 155 |
| 149 #if !defined(USE_SYSTEM_SQLITE) | 156 #if !defined(USE_SYSTEM_SQLITE) |
| 150 // This function is only defined in Chromium's version of sqlite. | 157 // This function is only defined in Chromium's version of sqlite. |
| 151 // Do not call it when using system sqlite. | 158 // Do not call it when using system sqlite. |
| 152 sqlite3_preload(db_); | 159 sqlite3_preload(db_); |
| 153 #endif | 160 #endif |
| 154 } | 161 } |
| 155 | 162 |
| 156 // Create an in-memory database with the existing database's page | 163 // Create an in-memory database with the existing database's page |
| 157 // size, then backup that database over the existing database. | 164 // size, then backup that database over the existing database. |
| 158 bool Connection::Raze() { | 165 bool Connection::Raze() { |
| 166 AssertIOAllowed(); |
| 167 |
| 159 if (!db_) { | 168 if (!db_) { |
| 160 DLOG(FATAL) << "Cannot raze null db"; | 169 DLOG(FATAL) << "Cannot raze null db"; |
| 161 return false; | 170 return false; |
| 162 } | 171 } |
| 163 | 172 |
| 164 if (transaction_nesting_ > 0) { | 173 if (transaction_nesting_ > 0) { |
| 165 DLOG(FATAL) << "Cannot raze within a transaction"; | 174 DLOG(FATAL) << "Cannot raze within a transaction"; |
| 166 return false; | 175 return false; |
| 167 } | 176 } |
| 168 | 177 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 if (needs_rollback_) { | 294 if (needs_rollback_) { |
| 286 DoRollback(); | 295 DoRollback(); |
| 287 return false; | 296 return false; |
| 288 } | 297 } |
| 289 | 298 |
| 290 Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT")); | 299 Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT")); |
| 291 return commit.Run(); | 300 return commit.Run(); |
| 292 } | 301 } |
| 293 | 302 |
| 294 int Connection::ExecuteAndReturnErrorCode(const char* sql) { | 303 int Connection::ExecuteAndReturnErrorCode(const char* sql) { |
| 304 AssertIOAllowed(); |
| 295 if (!db_) | 305 if (!db_) |
| 296 return false; | 306 return false; |
| 297 return sqlite3_exec(db_, sql, NULL, NULL, NULL); | 307 return sqlite3_exec(db_, sql, NULL, NULL, NULL); |
| 298 } | 308 } |
| 299 | 309 |
| 300 bool Connection::Execute(const char* sql) { | 310 bool Connection::Execute(const char* sql) { |
| 301 int error = ExecuteAndReturnErrorCode(sql); | 311 int error = ExecuteAndReturnErrorCode(sql); |
| 302 // This needs to be a FATAL log because the error case of arriving here is | 312 // This needs to be a FATAL log because the error case of arriving here is |
| 303 // that there's a malformed SQL statement. This can arise in development if | 313 // that there's a malformed SQL statement. This can arise in development if |
| 304 // a change alters the schema but not all queries adjust. | 314 // a change alters the schema but not all queries adjust. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 335 } | 345 } |
| 336 | 346 |
| 337 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); | 347 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql); |
| 338 if (statement->is_valid()) | 348 if (statement->is_valid()) |
| 339 statement_cache_[id] = statement; // Only cache valid statements. | 349 statement_cache_[id] = statement; // Only cache valid statements. |
| 340 return statement; | 350 return statement; |
| 341 } | 351 } |
| 342 | 352 |
| 343 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement( | 353 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement( |
| 344 const char* sql) { | 354 const char* sql) { |
| 355 AssertIOAllowed(); |
| 356 |
| 345 if (!db_) | 357 if (!db_) |
| 346 return new StatementRef(this, NULL); // Return inactive statement. | 358 return new StatementRef(this, NULL); // Return inactive statement. |
| 347 | 359 |
| 348 sqlite3_stmt* stmt = NULL; | 360 sqlite3_stmt* stmt = NULL; |
| 349 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) { | 361 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) { |
| 350 // This is evidence of a syntax error in the incoming SQL. | 362 // This is evidence of a syntax error in the incoming SQL. |
| 351 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); | 363 DLOG(FATAL) << "SQL compile error " << GetErrorMessage(); |
| 352 return new StatementRef(this, NULL); | 364 return new StatementRef(this, NULL); |
| 353 } | 365 } |
| 354 return new StatementRef(this, stmt); | 366 return new StatementRef(this, stmt); |
| 355 } | 367 } |
| 356 | 368 |
| 357 bool Connection::IsSQLValid(const char* sql) { | 369 bool Connection::IsSQLValid(const char* sql) { |
| 370 AssertIOAllowed(); |
| 358 sqlite3_stmt* stmt = NULL; | 371 sqlite3_stmt* stmt = NULL; |
| 359 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) | 372 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) |
| 360 return false; | 373 return false; |
| 361 | 374 |
| 362 sqlite3_finalize(stmt); | 375 sqlite3_finalize(stmt); |
| 363 return true; | 376 return true; |
| 364 } | 377 } |
| 365 | 378 |
| 366 bool Connection::DoesTableExist(const char* table_name) const { | 379 bool Connection::DoesTableExist(const char* table_name) const { |
| 367 return DoesTableOrIndexExist(table_name, "table"); | 380 return DoesTableOrIndexExist(table_name, "table"); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 return err; | 447 return err; |
| 435 } | 448 } |
| 436 | 449 |
| 437 const char* Connection::GetErrorMessage() const { | 450 const char* Connection::GetErrorMessage() const { |
| 438 if (!db_) | 451 if (!db_) |
| 439 return "sql::Connection has no connection."; | 452 return "sql::Connection has no connection."; |
| 440 return sqlite3_errmsg(db_); | 453 return sqlite3_errmsg(db_); |
| 441 } | 454 } |
| 442 | 455 |
| 443 bool Connection::OpenInternal(const std::string& file_name) { | 456 bool Connection::OpenInternal(const std::string& file_name) { |
| 457 AssertIOAllowed(); |
| 458 |
| 444 if (db_) { | 459 if (db_) { |
| 445 DLOG(FATAL) << "sql::Connection is already open."; | 460 DLOG(FATAL) << "sql::Connection is already open."; |
| 446 return false; | 461 return false; |
| 447 } | 462 } |
| 448 | 463 |
| 449 int err = sqlite3_open(file_name.c_str(), &db_); | 464 int err = sqlite3_open(file_name.c_str(), &db_); |
| 450 if (err != SQLITE_OK) { | 465 if (err != SQLITE_OK) { |
| 451 OnSqliteError(err, NULL); | 466 OnSqliteError(err, NULL); |
| 452 Close(); | 467 Close(); |
| 453 db_ = NULL; | 468 db_ = NULL; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 | 564 |
| 550 int Connection::OnSqliteError(int err, sql::Statement *stmt) { | 565 int Connection::OnSqliteError(int err, sql::Statement *stmt) { |
| 551 if (error_delegate_.get()) | 566 if (error_delegate_.get()) |
| 552 return error_delegate_->OnError(err, this, stmt); | 567 return error_delegate_->OnError(err, this, stmt); |
| 553 // The default handling is to assert on debug and to ignore on release. | 568 // The default handling is to assert on debug and to ignore on release. |
| 554 DLOG(FATAL) << GetErrorMessage(); | 569 DLOG(FATAL) << GetErrorMessage(); |
| 555 return err; | 570 return err; |
| 556 } | 571 } |
| 557 | 572 |
| 558 } // namespace sql | 573 } // namespace sql |
| OLD | NEW |