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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 open_statements_.clear(); | 229 open_statements_.clear(); |
230 | 230 |
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. |
Scott Hess - ex-Googler
2013/07/22 17:57:40
Erp, removing this TODO.
| |
240 sqlite3_close(db_); | 240 int rc = sqlite3_close(db_); |
241 if (rc != SQLITE_OK) { | |
242 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.CloseFailure", rc); | |
243 DLOG(FATAL) << "sqlite3_close failed: " << GetErrorMessage(); | |
244 } | |
241 db_ = NULL; | 245 db_ = NULL; |
242 } | 246 } |
243 } | 247 } |
244 | 248 |
245 void Connection::Close() { | 249 void Connection::Close() { |
246 // If the database was already closed by RazeAndClose(), then no | 250 // If the database was already closed by RazeAndClose(), then no |
247 // need to close again. Clear the |poisoned_| bit so that incorrect | 251 // need to close again. Clear the |poisoned_| bit so that incorrect |
248 // API calls are caught. | 252 // API calls are caught. |
249 if (poisoned_) { | 253 if (poisoned_) { |
250 poisoned_ = false; | 254 poisoned_ = false; |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
711 // RazeAndClose(). Until regular Close() is called, the caller | 715 // RazeAndClose(). Until regular Close() is called, the caller |
712 // should be treating the database as open, but is_open() currently | 716 // should be treating the database as open, but is_open() currently |
713 // only considers the sqlite3 handle's state. | 717 // only considers the sqlite3 handle's state. |
714 // TODO(shess): Revise is_open() to consider poisoned_, and review | 718 // TODO(shess): Revise is_open() to consider poisoned_, and review |
715 // to see if any non-testing code even depends on it. | 719 // to see if any non-testing code even depends on it. |
716 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open."; | 720 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open."; |
717 poisoned_ = false; | 721 poisoned_ = false; |
718 | 722 |
719 int err = sqlite3_open(file_name.c_str(), &db_); | 723 int err = sqlite3_open(file_name.c_str(), &db_); |
720 if (err != SQLITE_OK) { | 724 if (err != SQLITE_OK) { |
725 // Extended error codes cannot be enabled until a handle is | |
726 // available, fetch manually. | |
727 err = sqlite3_extended_errcode(db_); | |
728 | |
721 // Histogram failures specific to initial open for debugging | 729 // Histogram failures specific to initial open for debugging |
722 // purposes. | 730 // purposes. |
723 UMA_HISTOGRAM_ENUMERATION("Sqlite.OpenFailure", err & 0xff, 50); | 731 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.OpenFailure", err); |
724 | 732 |
725 OnSqliteError(err, NULL); | 733 OnSqliteError(err, NULL); |
726 Close(); | 734 Close(); |
727 db_ = NULL; | 735 db_ = NULL; |
728 return false; | 736 return false; |
729 } | 737 } |
730 | 738 |
731 // SQLite uses a lookaside buffer to improve performance of small mallocs. | 739 // SQLite uses a lookaside buffer to improve performance of small mallocs. |
732 // Chromium already depends on small mallocs being efficient, so we disable | 740 // Chromium already depends on small mallocs being efficient, so we disable |
733 // this to avoid the extra memory overhead. | 741 // this to avoid the extra memory overhead. |
734 // This must be called immediatly after opening the database before any SQL | 742 // This must be called immediatly after opening the database before any SQL |
735 // statements are run. | 743 // statements are run. |
736 sqlite3_db_config(db_, SQLITE_DBCONFIG_LOOKASIDE, NULL, 0, 0); | 744 sqlite3_db_config(db_, SQLITE_DBCONFIG_LOOKASIDE, NULL, 0, 0); |
737 | 745 |
746 // Enable extended result codes to provide more color on I/O errors. | |
747 // Not having extended result codes is not a fatal problem, as | |
748 // Chromium code does not attempt to handle I/O errors anyhow. The | |
749 // current implementation always returns SQLITE_OK, the DCHECK is to | |
750 // quickly notify someone if SQLite changes. | |
751 err = sqlite3_extended_result_codes(db_, 1); | |
752 DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes"; | |
753 | |
738 // sqlite3_open() does not actually read the database file (unless a | 754 // sqlite3_open() does not actually read the database file (unless a |
739 // hot journal is found). Successfully executing this pragma on an | 755 // hot journal is found). Successfully executing this pragma on an |
740 // existing database requires a valid header on page 1. | 756 // existing database requires a valid header on page 1. |
741 // TODO(shess): For now, just probing to see what the lay of the | 757 // TODO(shess): For now, just probing to see what the lay of the |
742 // land is. If it's mostly SQLITE_NOTADB, then the database should | 758 // land is. If it's mostly SQLITE_NOTADB, then the database should |
743 // be razed. | 759 // be razed. |
744 err = ExecuteAndReturnErrorCode("PRAGMA auto_vacuum"); | 760 err = ExecuteAndReturnErrorCode("PRAGMA auto_vacuum"); |
745 if (err != SQLITE_OK) | 761 if (err != SQLITE_OK) |
746 UMA_HISTOGRAM_ENUMERATION("Sqlite.OpenProbeFailure", err & 0xff, 50); | 762 UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.OpenProbeFailure", err); |
747 | |
748 // Enable extended result codes to provide more color on I/O errors. | |
749 // Not having extended result codes is not a fatal problem, as | |
750 // Chromium code does not attempt to handle I/O errors anyhow. The | |
751 // current implementation always returns SQLITE_OK, the DCHECK is to | |
752 // quickly notify someone if SQLite changes. | |
753 err = sqlite3_extended_result_codes(db_, 1); | |
754 DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes"; | |
755 | 763 |
756 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) | 764 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) |
757 // The version of SQLite shipped with iOS doesn't enable ICU, which includes | 765 // The version of SQLite shipped with iOS doesn't enable ICU, which includes |
758 // REGEXP support. Add it in dynamically. | 766 // REGEXP support. Add it in dynamically. |
759 err = sqlite3IcuInit(db_); | 767 err = sqlite3IcuInit(db_); |
760 DCHECK_EQ(err, SQLITE_OK) << "Could not enable ICU support"; | 768 DCHECK_EQ(err, SQLITE_OK) << "Could not enable ICU support"; |
761 #endif // OS_IOS && USE_SYSTEM_SQLITE | 769 #endif // OS_IOS && USE_SYSTEM_SQLITE |
762 | 770 |
763 // If indicated, lock up the database before doing anything else, so | 771 // If indicated, lock up the database before doing anything else, so |
764 // that the following code doesn't have to deal with locking. | 772 // that the following code doesn't have to deal with locking. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
899 } | 907 } |
900 | 908 |
901 // Best effort to put things back as they were before. | 909 // Best effort to put things back as they were before. |
902 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; | 910 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; |
903 ignore_result(Execute(kNoWritableSchema)); | 911 ignore_result(Execute(kNoWritableSchema)); |
904 | 912 |
905 return ret; | 913 return ret; |
906 } | 914 } |
907 | 915 |
908 } // namespace sql | 916 } // namespace sql |
OLD | NEW |