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

Side by Side Diff: sql/connection.cc

Issue 18641004: [sql] Retry Open() if error handler fixed things. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Pointless tweaking, rebase. Created 7 years, 5 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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 base::HistogramBase* histogram = 187 base::HistogramBase* histogram =
188 base::Histogram::FactoryGet( 188 base::Histogram::FactoryGet(
189 full_histogram_name, 1, 1000000, 50, 189 full_histogram_name, 1, 1000000, 50,
190 base::HistogramBase::kUmaTargetedHistogramFlag); 190 base::HistogramBase::kUmaTargetedHistogramFlag);
191 if (histogram) 191 if (histogram)
192 histogram->Add(sample); 192 histogram->Add(sample);
193 } 193 }
194 } 194 }
195 195
196 #if defined(OS_WIN) 196 #if defined(OS_WIN)
197 return OpenInternal(WideToUTF8(path.value())); 197 return OpenInternal(WideToUTF8(path.value()), RETRY_ON_POISON);
198 #elif defined(OS_POSIX) 198 #elif defined(OS_POSIX)
199 return OpenInternal(path.value()); 199 return OpenInternal(path.value(), RETRY_ON_POISON);
200 #endif 200 #endif
201 } 201 }
202 202
203 bool Connection::OpenInMemory() { 203 bool Connection::OpenInMemory() {
204 in_memory_ = true; 204 in_memory_ = true;
205 return OpenInternal(":memory:"); 205 return OpenInternal(":memory:", NO_RETRY);
206 } 206 }
207 207
208 void Connection::CloseInternal(bool forced) { 208 void Connection::CloseInternal(bool forced) {
209 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point 209 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point
210 // will delete the -journal file. For ChromiumOS or other more 210 // will delete the -journal file. For ChromiumOS or other more
211 // embedded systems, this is probably not appropriate, whereas on 211 // embedded systems, this is probably not appropriate, whereas on
212 // desktop it might make some sense. 212 // desktop it might make some sense.
213 213
214 // sqlite3_close() needs all prepared statements to be finalized. 214 // sqlite3_close() needs all prepared statements to be finalized.
215 215
(...skipping 15 matching lines...) Expand all
231 if (db_) { 231 if (db_) {
232 // Call to AssertIOAllowed() cannot go at the beginning of the function 232 // Call to AssertIOAllowed() cannot go at the beginning of the function
233 // because Close() must be called from destructor to clean 233 // because Close() must be called from destructor to clean
234 // statement_cache_, it won't cause any disk access and it most probably 234 // statement_cache_, it won't cause any disk access and it most probably
235 // will happen on thread not allowing disk access. 235 // will happen on thread not allowing disk access.
236 // TODO(paivanof@gmail.com): This should move to the beginning 236 // TODO(paivanof@gmail.com): This should move to the beginning
237 // of the function. http://crbug.com/136655. 237 // of the function. http://crbug.com/136655.
238 AssertIOAllowed(); 238 AssertIOAllowed();
239 // TODO(shess): Histogram for failure. 239 // TODO(shess): Histogram for failure.
240 sqlite3_close(db_); 240 sqlite3_close(db_);
241 db_ = NULL;
242 } 241 }
242 db_ = NULL;
243 } 243 }
244 244
245 void Connection::Close() { 245 void Connection::Close() {
246 // If the database was already closed by RazeAndClose(), then no 246 // If the database was already closed by RazeAndClose(), then no
247 // need to close again. Clear the |poisoned_| bit so that incorrect 247 // need to close again. Clear the |poisoned_| bit so that incorrect
248 // API calls are caught. 248 // API calls are caught.
249 if (poisoned_) { 249 if (poisoned_) {
250 poisoned_ = false; 250 poisoned_ = false;
251 return; 251 return;
252 } 252 }
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 692
693 return err; 693 return err;
694 } 694 }
695 695
696 const char* Connection::GetErrorMessage() const { 696 const char* Connection::GetErrorMessage() const {
697 if (!db_) 697 if (!db_)
698 return "sql::Connection has no connection."; 698 return "sql::Connection has no connection.";
699 return sqlite3_errmsg(db_); 699 return sqlite3_errmsg(db_);
700 } 700 }
701 701
702 bool Connection::OpenInternal(const std::string& file_name) { 702 bool Connection::OpenInternal(const std::string& file_name,
703 Connection::Retry retry_flag) {
703 AssertIOAllowed(); 704 AssertIOAllowed();
704 705
705 if (db_) { 706 if (db_) {
706 DLOG(FATAL) << "sql::Connection is already open."; 707 DLOG(FATAL) << "sql::Connection is already open.";
707 return false; 708 return false;
708 } 709 }
709 710
710 // If |poisoned_| is set, it means an error handler called 711 // If |poisoned_| is set, it means an error handler called
711 // RazeAndClose(). Until regular Close() is called, the caller 712 // RazeAndClose(). Until regular Close() is called, the caller
712 // should be treating the database as open, but is_open() currently 713 // should be treating the database as open, but is_open() currently
713 // only considers the sqlite3 handle's state. 714 // only considers the sqlite3 handle's state.
714 // TODO(shess): Revise is_open() to consider poisoned_, and review 715 // TODO(shess): Revise is_open() to consider poisoned_, and review
715 // to see if any non-testing code even depends on it. 716 // to see if any non-testing code even depends on it.
716 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open."; 717 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open.";
717 poisoned_ = false; 718 poisoned_ = false;
718 719
719 int err = sqlite3_open(file_name.c_str(), &db_); 720 int err = sqlite3_open(file_name.c_str(), &db_);
720 if (err != SQLITE_OK) { 721 if (err != SQLITE_OK) {
721 // Histogram failures specific to initial open for debugging 722 // Histogram failures specific to initial open for debugging
722 // purposes. 723 // purposes.
723 UMA_HISTOGRAM_ENUMERATION("Sqlite.OpenFailure", err & 0xff, 50); 724 UMA_HISTOGRAM_ENUMERATION("Sqlite.OpenFailure", err & 0xff, 50);
724 725
725 OnSqliteError(err, NULL); 726 OnSqliteError(err, NULL);
727 bool was_poisoned = poisoned_;
726 Close(); 728 Close();
727 db_ = NULL; 729
730 if (was_poisoned && retry_flag == RETRY_ON_POISON)
731 return OpenInternal(file_name, NO_RETRY);
728 return false; 732 return false;
729 } 733 }
730 734
731 // SQLite uses a lookaside buffer to improve performance of small mallocs. 735 // SQLite uses a lookaside buffer to improve performance of small mallocs.
732 // Chromium already depends on small mallocs being efficient, so we disable 736 // Chromium already depends on small mallocs being efficient, so we disable
733 // this to avoid the extra memory overhead. 737 // this to avoid the extra memory overhead.
734 // This must be called immediatly after opening the database before any SQL 738 // This must be called immediatly after opening the database before any SQL
735 // statements are run. 739 // statements are run.
736 sqlite3_db_config(db_, SQLITE_DBCONFIG_LOOKASIDE, NULL, 0, 0); 740 sqlite3_db_config(db_, SQLITE_DBCONFIG_LOOKASIDE, NULL, 0, 0);
737 741
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout)); 803 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout));
800 } 804 }
801 805
802 if (cache_size_ != 0) { 806 if (cache_size_ != 0) {
803 const std::string sql = 807 const std::string sql =
804 base::StringPrintf("PRAGMA cache_size=%d", cache_size_); 808 base::StringPrintf("PRAGMA cache_size=%d", cache_size_);
805 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout)); 809 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout));
806 } 810 }
807 811
808 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) { 812 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) {
813 bool was_poisoned = poisoned_;
809 Close(); 814 Close();
815 if (was_poisoned && retry_flag == RETRY_ON_POISON)
816 return OpenInternal(file_name, NO_RETRY);
810 return false; 817 return false;
811 } 818 }
812 819
813 return true; 820 return true;
814 } 821 }
815 822
816 void Connection::DoRollback() { 823 void Connection::DoRollback() {
817 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK")); 824 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK"));
818 rollback.Run(); 825 rollback.Run();
819 needs_rollback_ = false; 826 needs_rollback_ = false;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 } 909 }
903 910
904 // Best effort to put things back as they were before. 911 // Best effort to put things back as they were before.
905 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; 912 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF";
906 ignore_result(Execute(kNoWritableSchema)); 913 ignore_result(Execute(kNoWritableSchema));
907 914
908 return ret; 915 return ret;
909 } 916 }
910 917
911 } // namespace sql 918 } // 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