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" |
| 11 #include "base/lazy_instance.h" |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
13 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
14 #include "base/strings/string_split.h" | 15 #include "base/strings/string_split.h" |
15 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
17 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/synchronization/lock.h" |
18 #include "sql/statement.h" | 20 #include "sql/statement.h" |
19 #include "third_party/sqlite/sqlite3.h" | 21 #include "third_party/sqlite/sqlite3.h" |
20 | 22 |
21 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) | 23 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) |
22 #include "third_party/sqlite/src/ext/icu/sqliteicu.h" | 24 #include "third_party/sqlite/src/ext/icu/sqliteicu.h" |
23 #endif | 25 #endif |
24 | 26 |
25 namespace { | 27 namespace { |
26 | 28 |
27 // Spin for up to a second waiting for the lock to clear when setting | 29 // Spin for up to a second waiting for the lock to clear when setting |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 if (!((attachment_point[i] >= '0' && attachment_point[i] <= '9') || | 104 if (!((attachment_point[i] >= '0' && attachment_point[i] <= '9') || |
103 (attachment_point[i] >= 'a' && attachment_point[i] <= 'z') || | 105 (attachment_point[i] >= 'a' && attachment_point[i] <= 'z') || |
104 (attachment_point[i] >= 'A' && attachment_point[i] <= 'Z') || | 106 (attachment_point[i] >= 'A' && attachment_point[i] <= 'Z') || |
105 attachment_point[i] == '_')) { | 107 attachment_point[i] == '_')) { |
106 return false; | 108 return false; |
107 } | 109 } |
108 } | 110 } |
109 return true; | 111 return true; |
110 } | 112 } |
111 | 113 |
| 114 // SQLite automatically calls sqlite3_initialize() lazily, but |
| 115 // sqlite3_initialize() uses double-checked locking and thus can have |
| 116 // data races. |
| 117 // |
| 118 // TODO(shess): Another alternative would be to have |
| 119 // sqlite3_initialize() called as part of process bring-up. If this |
| 120 // is changed, remove the dynamic_annotations dependency in sql.gyp. |
| 121 base::LazyInstance<base::Lock>::Leaky |
| 122 g_sqlite_init_lock = LAZY_INSTANCE_INITIALIZER; |
| 123 void InitializeSqlite() { |
| 124 base::AutoLock lock(g_sqlite_init_lock.Get()); |
| 125 sqlite3_initialize(); |
| 126 } |
| 127 |
112 } // namespace | 128 } // namespace |
113 | 129 |
114 namespace sql { | 130 namespace sql { |
115 | 131 |
116 // static | 132 // static |
117 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL; | 133 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL; |
118 | 134 |
119 // static | 135 // static |
120 bool Connection::ShouldIgnore(int error) { | 136 bool Connection::ShouldIgnore(int error) { |
121 if (!current_ignorer_cb_) | 137 if (!current_ignorer_cb_) |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 | 808 |
793 bool Connection::OpenInternal(const std::string& file_name, | 809 bool Connection::OpenInternal(const std::string& file_name, |
794 Connection::Retry retry_flag) { | 810 Connection::Retry retry_flag) { |
795 AssertIOAllowed(); | 811 AssertIOAllowed(); |
796 | 812 |
797 if (db_) { | 813 if (db_) { |
798 DLOG(FATAL) << "sql::Connection is already open."; | 814 DLOG(FATAL) << "sql::Connection is already open."; |
799 return false; | 815 return false; |
800 } | 816 } |
801 | 817 |
| 818 // Make sure sqlite3_initialize() is called before anything else. |
| 819 InitializeSqlite(); |
| 820 |
802 // If |poisoned_| is set, it means an error handler called | 821 // If |poisoned_| is set, it means an error handler called |
803 // RazeAndClose(). Until regular Close() is called, the caller | 822 // RazeAndClose(). Until regular Close() is called, the caller |
804 // should be treating the database as open, but is_open() currently | 823 // should be treating the database as open, but is_open() currently |
805 // only considers the sqlite3 handle's state. | 824 // only considers the sqlite3 handle's state. |
806 // TODO(shess): Revise is_open() to consider poisoned_, and review | 825 // TODO(shess): Revise is_open() to consider poisoned_, and review |
807 // to see if any non-testing code even depends on it. | 826 // to see if any non-testing code even depends on it. |
808 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open."; | 827 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open."; |
809 poisoned_ = false; | 828 poisoned_ = false; |
810 | 829 |
811 int err = sqlite3_open(file_name.c_str(), &db_); | 830 int err = sqlite3_open(file_name.c_str(), &db_); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 } | 1043 } |
1025 | 1044 |
1026 // Best effort to put things back as they were before. | 1045 // Best effort to put things back as they were before. |
1027 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; | 1046 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; |
1028 ignore_result(Execute(kNoWritableSchema)); | 1047 ignore_result(Execute(kNoWritableSchema)); |
1029 | 1048 |
1030 return ret; | 1049 return ret; |
1031 } | 1050 } |
1032 | 1051 |
1033 } // namespace sql | 1052 } // namespace sql |
OLD | NEW |