| 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/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 } | 61 } |
| 62 | 62 |
| 63 private: | 63 private: |
| 64 sqlite3* db_; | 64 sqlite3* db_; |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 } // namespace | 67 } // namespace |
| 68 | 68 |
| 69 namespace sql { | 69 namespace sql { |
| 70 | 70 |
| 71 // static |
| 72 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL; |
| 73 |
| 74 // static |
| 75 bool Connection::ShouldIgnore(int error) { |
| 76 if (!current_ignorer_cb_) |
| 77 return false; |
| 78 return current_ignorer_cb_->Run(error); |
| 79 } |
| 80 |
| 81 // static |
| 82 void Connection::SetErrorIgnorer(Connection::ErrorIgnorerCallback* cb) { |
| 83 CHECK(current_ignorer_cb_ == NULL); |
| 84 current_ignorer_cb_ = cb; |
| 85 } |
| 86 |
| 87 // static |
| 88 void Connection::ResetErrorIgnorer() { |
| 89 CHECK(current_ignorer_cb_); |
| 90 current_ignorer_cb_ = NULL; |
| 91 } |
| 92 |
| 71 bool StatementID::operator<(const StatementID& other) const { | 93 bool StatementID::operator<(const StatementID& other) const { |
| 72 if (number_ != other.number_) | 94 if (number_ != other.number_) |
| 73 return number_ < other.number_; | 95 return number_ < other.number_; |
| 74 return strcmp(str_, other.str_) < 0; | 96 return strcmp(str_, other.str_) < 0; |
| 75 } | 97 } |
| 76 | 98 |
| 77 Connection::StatementRef::StatementRef(Connection* connection, | 99 Connection::StatementRef::StatementRef(Connection* connection, |
| 78 sqlite3_stmt* stmt, | 100 sqlite3_stmt* stmt, |
| 79 bool was_valid) | 101 bool was_valid) |
| 80 : connection_(connection), | 102 : connection_(connection), |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; | 450 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; |
| 429 return false; | 451 return false; |
| 430 } | 452 } |
| 431 | 453 |
| 432 int error = ExecuteAndReturnErrorCode(sql); | 454 int error = ExecuteAndReturnErrorCode(sql); |
| 433 if (error != SQLITE_OK) | 455 if (error != SQLITE_OK) |
| 434 error = OnSqliteError(error, NULL); | 456 error = OnSqliteError(error, NULL); |
| 435 | 457 |
| 436 // This needs to be a FATAL log because the error case of arriving here is | 458 // This needs to be a FATAL log because the error case of arriving here is |
| 437 // that there's a malformed SQL statement. This can arise in development if | 459 // that there's a malformed SQL statement. This can arise in development if |
| 438 // a change alters the schema but not all queries adjust. | 460 // a change alters the schema but not all queries adjust. This can happen |
| 461 // in production if the schema is corrupted. |
| 439 if (error == SQLITE_ERROR) | 462 if (error == SQLITE_ERROR) |
| 440 DLOG(FATAL) << "SQL Error in " << sql << ", " << GetErrorMessage(); | 463 DLOG(FATAL) << "SQL Error in " << sql << ", " << GetErrorMessage(); |
| 441 return error == SQLITE_OK; | 464 return error == SQLITE_OK; |
| 442 } | 465 } |
| 443 | 466 |
| 444 bool Connection::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) { | 467 bool Connection::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) { |
| 445 if (!db_) { | 468 if (!db_) { |
| 446 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; | 469 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; |
| 447 return false; | 470 return false; |
| 448 } | 471 } |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes"; | 676 DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes"; |
| 654 | 677 |
| 655 // If indicated, lock up the database before doing anything else, so | 678 // If indicated, lock up the database before doing anything else, so |
| 656 // that the following code doesn't have to deal with locking. | 679 // that the following code doesn't have to deal with locking. |
| 657 // TODO(shess): This code is brittle. Find the cases where code | 680 // TODO(shess): This code is brittle. Find the cases where code |
| 658 // doesn't request |exclusive_locking_| and audit that it does the | 681 // doesn't request |exclusive_locking_| and audit that it does the |
| 659 // right thing with SQLITE_BUSY, and that it doesn't make | 682 // right thing with SQLITE_BUSY, and that it doesn't make |
| 660 // assumptions about who might change things in the database. | 683 // assumptions about who might change things in the database. |
| 661 // http://crbug.com/56559 | 684 // http://crbug.com/56559 |
| 662 if (exclusive_locking_) { | 685 if (exclusive_locking_) { |
| 663 // TODO(shess): This should probably be a full CHECK(). Code | 686 // TODO(shess): This should probably be a failure. Code which |
| 664 // which requests exclusive locking but doesn't get it is almost | 687 // requests exclusive locking but doesn't get it is almost certain |
| 665 // certain to be ill-tested. | 688 // to be ill-tested. |
| 666 if (!Execute("PRAGMA locking_mode=EXCLUSIVE")) | 689 ignore_result(Execute("PRAGMA locking_mode=EXCLUSIVE")); |
| 667 DLOG(FATAL) << "Could not set locking mode: " << GetErrorMessage(); | |
| 668 } | 690 } |
| 669 | 691 |
| 670 // http://www.sqlite.org/pragma.html#pragma_journal_mode | 692 // http://www.sqlite.org/pragma.html#pragma_journal_mode |
| 671 // DELETE (default) - delete -journal file to commit. | 693 // DELETE (default) - delete -journal file to commit. |
| 672 // TRUNCATE - truncate -journal file to commit. | 694 // TRUNCATE - truncate -journal file to commit. |
| 673 // PERSIST - zero out header of -journal file to commit. | 695 // PERSIST - zero out header of -journal file to commit. |
| 674 // journal_size_limit provides size to trim to in PERSIST. | 696 // journal_size_limit provides size to trim to in PERSIST. |
| 675 // TODO(shess): Figure out if PERSIST and journal_size_limit really | 697 // TODO(shess): Figure out if PERSIST and journal_size_limit really |
| 676 // matter. In theory, it keeps pages pre-allocated, so if | 698 // matter. In theory, it keeps pages pre-allocated, so if |
| 677 // transactions usually fit, it should be faster. | 699 // transactions usually fit, it should be faster. |
| 678 ignore_result(Execute("PRAGMA journal_mode = PERSIST")); | 700 ignore_result(Execute("PRAGMA journal_mode = PERSIST")); |
| 679 ignore_result(Execute("PRAGMA journal_size_limit = 16384")); | 701 ignore_result(Execute("PRAGMA journal_size_limit = 16384")); |
| 680 | 702 |
| 681 const base::TimeDelta kBusyTimeout = | 703 const base::TimeDelta kBusyTimeout = |
| 682 base::TimeDelta::FromSeconds(kBusyTimeoutSeconds); | 704 base::TimeDelta::FromSeconds(kBusyTimeoutSeconds); |
| 683 | 705 |
| 684 if (page_size_ != 0) { | 706 if (page_size_ != 0) { |
| 685 // Enforce SQLite restrictions on |page_size_|. | 707 // Enforce SQLite restrictions on |page_size_|. |
| 686 DCHECK(!(page_size_ & (page_size_ - 1))) | 708 DCHECK(!(page_size_ & (page_size_ - 1))) |
| 687 << " page_size_ " << page_size_ << " is not a power of two."; | 709 << " page_size_ " << page_size_ << " is not a power of two."; |
| 688 const int kSqliteMaxPageSize = 32768; // from sqliteLimit.h | 710 const int kSqliteMaxPageSize = 32768; // from sqliteLimit.h |
| 689 DCHECK_LE(page_size_, kSqliteMaxPageSize); | 711 DCHECK_LE(page_size_, kSqliteMaxPageSize); |
| 690 const std::string sql = | 712 const std::string sql = |
| 691 base::StringPrintf("PRAGMA page_size=%d", page_size_); | 713 base::StringPrintf("PRAGMA page_size=%d", page_size_); |
| 692 if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout)) | 714 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout)); |
| 693 DLOG(FATAL) << "Could not set page size: " << GetErrorMessage(); | |
| 694 } | 715 } |
| 695 | 716 |
| 696 if (cache_size_ != 0) { | 717 if (cache_size_ != 0) { |
| 697 const std::string sql = | 718 const std::string sql = |
| 698 base::StringPrintf("PRAGMA cache_size=%d", cache_size_); | 719 base::StringPrintf("PRAGMA cache_size=%d", cache_size_); |
| 699 if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout)) | 720 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout)); |
| 700 DLOG(FATAL) << "Could not set cache size: " << GetErrorMessage(); | |
| 701 } | 721 } |
| 702 | 722 |
| 703 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) { | 723 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) { |
| 704 DLOG(FATAL) << "Could not enable secure_delete: " << GetErrorMessage(); | |
| 705 Close(); | 724 Close(); |
| 706 return false; | 725 return false; |
| 707 } | 726 } |
| 708 | 727 |
| 709 return true; | 728 return true; |
| 710 } | 729 } |
| 711 | 730 |
| 712 void Connection::DoRollback() { | 731 void Connection::DoRollback() { |
| 713 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK")); | 732 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK")); |
| 714 rollback.Run(); | 733 rollback.Run(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 LOG(ERROR) << "sqlite error " << err | 773 LOG(ERROR) << "sqlite error " << err |
| 755 << ", errno " << GetLastErrno() | 774 << ", errno " << GetLastErrno() |
| 756 << ": " << GetErrorMessage(); | 775 << ": " << GetErrorMessage(); |
| 757 | 776 |
| 758 if (!error_callback_.is_null()) { | 777 if (!error_callback_.is_null()) { |
| 759 error_callback_.Run(err, stmt); | 778 error_callback_.Run(err, stmt); |
| 760 return err; | 779 return err; |
| 761 } | 780 } |
| 762 | 781 |
| 763 // The default handling is to assert on debug and to ignore on release. | 782 // The default handling is to assert on debug and to ignore on release. |
| 764 DLOG(FATAL) << GetErrorMessage(); | 783 if (!ShouldIgnore(err)) |
| 784 DLOG(FATAL) << GetErrorMessage(); |
| 765 return err; | 785 return err; |
| 766 } | 786 } |
| 767 | 787 |
| 768 // TODO(shess): Allow specifying integrity_check versus quick_check. | 788 // TODO(shess): Allow specifying integrity_check versus quick_check. |
| 769 // TODO(shess): Allow specifying maximum results (default 100 lines). | 789 // TODO(shess): Allow specifying maximum results (default 100 lines). |
| 770 bool Connection::IntegrityCheck(std::vector<std::string>* messages) { | 790 bool Connection::IntegrityCheck(std::vector<std::string>* messages) { |
| 771 messages->clear(); | 791 messages->clear(); |
| 772 | 792 |
| 773 // This has the side effect of setting SQLITE_RecoveryMode, which | 793 // This has the side effect of setting SQLITE_RecoveryMode, which |
| 774 // allows SQLite to process through certain cases of corruption. | 794 // allows SQLite to process through certain cases of corruption. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 794 } | 814 } |
| 795 | 815 |
| 796 // Best effort to put things back as they were before. | 816 // Best effort to put things back as they were before. |
| 797 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; | 817 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; |
| 798 ignore_result(Execute(kNoWritableSchema)); | 818 ignore_result(Execute(kNoWritableSchema)); |
| 799 | 819 |
| 800 return ret; | 820 return ret; |
| 801 } | 821 } |
| 802 | 822 |
| 803 } // namespace sql | 823 } // namespace sql |
| OLD | NEW |