blob: 4813b8d060aaec37fd1468e502326c5fd2e38167 [file] [log] [blame]
[email protected]64021042012-02-10 20:02:291// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]e5ffd0e42009-09-11 21:30:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f0a54b22011-07-19 18:40:215#include "sql/connection.h"
[email protected]e5ffd0e42009-09-11 21:30:566
avi51ba3e692015-12-26 17:30:507#include <limits.h>
avi0b519202015-12-21 07:25:198#include <stddef.h>
9#include <stdint.h>
[email protected]e5ffd0e42009-09-11 21:30:5610#include <string.h>
mostynbd82cd9952016-04-11 20:05:3411
tzikb9dae932017-02-10 03:57:3012#include "base/debug/alias.h"
shessc8cd2a162015-10-22 20:30:4613#include "base/debug/dump_without_crashing.h"
[email protected]57999812013-02-24 05:40:5214#include "base/files/file_path.h"
thestig22dfc4012014-09-05 08:29:4415#include "base/files/file_util.h"
shessc8cd2a162015-10-22 20:30:4616#include "base/format_macros.h"
17#include "base/json/json_file_value_serializer.h"
fdoray2dfa76452016-06-07 13:11:2218#include "base/location.h"
[email protected]e5ffd0e42009-09-11 21:30:5619#include "base/logging.h"
Ilya Sherman1c811db2017-12-14 10:36:1820#include "base/metrics/histogram_functions.h"
asvitkine3033081a2016-08-30 04:01:0821#include "base/metrics/histogram_macros.h"
[email protected]210ce0af2013-05-15 09:10:3922#include "base/metrics/sparse_histogram.h"
Victor Costan3653df62018-02-08 21:38:1623#include "base/no_destructor.h"
fdoray2dfa76452016-06-07 13:11:2224#include "base/single_thread_task_runner.h"
[email protected]80abf152013-05-22 12:42:4225#include "base/strings/string_split.h"
[email protected]a4bbc1f92013-06-11 07:28:1926#include "base/strings/string_util.h"
27#include "base/strings/stringprintf.h"
[email protected]906265872013-06-07 22:40:4528#include "base/strings/utf_string_conversions.h"
[email protected]a7ec1292013-07-22 22:02:1829#include "base/synchronization/lock.h"
Victor Costan87cf8c72018-07-19 19:36:0430#include "base/time/default_tick_clock.h"
ssid9f8022f2015-10-12 17:49:0331#include "base/trace_event/memory_dump_manager.h"
Kevin Marshalla9f05ec2017-07-14 02:10:0532#include "build/build_config.h"
ssid3be5b1ec2016-01-13 14:21:5733#include "sql/connection_memory_dump_provider.h"
Victor Costan3653df62018-02-08 21:38:1634#include "sql/initialization.h"
shess9bf2c672015-12-18 01:18:0835#include "sql/meta_table.h"
[email protected]f0a54b22011-07-19 18:40:2136#include "sql/statement.h"
shess5f2c3442017-01-24 02:15:1037#include "sql/vfs_wrapper.h"
[email protected]e33cba42010-08-18 23:37:0338#include "third_party/sqlite/sqlite3.h"
[email protected]e5ffd0e42009-09-11 21:30:5639
[email protected]5b96f3772010-09-28 16:30:5740namespace {
41
42// Spin for up to a second waiting for the lock to clear when setting
43// up the database.
44// TODO(shess): Better story on this. http://crbug.com/56559
[email protected]c68ce172011-11-24 22:30:2745const int kBusyTimeoutSeconds = 1;
[email protected]5b96f3772010-09-28 16:30:5746
47class ScopedBusyTimeout {
48 public:
49 explicit ScopedBusyTimeout(sqlite3* db)
50 : db_(db) {
51 }
52 ~ScopedBusyTimeout() {
53 sqlite3_busy_timeout(db_, 0);
54 }
55
56 int SetTimeout(base::TimeDelta timeout) {
57 DCHECK_LT(timeout.InMilliseconds(), INT_MAX);
58 return sqlite3_busy_timeout(db_,
59 static_cast<int>(timeout.InMilliseconds()));
60 }
61
62 private:
63 sqlite3* db_;
64};
65
[email protected]6d42f152012-11-10 00:38:2466// Helper to "safely" enable writable_schema. No error checking
67// because it is reasonable to just forge ahead in case of an error.
68// If turning it on fails, then most likely nothing will work, whereas
69// if turning it off fails, it only matters if some code attempts to
70// continue working with the database and tries to modify the
71// sqlite_master table (none of our code does this).
72class ScopedWritableSchema {
73 public:
74 explicit ScopedWritableSchema(sqlite3* db)
75 : db_(db) {
Victor Costanbd623112018-07-18 04:17:2776 sqlite3_exec(db_, "PRAGMA writable_schema=1", nullptr, nullptr, nullptr);
[email protected]6d42f152012-11-10 00:38:2477 }
78 ~ScopedWritableSchema() {
Victor Costanbd623112018-07-18 04:17:2779 sqlite3_exec(db_, "PRAGMA writable_schema=0", nullptr, nullptr, nullptr);
[email protected]6d42f152012-11-10 00:38:2480 }
81
82 private:
83 sqlite3* db_;
84};
85
[email protected]7bae5742013-07-10 20:46:1686// Helper to wrap the sqlite3_backup_*() step of Raze(). Return
87// SQLite error code from running the backup step.
88int BackupDatabase(sqlite3* src, sqlite3* dst, const char* db_name) {
89 DCHECK_NE(src, dst);
90 sqlite3_backup* backup = sqlite3_backup_init(dst, db_name, src, db_name);
91 if (!backup) {
92 // Since this call only sets things up, this indicates a gross
93 // error in SQLite.
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:5294 DLOG(DCHECK) << "Unable to start sqlite3_backup(): " << sqlite3_errmsg(dst);
[email protected]7bae5742013-07-10 20:46:1695 return sqlite3_errcode(dst);
96 }
97
98 // -1 backs up the entire database.
99 int rc = sqlite3_backup_step(backup, -1);
100 int pages = sqlite3_backup_pagecount(backup);
101 sqlite3_backup_finish(backup);
102
103 // If successful, exactly one page should have been backed up. If
104 // this breaks, check this function to make sure assumptions aren't
105 // being broken.
106 if (rc == SQLITE_DONE)
107 DCHECK_EQ(pages, 1);
108
109 return rc;
110}
111
[email protected]8d409412013-07-19 18:25:30112// Be very strict on attachment point. SQLite can handle a much wider
113// character set with appropriate quoting, but Chromium code should
114// just use clean names to start with.
115bool ValidAttachmentPoint(const char* attachment_point) {
116 for (size_t i = 0; attachment_point[i]; ++i) {
zhongyi23960342016-04-12 23:13:20117 if (!(base::IsAsciiDigit(attachment_point[i]) ||
118 base::IsAsciiAlpha(attachment_point[i]) ||
[email protected]8d409412013-07-19 18:25:30119 attachment_point[i] == '_')) {
120 return false;
121 }
122 }
123 return true;
124}
125
[email protected]8ada10f2013-12-21 00:42:34126// Helper to get the sqlite3_file* associated with the "main" database.
127int GetSqlite3File(sqlite3* db, sqlite3_file** file) {
Victor Costanbd623112018-07-18 04:17:27128 *file = nullptr;
129 int rc = sqlite3_file_control(db, nullptr, SQLITE_FCNTL_FILE_POINTER, file);
[email protected]8ada10f2013-12-21 00:42:34130 if (rc != SQLITE_OK)
131 return rc;
132
Victor Costanbd623112018-07-18 04:17:27133 // TODO(shess): null in file->pMethods has been observed on android_dbg
[email protected]8ada10f2013-12-21 00:42:34134 // content_unittests, even though it should not be possible.
135 // http://crbug.com/329982
136 if (!*file || !(*file)->pMethods)
137 return SQLITE_ERROR;
138
139 return rc;
140}
141
shess5dac334f2015-11-05 20:47:42142// Convenience to get the sqlite3_file* and the size for the "main" database.
143int GetSqlite3FileAndSize(sqlite3* db,
144 sqlite3_file** file, sqlite3_int64* db_size) {
145 int rc = GetSqlite3File(db, file);
146 if (rc != SQLITE_OK)
147 return rc;
148
149 return (*file)->pMethods->xFileSize(*file, db_size);
150}
151
shess58b8df82015-06-03 00:19:32152// This should match UMA_HISTOGRAM_MEDIUM_TIMES().
153base::HistogramBase* GetMediumTimeHistogram(const std::string& name) {
154 return base::Histogram::FactoryTimeGet(
155 name,
156 base::TimeDelta::FromMilliseconds(10),
157 base::TimeDelta::FromMinutes(3),
158 50,
159 base::HistogramBase::kUmaTargetedHistogramFlag);
160}
161
erg102ceb412015-06-20 01:38:13162std::string AsUTF8ForSQL(const base::FilePath& path) {
163#if defined(OS_WIN)
164 return base::WideToUTF8(path.value());
Fabrice de Gans-Riberi65421f62018-05-22 23:16:18165#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
erg102ceb412015-06-20 01:38:13166 return path.value();
167#endif
168}
169
[email protected]5b96f3772010-09-28 16:30:57170} // namespace
171
[email protected]e5ffd0e42009-09-11 21:30:56172namespace sql {
173
[email protected]4350e322013-06-18 22:18:10174// static
Victor Costanbd623112018-07-18 04:17:27175Connection::ErrorExpecterCallback* Connection::current_expecter_cb_ = nullptr;
[email protected]4350e322013-06-18 22:18:10176
177// static
shess976814402016-06-21 06:56:25178bool Connection::IsExpectedSqliteError(int error) {
179 if (!current_expecter_cb_)
[email protected]4350e322013-06-18 22:18:10180 return false;
shess976814402016-06-21 06:56:25181 return current_expecter_cb_->Run(error);
[email protected]4350e322013-06-18 22:18:10182}
183
shessc8cd2a162015-10-22 20:30:46184void Connection::ReportDiagnosticInfo(int extended_error, Statement* stmt) {
185 AssertIOAllowed();
186
afakhry7c9abe72016-08-05 17:33:19187 std::string debug_info = GetDiagnosticInfo(extended_error, stmt);
shessc8cd2a162015-10-22 20:30:46188 if (!debug_info.empty() && RegisterIntentToUpload()) {
Lukasz Anforowicz68c21772018-01-13 03:42:44189 DEBUG_ALIAS_FOR_CSTR(debug_buf, debug_info.c_str(), 2000);
shessc8cd2a162015-10-22 20:30:46190 base::debug::DumpWithoutCrashing();
191 }
192}
193
[email protected]4350e322013-06-18 22:18:10194// static
shess976814402016-06-21 06:56:25195void Connection::SetErrorExpecter(Connection::ErrorExpecterCallback* cb) {
Victor Costanbd623112018-07-18 04:17:27196 CHECK(!current_expecter_cb_);
shess976814402016-06-21 06:56:25197 current_expecter_cb_ = cb;
[email protected]4350e322013-06-18 22:18:10198}
199
200// static
shess976814402016-06-21 06:56:25201void Connection::ResetErrorExpecter() {
202 CHECK(current_expecter_cb_);
Victor Costanbd623112018-07-18 04:17:27203 current_expecter_cb_ = nullptr;
[email protected]4350e322013-06-18 22:18:10204}
205
Victor Costance678e72018-07-24 10:25:00206// static
207base::FilePath Connection::JournalPath(const base::FilePath& db_path) {
208 return base::FilePath(db_path.value() + FILE_PATH_LITERAL("-journal"));
209}
210
211// static
212base::FilePath Connection::WriteAheadLogPath(const base::FilePath& db_path) {
213 return base::FilePath(db_path.value() + FILE_PATH_LITERAL("-wal"));
214}
215
216// static
217base::FilePath Connection::SharedMemoryFilePath(const base::FilePath& db_path) {
218 return base::FilePath(db_path.value() + FILE_PATH_LITERAL("-shm"));
219}
220
[email protected]e5ffd0e42009-09-11 21:30:56221Connection::StatementRef::StatementRef(Connection* connection,
[email protected]41a97c812013-02-07 02:35:38222 sqlite3_stmt* stmt,
223 bool was_valid)
[email protected]e5ffd0e42009-09-11 21:30:56224 : connection_(connection),
[email protected]41a97c812013-02-07 02:35:38225 stmt_(stmt),
226 was_valid_(was_valid) {
227 if (connection)
228 connection_->StatementRefCreated(this);
[email protected]e5ffd0e42009-09-11 21:30:56229}
230
231Connection::StatementRef::~StatementRef() {
232 if (connection_)
233 connection_->StatementRefDeleted(this);
[email protected]41a97c812013-02-07 02:35:38234 Close(false);
[email protected]e5ffd0e42009-09-11 21:30:56235}
236
[email protected]41a97c812013-02-07 02:35:38237void Connection::StatementRef::Close(bool forced) {
[email protected]e5ffd0e42009-09-11 21:30:56238 if (stmt_) {
[email protected]35f7e5392012-07-27 19:54:50239 // Call to AssertIOAllowed() cannot go at the beginning of the function
240 // because Close() is called unconditionally from destructor to clean
241 // connection_. And if this is inactive statement this won't cause any
242 // disk access and destructor most probably will be called on thread
243 // not allowing disk access.
244 // TODO([email protected]): This should move to the beginning
245 // of the function. http://crbug.com/136655.
246 AssertIOAllowed();
[email protected]e5ffd0e42009-09-11 21:30:56247 sqlite3_finalize(stmt_);
Victor Costanbd623112018-07-18 04:17:27248 stmt_ = nullptr;
[email protected]e5ffd0e42009-09-11 21:30:56249 }
Victor Costanbd623112018-07-18 04:17:27250 connection_ = nullptr; // The connection may be getting deleted.
[email protected]41a97c812013-02-07 02:35:38251
252 // Forced close is expected to happen from a statement error
253 // handler. In that case maintain the sense of |was_valid_| which
254 // previously held for this ref.
255 was_valid_ = was_valid_ && forced;
[email protected]e5ffd0e42009-09-11 21:30:56256}
257
Victor Costan7f6abbbe2018-07-29 02:57:27258static_assert(
259 Connection::kDefaultPageSize == SQLITE_DEFAULT_PAGE_SIZE,
260 "Connection::kDefaultPageSize must match the value configured into SQLite");
261
262constexpr int Connection::kDefaultPageSize;
263
[email protected]e5ffd0e42009-09-11 21:30:56264Connection::Connection()
Victor Costanbd623112018-07-18 04:17:27265 : db_(nullptr),
Victor Costan7f6abbbe2018-07-29 02:57:27266 page_size_(kDefaultPageSize),
[email protected]e5ffd0e42009-09-11 21:30:56267 cache_size_(0),
268 exclusive_locking_(false),
269 transaction_nesting_(0),
[email protected]35f7e5392012-07-27 19:54:50270 needs_rollback_(false),
[email protected]49dc4f22012-10-17 17:41:16271 in_memory_(false),
shess58b8df82015-06-03 00:19:32272 poisoned_(false),
shessa62504d2016-11-07 19:26:12273 mmap_alt_status_(false),
kerz42ff2a012016-04-27 04:50:06274 mmap_disabled_(false),
shess7dbd4dee2015-10-06 17:39:16275 mmap_enabled_(false),
276 total_changes_at_last_release_(0),
Victor Costanbd623112018-07-18 04:17:27277 stats_histogram_(nullptr),
278 commit_time_histogram_(nullptr),
279 autocommit_time_histogram_(nullptr),
280 update_time_histogram_(nullptr),
281 query_time_histogram_(nullptr),
Victor Costan87cf8c72018-07-19 19:36:04282 clock_(std::make_unique<base::DefaultTickClock>()) {}
[email protected]e5ffd0e42009-09-11 21:30:56283
284Connection::~Connection() {
285 Close();
286}
287
shess58b8df82015-06-03 00:19:32288void Connection::RecordEvent(Events event, size_t count) {
289 for (size_t i = 0; i < count; ++i) {
290 UMA_HISTOGRAM_ENUMERATION("Sqlite.Stats", event, EVENT_MAX_VALUE);
291 }
292
293 if (stats_histogram_) {
294 for (size_t i = 0; i < count; ++i) {
295 stats_histogram_->Add(event);
296 }
297 }
298}
299
300void Connection::RecordCommitTime(const base::TimeDelta& delta) {
301 RecordUpdateTime(delta);
302 UMA_HISTOGRAM_MEDIUM_TIMES("Sqlite.CommitTime", delta);
303 if (commit_time_histogram_)
304 commit_time_histogram_->AddTime(delta);
305}
306
307void Connection::RecordAutoCommitTime(const base::TimeDelta& delta) {
308 RecordUpdateTime(delta);
309 UMA_HISTOGRAM_MEDIUM_TIMES("Sqlite.AutoCommitTime", delta);
310 if (autocommit_time_histogram_)
311 autocommit_time_histogram_->AddTime(delta);
312}
313
314void Connection::RecordUpdateTime(const base::TimeDelta& delta) {
315 RecordQueryTime(delta);
316 UMA_HISTOGRAM_MEDIUM_TIMES("Sqlite.UpdateTime", delta);
317 if (update_time_histogram_)
318 update_time_histogram_->AddTime(delta);
319}
320
321void Connection::RecordQueryTime(const base::TimeDelta& delta) {
322 UMA_HISTOGRAM_MEDIUM_TIMES("Sqlite.QueryTime", delta);
323 if (query_time_histogram_)
324 query_time_histogram_->AddTime(delta);
325}
326
327void Connection::RecordTimeAndChanges(
328 const base::TimeDelta& delta, bool read_only) {
329 if (read_only) {
330 RecordQueryTime(delta);
331 } else {
332 const int changes = sqlite3_changes(db_);
333 if (sqlite3_get_autocommit(db_)) {
334 RecordAutoCommitTime(delta);
335 RecordEvent(EVENT_CHANGES_AUTOCOMMIT, changes);
336 } else {
337 RecordUpdateTime(delta);
338 RecordEvent(EVENT_CHANGES, changes);
339 }
340 }
341}
342
[email protected]a3ef4832013-02-02 05:12:33343bool Connection::Open(const base::FilePath& path) {
[email protected]348ac8f52013-05-21 03:27:02344 if (!histogram_tag_.empty()) {
tfarina720d4f32015-05-11 22:31:26345 int64_t size_64 = 0;
[email protected]56285702013-12-04 18:22:49346 if (base::GetFileSize(path, &size_64)) {
[email protected]348ac8f52013-05-21 03:27:02347 size_t sample = static_cast<size_t>(size_64 / 1024);
348 std::string full_histogram_name = "Sqlite.SizeKB." + histogram_tag_;
349 base::HistogramBase* histogram =
350 base::Histogram::FactoryGet(
351 full_histogram_name, 1, 1000000, 50,
352 base::HistogramBase::kUmaTargetedHistogramFlag);
353 if (histogram)
354 histogram->Add(sample);
shess9bf2c672015-12-18 01:18:08355 UMA_HISTOGRAM_COUNTS("Sqlite.SizeKB", sample);
[email protected]348ac8f52013-05-21 03:27:02356 }
357 }
358
erg102ceb412015-06-20 01:38:13359 return OpenInternal(AsUTF8ForSQL(path), RETRY_ON_POISON);
[email protected]765b44502009-10-02 05:01:42360}
[email protected]e5ffd0e42009-09-11 21:30:56361
[email protected]765b44502009-10-02 05:01:42362bool Connection::OpenInMemory() {
[email protected]35f7e5392012-07-27 19:54:50363 in_memory_ = true;
[email protected]fed734a2013-07-17 04:45:13364 return OpenInternal(":memory:", NO_RETRY);
[email protected]e5ffd0e42009-09-11 21:30:56365}
366
[email protected]8d409412013-07-19 18:25:30367bool Connection::OpenTemporary() {
368 return OpenInternal("", NO_RETRY);
369}
370
[email protected]41a97c812013-02-07 02:35:38371void Connection::CloseInternal(bool forced) {
[email protected]4e179ba62012-03-17 16:06:47372 // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point
373 // will delete the -journal file. For ChromiumOS or other more
374 // embedded systems, this is probably not appropriate, whereas on
375 // desktop it might make some sense.
376
[email protected]4b350052012-02-24 20:40:48377 // sqlite3_close() needs all prepared statements to be finalized.
[email protected]4b350052012-02-24 20:40:48378
[email protected]41a97c812013-02-07 02:35:38379 // Release cached statements.
380 statement_cache_.clear();
381
382 // With cached statements released, in-use statements will remain.
383 // Closing the database while statements are in use is an API
384 // violation, except for forced close (which happens from within a
385 // statement's error handler).
386 DCHECK(forced || open_statements_.empty());
387
388 // Deactivate any outstanding statements so sqlite3_close() works.
Victor Costanc7e7f2e2018-07-18 20:07:55389 for (StatementRef* statement_ref : open_statements_)
390 statement_ref->Close(forced);
[email protected]41a97c812013-02-07 02:35:38391 open_statements_.clear();
[email protected]4b350052012-02-24 20:40:48392
[email protected]e5ffd0e42009-09-11 21:30:56393 if (db_) {
[email protected]35f7e5392012-07-27 19:54:50394 // Call to AssertIOAllowed() cannot go at the beginning of the function
395 // because Close() must be called from destructor to clean
396 // statement_cache_, it won't cause any disk access and it most probably
397 // will happen on thread not allowing disk access.
398 // TODO([email protected]): This should move to the beginning
399 // of the function. http://crbug.com/136655.
400 AssertIOAllowed();
[email protected]73fb8d52013-07-24 05:04:28401
ssid3be5b1ec2016-01-13 14:21:57402 // Reseting acquires a lock to ensure no dump is happening on the database
403 // at the same time. Unregister takes ownership of provider and it is safe
404 // since the db is reset. memory_dump_provider_ could be null if db_ was
405 // poisoned.
406 if (memory_dump_provider_) {
407 memory_dump_provider_->ResetDatabase();
408 base::trace_event::MemoryDumpManager::GetInstance()
409 ->UnregisterAndDeleteDumpProviderSoon(
410 std::move(memory_dump_provider_));
411 }
412
[email protected]73fb8d52013-07-24 05:04:28413 int rc = sqlite3_close(db_);
414 if (rc != SQLITE_OK) {
Ilya Sherman1c811db2017-12-14 10:36:18415 base::UmaHistogramSparse("Sqlite.CloseFailure", rc);
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:52416 DLOG(DCHECK) << "sqlite3_close failed: " << GetErrorMessage();
[email protected]73fb8d52013-07-24 05:04:28417 }
[email protected]e5ffd0e42009-09-11 21:30:56418 }
Victor Costanbd623112018-07-18 04:17:27419 db_ = nullptr;
[email protected]e5ffd0e42009-09-11 21:30:56420}
421
[email protected]41a97c812013-02-07 02:35:38422void Connection::Close() {
423 // If the database was already closed by RazeAndClose(), then no
424 // need to close again. Clear the |poisoned_| bit so that incorrect
425 // API calls are caught.
426 if (poisoned_) {
427 poisoned_ = false;
428 return;
429 }
430
431 CloseInternal(false);
432}
433
[email protected]e5ffd0e42009-09-11 21:30:56434void Connection::Preload() {
[email protected]35f7e5392012-07-27 19:54:50435 AssertIOAllowed();
436
[email protected]e5ffd0e42009-09-11 21:30:56437 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:52438 DCHECK(poisoned_) << "Cannot preload null db";
[email protected]e5ffd0e42009-09-11 21:30:56439 return;
440 }
441
Victor Costan7f6abbbe2018-07-29 02:57:27442 // The constructor and set_page_size() ensure that page_size_ is never zero.
443 const int page_size = page_size_;
444 DCHECK(page_size);
445
[email protected]8ada10f2013-12-21 00:42:34446 // Use local settings if provided, otherwise use documented defaults. The
447 // actual results could be fetching via PRAGMA calls.
[email protected]8ada10f2013-12-21 00:42:34448 sqlite3_int64 preload_size = page_size * (cache_size_ ? cache_size_ : 2000);
449 if (preload_size < 1)
[email protected]e5ffd0e42009-09-11 21:30:56450 return;
451
Victor Costanbd623112018-07-18 04:17:27452 sqlite3_file* file = nullptr;
[email protected]8ada10f2013-12-21 00:42:34453 sqlite3_int64 file_size = 0;
shess5dac334f2015-11-05 20:47:42454 int rc = GetSqlite3FileAndSize(db_, &file, &file_size);
[email protected]8ada10f2013-12-21 00:42:34455 if (rc != SQLITE_OK)
456 return;
457
458 // Don't preload more than the file contains.
459 if (preload_size > file_size)
460 preload_size = file_size;
461
mostynbd82cd9952016-04-11 20:05:34462 std::unique_ptr<char[]> buf(new char[page_size]);
shessde60c5f12015-04-21 17:34:46463 for (sqlite3_int64 pos = 0; pos < preload_size; pos += page_size) {
[email protected]8ada10f2013-12-21 00:42:34464 rc = file->pMethods->xRead(file, buf.get(), page_size, pos);
shessd90aeea82015-11-13 02:24:31465
466 // TODO(shess): Consider calling OnSqliteError().
[email protected]8ada10f2013-12-21 00:42:34467 if (rc != SQLITE_OK)
468 return;
469 }
[email protected]e5ffd0e42009-09-11 21:30:56470}
471
shess7dbd4dee2015-10-06 17:39:16472// SQLite keeps unused pages associated with a connection in a cache. It asks
473// the cache for pages by an id, and if the page is present and the database is
474// unchanged, it considers the content of the page valid and doesn't read it
475// from disk. When memory-mapped I/O is enabled, on read SQLite uses page
476// structures created from the memory map data before consulting the cache. On
477// write SQLite creates a new in-memory page structure, copies the data from the
478// memory map, and later writes it, releasing the updated page back to the
479// cache.
480//
481// This means that in memory-mapped mode, the contents of the cached pages are
482// not re-used for reads, but they are re-used for writes if the re-written page
483// is still in the cache. The implementation of sqlite3_db_release_memory() as
484// of SQLite 3.8.7.4 frees all pages from pcaches associated with the
485// connection, so it should free these pages.
486//
487// Unfortunately, the zero page is also freed. That page is never accessed
488// using memory-mapped I/O, and the cached copy can be re-used after verifying
489// the file change counter on disk. Also, fresh pages from cache receive some
490// pager-level initialization before they can be used. Since the information
491// involved will immediately be accessed in various ways, it is unclear if the
492// additional overhead is material, or just moving processor cache effects
493// around.
494//
495// TODO(shess): It would be better to release the pages immediately when they
496// are no longer needed. This would basically happen after SQLite commits a
497// transaction. I had implemented a pcache wrapper to do this, but it involved
498// layering violations, and it had to be setup before any other sqlite call,
499// which was brittle. Also, for large files it would actually make sense to
500// maintain the existing pcache behavior for blocks past the memory-mapped
501// segment. I think drh would accept a reasonable implementation of the overall
502// concept for upstreaming to SQLite core.
503//
504// TODO(shess): Another possibility would be to set the cache size small, which
505// would keep the zero page around, plus some pre-initialized pages, and SQLite
506// can manage things. The downside is that updates larger than the cache would
507// spill to the journal. That could be compensated by setting cache_spill to
508// false. The downside then is that it allows open-ended use of memory for
509// large transactions.
510//
511// TODO(shess): The TrimMemory() trick of bouncing the cache size would also
512// work. There could be two prepared statements, one for cache_size=1 one for
513// cache_size=goal.
514void Connection::ReleaseCacheMemoryIfNeeded(bool implicit_change_performed) {
shess644fc8a2016-02-26 18:15:58515 // The database could have been closed during a transaction as part of error
516 // recovery.
517 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:52518 DCHECK(poisoned_) << "Illegal use of connection without a db";
shess644fc8a2016-02-26 18:15:58519 return;
520 }
shess7dbd4dee2015-10-06 17:39:16521
522 // If memory-mapping is not enabled, the page cache helps performance.
523 if (!mmap_enabled_)
524 return;
525
526 // On caller request, force the change comparison to fail. Done before the
527 // transaction-nesting test so that the signal can carry to transaction
528 // commit.
529 if (implicit_change_performed)
530 --total_changes_at_last_release_;
531
532 // Cached pages may be re-used within the same transaction.
533 if (transaction_nesting())
534 return;
535
536 // If no changes have been made, skip flushing. This allows the first page of
537 // the database to remain in cache across multiple reads.
538 const int total_changes = sqlite3_total_changes(db_);
539 if (total_changes == total_changes_at_last_release_)
540 return;
541
542 total_changes_at_last_release_ = total_changes;
543 sqlite3_db_release_memory(db_);
544}
545
shessc8cd2a162015-10-22 20:30:46546base::FilePath Connection::DbPath() const {
547 if (!is_open())
548 return base::FilePath();
549
550 const char* path = sqlite3_db_filename(db_, "main");
551 const base::StringPiece db_path(path);
552#if defined(OS_WIN)
553 return base::FilePath(base::UTF8ToWide(db_path));
Fabrice de Gans-Riberi65421f62018-05-22 23:16:18554#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
shessc8cd2a162015-10-22 20:30:46555 return base::FilePath(db_path);
556#else
557 NOTREACHED();
558 return base::FilePath();
559#endif
560}
561
562// Data is persisted in a file shared between databases in the same directory.
563// The "sqlite-diag" file contains a dictionary with the version number, and an
564// array of histogram tags for databases which have been dumped.
565bool Connection::RegisterIntentToUpload() const {
566 static const char* kVersionKey = "version";
567 static const char* kDiagnosticDumpsKey = "DiagnosticDumps";
568 static int kVersion = 1;
569
570 AssertIOAllowed();
571
572 if (histogram_tag_.empty())
573 return false;
574
575 if (!is_open())
576 return false;
577
578 if (in_memory_)
579 return false;
580
581 const base::FilePath db_path = DbPath();
582 if (db_path.empty())
583 return false;
584
585 // Put the collection of diagnostic data next to the databases. In most
586 // cases, this is the profile directory, but safe-browsing stores a Cookies
587 // file in the directory above the profile directory.
Victor Costance678e72018-07-24 10:25:00588 base::FilePath breadcrumb_path = db_path.DirName().AppendASCII("sqlite-diag");
shessc8cd2a162015-10-22 20:30:46589
590 // Lock against multiple updates to the diagnostics file. This code should
591 // seldom be called in the first place, and when called it should seldom be
592 // called for multiple databases, and when called for multiple databases there
593 // is _probably_ something systemic wrong with the user's system. So the lock
594 // should never be contended, but when it is the database experience is
595 // already bad.
Victor Costan3653df62018-02-08 21:38:16596 static base::NoDestructor<base::Lock> lock;
597 base::AutoLock auto_lock(*lock);
shessc8cd2a162015-10-22 20:30:46598
mostynbd82cd9952016-04-11 20:05:34599 std::unique_ptr<base::Value> root;
shessc8cd2a162015-10-22 20:30:46600 if (!base::PathExists(breadcrumb_path)) {
mostynbd82cd9952016-04-11 20:05:34601 std::unique_ptr<base::DictionaryValue> root_dict(
602 new base::DictionaryValue());
shessc8cd2a162015-10-22 20:30:46603 root_dict->SetInteger(kVersionKey, kVersion);
604
mostynbd82cd9952016-04-11 20:05:34605 std::unique_ptr<base::ListValue> dumps(new base::ListValue);
shessc8cd2a162015-10-22 20:30:46606 dumps->AppendString(histogram_tag_);
dchenge48600452015-12-28 02:24:50607 root_dict->Set(kDiagnosticDumpsKey, std::move(dumps));
shessc8cd2a162015-10-22 20:30:46608
dchenge48600452015-12-28 02:24:50609 root = std::move(root_dict);
shessc8cd2a162015-10-22 20:30:46610 } else {
611 // Failure to read a valid dictionary implies that something is going wrong
612 // on the system.
613 JSONFileValueDeserializer deserializer(breadcrumb_path);
mostynbd82cd9952016-04-11 20:05:34614 std::unique_ptr<base::Value> read_root(
shessc8cd2a162015-10-22 20:30:46615 deserializer.Deserialize(nullptr, nullptr));
616 if (!read_root.get())
617 return false;
mostynbd82cd9952016-04-11 20:05:34618 std::unique_ptr<base::DictionaryValue> root_dict =
dchenge48600452015-12-28 02:24:50619 base::DictionaryValue::From(std::move(read_root));
shessc8cd2a162015-10-22 20:30:46620 if (!root_dict)
621 return false;
622
623 // Don't upload if the version is missing or newer.
624 int version = 0;
625 if (!root_dict->GetInteger(kVersionKey, &version) || version > kVersion)
626 return false;
627
628 base::ListValue* dumps = nullptr;
629 if (!root_dict->GetList(kDiagnosticDumpsKey, &dumps))
630 return false;
631
632 const size_t size = dumps->GetSize();
633 for (size_t i = 0; i < size; ++i) {
634 std::string s;
635
636 // Don't upload if the value isn't a string, or indicates a prior upload.
637 if (!dumps->GetString(i, &s) || s == histogram_tag_)
638 return false;
639 }
640
641 // Record intention to proceed with upload.
642 dumps->AppendString(histogram_tag_);
dchenge48600452015-12-28 02:24:50643 root = std::move(root_dict);
shessc8cd2a162015-10-22 20:30:46644 }
645
646 const base::FilePath breadcrumb_new =
647 breadcrumb_path.AddExtension(FILE_PATH_LITERAL("new"));
648 base::DeleteFile(breadcrumb_new, false);
649
650 // No upload if the breadcrumb file cannot be updated.
651 // TODO(shess): Consider ImportantFileWriter::WriteFileAtomically() to land
652 // the data on disk. For now, losing the data is not a big problem, so the
653 // sync overhead would probably not be worth it.
654 JSONFileValueSerializer serializer(breadcrumb_new);
655 if (!serializer.Serialize(*root))
656 return false;
657 if (!base::PathExists(breadcrumb_new))
658 return false;
659 if (!base::ReplaceFile(breadcrumb_new, breadcrumb_path, nullptr)) {
660 base::DeleteFile(breadcrumb_new, false);
661 return false;
662 }
663
664 return true;
665}
666
667std::string Connection::CollectErrorInfo(int error, Statement* stmt) const {
668 // Buffer for accumulating debugging info about the error. Place
669 // more-relevant information earlier, in case things overflow the
670 // fixed-size reporting buffer.
671 std::string debug_info;
672
673 // The error message from the failed operation.
674 base::StringAppendF(&debug_info, "db error: %d/%s\n",
675 GetErrorCode(), GetErrorMessage());
676
677 // TODO(shess): |error| and |GetErrorCode()| should always be the same, but
678 // reading code does not entirely convince me. Remove if they turn out to be
679 // the same.
680 if (error != GetErrorCode())
681 base::StringAppendF(&debug_info, "reported error: %d\n", error);
682
683 // System error information. Interpretation of Windows errors is different
684 // from posix.
685#if defined(OS_WIN)
686 base::StringAppendF(&debug_info, "LastError: %d\n", GetLastErrno());
Fabrice de Gans-Riberi65421f62018-05-22 23:16:18687#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
shessc8cd2a162015-10-22 20:30:46688 base::StringAppendF(&debug_info, "errno: %d\n", GetLastErrno());
689#else
690 NOTREACHED(); // Add appropriate log info.
691#endif
692
693 if (stmt) {
694 base::StringAppendF(&debug_info, "statement: %s\n",
695 stmt->GetSQLStatement());
696 } else {
697 base::StringAppendF(&debug_info, "statement: NULL\n");
698 }
699
700 // SQLITE_ERROR often indicates some sort of mismatch between the statement
701 // and the schema, possibly due to a failed schema migration.
702 if (error == SQLITE_ERROR) {
703 const char* kVersionSql = "SELECT value FROM meta WHERE key = 'version'";
704 sqlite3_stmt* s;
705 int rc = sqlite3_prepare_v2(db_, kVersionSql, -1, &s, nullptr);
706 if (rc == SQLITE_OK) {
707 rc = sqlite3_step(s);
708 if (rc == SQLITE_ROW) {
709 base::StringAppendF(&debug_info, "version: %d\n",
710 sqlite3_column_int(s, 0));
711 } else if (rc == SQLITE_DONE) {
712 debug_info += "version: none\n";
713 } else {
714 base::StringAppendF(&debug_info, "version: error %d\n", rc);
715 }
716 sqlite3_finalize(s);
717 } else {
718 base::StringAppendF(&debug_info, "version: prepare error %d\n", rc);
719 }
720
721 debug_info += "schema:\n";
722
723 // sqlite_master has columns:
724 // type - "index" or "table".
725 // name - name of created element.
726 // tbl_name - name of element, or target table in case of index.
727 // rootpage - root page of the element in database file.
728 // sql - SQL to create the element.
729 // In general, the |sql| column is sufficient to derive the other columns.
730 // |rootpage| is not interesting for debugging, without the contents of the
731 // database. The COALESCE is because certain automatic elements will have a
732 // |name| but no |sql|,
733 const char* kSchemaSql = "SELECT COALESCE(sql, name) FROM sqlite_master";
734 rc = sqlite3_prepare_v2(db_, kSchemaSql, -1, &s, nullptr);
735 if (rc == SQLITE_OK) {
736 while ((rc = sqlite3_step(s)) == SQLITE_ROW) {
737 base::StringAppendF(&debug_info, "%s\n", sqlite3_column_text(s, 0));
738 }
739 if (rc != SQLITE_DONE)
740 base::StringAppendF(&debug_info, "error %d\n", rc);
741 sqlite3_finalize(s);
742 } else {
743 base::StringAppendF(&debug_info, "prepare error %d\n", rc);
744 }
745 }
746
747 return debug_info;
748}
749
750// TODO(shess): Since this is only called in an error situation, it might be
751// prudent to rewrite in terms of SQLite API calls, and mark the function const.
752std::string Connection::CollectCorruptionInfo() {
753 AssertIOAllowed();
754
755 // If the file cannot be accessed it is unlikely that an integrity check will
756 // turn up actionable information.
757 const base::FilePath db_path = DbPath();
avi0b519202015-12-21 07:25:19758 int64_t db_size = -1;
shessc8cd2a162015-10-22 20:30:46759 if (!base::GetFileSize(db_path, &db_size) || db_size < 0)
760 return std::string();
761
762 // Buffer for accumulating debugging info about the error. Place
763 // more-relevant information earlier, in case things overflow the
764 // fixed-size reporting buffer.
765 std::string debug_info;
766 base::StringAppendF(&debug_info, "SQLITE_CORRUPT, db size %" PRId64 "\n",
767 db_size);
768
769 // Only check files up to 8M to keep things from blocking too long.
avi0b519202015-12-21 07:25:19770 const int64_t kMaxIntegrityCheckSize = 8192 * 1024;
shessc8cd2a162015-10-22 20:30:46771 if (db_size > kMaxIntegrityCheckSize) {
772 debug_info += "integrity_check skipped due to size\n";
773 } else {
774 std::vector<std::string> messages;
775
776 // TODO(shess): FullIntegrityCheck() splits into a vector while this joins
777 // into a string. Probably should be refactored.
778 const base::TimeTicks before = base::TimeTicks::Now();
779 FullIntegrityCheck(&messages);
780 base::StringAppendF(
781 &debug_info,
782 "integrity_check %" PRId64 " ms, %" PRIuS " records:\n",
783 (base::TimeTicks::Now() - before).InMilliseconds(),
784 messages.size());
785
786 // SQLite returns up to 100 messages by default, trim deeper to
787 // keep close to the 2000-character size limit for dumping.
788 const size_t kMaxMessages = 20;
789 for (size_t i = 0; i < kMaxMessages && i < messages.size(); ++i) {
790 base::StringAppendF(&debug_info, "%s\n", messages[i].c_str());
791 }
792 }
793
794 return debug_info;
795}
796
shessa62504d2016-11-07 19:26:12797bool Connection::GetMmapAltStatus(int64_t* status) {
798 // The [meta] version uses a missing table as a signal for a fresh database.
799 // That will not work for the view, which would not exist in either a new or
800 // an existing database. A new database _should_ be only one page long, so
801 // just don't bother optimizing this case (start at offset 0).
802 // TODO(shess): Could the [meta] case also get simpler, then?
803 if (!DoesViewExist("MmapStatus")) {
804 *status = 0;
805 return true;
806 }
807
808 const char* kMmapStatusSql = "SELECT * FROM MmapStatus";
809 Statement s(GetUniqueStatement(kMmapStatusSql));
810 if (s.Step())
811 *status = s.ColumnInt64(0);
812 return s.Succeeded();
813}
814
815bool Connection::SetMmapAltStatus(int64_t status) {
816 if (!BeginTransaction())
817 return false;
818
819 // View may not exist on first run.
820 if (!Execute("DROP VIEW IF EXISTS MmapStatus")) {
821 RollbackTransaction();
822 return false;
823 }
824
825 // Views live in the schema, so they cannot be parameterized. For an integer
826 // value, this construct should be safe from SQL injection, if the value
827 // becomes more complicated use "SELECT quote(?)" to generate a safe quoted
828 // value.
829 const std::string createViewSql =
830 base::StringPrintf("CREATE VIEW MmapStatus (value) AS SELECT %" PRId64,
831 status);
832 if (!Execute(createViewSql.c_str())) {
833 RollbackTransaction();
834 return false;
835 }
836
837 return CommitTransaction();
838}
839
shessd90aeea82015-11-13 02:24:31840size_t Connection::GetAppropriateMmapSize() {
841 AssertIOAllowed();
842
shess9bf2c672015-12-18 01:18:08843 // How much to map if no errors are found. 50MB encompasses the 99th
844 // percentile of Chrome databases in the wild, so this should be good.
845 const size_t kMmapEverything = 256 * 1024 * 1024;
846
shessa62504d2016-11-07 19:26:12847 // Progress information is tracked in the [meta] table for databases which use
848 // sql::MetaTable, otherwise it is tracked in a special view.
849 // TODO(shess): Move all cases to the view implementation.
shess9bf2c672015-12-18 01:18:08850 int64_t mmap_ofs = 0;
shessa62504d2016-11-07 19:26:12851 if (mmap_alt_status_) {
852 if (!GetMmapAltStatus(&mmap_ofs)) {
853 RecordOneEvent(EVENT_MMAP_STATUS_FAILURE_READ);
854 return 0;
855 }
856 } else {
857 // If [meta] doesn't exist, yet, it's a new database, assume the best.
858 // sql::MetaTable::Init() will preload kMmapSuccess.
859 if (!MetaTable::DoesTableExist(this)) {
860 RecordOneEvent(EVENT_MMAP_META_MISSING);
861 return kMmapEverything;
862 }
863
864 if (!MetaTable::GetMmapStatus(this, &mmap_ofs)) {
865 RecordOneEvent(EVENT_MMAP_META_FAILURE_READ);
866 return 0;
867 }
shessd90aeea82015-11-13 02:24:31868 }
869
870 // Database read failed in the past, don't memory map.
shess9bf2c672015-12-18 01:18:08871 if (mmap_ofs == MetaTable::kMmapFailure) {
shessd90aeea82015-11-13 02:24:31872 RecordOneEvent(EVENT_MMAP_FAILED);
873 return 0;
shess9bf2c672015-12-18 01:18:08874 } else if (mmap_ofs != MetaTable::kMmapSuccess) {
shessd90aeea82015-11-13 02:24:31875 // Continue reading from previous offset.
876 DCHECK_GE(mmap_ofs, 0);
877
878 // TODO(shess): Could this reading code be shared with Preload()? It would
879 // require locking twice (this code wouldn't be able to access |db_size| so
880 // the helper would have to return amount read).
881
882 // Read more of the database looking for errors. The VFS interface is used
883 // to assure that the reads are valid for SQLite. |g_reads_allowed| is used
884 // to limit checking to 20MB per run of Chromium.
Victor Costanbd623112018-07-18 04:17:27885 sqlite3_file* file = nullptr;
shessd90aeea82015-11-13 02:24:31886 sqlite3_int64 db_size = 0;
887 if (SQLITE_OK != GetSqlite3FileAndSize(db_, &file, &db_size)) {
888 RecordOneEvent(EVENT_MMAP_VFS_FAILURE);
889 return 0;
890 }
891
892 // Read the data left, or |g_reads_allowed|, whichever is smaller.
893 // |g_reads_allowed| limits the total amount of I/O to spend verifying data
894 // in a single Chromium run.
895 sqlite3_int64 amount = db_size - mmap_ofs;
896 if (amount < 0)
897 amount = 0;
898 if (amount > 0) {
Victor Costan3653df62018-02-08 21:38:16899 static base::NoDestructor<base::Lock> lock;
900 base::AutoLock auto_lock(*lock);
shessd90aeea82015-11-13 02:24:31901 static sqlite3_int64 g_reads_allowed = 20 * 1024 * 1024;
902 if (g_reads_allowed < amount)
903 amount = g_reads_allowed;
904 g_reads_allowed -= amount;
905 }
906
907 // |amount| can be <= 0 if |g_reads_allowed| ran out of quota, or if the
908 // database was truncated after a previous pass.
909 if (amount <= 0 && mmap_ofs < db_size) {
910 DCHECK_EQ(0, amount);
911 RecordOneEvent(EVENT_MMAP_SUCCESS_NO_PROGRESS);
912 } else {
913 static const int kPageSize = 4096;
914 char buf[kPageSize];
915 while (amount > 0) {
916 int rc = file->pMethods->xRead(file, buf, sizeof(buf), mmap_ofs);
917 if (rc == SQLITE_OK) {
918 mmap_ofs += sizeof(buf);
919 amount -= sizeof(buf);
920 } else if (rc == SQLITE_IOERR_SHORT_READ) {
921 // Reached EOF for a database with page size < |kPageSize|.
922 mmap_ofs = db_size;
923 break;
924 } else {
925 // TODO(shess): Consider calling OnSqliteError().
shess9bf2c672015-12-18 01:18:08926 mmap_ofs = MetaTable::kMmapFailure;
shessd90aeea82015-11-13 02:24:31927 break;
928 }
929 }
930
931 // Log these events after update to distinguish meta update failure.
932 Events event;
933 if (mmap_ofs >= db_size) {
shess9bf2c672015-12-18 01:18:08934 mmap_ofs = MetaTable::kMmapSuccess;
shessd90aeea82015-11-13 02:24:31935 event = EVENT_MMAP_SUCCESS_NEW;
936 } else if (mmap_ofs > 0) {
937 event = EVENT_MMAP_SUCCESS_PARTIAL;
938 } else {
shess9bf2c672015-12-18 01:18:08939 DCHECK_EQ(MetaTable::kMmapFailure, mmap_ofs);
shessd90aeea82015-11-13 02:24:31940 event = EVENT_MMAP_FAILED_NEW;
941 }
942
shessa62504d2016-11-07 19:26:12943 if (mmap_alt_status_) {
944 if (!SetMmapAltStatus(mmap_ofs)) {
945 RecordOneEvent(EVENT_MMAP_STATUS_FAILURE_UPDATE);
946 return 0;
947 }
948 } else {
949 if (!MetaTable::SetMmapStatus(this, mmap_ofs)) {
950 RecordOneEvent(EVENT_MMAP_META_FAILURE_UPDATE);
951 return 0;
952 }
shessd90aeea82015-11-13 02:24:31953 }
954
955 RecordOneEvent(event);
956 }
957 }
958
shess9bf2c672015-12-18 01:18:08959 if (mmap_ofs == MetaTable::kMmapFailure)
shessd90aeea82015-11-13 02:24:31960 return 0;
shess9bf2c672015-12-18 01:18:08961 if (mmap_ofs == MetaTable::kMmapSuccess)
962 return kMmapEverything;
shessd90aeea82015-11-13 02:24:31963 return mmap_ofs;
964}
965
[email protected]be7995f12013-07-18 18:49:14966void Connection::TrimMemory(bool aggressively) {
967 if (!db_)
968 return;
969
970 // TODO(shess): investigate using sqlite3_db_release_memory() when possible.
971 int original_cache_size;
972 {
973 Statement sql_get_original(GetUniqueStatement("PRAGMA cache_size"));
974 if (!sql_get_original.Step()) {
975 DLOG(WARNING) << "Could not get cache size " << GetErrorMessage();
976 return;
977 }
978 original_cache_size = sql_get_original.ColumnInt(0);
979 }
980 int shrink_cache_size = aggressively ? 1 : (original_cache_size / 2);
981
982 // Force sqlite to try to reduce page cache usage.
983 const std::string sql_shrink =
984 base::StringPrintf("PRAGMA cache_size=%d", shrink_cache_size);
985 if (!Execute(sql_shrink.c_str()))
986 DLOG(WARNING) << "Could not shrink cache size: " << GetErrorMessage();
987
988 // Restore cache size.
989 const std::string sql_restore =
990 base::StringPrintf("PRAGMA cache_size=%d", original_cache_size);
991 if (!Execute(sql_restore.c_str()))
992 DLOG(WARNING) << "Could not restore cache size: " << GetErrorMessage();
993}
994
[email protected]8e0c01282012-04-06 19:36:49995// Create an in-memory database with the existing database's page
996// size, then backup that database over the existing database.
997bool Connection::Raze() {
[email protected]35f7e5392012-07-27 19:54:50998 AssertIOAllowed();
999
[email protected]8e0c01282012-04-06 19:36:491000 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521001 DCHECK(poisoned_) << "Cannot raze null db";
[email protected]8e0c01282012-04-06 19:36:491002 return false;
1003 }
1004
1005 if (transaction_nesting_ > 0) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521006 DLOG(DCHECK) << "Cannot raze within a transaction";
[email protected]8e0c01282012-04-06 19:36:491007 return false;
1008 }
1009
1010 sql::Connection null_db;
1011 if (!null_db.OpenInMemory()) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521012 DLOG(DCHECK) << "Unable to open in-memory database.";
[email protected]8e0c01282012-04-06 19:36:491013 return false;
1014 }
1015
Victor Costan7f6abbbe2018-07-29 02:57:271016 const std::string sql = base::StringPrintf("PRAGMA page_size=%d", page_size_);
1017 if (!null_db.Execute(sql.c_str()))
1018 return false;
[email protected]69c58452012-08-06 19:22:421019
[email protected]6d42f152012-11-10 00:38:241020#if defined(OS_ANDROID)
1021 // Android compiles with SQLITE_DEFAULT_AUTOVACUUM. Unfortunately,
1022 // in-memory databases do not respect this define.
1023 // TODO(shess): Figure out a way to set this without using platform
1024 // specific code. AFAICT from sqlite3.c, the only way to do it
1025 // would be to create an actual filesystem database, which is
1026 // unfortunate.
1027 if (!null_db.Execute("PRAGMA auto_vacuum = 1"))
1028 return false;
1029#endif
[email protected]8e0c01282012-04-06 19:36:491030
1031 // The page size doesn't take effect until a database has pages, and
1032 // at this point the null database has none. Changing the schema
1033 // version will create the first page. This will not affect the
1034 // schema version in the resulting database, as SQLite's backup
1035 // implementation propagates the schema version from the original
1036 // connection to the new version of the database, incremented by one
1037 // so that other readers see the schema change and act accordingly.
1038 if (!null_db.Execute("PRAGMA schema_version = 1"))
1039 return false;
1040
[email protected]6d42f152012-11-10 00:38:241041 // SQLite tracks the expected number of database pages in the first
1042 // page, and if it does not match the total retrieved from a
1043 // filesystem call, treats the database as corrupt. This situation
1044 // breaks almost all SQLite calls. "PRAGMA writable_schema" can be
1045 // used to hint to SQLite to soldier on in that case, specifically
1046 // for purposes of recovery. [See SQLITE_CORRUPT_BKPT case in
1047 // sqlite3.c lockBtree().]
1048 // TODO(shess): With this, "PRAGMA auto_vacuum" and "PRAGMA
1049 // page_size" can be used to query such a database.
1050 ScopedWritableSchema writable_schema(db_);
1051
shess92a6fb22017-04-23 04:33:301052#if defined(OS_WIN)
1053 // On Windows, truncate silently fails when applied to memory-mapped files.
1054 // Disable memory-mapping so that the truncate succeeds. Note that other
1055 // connections may have memory-mapped the file, so this may not entirely
1056 // prevent the problem.
1057 // [Source: <https://sqlite.org/mmap.html> plus experiments.]
1058 ignore_result(Execute("PRAGMA mmap_size = 0"));
1059#endif
1060
[email protected]7bae5742013-07-10 20:46:161061 const char* kMain = "main";
1062 int rc = BackupDatabase(null_db.db_, db_, kMain);
Ilya Sherman1c811db2017-12-14 10:36:181063 base::UmaHistogramSparse("Sqlite.RazeDatabase", rc);
[email protected]8e0c01282012-04-06 19:36:491064
1065 // The destination database was locked.
1066 if (rc == SQLITE_BUSY) {
1067 return false;
1068 }
1069
[email protected]7bae5742013-07-10 20:46:161070 // SQLITE_NOTADB can happen if page 1 of db_ exists, but is not
1071 // formatted correctly. SQLITE_IOERR_SHORT_READ can happen if db_
1072 // isn't even big enough for one page. Either way, reach in and
1073 // truncate it before trying again.
1074 // TODO(shess): Maybe it would be worthwhile to just truncate from
1075 // the get-go?
1076 if (rc == SQLITE_NOTADB || rc == SQLITE_IOERR_SHORT_READ) {
Victor Costanbd623112018-07-18 04:17:271077 sqlite3_file* file = nullptr;
[email protected]8ada10f2013-12-21 00:42:341078 rc = GetSqlite3File(db_, &file);
[email protected]7bae5742013-07-10 20:46:161079 if (rc != SQLITE_OK) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521080 DLOG(DCHECK) << "Failure getting file handle.";
[email protected]7bae5742013-07-10 20:46:161081 return false;
[email protected]7bae5742013-07-10 20:46:161082 }
1083
1084 rc = file->pMethods->xTruncate(file, 0);
1085 if (rc != SQLITE_OK) {
Ilya Sherman1c811db2017-12-14 10:36:181086 base::UmaHistogramSparse("Sqlite.RazeDatabaseTruncate", rc);
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521087 DLOG(DCHECK) << "Failed to truncate file.";
[email protected]7bae5742013-07-10 20:46:161088 return false;
1089 }
1090
1091 rc = BackupDatabase(null_db.db_, db_, kMain);
Ilya Sherman1c811db2017-12-14 10:36:181092 base::UmaHistogramSparse("Sqlite.RazeDatabase2", rc);
[email protected]7bae5742013-07-10 20:46:161093
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521094 DCHECK_EQ(rc, SQLITE_DONE) << "Failed retrying Raze().";
[email protected]7bae5742013-07-10 20:46:161095 }
1096
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521097 // TODO(shess): Figure out which other cases can happen.
1098 DCHECK_EQ(rc, SQLITE_DONE) << "Unable to copy entire null database.";
1099
[email protected]8e0c01282012-04-06 19:36:491100 // The entire database should have been backed up.
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521101 return rc == SQLITE_DONE;
[email protected]8e0c01282012-04-06 19:36:491102}
1103
[email protected]41a97c812013-02-07 02:35:381104bool Connection::RazeAndClose() {
1105 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521106 DCHECK(poisoned_) << "Cannot raze null db";
[email protected]41a97c812013-02-07 02:35:381107 return false;
1108 }
1109
1110 // Raze() cannot run in a transaction.
[email protected]8d409412013-07-19 18:25:301111 RollbackAllTransactions();
[email protected]41a97c812013-02-07 02:35:381112
1113 bool result = Raze();
1114
1115 CloseInternal(true);
1116
1117 // Mark the database so that future API calls fail appropriately,
1118 // but don't DCHECK (because after calling this function they are
1119 // expected to fail).
1120 poisoned_ = true;
1121
1122 return result;
1123}
1124
[email protected]8d409412013-07-19 18:25:301125void Connection::Poison() {
1126 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521127 DCHECK(poisoned_) << "Cannot poison null db";
[email protected]8d409412013-07-19 18:25:301128 return;
1129 }
1130
1131 RollbackAllTransactions();
1132 CloseInternal(true);
1133
1134 // Mark the database so that future API calls fail appropriately,
1135 // but don't DCHECK (because after calling this function they are
1136 // expected to fail).
1137 poisoned_ = true;
1138}
1139
[email protected]8d2e39e2013-06-24 05:55:081140// TODO(shess): To the extent possible, figure out the optimal
1141// ordering for these deletes which will prevent other connections
1142// from seeing odd behavior. For instance, it may be necessary to
1143// manually lock the main database file in a SQLite-compatible fashion
1144// (to prevent other processes from opening it), then delete the
1145// journal files, then delete the main database file. Another option
1146// might be to lock the main database file and poison the header with
1147// junk to prevent other processes from opening it successfully (like
1148// Gears "SQLite poison 3" trick).
1149//
1150// static
1151bool Connection::Delete(const base::FilePath& path) {
Francois Doray66bdfd82017-10-20 13:50:371152 base::AssertBlockingAllowed();
[email protected]8d2e39e2013-06-24 05:55:081153
Victor Costance678e72018-07-24 10:25:001154 base::FilePath journal_path = Connection::JournalPath(path);
1155 base::FilePath wal_path = Connection::WriteAheadLogPath(path);
[email protected]8d2e39e2013-06-24 05:55:081156
erg102ceb412015-06-20 01:38:131157 std::string journal_str = AsUTF8ForSQL(journal_path);
1158 std::string wal_str = AsUTF8ForSQL(wal_path);
1159 std::string path_str = AsUTF8ForSQL(path);
[email protected]8d2e39e2013-06-24 05:55:081160
Victor Costan3653df62018-02-08 21:38:161161 EnsureSqliteInitialized();
shess702467622015-09-16 19:04:551162
Victor Costanbd623112018-07-18 04:17:271163 sqlite3_vfs* vfs = sqlite3_vfs_find(nullptr);
erg102ceb412015-06-20 01:38:131164 CHECK(vfs);
1165 CHECK(vfs->xDelete);
1166 CHECK(vfs->xAccess);
1167
1168 // We only work with unix, win32 and mojo filesystems. If you're trying to
1169 // use this code with any other VFS, you're not in a good place.
1170 CHECK(strncmp(vfs->zName, "unix", 4) == 0 ||
1171 strncmp(vfs->zName, "win32", 5) == 0 ||
1172 strcmp(vfs->zName, "mojo") == 0);
1173
1174 vfs->xDelete(vfs, journal_str.c_str(), 0);
1175 vfs->xDelete(vfs, wal_str.c_str(), 0);
1176 vfs->xDelete(vfs, path_str.c_str(), 0);
1177
1178 int journal_exists = 0;
Victor Costance678e72018-07-24 10:25:001179 vfs->xAccess(vfs, journal_str.c_str(), SQLITE_ACCESS_EXISTS, &journal_exists);
erg102ceb412015-06-20 01:38:131180
1181 int wal_exists = 0;
Victor Costance678e72018-07-24 10:25:001182 vfs->xAccess(vfs, wal_str.c_str(), SQLITE_ACCESS_EXISTS, &wal_exists);
erg102ceb412015-06-20 01:38:131183
1184 int path_exists = 0;
Victor Costance678e72018-07-24 10:25:001185 vfs->xAccess(vfs, path_str.c_str(), SQLITE_ACCESS_EXISTS, &path_exists);
erg102ceb412015-06-20 01:38:131186
1187 return !journal_exists && !wal_exists && !path_exists;
[email protected]8d2e39e2013-06-24 05:55:081188}
1189
[email protected]e5ffd0e42009-09-11 21:30:561190bool Connection::BeginTransaction() {
1191 if (needs_rollback_) {
[email protected]88563f62011-03-13 22:13:331192 DCHECK_GT(transaction_nesting_, 0);
[email protected]e5ffd0e42009-09-11 21:30:561193
1194 // When we're going to rollback, fail on this begin and don't actually
1195 // mark us as entering the nested transaction.
1196 return false;
1197 }
1198
1199 bool success = true;
1200 if (!transaction_nesting_) {
1201 needs_rollback_ = false;
1202
1203 Statement begin(GetCachedStatement(SQL_FROM_HERE, "BEGIN TRANSACTION"));
shess58b8df82015-06-03 00:19:321204 RecordOneEvent(EVENT_BEGIN);
[email protected]eff1fa522011-12-12 23:50:591205 if (!begin.Run())
[email protected]e5ffd0e42009-09-11 21:30:561206 return false;
1207 }
1208 transaction_nesting_++;
1209 return success;
1210}
1211
1212void Connection::RollbackTransaction() {
1213 if (!transaction_nesting_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521214 DCHECK(poisoned_) << "Rolling back a nonexistent transaction";
[email protected]e5ffd0e42009-09-11 21:30:561215 return;
1216 }
1217
1218 transaction_nesting_--;
1219
1220 if (transaction_nesting_ > 0) {
1221 // Mark the outermost transaction as needing rollback.
1222 needs_rollback_ = true;
1223 return;
1224 }
1225
1226 DoRollback();
1227}
1228
1229bool Connection::CommitTransaction() {
1230 if (!transaction_nesting_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521231 DCHECK(poisoned_) << "Committing a nonexistent transaction";
[email protected]e5ffd0e42009-09-11 21:30:561232 return false;
1233 }
1234 transaction_nesting_--;
1235
1236 if (transaction_nesting_ > 0) {
1237 // Mark any nested transactions as failing after we've already got one.
1238 return !needs_rollback_;
1239 }
1240
1241 if (needs_rollback_) {
1242 DoRollback();
1243 return false;
1244 }
1245
1246 Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT"));
shess58b8df82015-06-03 00:19:321247
1248 // Collect the commit time manually, sql::Statement would register it as query
1249 // time only.
Victor Costan87cf8c72018-07-19 19:36:041250 const base::TimeTicks before = NowTicks();
shess58b8df82015-06-03 00:19:321251 bool ret = commit.RunWithoutTimers();
Victor Costan87cf8c72018-07-19 19:36:041252 const base::TimeDelta delta = NowTicks() - before;
shess58b8df82015-06-03 00:19:321253
1254 RecordCommitTime(delta);
1255 RecordOneEvent(EVENT_COMMIT);
1256
shess7dbd4dee2015-10-06 17:39:161257 // Release dirty cache pages after the transaction closes.
1258 ReleaseCacheMemoryIfNeeded(false);
1259
shess58b8df82015-06-03 00:19:321260 return ret;
[email protected]e5ffd0e42009-09-11 21:30:561261}
1262
[email protected]8d409412013-07-19 18:25:301263void Connection::RollbackAllTransactions() {
1264 if (transaction_nesting_ > 0) {
1265 transaction_nesting_ = 0;
1266 DoRollback();
1267 }
1268}
1269
1270bool Connection::AttachDatabase(const base::FilePath& other_db_path,
Victor Costan7f6abbbe2018-07-29 02:57:271271 const char* attachment_point,
1272 InternalApiToken) {
[email protected]8d409412013-07-19 18:25:301273 DCHECK(ValidAttachmentPoint(attachment_point));
1274
1275 Statement s(GetUniqueStatement("ATTACH DATABASE ? AS ?"));
1276#if OS_WIN
1277 s.BindString16(0, other_db_path.value());
Fabrice de Gans-Riberi65421f62018-05-22 23:16:181278#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
Fabrice de Gans-Riberibd1301f2018-05-18 21:00:091279 s.BindString(0, other_db_path.value());
Fabrice de Gans-Riberi65421f62018-05-22 23:16:181280#else
1281#error Unsupported platform
[email protected]8d409412013-07-19 18:25:301282#endif
1283 s.BindString(1, attachment_point);
1284 return s.Run();
1285}
1286
Victor Costan7f6abbbe2018-07-29 02:57:271287bool Connection::DetachDatabase(const char* attachment_point,
1288 InternalApiToken) {
[email protected]8d409412013-07-19 18:25:301289 DCHECK(ValidAttachmentPoint(attachment_point));
1290
1291 Statement s(GetUniqueStatement("DETACH DATABASE ?"));
1292 s.BindString(0, attachment_point);
1293 return s.Run();
1294}
1295
shess58b8df82015-06-03 00:19:321296// TODO(shess): Consider changing this to execute exactly one statement. If a
1297// caller wishes to execute multiple statements, that should be explicit, and
1298// perhaps tucked into an explicit transaction with rollback in case of error.
[email protected]eff1fa522011-12-12 23:50:591299int Connection::ExecuteAndReturnErrorCode(const char* sql) {
[email protected]35f7e5392012-07-27 19:54:501300 AssertIOAllowed();
[email protected]41a97c812013-02-07 02:35:381301 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521302 DCHECK(poisoned_) << "Illegal use of connection without a db";
[email protected]41a97c812013-02-07 02:35:381303 return SQLITE_ERROR;
1304 }
shess58b8df82015-06-03 00:19:321305 DCHECK(sql);
1306
1307 RecordOneEvent(EVENT_EXECUTE);
1308 int rc = SQLITE_OK;
1309 while ((rc == SQLITE_OK) && *sql) {
Victor Costanbd623112018-07-18 04:17:271310 sqlite3_stmt* stmt = nullptr;
shess58b8df82015-06-03 00:19:321311 const char *leftover_sql;
1312
Victor Costan87cf8c72018-07-19 19:36:041313 const base::TimeTicks before = NowTicks();
shess58b8df82015-06-03 00:19:321314 rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, &leftover_sql);
1315 sql = leftover_sql;
1316
1317 // Stop if an error is encountered.
1318 if (rc != SQLITE_OK)
1319 break;
1320
1321 // This happens if |sql| originally only contained comments or whitespace.
1322 // TODO(shess): Audit to see if this can become a DCHECK(). Having
1323 // extraneous comments and whitespace in the SQL statements increases
1324 // runtime cost and can easily be shifted out to the C++ layer.
1325 if (!stmt)
1326 continue;
1327
1328 // Save for use after statement is finalized.
1329 const bool read_only = !!sqlite3_stmt_readonly(stmt);
1330
1331 RecordOneEvent(Connection::EVENT_STATEMENT_RUN);
1332 while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
1333 // TODO(shess): Audit to see if this can become a DCHECK. I think PRAGMA
1334 // is the only legitimate case for this.
1335 RecordOneEvent(Connection::EVENT_STATEMENT_ROWS);
1336 }
1337
1338 // sqlite3_finalize() returns SQLITE_OK if the most recent sqlite3_step()
1339 // returned SQLITE_DONE or SQLITE_ROW, otherwise the error code.
1340 rc = sqlite3_finalize(stmt);
1341 if (rc == SQLITE_OK)
1342 RecordOneEvent(Connection::EVENT_STATEMENT_SUCCESS);
1343
1344 // sqlite3_exec() does this, presumably to avoid spinning the parser for
1345 // trailing whitespace.
1346 // TODO(shess): Audit to see if this can become a DCHECK.
brettwb3413062015-06-24 00:39:021347 while (base::IsAsciiWhitespace(*sql)) {
shess58b8df82015-06-03 00:19:321348 sql++;
1349 }
1350
Victor Costan87cf8c72018-07-19 19:36:041351 const base::TimeDelta delta = NowTicks() - before;
shess58b8df82015-06-03 00:19:321352 RecordTimeAndChanges(delta, read_only);
1353 }
shess7dbd4dee2015-10-06 17:39:161354
1355 // Most calls to Execute() modify the database. The main exceptions would be
1356 // calls such as CREATE TABLE IF NOT EXISTS which could modify the database
1357 // but sometimes don't.
1358 ReleaseCacheMemoryIfNeeded(true);
1359
shess58b8df82015-06-03 00:19:321360 return rc;
[email protected]eff1fa522011-12-12 23:50:591361}
1362
1363bool Connection::Execute(const char* sql) {
[email protected]41a97c812013-02-07 02:35:381364 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521365 DCHECK(poisoned_) << "Illegal use of connection without a db";
[email protected]41a97c812013-02-07 02:35:381366 return false;
1367 }
1368
[email protected]eff1fa522011-12-12 23:50:591369 int error = ExecuteAndReturnErrorCode(sql);
[email protected]473ad792012-11-10 00:55:001370 if (error != SQLITE_OK)
Victor Costanbd623112018-07-18 04:17:271371 error = OnSqliteError(error, nullptr, sql);
[email protected]473ad792012-11-10 00:55:001372
[email protected]28fe0ff2012-02-25 00:40:331373 // This needs to be a FATAL log because the error case of arriving here is
1374 // that there's a malformed SQL statement. This can arise in development if
[email protected]4350e322013-06-18 22:18:101375 // a change alters the schema but not all queries adjust. This can happen
1376 // in production if the schema is corrupted.
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521377 DCHECK_NE(error, SQLITE_ERROR)
1378 << "SQL Error in " << sql << ", " << GetErrorMessage();
[email protected]eff1fa522011-12-12 23:50:591379 return error == SQLITE_OK;
[email protected]e5ffd0e42009-09-11 21:30:561380}
1381
[email protected]5b96f3772010-09-28 16:30:571382bool Connection::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) {
[email protected]41a97c812013-02-07 02:35:381383 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521384 DCHECK(poisoned_) << "Illegal use of connection without a db";
[email protected]5b96f3772010-09-28 16:30:571385 return false;
[email protected]41a97c812013-02-07 02:35:381386 }
[email protected]5b96f3772010-09-28 16:30:571387
1388 ScopedBusyTimeout busy_timeout(db_);
1389 busy_timeout.SetTimeout(timeout);
[email protected]eff1fa522011-12-12 23:50:591390 return Execute(sql);
[email protected]5b96f3772010-09-28 16:30:571391}
1392
[email protected]e5ffd0e42009-09-11 21:30:561393scoped_refptr<Connection::StatementRef> Connection::GetCachedStatement(
Victor Costan12daa3ac92018-07-19 01:05:581394 StatementID id,
[email protected]e5ffd0e42009-09-11 21:30:561395 const char* sql) {
Victor Costanc7e7f2e2018-07-18 20:07:551396 auto it = statement_cache_.find(id);
1397 if (it != statement_cache_.end()) {
Victor Costan87cf8c72018-07-19 19:36:041398 // Statement is in the cache. It should still be active. We're the only
1399 // one invalidating cached statements, and we remove them from the cache
1400 // when we do that.
Victor Costanc7e7f2e2018-07-18 20:07:551401 DCHECK(it->second->is_valid());
Victor Costan87cf8c72018-07-19 19:36:041402
1403 DCHECK_EQ(std::string(sql), std::string(sqlite3_sql(it->second->stmt())))
1404 << "GetCachedStatement used with same ID but different SQL";
1405
1406 // Reset the statement so it can be reused.
Victor Costanc7e7f2e2018-07-18 20:07:551407 sqlite3_reset(it->second->stmt());
1408 return it->second;
[email protected]e5ffd0e42009-09-11 21:30:561409 }
1410
1411 scoped_refptr<StatementRef> statement = GetUniqueStatement(sql);
1412 if (statement->is_valid())
1413 statement_cache_[id] = statement; // Only cache valid statements.
1414 return statement;
1415}
1416
1417scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement(
1418 const char* sql) {
shess9e77283d2016-06-13 23:53:201419 return GetStatementImpl(this, sql);
1420}
1421
1422scoped_refptr<Connection::StatementRef> Connection::GetStatementImpl(
1423 sql::Connection* tracking_db, const char* sql) const {
[email protected]35f7e5392012-07-27 19:54:501424 AssertIOAllowed();
shess9e77283d2016-06-13 23:53:201425 DCHECK(sql);
Victor Costan87cf8c72018-07-19 19:36:041426 DCHECK(!tracking_db || tracking_db == this);
[email protected]35f7e5392012-07-27 19:54:501427
[email protected]41a97c812013-02-07 02:35:381428 // Return inactive statement.
[email protected]e5ffd0e42009-09-11 21:30:561429 if (!db_)
Victor Costan3b02cdf2018-07-18 00:39:561430 return base::MakeRefCounted<StatementRef>(nullptr, nullptr, poisoned_);
[email protected]e5ffd0e42009-09-11 21:30:561431
Victor Costanbd623112018-07-18 04:17:271432 sqlite3_stmt* stmt = nullptr;
1433 int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr);
[email protected]473ad792012-11-10 00:55:001434 if (rc != SQLITE_OK) {
[email protected]eff1fa522011-12-12 23:50:591435 // This is evidence of a syntax error in the incoming SQL.
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521436 DCHECK_NE(rc, SQLITE_ERROR) << "SQL compile error " << GetErrorMessage();
[email protected]473ad792012-11-10 00:55:001437
1438 // It could also be database corruption.
Victor Costanbd623112018-07-18 04:17:271439 OnSqliteError(rc, nullptr, sql);
Victor Costan3b02cdf2018-07-18 00:39:561440 return base::MakeRefCounted<StatementRef>(nullptr, nullptr, false);
[email protected]e5ffd0e42009-09-11 21:30:561441 }
Victor Costan3b02cdf2018-07-18 00:39:561442 return base::MakeRefCounted<StatementRef>(tracking_db, stmt, true);
[email protected]e5ffd0e42009-09-11 21:30:561443}
1444
[email protected]2eec0a22012-07-24 01:59:581445scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement(
1446 const char* sql) const {
Victor Costanbd623112018-07-18 04:17:271447 return GetStatementImpl(nullptr, sql);
[email protected]2eec0a22012-07-24 01:59:581448}
1449
[email protected]92cd00a2013-08-16 11:09:581450std::string Connection::GetSchema() const {
1451 // The ORDER BY should not be necessary, but relying on organic
1452 // order for something like this is questionable.
Victor Costan87cf8c72018-07-19 19:36:041453 static const char kSql[] =
[email protected]92cd00a2013-08-16 11:09:581454 "SELECT type, name, tbl_name, sql "
1455 "FROM sqlite_master ORDER BY 1, 2, 3, 4";
1456 Statement statement(GetUntrackedStatement(kSql));
1457
1458 std::string schema;
1459 while (statement.Step()) {
1460 schema += statement.ColumnString(0);
1461 schema += '|';
1462 schema += statement.ColumnString(1);
1463 schema += '|';
1464 schema += statement.ColumnString(2);
1465 schema += '|';
1466 schema += statement.ColumnString(3);
1467 schema += '\n';
1468 }
1469
1470 return schema;
1471}
1472
[email protected]eff1fa522011-12-12 23:50:591473bool Connection::IsSQLValid(const char* sql) {
[email protected]35f7e5392012-07-27 19:54:501474 AssertIOAllowed();
[email protected]41a97c812013-02-07 02:35:381475 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521476 DCHECK(poisoned_) << "Illegal use of connection without a db";
[email protected]41a97c812013-02-07 02:35:381477 return false;
1478 }
1479
Victor Costanbd623112018-07-18 04:17:271480 sqlite3_stmt* stmt = nullptr;
1481 if (sqlite3_prepare_v2(db_, sql, -1, &stmt, nullptr) != SQLITE_OK)
[email protected]eff1fa522011-12-12 23:50:591482 return false;
1483
1484 sqlite3_finalize(stmt);
1485 return true;
1486}
1487
[email protected]e2cadec82011-12-13 02:00:531488bool Connection::DoesIndexExist(const char* index_name) const {
shessa62504d2016-11-07 19:26:121489 return DoesSchemaItemExist(index_name, "index");
[email protected]e2cadec82011-12-13 02:00:531490}
1491
shessa62504d2016-11-07 19:26:121492bool Connection::DoesTableExist(const char* table_name) const {
1493 return DoesSchemaItemExist(table_name, "table");
1494}
1495
1496bool Connection::DoesViewExist(const char* view_name) const {
1497 return DoesSchemaItemExist(view_name, "view");
1498}
1499
1500bool Connection::DoesSchemaItemExist(
[email protected]e2cadec82011-12-13 02:00:531501 const char* name, const char* type) const {
shess92a2ab12015-04-09 01:59:471502 const char* kSql =
1503 "SELECT name FROM sqlite_master WHERE type=? AND name=? COLLATE NOCASE";
[email protected]2eec0a22012-07-24 01:59:581504 Statement statement(GetUntrackedStatement(kSql));
shess92a2ab12015-04-09 01:59:471505
shess976814402016-06-21 06:56:251506 // This can happen if the database is corrupt and the error is a test
1507 // expectation.
shess92a2ab12015-04-09 01:59:471508 if (!statement.is_valid())
1509 return false;
1510
[email protected]e2cadec82011-12-13 02:00:531511 statement.BindString(0, type);
1512 statement.BindString(1, name);
[email protected]28fe0ff2012-02-25 00:40:331513
[email protected]e5ffd0e42009-09-11 21:30:561514 return statement.Step(); // Table exists if any row was returned.
1515}
1516
1517bool Connection::DoesColumnExist(const char* table_name,
[email protected]1ed78a32009-09-15 20:24:171518 const char* column_name) const {
[email protected]e5ffd0e42009-09-11 21:30:561519 std::string sql("PRAGMA TABLE_INFO(");
1520 sql.append(table_name);
1521 sql.append(")");
1522
[email protected]2eec0a22012-07-24 01:59:581523 Statement statement(GetUntrackedStatement(sql.c_str()));
shess92a2ab12015-04-09 01:59:471524
shess976814402016-06-21 06:56:251525 // This can happen if the database is corrupt and the error is a test
1526 // expectation.
shess92a2ab12015-04-09 01:59:471527 if (!statement.is_valid())
1528 return false;
1529
[email protected]e5ffd0e42009-09-11 21:30:561530 while (statement.Step()) {
brettw8a800902015-07-10 18:28:331531 if (base::EqualsCaseInsensitiveASCII(statement.ColumnString(1),
1532 column_name))
[email protected]e5ffd0e42009-09-11 21:30:561533 return true;
1534 }
1535 return false;
1536}
1537
tfarina720d4f32015-05-11 22:31:261538int64_t Connection::GetLastInsertRowId() const {
[email protected]e5ffd0e42009-09-11 21:30:561539 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521540 DCHECK(poisoned_) << "Illegal use of connection without a db";
[email protected]e5ffd0e42009-09-11 21:30:561541 return 0;
1542 }
1543 return sqlite3_last_insert_rowid(db_);
1544}
1545
[email protected]1ed78a32009-09-15 20:24:171546int Connection::GetLastChangeCount() const {
1547 if (!db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521548 DCHECK(poisoned_) << "Illegal use of connection without a db";
[email protected]1ed78a32009-09-15 20:24:171549 return 0;
1550 }
1551 return sqlite3_changes(db_);
1552}
1553
[email protected]e5ffd0e42009-09-11 21:30:561554int Connection::GetErrorCode() const {
1555 if (!db_)
1556 return SQLITE_ERROR;
1557 return sqlite3_errcode(db_);
1558}
1559
[email protected]767718e52010-09-21 23:18:491560int Connection::GetLastErrno() const {
1561 if (!db_)
1562 return -1;
1563
1564 int err = 0;
Victor Costanbd623112018-07-18 04:17:271565 if (SQLITE_OK != sqlite3_file_control(db_, nullptr, SQLITE_LAST_ERRNO, &err))
[email protected]767718e52010-09-21 23:18:491566 return -2;
1567
1568 return err;
1569}
1570
[email protected]e5ffd0e42009-09-11 21:30:561571const char* Connection::GetErrorMessage() const {
1572 if (!db_)
1573 return "sql::Connection has no connection.";
1574 return sqlite3_errmsg(db_);
1575}
1576
[email protected]fed734a2013-07-17 04:45:131577bool Connection::OpenInternal(const std::string& file_name,
1578 Connection::Retry retry_flag) {
[email protected]35f7e5392012-07-27 19:54:501579 AssertIOAllowed();
1580
[email protected]9cfbc922009-11-17 20:13:171581 if (db_) {
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521582 DLOG(DCHECK) << "sql::Connection is already open.";
[email protected]9cfbc922009-11-17 20:13:171583 return false;
1584 }
1585
Victor Costan3653df62018-02-08 21:38:161586 EnsureSqliteInitialized();
[email protected]a7ec1292013-07-22 22:02:181587
shess58b8df82015-06-03 00:19:321588 // Setup the stats histograms immediately rather than allocating lazily.
1589 // Connections which won't exercise all of these probably shouldn't exist.
1590 if (!histogram_tag_.empty()) {
1591 stats_histogram_ =
1592 base::LinearHistogram::FactoryGet(
1593 "Sqlite.Stats." + histogram_tag_,
1594 1, EVENT_MAX_VALUE, EVENT_MAX_VALUE + 1,
1595 base::HistogramBase::kUmaTargetedHistogramFlag);
1596
1597 // The timer setup matches UMA_HISTOGRAM_MEDIUM_TIMES(). 3 minutes is an
1598 // unreasonable time for any single operation, so there is not much value to
1599 // knowing if it was 3 minutes or 5 minutes. In reality at that point
1600 // things are entirely busted.
1601 commit_time_histogram_ =
1602 GetMediumTimeHistogram("Sqlite.CommitTime." + histogram_tag_);
1603
1604 autocommit_time_histogram_ =
1605 GetMediumTimeHistogram("Sqlite.AutoCommitTime." + histogram_tag_);
1606
1607 update_time_histogram_ =
1608 GetMediumTimeHistogram("Sqlite.UpdateTime." + histogram_tag_);
1609
1610 query_time_histogram_ =
1611 GetMediumTimeHistogram("Sqlite.QueryTime." + histogram_tag_);
1612 }
1613
[email protected]41a97c812013-02-07 02:35:381614 // If |poisoned_| is set, it means an error handler called
1615 // RazeAndClose(). Until regular Close() is called, the caller
1616 // should be treating the database as open, but is_open() currently
1617 // only considers the sqlite3 handle's state.
1618 // TODO(shess): Revise is_open() to consider poisoned_, and review
1619 // to see if any non-testing code even depends on it.
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521620 DCHECK(!poisoned_) << "sql::Connection is already open.";
[email protected]7bae5742013-07-10 20:46:161621 poisoned_ = false;
[email protected]41a97c812013-02-07 02:35:381622
shess5f2c3442017-01-24 02:15:101623 // Custom memory-mapping VFS which reads pages using regular I/O on first hit.
1624 sqlite3_vfs* vfs = VFSWrapper();
1625 const char* vfs_name = (vfs ? vfs->zName : nullptr);
1626 int err = sqlite3_open_v2(file_name.c_str(), &db_,
1627 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1628 vfs_name);
[email protected]765b44502009-10-02 05:01:421629 if (err != SQLITE_OK) {
[email protected]73fb8d52013-07-24 05:04:281630 // Extended error codes cannot be enabled until a handle is
1631 // available, fetch manually.
1632 err = sqlite3_extended_errcode(db_);
1633
[email protected]bd2ccdb4a2012-12-07 22:14:501634 // Histogram failures specific to initial open for debugging
1635 // purposes.
Ilya Sherman1c811db2017-12-14 10:36:181636 base::UmaHistogramSparse("Sqlite.OpenFailure", err);
[email protected]bd2ccdb4a2012-12-07 22:14:501637
Victor Costanbd623112018-07-18 04:17:271638 OnSqliteError(err, nullptr, "-- sqlite3_open()");
[email protected]fed734a2013-07-17 04:45:131639 bool was_poisoned = poisoned_;
[email protected]64021042012-02-10 20:02:291640 Close();
[email protected]fed734a2013-07-17 04:45:131641
1642 if (was_poisoned && retry_flag == RETRY_ON_POISON)
1643 return OpenInternal(file_name, NO_RETRY);
[email protected]765b44502009-10-02 05:01:421644 return false;
1645 }
1646
[email protected]73fb8d52013-07-24 05:04:281647 // Enable extended result codes to provide more color on I/O errors.
1648 // Not having extended result codes is not a fatal problem, as
1649 // Chromium code does not attempt to handle I/O errors anyhow. The
1650 // current implementation always returns SQLITE_OK, the DCHECK is to
1651 // quickly notify someone if SQLite changes.
1652 err = sqlite3_extended_result_codes(db_, 1);
1653 DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes";
1654
shessbccd300e2016-08-20 00:06:561655 // sqlite3_open() does not actually read the database file (unless a hot
1656 // journal is found). Successfully executing this pragma on an existing
1657 // database requires a valid header on page 1. ExecuteAndReturnErrorCode() to
1658 // get the error code before error callback (potentially) overwrites.
[email protected]bd2ccdb4a2012-12-07 22:14:501659 // TODO(shess): For now, just probing to see what the lay of the
1660 // land is. If it's mostly SQLITE_NOTADB, then the database should
1661 // be razed.
1662 err = ExecuteAndReturnErrorCode("PRAGMA auto_vacuum");
shessbccd300e2016-08-20 00:06:561663 if (err != SQLITE_OK) {
Ilya Sherman1c811db2017-12-14 10:36:181664 base::UmaHistogramSparse("Sqlite.OpenProbeFailure", err);
shessbccd300e2016-08-20 00:06:561665 OnSqliteError(err, nullptr, "PRAGMA auto_vacuum");
1666
1667 // Retry or bail out if the error handler poisoned the handle.
1668 // TODO(shess): Move this handling to one place (see also sqlite3_open and
1669 // secure_delete). Possibly a wrapper function?
1670 if (poisoned_) {
1671 Close();
1672 if (retry_flag == RETRY_ON_POISON)
1673 return OpenInternal(file_name, NO_RETRY);
1674 return false;
1675 }
1676 }
[email protected]658f8332010-09-18 04:40:431677
[email protected]5b96f3772010-09-28 16:30:571678 // If indicated, lock up the database before doing anything else, so
1679 // that the following code doesn't have to deal with locking.
1680 // TODO(shess): This code is brittle. Find the cases where code
1681 // doesn't request |exclusive_locking_| and audit that it does the
1682 // right thing with SQLITE_BUSY, and that it doesn't make
1683 // assumptions about who might change things in the database.
1684 // http://crbug.com/56559
1685 if (exclusive_locking_) {
[email protected]4350e322013-06-18 22:18:101686 // TODO(shess): This should probably be a failure. Code which
1687 // requests exclusive locking but doesn't get it is almost certain
1688 // to be ill-tested.
1689 ignore_result(Execute("PRAGMA locking_mode=EXCLUSIVE"));
[email protected]5b96f3772010-09-28 16:30:571690 }
1691
[email protected]4e179ba62012-03-17 16:06:471692 // http://www.sqlite.org/pragma.html#pragma_journal_mode
1693 // DELETE (default) - delete -journal file to commit.
1694 // TRUNCATE - truncate -journal file to commit.
1695 // PERSIST - zero out header of -journal file to commit.
shess2c21ecf2015-06-02 01:31:091696 // TRUNCATE should be faster than DELETE because it won't need directory
1697 // changes for each transaction. PERSIST may break the spirit of using
1698 // secure_delete.
1699 ignore_result(Execute("PRAGMA journal_mode = TRUNCATE"));
[email protected]4e179ba62012-03-17 16:06:471700
[email protected]c68ce172011-11-24 22:30:271701 const base::TimeDelta kBusyTimeout =
1702 base::TimeDelta::FromSeconds(kBusyTimeoutSeconds);
1703
Victor Costan7f6abbbe2018-07-29 02:57:271704 const std::string sql = base::StringPrintf("PRAGMA page_size=%d", page_size_);
1705 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout));
[email protected]765b44502009-10-02 05:01:421706
1707 if (cache_size_ != 0) {
[email protected]7d3cbc92013-03-18 22:33:041708 const std::string sql =
1709 base::StringPrintf("PRAGMA cache_size=%d", cache_size_);
[email protected]4350e322013-06-18 22:18:101710 ignore_result(ExecuteWithTimeout(sql.c_str(), kBusyTimeout));
[email protected]765b44502009-10-02 05:01:421711 }
1712
[email protected]6e0b1442011-08-09 23:23:581713 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) {
[email protected]fed734a2013-07-17 04:45:131714 bool was_poisoned = poisoned_;
[email protected]6e0b1442011-08-09 23:23:581715 Close();
[email protected]fed734a2013-07-17 04:45:131716 if (was_poisoned && retry_flag == RETRY_ON_POISON)
1717 return OpenInternal(file_name, NO_RETRY);
[email protected]6e0b1442011-08-09 23:23:581718 return false;
1719 }
1720
shess5dac334f2015-11-05 20:47:421721 // Set a reasonable chunk size for larger files. This reduces churn from
1722 // remapping memory on size changes. It also reduces filesystem
1723 // fragmentation.
1724 // TODO(shess): It may make sense to have this be hinted by the client.
1725 // Database sizes seem to be bimodal, some clients have consistently small
1726 // databases (<20k) while other clients have a broad distribution of sizes
1727 // (hundreds of kilobytes to many megabytes).
Victor Costanbd623112018-07-18 04:17:271728 sqlite3_file* file = nullptr;
shess5dac334f2015-11-05 20:47:421729 sqlite3_int64 db_size = 0;
1730 int rc = GetSqlite3FileAndSize(db_, &file, &db_size);
1731 if (rc == SQLITE_OK && db_size > 16 * 1024) {
1732 int chunk_size = 4 * 1024;
1733 if (db_size > 128 * 1024)
1734 chunk_size = 32 * 1024;
Victor Costanbd623112018-07-18 04:17:271735 sqlite3_file_control(db_, nullptr, SQLITE_FCNTL_CHUNK_SIZE, &chunk_size);
shess5dac334f2015-11-05 20:47:421736 }
1737
shess2f3a814b2015-11-05 18:11:101738 // Enable memory-mapped access. The explicit-disable case is because SQLite
shessd90aeea82015-11-13 02:24:311739 // can be built to default-enable mmap. GetAppropriateMmapSize() calculates a
1740 // safe range to memory-map based on past regular I/O. This value will be
1741 // capped by SQLITE_MAX_MMAP_SIZE, which could be different between 32-bit and
1742 // 64-bit platforms.
1743 size_t mmap_size = mmap_disabled_ ? 0 : GetAppropriateMmapSize();
1744 std::string mmap_sql =
1745 base::StringPrintf("PRAGMA mmap_size = %" PRIuS, mmap_size);
1746 ignore_result(Execute(mmap_sql.c_str()));
shess2f3a814b2015-11-05 18:11:101747
1748 // Determine if memory-mapping has actually been enabled. The Execute() above
1749 // can succeed without changing the amount mapped.
1750 mmap_enabled_ = false;
1751 {
1752 Statement s(GetUniqueStatement("PRAGMA mmap_size"));
1753 if (s.Step() && s.ColumnInt64(0) > 0)
1754 mmap_enabled_ = true;
1755 }
1756
ssid3be5b1ec2016-01-13 14:21:571757 DCHECK(!memory_dump_provider_);
1758 memory_dump_provider_.reset(
1759 new ConnectionMemoryDumpProvider(db_, histogram_tag_));
1760 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
1761 memory_dump_provider_.get(), "sql::Connection", nullptr);
1762
[email protected]765b44502009-10-02 05:01:421763 return true;
1764}
1765
[email protected]e5ffd0e42009-09-11 21:30:561766void Connection::DoRollback() {
1767 Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK"));
shess58b8df82015-06-03 00:19:321768
1769 // Collect the rollback time manually, sql::Statement would register it as
1770 // query time only.
Victor Costan87cf8c72018-07-19 19:36:041771 const base::TimeTicks before = NowTicks();
shess58b8df82015-06-03 00:19:321772 rollback.RunWithoutTimers();
Victor Costan87cf8c72018-07-19 19:36:041773 const base::TimeDelta delta = NowTicks() - before;
shess58b8df82015-06-03 00:19:321774
1775 RecordUpdateTime(delta);
1776 RecordOneEvent(EVENT_ROLLBACK);
1777
shess7dbd4dee2015-10-06 17:39:161778 // The cache may have been accumulating dirty pages for commit. Note that in
1779 // some cases sql::Transaction can fire rollback after a database is closed.
1780 if (is_open())
1781 ReleaseCacheMemoryIfNeeded(false);
1782
[email protected]44ad7d902012-03-23 00:09:051783 needs_rollback_ = false;
[email protected]e5ffd0e42009-09-11 21:30:561784}
1785
1786void Connection::StatementRefCreated(StatementRef* ref) {
Victor Costanc7e7f2e2018-07-18 20:07:551787 DCHECK(!open_statements_.count(ref))
1788 << __func__ << " already called with this statement";
[email protected]e5ffd0e42009-09-11 21:30:561789 open_statements_.insert(ref);
1790}
1791
1792void Connection::StatementRefDeleted(StatementRef* ref) {
Victor Costanc7e7f2e2018-07-18 20:07:551793 DCHECK(open_statements_.count(ref))
1794 << __func__ << " called with non-existing statement";
1795 open_statements_.erase(ref);
[email protected]e5ffd0e42009-09-11 21:30:561796}
1797
shess58b8df82015-06-03 00:19:321798void Connection::set_histogram_tag(const std::string& tag) {
1799 DCHECK(!is_open());
Victor Costan87cf8c72018-07-19 19:36:041800
shess58b8df82015-06-03 00:19:321801 histogram_tag_ = tag;
1802}
1803
[email protected]210ce0af2013-05-15 09:10:391804void Connection::AddTaggedHistogram(const std::string& name,
1805 size_t sample) const {
1806 if (histogram_tag_.empty())
1807 return;
1808
1809 // TODO(shess): The histogram macros create a bit of static storage
1810 // for caching the histogram object. This code shouldn't execute
1811 // often enough for such caching to be crucial. If it becomes an
1812 // issue, the object could be cached alongside histogram_prefix_.
1813 std::string full_histogram_name = name + "." + histogram_tag_;
1814 base::HistogramBase* histogram =
1815 base::SparseHistogram::FactoryGet(
1816 full_histogram_name,
1817 base::HistogramBase::kUmaTargetedHistogramFlag);
1818 if (histogram)
1819 histogram->Add(sample);
1820}
1821
shess9e77283d2016-06-13 23:53:201822int Connection::OnSqliteError(
1823 int err, sql::Statement *stmt, const char* sql) const {
Ilya Sherman1c811db2017-12-14 10:36:181824 base::UmaHistogramSparse("Sqlite.Error", err);
[email protected]210ce0af2013-05-15 09:10:391825 AddTaggedHistogram("Sqlite.Error", err);
[email protected]c088e3a32013-01-03 23:59:141826
1827 // Always log the error.
[email protected]2f496b42013-09-26 18:36:581828 if (!sql && stmt)
1829 sql = stmt->GetSQLStatement();
1830 if (!sql)
1831 sql = "-- unknown";
shessf7e988f2015-11-13 00:41:061832
1833 std::string id = histogram_tag_;
1834 if (id.empty())
1835 id = DbPath().BaseName().AsUTF8Unsafe();
1836 LOG(ERROR) << id << " sqlite error " << err
[email protected]c088e3a32013-01-03 23:59:141837 << ", errno " << GetLastErrno()
[email protected]2f496b42013-09-26 18:36:581838 << ": " << GetErrorMessage()
1839 << ", sql: " << sql;
[email protected]c088e3a32013-01-03 23:59:141840
[email protected]c3881b372013-05-17 08:39:461841 if (!error_callback_.is_null()) {
[email protected]98cf3002013-07-12 01:38:561842 // Fire from a copy of the callback in case of reentry into
1843 // re/set_error_callback().
1844 // TODO(shess): <http://crbug.com/254584>
1845 ErrorCallback(error_callback_).Run(err, stmt);
[email protected]c3881b372013-05-17 08:39:461846 return err;
1847 }
1848
[email protected]faa604e2009-09-25 22:38:591849 // The default handling is to assert on debug and to ignore on release.
shess976814402016-06-21 06:56:251850 if (!IsExpectedSqliteError(err))
Sigurdur Asgeirsson8d82bd02017-09-25 21:05:521851 DLOG(DCHECK) << GetErrorMessage();
[email protected]faa604e2009-09-25 22:38:591852 return err;
1853}
1854
[email protected]579446c2013-12-16 18:36:521855bool Connection::FullIntegrityCheck(std::vector<std::string>* messages) {
1856 return IntegrityCheckHelper("PRAGMA integrity_check", messages);
1857}
1858
1859bool Connection::QuickIntegrityCheck() {
1860 std::vector<std::string> messages;
1861 if (!IntegrityCheckHelper("PRAGMA quick_check", &messages))
1862 return false;
1863 return messages.size() == 1 && messages[0] == "ok";
1864}
1865
afakhry7c9abe72016-08-05 17:33:191866std::string Connection::GetDiagnosticInfo(int extended_error,
1867 Statement* statement) {
1868 // Prevent reentrant calls to the error callback.
1869 ErrorCallback original_callback = std::move(error_callback_);
1870 reset_error_callback();
1871
1872 // Trim extended error codes.
1873 const int error = (extended_error & 0xFF);
1874 // CollectCorruptionInfo() is implemented in terms of sql::Connection,
1875 // TODO(shess): Rewrite IntegrityCheckHelper() in terms of raw SQLite.
1876 std::string result = (error == SQLITE_CORRUPT)
1877 ? CollectCorruptionInfo()
1878 : CollectErrorInfo(extended_error, statement);
1879
1880 // The following queries must be executed after CollectErrorInfo() above, so
1881 // if they result in their own errors, they don't interfere with
1882 // CollectErrorInfo().
1883 const bool has_valid_header =
1884 (ExecuteAndReturnErrorCode("PRAGMA auto_vacuum") == SQLITE_OK);
1885 const bool select_sqlite_master_result =
1886 (ExecuteAndReturnErrorCode("SELECT COUNT(*) FROM sqlite_master") ==
1887 SQLITE_OK);
1888
1889 // Restore the original error callback.
1890 error_callback_ = std::move(original_callback);
1891
1892 base::StringAppendF(&result, "Has valid header: %s\n",
1893 (has_valid_header ? "Yes" : "No"));
1894 base::StringAppendF(&result, "Has valid schema: %s\n",
1895 (select_sqlite_master_result ? "Yes" : "No"));
1896
1897 return result;
1898}
1899
[email protected]80abf152013-05-22 12:42:421900// TODO(shess): Allow specifying maximum results (default 100 lines).
[email protected]579446c2013-12-16 18:36:521901bool Connection::IntegrityCheckHelper(
1902 const char* pragma_sql,
1903 std::vector<std::string>* messages) {
[email protected]80abf152013-05-22 12:42:421904 messages->clear();
1905
[email protected]4658e2a02013-06-06 23:05:001906 // This has the side effect of setting SQLITE_RecoveryMode, which
1907 // allows SQLite to process through certain cases of corruption.
1908 // Failing to set this pragma probably means that the database is
1909 // beyond recovery.
Victor Costan1d868352018-06-26 19:06:481910 static const char kWritableSchemaSql[] = "PRAGMA writable_schema = ON";
1911 if (!Execute(kWritableSchemaSql))
[email protected]4658e2a02013-06-06 23:05:001912 return false;
1913
1914 bool ret = false;
1915 {
[email protected]579446c2013-12-16 18:36:521916 sql::Statement stmt(GetUniqueStatement(pragma_sql));
[email protected]4658e2a02013-06-06 23:05:001917
1918 // The pragma appears to return all results (up to 100 by default)
1919 // as a single string. This doesn't appear to be an API contract,
1920 // it could return separate lines, so loop _and_ split.
1921 while (stmt.Step()) {
1922 std::string result(stmt.ColumnString(0));
brettw83dc1612015-08-12 07:31:181923 *messages = base::SplitString(result, "\n", base::TRIM_WHITESPACE,
1924 base::SPLIT_WANT_ALL);
[email protected]4658e2a02013-06-06 23:05:001925 }
1926 ret = stmt.Succeeded();
[email protected]80abf152013-05-22 12:42:421927 }
[email protected]4658e2a02013-06-06 23:05:001928
1929 // Best effort to put things back as they were before.
Victor Costan1d868352018-06-26 19:06:481930 static const char kNoWritableSchemaSql[] = "PRAGMA writable_schema = OFF";
1931 ignore_result(Execute(kNoWritableSchemaSql));
[email protected]4658e2a02013-06-06 23:05:001932
1933 return ret;
[email protected]80abf152013-05-22 12:42:421934}
1935
ssid1f4e5362016-12-08 20:41:381936bool Connection::ReportMemoryUsage(base::trace_event::ProcessMemoryDump* pmd,
1937 const std::string& dump_name) {
dskibab4199f82016-11-21 20:16:131938 return memory_dump_provider_ &&
ssid1f4e5362016-12-08 20:41:381939 memory_dump_provider_->ReportMemoryUsage(pmd, dump_name);
dskibab4199f82016-11-21 20:16:131940}
1941
[email protected]e5ffd0e42009-09-11 21:30:561942} // namespace sql