Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: sql/connection.cc

Issue 16664005: [sql] Framework for allowing tests to handle errors. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: final gyp cleanup. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sql/connection.h ('k') | sql/connection_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « sql/connection.h ('k') | sql/connection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698