Add sql::DatabaseOptions to encapsulate its configuration options
sql::Database uses internal state to manage its configuration options
like page size, journal mode etc. These options need to be set before
Database::Open() is called. Any change to this state has no effect if
done after the database has already been opened. There are also some
SQLite subtleties around different behaviour of this state depending on
whether the database is being opened for the first time or being
re-opened.
This change encapsulates all such state into a sql::DatabaseOptions
struct which is passed to the sql::Database constructor. This ensures
that the required options have been configured before calling Open().
We migrate sql/ to use the new constructor instead of the setters for
the state. In upcoming changes, we plan to remove the setters for this
state. This will make the Database API enforce that the options are set
only once and stay the same over the lifetime of the object.
Bug: 1126968
Change-Id: Id44b6b3883f7a695f3b5cd96ad071e15cb1dc44a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2427035
Commit-Queue: Shubham Aggarwal <[email protected]>
Reviewed-by: Victor Costan <[email protected]>
Cr-Commit-Position: refs/heads/master@{#817386}
diff --git a/sql/database.cc b/sql/database.cc
index db46be6..59f1959d 100644
--- a/sql/database.cc
+++ b/sql/database.cc
@@ -233,19 +233,15 @@
was_valid_ = was_valid_ && forced;
}
-static_assert(
- Database::kDefaultPageSize == SQLITE_DEFAULT_PAGE_SIZE,
- "Database::kDefaultPageSize must match the value configured into SQLite");
+static_assert(DatabaseOptions::kDefaultPageSize == SQLITE_DEFAULT_PAGE_SIZE,
+ "DatabaseOptions::kDefaultPageSize must match the value "
+ "configured into SQLite");
-constexpr int Database::kDefaultPageSize;
+Database::Database() : Database({.exclusive_locking = false}) {}
-Database::Database()
+Database::Database(DatabaseOptions options)
: db_(nullptr),
- page_size_(kDefaultPageSize),
- cache_size_(0),
- exclusive_locking_(false),
- want_wal_mode_(
- base::FeatureList::IsEnabled(features::kEnableWALModeByDefault)),
+ options_(options),
transaction_nesting_(0),
needs_rollback_(false),
in_memory_(false),
@@ -254,7 +250,12 @@
mmap_disabled_(!enable_mmap_by_default_),
mmap_enabled_(false),
total_changes_at_last_release_(0),
- stats_histogram_(nullptr) {}
+ stats_histogram_(nullptr) {
+ DCHECK_GE(options.page_size, 512);
+ DCHECK_LE(options.page_size, 65536);
+ DCHECK(!(options.page_size & (options.page_size - 1)))
+ << "page_size must be a power of two";
+}
Database::~Database() {
Close();
@@ -821,7 +822,7 @@
}
const std::string page_size_sql =
- base::StringPrintf("PRAGMA page_size=%d", page_size_);
+ base::StringPrintf("PRAGMA page_size=%d", options_.page_size);
if (!null_db.Execute(page_size_sql.c_str()))
return false;
@@ -1519,7 +1520,7 @@
// enabled.
//
// TODO(crbug.com/1120969): Remove support for non-exclusive mode.
- if (!exclusive_locking_) {
+ if (!options_.exclusive_locking) {
err = ExecuteAndReturnErrorCode("PRAGMA locking_mode=NORMAL");
if (err != SQLITE_OK)
return false;
@@ -1562,7 +1563,7 @@
// Needs to happen before entering WAL mode. Will only work if this the first
// time the database is being opened in WAL mode.
const std::string page_size_sql =
- base::StringPrintf("PRAGMA page_size=%d", page_size_);
+ base::StringPrintf("PRAGMA page_size=%d", options_.page_size);
ignore_result(ExecuteWithTimeout(page_size_sql.c_str(), kBusyTimeout));
// http://www.sqlite.org/pragma.html#pragma_journal_mode
@@ -1594,9 +1595,9 @@
ignore_result(Execute("PRAGMA journal_mode=TRUNCATE"));
}
- if (cache_size_ != 0) {
+ if (options_.cache_size != 0) {
const std::string cache_size_sql =
- base::StringPrintf("PRAGMA cache_size=%d", cache_size_);
+ base::StringPrintf("PRAGMA cache_size=%d", options_.cache_size);
ignore_result(ExecuteWithTimeout(cache_size_sql.c_str(), kBusyTimeout));
}
@@ -1822,9 +1823,9 @@
// locking, because this case does not require shared memory support.
// At the time this was implemented (May 2020), Fuchsia's shared
// memory support was insufficient for SQLite's needs.
- return want_wal_mode_ && exclusive_locking_;
+ return options_.wal_mode && options_.exclusive_locking;
#else
- return want_wal_mode_;
+ return options_.wal_mode;
#endif // defined(OS_FUCHSIA)
}