Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

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: Refactor along lines of comment #4. 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
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_;
73
74 // static
75 bool Connection::ShouldIgnore(int error) {
76 if (current_ignorer_cb_.is_null())
77 return false;
78 return current_ignorer_cb_.Run(error);
79 }
80
81 // static
82 void Connection::SetErrorIgnorer(const Connection::ErrorIgnorerCallback& cb) {
83 CHECK(current_ignorer_cb_.is_null());
84 current_ignorer_cb_ = cb;
85 }
86
87 // static
88 void Connection::ResetErrorIgnorer() {
89 current_ignorer_cb_.Reset();
90 }
91
71 bool StatementID::operator<(const StatementID& other) const { 92 bool StatementID::operator<(const StatementID& other) const {
72 if (number_ != other.number_) 93 if (number_ != other.number_)
73 return number_ < other.number_; 94 return number_ < other.number_;
74 return strcmp(str_, other.str_) < 0; 95 return strcmp(str_, other.str_) < 0;
75 } 96 }
76 97
77 ErrorDelegate::~ErrorDelegate() { 98 ErrorDelegate::~ErrorDelegate() {
78 } 99 }
79 100
80 Connection::StatementRef::StatementRef(Connection* connection, 101 Connection::StatementRef::StatementRef(Connection* connection,
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 return false; 454 return false;
434 } 455 }
435 456
436 int error = ExecuteAndReturnErrorCode(sql); 457 int error = ExecuteAndReturnErrorCode(sql);
437 if (error != SQLITE_OK) 458 if (error != SQLITE_OK)
438 error = OnSqliteError(error, NULL); 459 error = OnSqliteError(error, NULL);
439 460
440 // This needs to be a FATAL log because the error case of arriving here is 461 // This needs to be a FATAL log because the error case of arriving here is
441 // that there's a malformed SQL statement. This can arise in development if 462 // that there's a malformed SQL statement. This can arise in development if
442 // a change alters the schema but not all queries adjust. 463 // a change alters the schema but not all queries adjust.
464 // in production if the schema is corrupted.
erikwright (departed) 2013/06/13 01:26:24 Fix up the capitalization/grammar here.
Scott Hess - ex-Googler 2013/06/13 03:23:27 Done. A snippet got lost somewhere in editing.
443 if (error == SQLITE_ERROR) 465 if (error == SQLITE_ERROR)
444 DLOG(FATAL) << "SQL Error in " << sql << ", " << GetErrorMessage(); 466 DLOG(FATAL) << "SQL Error in " << sql << ", " << GetErrorMessage();
445 return error == SQLITE_OK; 467 return error == SQLITE_OK;
446 } 468 }
447 469
448 bool Connection::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) { 470 bool Connection::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) {
449 if (!db_) { 471 if (!db_) {
450 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db"; 472 DLOG_IF(FATAL, !poisoned_) << "Illegal use of connection without a db";
451 return false; 473 return false;
452 } 474 }
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes"; 679 DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes";
658 680
659 // If indicated, lock up the database before doing anything else, so 681 // If indicated, lock up the database before doing anything else, so
660 // that the following code doesn't have to deal with locking. 682 // that the following code doesn't have to deal with locking.
661 // TODO(shess): This code is brittle. Find the cases where code 683 // TODO(shess): This code is brittle. Find the cases where code
662 // doesn't request |exclusive_locking_| and audit that it does the 684 // doesn't request |exclusive_locking_| and audit that it does the
663 // right thing with SQLITE_BUSY, and that it doesn't make 685 // right thing with SQLITE_BUSY, and that it doesn't make
664 // assumptions about who might change things in the database. 686 // assumptions about who might change things in the database.
665 // http://crbug.com/56559 687 // http://crbug.com/56559
666 if (exclusive_locking_) { 688 if (exclusive_locking_) {
667 // TODO(shess): This should probably be a full CHECK(). Code 689 // TODO(shess): This should probably be a failure. Code which
668 // which requests exclusive locking but doesn't get it is almost 690 // requests exclusive locking but doesn't get it is almost certain
669 // certain to be ill-tested. 691 // to be ill-tested.
670 if (!Execute("PRAGMA locking_mode=EXCLUSIVE")) 692 ignore_result(Execute("PRAGMA locking_mode=EXCLUSIVE"));
671 DLOG(FATAL) << "Could not set locking mode: " << GetErrorMessage();
672 } 693 }
673 694
674 // http://www.sqlite.org/pragma.html#pragma_journal_mode 695 // http://www.sqlite.org/pragma.html#pragma_journal_mode
675 // DELETE (default) - delete -journal file to commit. 696 // DELETE (default) - delete -journal file to commit.
676 // TRUNCATE - truncate -journal file to commit. 697 // TRUNCATE - truncate -journal file to commit.
677 // PERSIST - zero out header of -journal file to commit. 698 // PERSIST - zero out header of -journal file to commit.
678 // journal_size_limit provides size to trim to in PERSIST. 699 // journal_size_limit provides size to trim to in PERSIST.
679 // TODO(shess): Figure out if PERSIST and journal_size_limit really 700 // TODO(shess): Figure out if PERSIST and journal_size_limit really
680 // matter. In theory, it keeps pages pre-allocated, so if 701 // matter. In theory, it keeps pages pre-allocated, so if
681 // transactions usually fit, it should be faster. 702 // transactions usually fit, it should be faster.
682 ignore_result(Execute("PRAGMA journal_mode = PERSIST")); 703 ignore_result(Execute("PRAGMA journal_mode = PERSIST"));
683 ignore_result(Execute("PRAGMA journal_size_limit = 16384")); 704 ignore_result(Execute("PRAGMA journal_size_limit = 16384"));
684 705
685 const base::TimeDelta kBusyTimeout = 706 const base::TimeDelta kBusyTimeout =
686 base::TimeDelta::FromSeconds(kBusyTimeoutSeconds); 707 base::TimeDelta::FromSeconds(kBusyTimeoutSeconds);
687 708
688 if (page_size_ != 0) { 709 if (page_size_ != 0) {
689 // Enforce SQLite restrictions on |page_size_|. 710 // Enforce SQLite restrictions on |page_size_|.
690 DCHECK(!(page_size_ & (page_size_ - 1))) 711 DCHECK(!(page_size_ & (page_size_ - 1)))
691 << " page_size_ " << page_size_ << " is not a power of two."; 712 << " page_size_ " << page_size_ << " is not a power of two.";
692 const int kSqliteMaxPageSize = 32768; // from sqliteLimit.h 713 const int kSqliteMaxPageSize = 32768; // from sqliteLimit.h
693 DCHECK_LE(page_size_, kSqliteMaxPageSize); 714 DCHECK_LE(page_size_, kSqliteMaxPageSize);
694 const std::string sql = 715 const std::string sql =
695 base::StringPrintf("PRAGMA page_size=%d", page_size_); 716 base::StringPrintf("PRAGMA page_size=%d", page_size_);
696 if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout)) 717 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout));
697 DLOG(FATAL) << "Could not set page size: " << GetErrorMessage();
698 } 718 }
699 719
700 if (cache_size_ != 0) { 720 if (cache_size_ != 0) {
701 const std::string sql = 721 const std::string sql =
702 base::StringPrintf("PRAGMA cache_size=%d", cache_size_); 722 base::StringPrintf("PRAGMA cache_size=%d", cache_size_);
703 if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout)) 723 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout));
704 DLOG(FATAL) << "Could not set cache size: " << GetErrorMessage();
705 } 724 }
706 725
707 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) { 726 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) {
708 DLOG(FATAL) << "Could not enable secure_delete: " << GetErrorMessage();
709 Close(); 727 Close();
710 return false; 728 return false;
711 } 729 }
712 730
713 return true; 731 return true;
714 } 732 }
715 733
716 void Connection::DoRollback() { 734 void Connection::DoRollback() {
717 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK")); 735 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK"));
718 rollback.Run(); 736 rollback.Run();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 error_callback_.Run(err, stmt); 781 error_callback_.Run(err, stmt);
764 return err; 782 return err;
765 } 783 }
766 784
767 // TODO(shess): Remove |error_delegate_| once everything is 785 // TODO(shess): Remove |error_delegate_| once everything is
768 // converted to |error_callback_|. 786 // converted to |error_callback_|.
769 if (error_delegate_.get()) 787 if (error_delegate_.get())
770 return error_delegate_->OnError(err, this, stmt); 788 return error_delegate_->OnError(err, this, stmt);
771 789
772 // The default handling is to assert on debug and to ignore on release. 790 // The default handling is to assert on debug and to ignore on release.
773 DLOG(FATAL) << GetErrorMessage(); 791 if (!ShouldIgnore(err))
792 DLOG(FATAL) << GetErrorMessage();
774 return err; 793 return err;
775 } 794 }
776 795
777 // TODO(shess): Allow specifying integrity_check versus quick_check. 796 // TODO(shess): Allow specifying integrity_check versus quick_check.
778 // TODO(shess): Allow specifying maximum results (default 100 lines). 797 // TODO(shess): Allow specifying maximum results (default 100 lines).
779 bool Connection::IntegrityCheck(std::vector<std::string>* messages) { 798 bool Connection::IntegrityCheck(std::vector<std::string>* messages) {
780 messages->clear(); 799 messages->clear();
781 800
782 // This has the side effect of setting SQLITE_RecoveryMode, which 801 // This has the side effect of setting SQLITE_RecoveryMode, which
783 // allows SQLite to process through certain cases of corruption. 802 // allows SQLite to process through certain cases of corruption.
(...skipping 19 matching lines...) Expand all
803 } 822 }
804 823
805 // Best effort to put things back as they were before. 824 // Best effort to put things back as they were before.
806 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; 825 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF";
807 ignore_result(Execute(kNoWritableSchema)); 826 ignore_result(Execute(kNoWritableSchema));
808 827
809 return ret; 828 return ret;
810 } 829 }
811 830
812 } // namespace sql 831 } // namespace sql
OLDNEW
« no previous file with comments | « sql/connection.h ('k') | sql/connection_unittest.cc » ('j') | sql/sql.gyp » ('J')

Powered by Google App Engine
This is Rietveld 408576698