Builder pattern in DatabaseOptions
DatabaseOptions is getting too large for the "explicit out of line constructor for complex types" presubmit. Adding a constructor to it prevents it from being an aggregate type, which is how most of the callers currently use it. This Cl makes DatabaseOptions members private and adds builder-type setters for each member. It also updates all callers, and adds an out of line constructor. A future improvement could be to add a passkey to the setters for discouraged options. Bug: None Change-Id: I63562f43c8b290247878d194039487b240e958c2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6216099 Reviewed-by: Gabriel Charette <gab@chromium.org> Reviewed-by: Greg Thompson <grt@chromium.org> Owners-Override: Gabriel Charette <gab@chromium.org> Commit-Queue: Anthony Vallée-Dubois <anthonyvd@chromium.org> Cr-Commit-Position: refs/heads/main@{#1414974}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
b198160771
commit
9adf0bbf4b
chrome
browser
test
fuzzing
components
blocklist
opt_out_blocklist
favicon
history
core
media_device_salt
password_manager
core
browser
password_store
power_bookmarks
segmentation_platform
internal
database
services
storage
shared_storage
webdata
common
content/browser
aggregation_service
attribution_reporting
browsing_topics
dips
first_party_sets
database
interest_group
media
private_aggregation
tracing
trace_report
net/extras/sqlite
services/network/trust_tokens
sql
database.ccdatabase.hdatabase_options_unittest.ccdatabase_unittest.cc
fuzzers
recovery.ccrecovery_unittest.cctest
storage/browser/quota
@ -39,14 +39,13 @@ static const int kSizeThresholdForFlush = 200;
|
||||
|
||||
ActivityDatabase::ActivityDatabase(ActivityDatabase::Delegate* delegate)
|
||||
: delegate_(delegate),
|
||||
db_(
|
||||
{
|
||||
.page_size = 4096,
|
||||
.cache_size = 32,
|
||||
db_(sql::DatabaseOptions()
|
||||
.set_page_size(4096)
|
||||
.set_cache_size(32)
|
||||
// TODO(pwnall): Add a meta table and remove this option.
|
||||
.mmap_alt_status_discouraged = true,
|
||||
.enable_views_discouraged = true, // Required by mmap_alt_status.
|
||||
},
|
||||
.set_mmap_alt_status_discouraged(true)
|
||||
.set_enable_views_discouraged(
|
||||
true), // Required by mmap_alt_status.
|
||||
/*tag=*/"Activity"),
|
||||
valid_db_(false),
|
||||
batch_mode_(true),
|
||||
|
@ -91,11 +91,11 @@ PredictorDatabaseInternal::PredictorDatabaseInternal(
|
||||
scoped_refptr<base::SequencedTaskRunner> db_task_runner)
|
||||
: db_path_(profile->GetPath().Append(kPredictorDatabaseName)),
|
||||
db_(std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{
|
||||
sql::DatabaseOptions()
|
||||
// TODO(pwnall): Add a meta table and remove this option.
|
||||
.mmap_alt_status_discouraged = true,
|
||||
.enable_views_discouraged = true, // Required by mmap_alt_status.
|
||||
},
|
||||
.set_mmap_alt_status_discouraged(true)
|
||||
.set_enable_views_discouraged(
|
||||
true), // Required by mmap_alt_status.
|
||||
sql::Database::Tag("Predictor"))),
|
||||
db_task_runner_(db_task_runner),
|
||||
autocomplete_table_(
|
||||
|
@ -1070,12 +1070,9 @@ Database* Database::GetInstance() {
|
||||
Database::Database() {
|
||||
base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
db_ = std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{
|
||||
.exclusive_locking =
|
||||
false, // centipede may run several fuzzers at once
|
||||
.page_size = sql::DatabaseOptions::kDefaultPageSize,
|
||||
.cache_size = 0,
|
||||
},
|
||||
sql::DatabaseOptions()
|
||||
// centipede may run several fuzzers at once
|
||||
.set_exclusive_locking(false),
|
||||
sql::test::kTestTag);
|
||||
base::FilePath db_path;
|
||||
CHECK(base::PathService::Get(base::DIR_TEMP, &db_path));
|
||||
|
@ -382,7 +382,7 @@ void OptOutStoreSQL::LoadBlockList(
|
||||
DCHECK(io_task_runner_->BelongsToCurrentThread());
|
||||
if (!db_) {
|
||||
db_ = std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{
|
||||
sql::DatabaseOptions()
|
||||
// The entry size should be between 11 and 10 + x bytes, where x is
|
||||
// the the length of the host name string in bytes. The total number
|
||||
// of entries per host is bounded at 32, and the total number of
|
||||
@ -394,8 +394,8 @@ void OptOutStoreSQL::LoadBlockList(
|
||||
// in their top 20 hosts. It should be closer to 32 * 100 * 20 for
|
||||
// most users, which is about 4096 * 15. The total size of the
|
||||
// database will be capped at 3200 entries.
|
||||
.page_size = 4096,
|
||||
.cache_size = 250},
|
||||
.set_page_size(4096)
|
||||
.set_cache_size(250),
|
||||
// TODO(crbug.com/40134470): Migrate to OptOutBlocklist and update any
|
||||
// backend code that may depend on this tag.
|
||||
sql::Database::Tag("OptOutBlacklist"));
|
||||
|
@ -237,11 +237,11 @@ bool FaviconDatabase::IconMappingEnumerator::GetNextIconMapping(
|
||||
}
|
||||
|
||||
FaviconDatabase::FaviconDatabase()
|
||||
: db_(
|
||||
{// Favicons db only stores favicons, so we don't need that big a page
|
||||
// size or cache.
|
||||
.page_size = 2048,
|
||||
.cache_size = 32},
|
||||
: db_(sql::DatabaseOptions()
|
||||
// Favicons db only stores favicons, so we don't need that big a
|
||||
// page size or cache.
|
||||
.set_page_size(2048)
|
||||
.set_cache_size(32),
|
||||
/*tag=*/"Thumbnail") {}
|
||||
|
||||
FaviconDatabase::~FaviconDatabase() {
|
||||
|
@ -83,22 +83,22 @@ HistoryDatabase::HistoryDatabase(
|
||||
DownloadInterruptReason download_interrupt_reason_crash)
|
||||
: DownloadDatabase(download_interrupt_reason_none,
|
||||
download_interrupt_reason_crash),
|
||||
db_(
|
||||
{// Note that we don't set exclusive locking here. That's done by
|
||||
// BeginExclusiveMode below which is called later (we have to be in
|
||||
// shared mode to start out for the in-memory backend to read the
|
||||
// data).
|
||||
// TODO(crbug.com/40159106) Remove this dependency on normal locking
|
||||
// mode.
|
||||
.exclusive_locking = false,
|
||||
// Set the database page size to something a little larger to give us
|
||||
// better performance (we're typically seek rather than bandwidth
|
||||
// limited). Must be a power of 2 and a max of 65536.
|
||||
.page_size = 4096,
|
||||
// Set the cache size. The page size, plus a little extra, times this
|
||||
// value, tells us how much memory the cache will use maximum.
|
||||
// 1000 * 4kB = 4MB
|
||||
.cache_size = 1000},
|
||||
db_(sql::DatabaseOptions()
|
||||
// Note that we don't set exclusive locking here. That's done by
|
||||
// BeginExclusiveMode below which is called later (we have to be
|
||||
// in shared mode to start out for the in-memory backend to read
|
||||
// the data).
|
||||
// TODO(crbug.com/40159106) Remove this dependency on normal
|
||||
// locking mode.
|
||||
.set_exclusive_locking(false)
|
||||
// Set the database page size to something a little larger to give
|
||||
// us better performance (we're typically seek rather than
|
||||
// bandwidth limited). Must be a power of 2 and a max of 65536.
|
||||
.set_page_size(4096)
|
||||
// Set the cache size. The page size, plus a little extra, times
|
||||
// this value, tells us how much memory the cache will use
|
||||
// maximum. 1000 * 4kB = 4MB
|
||||
.set_cache_size(1000),
|
||||
/*tag=*/"History"),
|
||||
history_metadata_db_(&db_, &meta_table_) {}
|
||||
|
||||
|
@ -206,7 +206,7 @@ bool TopSitesDatabase::InitImpl(const base::FilePath& db_name) {
|
||||
|
||||
// Settings copied from FaviconDatabase.
|
||||
db_ = std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{.page_size = 4096, .cache_size = 32},
|
||||
sql::DatabaseOptions().set_page_size(4096).set_cache_size(32),
|
||||
sql::Database::Tag("TopSites"));
|
||||
db_->set_error_callback(
|
||||
base::BindRepeating(&TopSitesDatabase::DatabaseErrorCallback,
|
||||
|
@ -34,7 +34,7 @@ std::string CreateRandomSalt() {
|
||||
|
||||
MediaDeviceSaltDatabase::MediaDeviceSaltDatabase(const base::FilePath& db_path)
|
||||
: db_path_(db_path),
|
||||
db_(sql::DatabaseOptions{.page_size = 4096, .cache_size = 16},
|
||||
db_(sql::DatabaseOptions().set_page_size(4096).set_cache_size(16),
|
||||
/*tag=*/"MediaDeviceSalts") {}
|
||||
|
||||
std::optional<std::string> MediaDeviceSaltDatabase::GetOrInsertSalt(
|
||||
|
@ -1109,7 +1109,8 @@ LoginDatabase::LoginDatabase(const base::FilePath& db_path,
|
||||
: db_path_(db_path),
|
||||
is_account_store_(is_account_store),
|
||||
// Set options for a small, private database (based on WebDatabase).
|
||||
db_({.page_size = 2048, .cache_size = 32}, /*tag=*/"Passwords"),
|
||||
db_(sql::DatabaseOptions().set_page_size(2048).set_cache_size(32),
|
||||
/*tag=*/"Passwords"),
|
||||
is_deleting_undecryptable_logins_enabled_by_policy_(can_delete) {}
|
||||
|
||||
LoginDatabase::~LoginDatabase() = default;
|
||||
|
@ -154,7 +154,7 @@ bool SqliteDatabaseTransaction::Commit() {
|
||||
|
||||
PowerBookmarkDatabaseImpl::PowerBookmarkDatabaseImpl(
|
||||
const base::FilePath& database_dir)
|
||||
: db_(sql::DatabaseOptions{.page_size = 4096, .cache_size = 128},
|
||||
: db_(sql::DatabaseOptions().set_page_size(4096).set_cache_size(128),
|
||||
/*tag=*/"PowerBookmarks"),
|
||||
database_path_(database_dir.Append(kDatabaseName)) {
|
||||
sync_db_ =
|
||||
|
@ -114,8 +114,8 @@ UkmDatabaseBackend::UkmDatabaseBackend(
|
||||
: database_path_(database_path),
|
||||
in_memory_(in_memory),
|
||||
callback_task_runner_(callback_task_runner),
|
||||
db_(sql::DatabaseOptions{.wal_mode = base::FeatureList::IsEnabled(
|
||||
kSqlWALModeOnSegmentationDatabase)},
|
||||
db_(sql::DatabaseOptions().set_wal_mode(
|
||||
base::FeatureList::IsEnabled(kSqlWALModeOnSegmentationDatabase)),
|
||||
/*tag=*/"UKMMetrics"),
|
||||
metrics_table_(&db_),
|
||||
url_table_(&db_),
|
||||
|
@ -209,12 +209,13 @@ SharedStorageDatabase::SharedStorageDatabase(
|
||||
base::FilePath db_path,
|
||||
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
|
||||
std::unique_ptr<SharedStorageDatabaseOptions> options)
|
||||
: db_({.wal_mode = base::FeatureList::IsEnabled(
|
||||
blink::features::kSharedStorageAPIEnableWALForDatabase),
|
||||
// We DCHECK that the page size is valid in the constructor for
|
||||
// `SharedStorageOptions`.
|
||||
.page_size = options->max_page_size,
|
||||
.cache_size = options->max_cache_size},
|
||||
: db_(sql::DatabaseOptions()
|
||||
.set_wal_mode(base::FeatureList::IsEnabled(
|
||||
blink::features::kSharedStorageAPIEnableWALForDatabase))
|
||||
// We DCHECK that the page size is valid in the constructor for
|
||||
// `SharedStorageOptions`.
|
||||
.set_page_size(options->max_page_size)
|
||||
.set_cache_size(options->max_cache_size),
|
||||
/*tag=*/"SharedStorage"),
|
||||
db_path_(std::move(db_path)),
|
||||
special_storage_policy_(std::move(special_storage_policy)),
|
||||
|
@ -73,14 +73,16 @@ sql::InitStatus FailedMigrationTo(int version_num) {
|
||||
} // namespace
|
||||
|
||||
WebDatabase::WebDatabase()
|
||||
: db_({.wal_mode = base::FeatureList::IsEnabled(kSqlWALModeOnWebDatabase),
|
||||
// We don't store that much data in the tables so use a small page
|
||||
// size. This provides a large benefit for empty tables (which is
|
||||
// very likely with the tables we create).
|
||||
.page_size = 2048,
|
||||
// We shouldn't have much data and what access we currently have is
|
||||
// quite infrequent. So we go with a small cache size.
|
||||
.cache_size = 32},
|
||||
: db_(sql::DatabaseOptions()
|
||||
.set_wal_mode(
|
||||
base::FeatureList::IsEnabled(kSqlWALModeOnWebDatabase))
|
||||
// We don't store that much data in the tables so use a small page
|
||||
// size. This provides a large benefit for empty tables (which is
|
||||
// very likely with the tables we create).
|
||||
.set_page_size(2048)
|
||||
// We shouldn't have much data and what access we currently have
|
||||
// is quite infrequent. So we go with a small cache size.
|
||||
.set_cache_size(32),
|
||||
/*tag=*/"Web") {}
|
||||
|
||||
WebDatabase::~WebDatabase() {
|
||||
|
@ -157,7 +157,7 @@ AggregationServiceStorageSql::AggregationServiceStorageSql(
|
||||
clock_(*clock),
|
||||
max_stored_requests_per_reporting_origin_(
|
||||
max_stored_requests_per_reporting_origin),
|
||||
db_(sql::DatabaseOptions{.page_size = 4096, .cache_size = 32},
|
||||
db_(sql::DatabaseOptions().set_page_size(4096).set_cache_size(32),
|
||||
/*tag=*/"AggregationService") {
|
||||
DETACH_FROM_SEQUENCE(sequence_checker_);
|
||||
CHECK(clock);
|
||||
|
@ -557,7 +557,7 @@ AttributionStorageSql::AttributionStorageSql(
|
||||
: path_to_database_(user_data_directory.empty()
|
||||
? base::FilePath()
|
||||
: DatabasePath(user_data_directory)),
|
||||
db_(sql::DatabaseOptions{.page_size = 4096, .cache_size = 32},
|
||||
db_(sql::DatabaseOptions().set_page_size(4096).set_cache_size(32),
|
||||
/*tag=*/"Conversions"),
|
||||
delegate_(delegate),
|
||||
rate_limit_table_(delegate_),
|
||||
|
@ -237,7 +237,7 @@ bool BrowsingTopicsSiteDataStorage::LazyInit() {
|
||||
return db_init_status_ == InitStatus::kSuccess;
|
||||
|
||||
db_ = std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{.page_size = 4096, .cache_size = 32},
|
||||
sql::DatabaseOptions().set_page_size(4096).set_cache_size(32),
|
||||
sql::Database::Tag("BrowsingTopics"));
|
||||
|
||||
// base::Unretained is safe here because this BrowsingTopicsSiteDataStorage
|
||||
|
@ -100,13 +100,13 @@ BtmDatabase::BtmDatabase(const std::optional<base::FilePath>& db_path)
|
||||
: db_path_(db_path.value_or(base::FilePath())) {
|
||||
DCHECK(base::FeatureList::IsEnabled(features::kBtm));
|
||||
|
||||
sql::DatabaseOptions db_options{
|
||||
.wal_mode = base::FeatureList::IsEnabled(kSqlWALModeOnDipsDatabase),
|
||||
.page_size = 4096,
|
||||
.cache_size = 32};
|
||||
if (base::FeatureList::IsEnabled(kDisableExclusiveLockingOnDipsDatabase)) {
|
||||
db_options.exclusive_locking = false;
|
||||
}
|
||||
sql::DatabaseOptions db_options =
|
||||
sql::DatabaseOptions()
|
||||
.set_wal_mode(base::FeatureList::IsEnabled(kSqlWALModeOnDipsDatabase))
|
||||
.set_page_size(4096)
|
||||
.set_cache_size(32)
|
||||
.set_exclusive_locking(!base::FeatureList::IsEnabled(
|
||||
kDisableExclusiveLockingOnDipsDatabase));
|
||||
|
||||
db_ = std::make_unique<sql::Database>(db_options, sql::Database::Tag("DIPS"));
|
||||
|
||||
|
@ -750,7 +750,7 @@ bool FirstPartySetsDatabase::LazyInit() {
|
||||
|
||||
CHECK_EQ(db_.get(), nullptr);
|
||||
db_ = std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{.page_size = 4096, .cache_size = 32},
|
||||
sql::DatabaseOptions().set_page_size(4096).set_cache_size(32),
|
||||
sql::Database::Tag("FirstPartySets"));
|
||||
// base::Unretained is safe here because this FirstPartySetsDatabase owns
|
||||
// the sql::Database instance that stores and uses the callback. So,
|
||||
|
@ -5413,9 +5413,8 @@ base::FilePath DBPath(const base::FilePath& base) {
|
||||
}
|
||||
|
||||
sql::DatabaseOptions GetDatabaseOptions() {
|
||||
return sql::DatabaseOptions{
|
||||
.wal_mode = base::FeatureList::IsEnabled(
|
||||
features::kFledgeEnableWALForInterestGroupStorage)};
|
||||
return sql::DatabaseOptions().set_wal_mode(base::FeatureList::IsEnabled(
|
||||
features::kFledgeEnableWALForInterestGroupStorage));
|
||||
}
|
||||
|
||||
void ReportCreateSchemaResult(
|
||||
|
@ -53,7 +53,7 @@ CdmStorageDatabase::CdmStorageDatabase(const base::FilePath& path)
|
||||
// bytes) and that we'll typically only be pulling one file at a time
|
||||
// (playback), specify a large page size to allow inner nodes can pack
|
||||
// many keys, to keep the index B-tree flat.
|
||||
db_(sql::DatabaseOptions{.page_size = 32768, .cache_size = 8},
|
||||
db_(sql::DatabaseOptions().set_page_size(32768).set_cache_size(8),
|
||||
/*tag=*/"CdmStorage") {
|
||||
// base::Unretained is safe because `db_` is owned by `this`
|
||||
db_.set_error_callback(base::BindRepeating(
|
||||
|
@ -96,7 +96,7 @@ class MockCdmStorageDatabaseV1 {
|
||||
public:
|
||||
// The database will be in-memory if `path` is empty.
|
||||
explicit MockCdmStorageDatabaseV1()
|
||||
: db_(sql::DatabaseOptions{.page_size = 32768, .cache_size = 8},
|
||||
: db_(sql::DatabaseOptions().set_page_size(32768).set_cache_size(8),
|
||||
sql::test::kTestTag) {}
|
||||
~MockCdmStorageDatabaseV1() = default;
|
||||
|
||||
|
@ -113,7 +113,7 @@ PrivateAggregationBudgetStorage::PrivateAggregationBudgetStorage(
|
||||
kFlushDelay),
|
||||
db_task_runner_(std::move(db_task_runner)),
|
||||
db_(std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{.page_size = 4096, .cache_size = 32},
|
||||
sql::DatabaseOptions().set_page_size(4096).set_cache_size(32),
|
||||
sql::Database::Tag("PrivateAggregation"))) {}
|
||||
|
||||
PrivateAggregationBudgetStorage::~PrivateAggregationBudgetStorage() {
|
||||
|
@ -89,7 +89,7 @@ ClientTraceReport::ClientTraceReport() = default;
|
||||
ClientTraceReport::~ClientTraceReport() = default;
|
||||
|
||||
TraceReportDatabase::TraceReportDatabase()
|
||||
: database_(sql::DatabaseOptions{.page_size = 4096, .cache_size = 128},
|
||||
: database_(sql::DatabaseOptions().set_page_size(4096).set_cache_size(128),
|
||||
/*tag=*/"LocalTraces") {
|
||||
DETACH_FROM_SEQUENCE(sequence_checker_);
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ bool SQLitePersistentStoreBackendBase::InitializeDatabase() {
|
||||
// TODO(crbug.com/40262972): Remove explicit_locking = false. This currently
|
||||
// needs to be set to false because of several failing MigrationTests.
|
||||
db_ = std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{
|
||||
.exclusive_locking = false,
|
||||
.exclusive_database_file_lock = enable_exclusive_access_},
|
||||
sql::DatabaseOptions()
|
||||
.set_exclusive_locking(false)
|
||||
.set_exclusive_database_file_lock(enable_exclusive_access_),
|
||||
histogram_tag_);
|
||||
|
||||
// base::Unretained is safe because |this| owns (and therefore outlives) the
|
||||
|
@ -90,11 +90,11 @@ NOINLINE TrustTokenDatabaseOwner::TrustTokenDatabaseOwner(
|
||||
db_task_runner)),
|
||||
db_task_runner_(db_task_runner),
|
||||
backing_database_(std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions{
|
||||
sql::DatabaseOptions()
|
||||
// TODO(pwnall): Add a meta table and remove this option.
|
||||
.mmap_alt_status_discouraged = true,
|
||||
.enable_views_discouraged = true, // Required by mmap_alt_status.
|
||||
},
|
||||
.set_mmap_alt_status_discouraged(true)
|
||||
.set_enable_views_discouraged(
|
||||
true), // Required by mmap_alt_status.
|
||||
sql::Database::Tag("TrustTokens"))),
|
||||
issuer_table_(
|
||||
std::make_unique<sqlite_proto::KeyValueTable<TrustTokenIssuerConfig>>(
|
||||
|
@ -218,6 +218,9 @@ void RecordOpenDatabaseFailureReason(const std::string& histogram_tag,
|
||||
|
||||
} // namespace
|
||||
|
||||
DatabaseOptions::DatabaseOptions() = default;
|
||||
DatabaseOptions::~DatabaseOptions() = default;
|
||||
|
||||
// static
|
||||
Database::ScopedErrorExpecterCallback* Database::current_expecter_cb_ = nullptr;
|
||||
|
||||
@ -351,12 +354,12 @@ Database::Database(DatabaseOptions options, Database::Tag tag)
|
||||
mmap_disabled_(!enable_mmap_by_default_),
|
||||
histogram_tag_(tag.value),
|
||||
tracing_track_name_(base::StrCat({"Database: ", histogram_tag_})) {
|
||||
DCHECK_GE(options.page_size, 512);
|
||||
DCHECK_LE(options.page_size, 65536);
|
||||
DCHECK(!(options.page_size & (options.page_size - 1)))
|
||||
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";
|
||||
DCHECK(!options_.mmap_alt_status_discouraged ||
|
||||
options_.enable_views_discouraged)
|
||||
DCHECK(!options_.mmap_alt_status_discouraged_ ||
|
||||
options_.enable_views_discouraged_)
|
||||
<< "mmap_alt_status requires views";
|
||||
|
||||
// It's valid to construct a database on a sequence and then pass it to a
|
||||
@ -513,7 +516,7 @@ void Database::Preload() {
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK(!options_.exclusive_database_file_lock)
|
||||
CHECK(!options_.exclusive_database_file_lock_)
|
||||
<< "Cannot preload an exclusively locked database.";
|
||||
|
||||
std::optional<base::ScopedBlockingCall> scoped_blocking_call;
|
||||
@ -882,7 +885,7 @@ size_t Database::ComputeMmapSizeForOpen() {
|
||||
// sql::MetaTable, otherwise it is tracked in a special view.
|
||||
// TODO(pwnall): Migrate all databases to using a meta table.
|
||||
int64_t mmap_ofs = 0;
|
||||
if (options_.mmap_alt_status_discouraged) {
|
||||
if (options_.mmap_alt_status_discouraged_) {
|
||||
if (!GetMmapAltStatus(&mmap_ofs)) {
|
||||
return 0;
|
||||
}
|
||||
@ -973,7 +976,7 @@ size_t Database::ComputeMmapSizeForOpen() {
|
||||
DCHECK(mmap_ofs > 0 || mmap_ofs == MetaTable::kMmapFailure);
|
||||
}
|
||||
|
||||
if (options_.mmap_alt_status_discouraged) {
|
||||
if (options_.mmap_alt_status_discouraged_) {
|
||||
if (!SetMmapAltStatus(mmap_ofs)) {
|
||||
return 0;
|
||||
}
|
||||
@ -1099,13 +1102,11 @@ bool Database::Raze() {
|
||||
return false;
|
||||
}
|
||||
|
||||
sql::Database null_db(
|
||||
sql::DatabaseOptions{
|
||||
.exclusive_locking = true,
|
||||
.page_size = options_.page_size,
|
||||
.cache_size = 0,
|
||||
.enable_views_discouraged = options_.enable_views_discouraged,
|
||||
},
|
||||
Database null_db(
|
||||
DatabaseOptions()
|
||||
.set_exclusive_locking(true)
|
||||
.set_page_size(options_.page_size_)
|
||||
.set_enable_views_discouraged(options_.enable_views_discouraged_),
|
||||
"RazeNullDB");
|
||||
if (!null_db.OpenInMemory()) {
|
||||
DLOG(FATAL) << "Unable to open in-memory database.";
|
||||
@ -1189,7 +1190,7 @@ bool Database::Raze() {
|
||||
// database connection open.
|
||||
std::ignore = Execute("PRAGMA journal_mode=TRUNCATE;");
|
||||
const std::string page_size_sql = base::StrCat(
|
||||
{"PRAGMA page_size=", base::NumberToString(options_.page_size)});
|
||||
{"PRAGMA page_size=", base::NumberToString(options_.page_size_)});
|
||||
if (!Execute(page_size_sql)) {
|
||||
return false;
|
||||
}
|
||||
@ -1989,7 +1990,7 @@ bool Database::OpenInternal(const std::string& db_file_path) {
|
||||
int open_flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
|
||||
SQLITE_OPEN_EXRESCODE | SQLITE_OPEN_PRIVATECACHE;
|
||||
std::string uri_file_path = db_file_path;
|
||||
if (options_.exclusive_database_file_lock) {
|
||||
if (options_.exclusive_database_file_lock_) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
const bool in_memory = db_file_path == kSqliteOpenInMemoryPath;
|
||||
if (!in_memory) {
|
||||
@ -2026,7 +2027,7 @@ bool Database::OpenInternal(const std::string& db_file_path) {
|
||||
for (int i = 1; i <= kMaxOpenAttempts; ++i) {
|
||||
sqlite_result_code = ToSqliteResultCode(
|
||||
sqlite3_open_v2(uri_file_path.c_str(), &db, open_flags,
|
||||
options_.vfs_name_discouraged));
|
||||
options_.vfs_name_discouraged_));
|
||||
if (sqlite_result_code != sql::SqliteResultCode::kBusy) {
|
||||
// Record how many iterations were required to open the database. The
|
||||
// histogram is not emitted if sqlite3_open_v2(...) fails.
|
||||
@ -2088,7 +2089,7 @@ bool Database::OpenInternal(const std::string& db_file_path) {
|
||||
static_assert(
|
||||
SQLITE_DEFAULT_LOCKING_MODE == 1,
|
||||
"Chrome assumes SQLite is configured to default to EXCLUSIVE locking");
|
||||
if (!options_.exclusive_locking) {
|
||||
if (!options_.exclusive_locking_) {
|
||||
if (!Execute("PRAGMA locking_mode=NORMAL")) {
|
||||
RecordOpenDatabaseFailureReason(
|
||||
histogram_tag_, OpenDatabaseFailedReason::kLockingModeFailed);
|
||||
@ -2132,7 +2133,7 @@ bool Database::OpenInternal(const std::string& db_file_path) {
|
||||
// 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", options_.page_size);
|
||||
base::StringPrintf("PRAGMA page_size=%d", options_.page_size_);
|
||||
if (!ExecuteWithTimeout(page_size_sql, kBusyTimeout)) {
|
||||
RecordOpenDatabaseFailureReason(histogram_tag_,
|
||||
OpenDatabaseFailedReason::kPageSizeFailed);
|
||||
@ -2197,13 +2198,13 @@ bool Database::OpenInternal(const std::string& db_file_path) {
|
||||
}
|
||||
CHECK(db_);
|
||||
|
||||
if (options_.flush_to_media) {
|
||||
if (options_.flush_to_media_) {
|
||||
std::ignore = Execute("PRAGMA fullfsync=1");
|
||||
}
|
||||
|
||||
if (options_.cache_size != 0) {
|
||||
if (options_.cache_size_ != 0) {
|
||||
const std::string cache_size_sql = base::StrCat(
|
||||
{"PRAGMA cache_size=", base::NumberToString(options_.cache_size)});
|
||||
{"PRAGMA cache_size=", base::NumberToString(options_.cache_size_)});
|
||||
std::ignore = ExecuteWithTimeout(cache_size_sql, kBusyTimeout);
|
||||
}
|
||||
|
||||
@ -2302,7 +2303,7 @@ void Database::ConfigureSqliteDatabaseObject() {
|
||||
|
||||
sqlite_result_code = ToSqliteResultCode(
|
||||
sqlite3_db_config(db_, SQLITE_DBCONFIG_ENABLE_VIEW,
|
||||
options_.enable_views_discouraged ? 1 : 0, nullptr));
|
||||
options_.enable_views_discouraged_ ? 1 : 0, nullptr));
|
||||
DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
|
||||
<< "sqlite3_db_config() should not fail";
|
||||
}
|
||||
@ -2521,9 +2522,9 @@ bool Database::UseWALMode() const {
|
||||
// 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 options_.wal_mode && options_.exclusive_locking;
|
||||
return options_.wal_mode_ && options_.exclusive_locking_;
|
||||
#else
|
||||
return options_.wal_mode;
|
||||
return options_.wal_mode_;
|
||||
#endif // BUILDFLAG(IS_FUCHSIA)
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,9 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
// Guaranteed to match SQLITE_DEFAULT_PAGE_SIZE.
|
||||
static constexpr int kDefaultPageSize = 4096;
|
||||
|
||||
DatabaseOptions();
|
||||
~DatabaseOptions();
|
||||
|
||||
// If true, the database can only be opened by one process at a time.
|
||||
//
|
||||
// SQLite supports a locking protocol that allows multiple processes to safely
|
||||
@ -93,7 +96,10 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
// Exclusive mode is strongly recommended. It reduces the I/O cost of setting
|
||||
// up a transaction. It also removes the need of handling transaction failures
|
||||
// due to lock contention.
|
||||
bool exclusive_locking = true;
|
||||
DatabaseOptions& set_exclusive_locking(bool exclusive_locking) {
|
||||
exclusive_locking_ = exclusive_locking;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// If true, enables exclusive=true vfs URI parameter on the database file.
|
||||
// This is only supported on Windows.
|
||||
@ -112,7 +118,11 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
// This option is experimental and will be merged into the `exclusive_locking`
|
||||
// option above if proven to cause no OS compatibility issues.
|
||||
// TODO(crbug.com/40262539): Merge into above option, if possible.
|
||||
bool exclusive_database_file_lock = false;
|
||||
DatabaseOptions& set_exclusive_database_file_lock(
|
||||
bool exclusive_database_file_lock) {
|
||||
exclusive_database_file_lock_ = exclusive_database_file_lock;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// If true, enables SQLite's Write-Ahead Logging (WAL).
|
||||
//
|
||||
@ -127,8 +137,10 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
// 'PRAGMA page_size = <new-size>' will result in no-ops.
|
||||
//
|
||||
// More details at https://www.sqlite.org/wal.html
|
||||
bool wal_mode =
|
||||
base::FeatureList::IsEnabled(sql::features::kEnableWALModeByDefault);
|
||||
DatabaseOptions& set_wal_mode(bool wal_mode) {
|
||||
wal_mode_ = wal_mode;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// If true, transaction commit waits for data to reach persistent media.
|
||||
//
|
||||
@ -148,7 +160,10 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
// until the data is written to the persistent media. This guarantees
|
||||
// durability in the event of power loss, which is needed to guarantee the
|
||||
// integrity of non-WAL databases.
|
||||
bool flush_to_media = false;
|
||||
DatabaseOptions& set_flush_to_media(bool flush_to_media) {
|
||||
flush_to_media_ = flush_to_media;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Database page size.
|
||||
//
|
||||
@ -164,7 +179,10 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
// more I/O when making small changes to existing records.
|
||||
//
|
||||
// Must be a power of two between 512 and 65536 inclusive.
|
||||
int page_size = kDefaultPageSize;
|
||||
DatabaseOptions& set_page_size(int page_size) {
|
||||
page_size_ = page_size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// The size of in-memory cache, in pages.
|
||||
//
|
||||
@ -173,7 +191,10 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
//
|
||||
// 0 invokes SQLite's default, which is currently to size up the cache to use
|
||||
// exactly 2,048,000 bytes of RAM.
|
||||
int cache_size = 0;
|
||||
DatabaseOptions& set_cache_size(int cache_size) {
|
||||
cache_size_ = cache_size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Stores mmap failures in the SQL schema, instead of the meta table.
|
||||
//
|
||||
@ -183,7 +204,11 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
// If this option is true, the mmap status is stored in the database schema.
|
||||
// Like any other schema change, changing the mmap status invalidates all
|
||||
// pre-compiled SQL statements.
|
||||
bool mmap_alt_status_discouraged = false;
|
||||
DatabaseOptions& set_mmap_alt_status_discouraged(
|
||||
bool mmap_alt_status_discouraged) {
|
||||
mmap_alt_status_discouraged_ = mmap_alt_status_discouraged;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// If true, enables SQL views (a discouraged feature) for this database.
|
||||
//
|
||||
@ -192,13 +217,37 @@ struct COMPONENT_EXPORT(SQL) DatabaseOptions {
|
||||
//
|
||||
// If this option is false, CREATE VIEW and DROP VIEW succeed, but SELECT
|
||||
// statements targeting views fail.
|
||||
bool enable_views_discouraged = false;
|
||||
DatabaseOptions& set_enable_views_discouraged(bool enable_views_discouraged) {
|
||||
enable_views_discouraged_ = enable_views_discouraged;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// If non-null, specifies the vfs implementation for the database to look for.
|
||||
// Most use-cases do not require the use of a
|
||||
// VFS(https://www.sqlite.org/vfs.html). This option should only be used when
|
||||
// there is a clear need for it.
|
||||
const char* vfs_name_discouraged = nullptr;
|
||||
DatabaseOptions& set_vfs_name_discouraged(const char* vfs_name_discouraged) {
|
||||
vfs_name_discouraged_ = vfs_name_discouraged;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Database;
|
||||
FRIEND_TEST_ALL_PREFIXES(DatabaseOptionsTest,
|
||||
EnableViewsDiscouraged_FalseByDefault);
|
||||
FRIEND_TEST_ALL_PREFIXES(DatabaseOptionsTest, FlushToDisk_FalseByDefault);
|
||||
FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest, ReOpenWithDifferentJournalMode);
|
||||
|
||||
bool exclusive_locking_ = true;
|
||||
bool exclusive_database_file_lock_ = false;
|
||||
bool wal_mode_ =
|
||||
base::FeatureList::IsEnabled(sql::features::kEnableWALModeByDefault);
|
||||
bool flush_to_media_ = false;
|
||||
int page_size_ = kDefaultPageSize;
|
||||
int cache_size_ = 0;
|
||||
bool mmap_alt_status_discouraged_ = false;
|
||||
bool enable_views_discouraged_ = false;
|
||||
const char* vfs_name_discouraged_ = nullptr;
|
||||
};
|
||||
|
||||
// Holds database diagnostics in a structured format.
|
||||
@ -324,7 +373,7 @@ class COMPONENT_EXPORT(SQL) Database {
|
||||
// Pre-init configuration ----------------------------------------------------
|
||||
|
||||
// The page size that will be used when creating a new database.
|
||||
int page_size() const { return options_.page_size; }
|
||||
int page_size() const { return options_.page_size_; }
|
||||
|
||||
// Returns whether a database will be opened in WAL mode.
|
||||
bool UseWALMode() const;
|
||||
|
@ -25,6 +25,8 @@ enum class OpenVariant {
|
||||
kOnDiskExclusiveWal = 4,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// We use the parameter to run all tests with WAL mode on and off.
|
||||
class DatabaseOptionsTest : public testing::TestWithParam<OpenVariant> {
|
||||
public:
|
||||
@ -89,11 +91,10 @@ class DatabaseOptionsTest : public testing::TestWithParam<OpenVariant> {
|
||||
};
|
||||
|
||||
TEST_P(DatabaseOptionsTest, FlushToDisk_FalseByDefault) {
|
||||
DatabaseOptions options = {
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
};
|
||||
EXPECT_FALSE(options.flush_to_media) << "Invalid test assumption";
|
||||
DatabaseOptions options = DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode());
|
||||
EXPECT_FALSE(options.flush_to_media_) << "Invalid test assumption";
|
||||
|
||||
Database db(options, test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
@ -102,26 +103,22 @@ TEST_P(DatabaseOptionsTest, FlushToDisk_FalseByDefault) {
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, FlushToDisk_True) {
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.flush_to_media = true,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_flush_to_media(true),
|
||||
test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
|
||||
EXPECT_EQ("1", sql::test::ExecuteWithResult(&db, "PRAGMA fullfsync"));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, FlushToDisk_False_DoesNotCrash) {
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.flush_to_media = false,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_flush_to_media(false),
|
||||
test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
|
||||
EXPECT_EQ("0", sql::test::ExecuteWithResult(&db, "PRAGMA fullfsync"))
|
||||
@ -130,13 +127,11 @@ TEST_P(DatabaseOptionsTest, FlushToDisk_False_DoesNotCrash) {
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, FlushToDisk_True_DoesNotCrash) {
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.flush_to_media = true,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_flush_to_media(true),
|
||||
test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
|
||||
EXPECT_EQ("1", sql::test::ExecuteWithResult(&db, "PRAGMA fullfsync"))
|
||||
@ -147,13 +142,11 @@ TEST_P(DatabaseOptionsTest, FlushToDisk_True_DoesNotCrash) {
|
||||
TEST_P(DatabaseOptionsTest, PageSize_Default) {
|
||||
static_assert(DatabaseOptions::kDefaultPageSize == 4096,
|
||||
"The page size numbers in this test file need to change");
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.page_size = 4096,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_page_size(4096),
|
||||
test::kTestTag);
|
||||
|
||||
OpenDatabase(db);
|
||||
EXPECT_EQ("4096", sql::test::ExecuteWithResult(&db, "PRAGMA page_size"));
|
||||
@ -168,13 +161,11 @@ TEST_P(DatabaseOptionsTest, PageSize_Default) {
|
||||
TEST_P(DatabaseOptionsTest, PageSize_Large) {
|
||||
static_assert(DatabaseOptions::kDefaultPageSize < 16384,
|
||||
"The page size numbers in this test file need to change");
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.page_size = 16384,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_page_size(16384),
|
||||
test::kTestTag);
|
||||
|
||||
OpenDatabase(db);
|
||||
EXPECT_EQ("16384", sql::test::ExecuteWithResult(&db, "PRAGMA page_size"));
|
||||
@ -189,13 +180,11 @@ TEST_P(DatabaseOptionsTest, PageSize_Large) {
|
||||
TEST_P(DatabaseOptionsTest, PageSize_Small) {
|
||||
static_assert(DatabaseOptions::kDefaultPageSize > 1024,
|
||||
"The page size numbers in this test file need to change");
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.page_size = 1024,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_page_size(1024),
|
||||
test::kTestTag);
|
||||
|
||||
OpenDatabase(db);
|
||||
EXPECT_EQ("1024", sql::test::ExecuteWithResult(&db, "PRAGMA page_size"));
|
||||
@ -208,48 +197,41 @@ TEST_P(DatabaseOptionsTest, PageSize_Small) {
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, CacheSize_Legacy) {
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.cache_size = 0,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_cache_size(0),
|
||||
test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
|
||||
EXPECT_EQ("-2000", sql::test::ExecuteWithResult(&db, "PRAGMA cache_size"));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, CacheSize_Small) {
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.cache_size = 16,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_cache_size(16),
|
||||
test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
EXPECT_EQ("16", sql::test::ExecuteWithResult(&db, "PRAGMA cache_size"));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, CacheSize_Large) {
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.cache_size = 1000,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_cache_size(1000),
|
||||
test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
EXPECT_EQ("1000", sql::test::ExecuteWithResult(&db, "PRAGMA cache_size"));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, EnableViewsDiscouraged_FalseByDefault) {
|
||||
DatabaseOptions options = {
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
};
|
||||
EXPECT_FALSE(options.enable_views_discouraged) << "Invalid test assumption";
|
||||
DatabaseOptions options = DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode());
|
||||
EXPECT_FALSE(options.enable_views_discouraged_) << "Invalid test assumption";
|
||||
|
||||
Database db(options, test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
@ -272,13 +254,11 @@ TEST_P(DatabaseOptionsTest, EnableViewsDiscouraged_FalseByDefault) {
|
||||
}
|
||||
|
||||
TEST_P(DatabaseOptionsTest, EnableViewsDiscouraged_True) {
|
||||
Database db(
|
||||
DatabaseOptions{
|
||||
.exclusive_locking = exclusive_locking(),
|
||||
.wal_mode = wal_mode(),
|
||||
.enable_views_discouraged = true,
|
||||
},
|
||||
test::kTestTag);
|
||||
Database db(DatabaseOptions()
|
||||
.set_exclusive_locking(exclusive_locking())
|
||||
.set_wal_mode(wal_mode())
|
||||
.set_enable_views_discouraged(true),
|
||||
test::kTestTag);
|
||||
OpenDatabase(db);
|
||||
|
||||
ASSERT_TRUE(db.Execute("CREATE VIEW view(id) AS SELECT 1"));
|
||||
@ -299,6 +279,4 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
OpenVariant::kOnDiskNonExclusiveJournal,
|
||||
OpenVariant::kOnDiskExclusiveWal));
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace sql
|
||||
|
@ -147,18 +147,16 @@ class SQLDatabaseTest : public testing::Test,
|
||||
}
|
||||
|
||||
DatabaseOptions GetDBOptions() {
|
||||
DatabaseOptions options;
|
||||
options.wal_mode = IsWALEnabled();
|
||||
return DatabaseOptions()
|
||||
.set_wal_mode(IsWALEnabled())
|
||||
// TODO(crbug.com/40146017): Remove after switching to exclusive mode on by
|
||||
// default.
|
||||
options.exclusive_locking = false;
|
||||
#if BUILDFLAG(IS_FUCHSIA) // Exclusive mode needs to be enabled to enter WAL
|
||||
// mode on Fuchsia
|
||||
if (IsWALEnabled()) {
|
||||
options.exclusive_locking = true;
|
||||
}
|
||||
.set_exclusive_locking(IsWALEnabled())
|
||||
#else
|
||||
.set_exclusive_locking(false)
|
||||
#endif // BUILDFLAG(IS_FUCHSIA)
|
||||
return options;
|
||||
;
|
||||
}
|
||||
|
||||
bool IsWALEnabled() { return GetParam(); }
|
||||
@ -706,8 +704,7 @@ TEST_P(SQLDatabaseTest, UseVfs) {
|
||||
sqlite3_vfs_register(&vfs, /*makeDflt=*/false);
|
||||
absl::Cleanup vfs_unregisterer = [&vfs]() { sqlite3_vfs_unregister(&vfs); };
|
||||
|
||||
DatabaseOptions options = GetDBOptions();
|
||||
options.vfs_name_discouraged = kVFSName;
|
||||
DatabaseOptions options = GetDBOptions().set_vfs_name_discouraged(kVFSName);
|
||||
Database other_db(options, test::kTestTag);
|
||||
|
||||
// Since the vfs's Open function is not implemented `Open()` will fail.
|
||||
@ -1050,7 +1047,8 @@ void TestPageSize(const base::FilePath& db_prefix,
|
||||
const base::FilePath db_path = db_prefix.InsertBeforeExtensionASCII(
|
||||
base::NumberToString(initial_page_size));
|
||||
Database::Delete(db_path);
|
||||
Database db({.page_size = initial_page_size}, test::kTestTag);
|
||||
Database db(DatabaseOptions().set_page_size(initial_page_size),
|
||||
test::kTestTag);
|
||||
ASSERT_TRUE(db.Open(db_path));
|
||||
ASSERT_TRUE(db.Execute(kCreateSql));
|
||||
ASSERT_TRUE(db.Execute(kInsertSql1));
|
||||
@ -1060,7 +1058,8 @@ void TestPageSize(const base::FilePath& db_prefix,
|
||||
db.Close();
|
||||
|
||||
// Re-open the database while setting a new |options.page_size| in the object.
|
||||
Database razed_db({.page_size = final_page_size}, test::kTestTag);
|
||||
Database razed_db(DatabaseOptions().set_page_size(final_page_size),
|
||||
test::kTestTag);
|
||||
ASSERT_TRUE(razed_db.Open(db_path));
|
||||
// Raze will use the page size set in the connection object, which may not
|
||||
// match the file's page size.
|
||||
@ -1938,9 +1937,9 @@ TEST_P(SQLDatabaseTest, MmapInitiallyEnabledAltStatus) {
|
||||
db_->Close();
|
||||
Database::Delete(db_path_);
|
||||
|
||||
DatabaseOptions options = GetDBOptions();
|
||||
options.mmap_alt_status_discouraged = true;
|
||||
options.enable_views_discouraged = true;
|
||||
DatabaseOptions options = GetDBOptions()
|
||||
.set_mmap_alt_status_discouraged(true)
|
||||
.set_enable_views_discouraged(true);
|
||||
db_ = std::make_unique<Database>(options, test::kTestTag);
|
||||
ASSERT_TRUE(db_->Open(db_path_));
|
||||
|
||||
@ -2023,9 +2022,9 @@ TEST_P(SQLDatabaseTest, ComputeMmapSizeForOpenAltStatus) {
|
||||
ASSERT_FALSE(db_->DoesViewExist("MmapStatus"));
|
||||
|
||||
// Using alt status, everything should be mapped, with state in the view.
|
||||
DatabaseOptions options = GetDBOptions();
|
||||
options.mmap_alt_status_discouraged = true;
|
||||
options.enable_views_discouraged = true;
|
||||
DatabaseOptions options = GetDBOptions()
|
||||
.set_mmap_alt_status_discouraged(true)
|
||||
.set_enable_views_discouraged(true);
|
||||
db_ = std::make_unique<Database>(options, test::kTestTag);
|
||||
ASSERT_TRUE(db_->Open(db_path_));
|
||||
|
||||
@ -2189,14 +2188,14 @@ TEST_P(SQLDatabaseTest, ReOpenWithDifferentJournalMode) {
|
||||
}
|
||||
|
||||
// Re-open the database with a different mode (Rollback vs WAL).
|
||||
DatabaseOptions options = GetDBOptions();
|
||||
options.wal_mode = !is_wal;
|
||||
DatabaseOptions options =
|
||||
GetDBOptions()
|
||||
.set_wal_mode(!is_wal)
|
||||
#if BUILDFLAG(IS_FUCHSIA)
|
||||
// Exclusive mode needs to be enabled to enter WAL mode on Fuchsia.
|
||||
if (options.wal_mode) {
|
||||
options.exclusive_locking = true;
|
||||
}
|
||||
// Exclusive mode needs to be enabled to enter WAL mode on Fuchsia.
|
||||
.set_exclusive_locking(!is_wal)
|
||||
#endif // BUILDFLAG(IS_FUCHSIA)
|
||||
;
|
||||
|
||||
db_ = std::make_unique<Database>(options, test::kTestTag);
|
||||
ASSERT_TRUE(db_->Open(db_path_));
|
||||
@ -2210,8 +2209,8 @@ TEST_P(SQLDatabaseTest, ReOpenWithDifferentJournalMode) {
|
||||
}
|
||||
|
||||
// Ensure appropriate journal file exists.
|
||||
EXPECT_TRUE(IsOpenedInCorrectJournalMode(db_.get(), options.wal_mode));
|
||||
EXPECT_EQ(base::PathExists(wal_path), options.wal_mode);
|
||||
EXPECT_TRUE(IsOpenedInCorrectJournalMode(db_.get(), options.wal_mode_));
|
||||
EXPECT_EQ(base::PathExists(wal_path), options.wal_mode_);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
@ -2230,11 +2229,10 @@ class SQLDatabaseTestExclusiveFileLockMode
|
||||
}
|
||||
|
||||
DatabaseOptions GetDBOptions() {
|
||||
DatabaseOptions options;
|
||||
options.wal_mode = IsWALEnabled();
|
||||
options.exclusive_locking = true;
|
||||
options.exclusive_database_file_lock = IsExclusivelockEnabled();
|
||||
return options;
|
||||
return DatabaseOptions()
|
||||
.set_wal_mode(IsWALEnabled())
|
||||
.set_exclusive_locking(true)
|
||||
.set_exclusive_database_file_lock(IsExclusivelockEnabled());
|
||||
}
|
||||
|
||||
bool IsWALEnabled() { return std::get<0>(GetParam()); }
|
||||
@ -2276,7 +2274,8 @@ TEST(SQLInvalidDatabaseFlagsDeathTest, ExclusiveDatabaseLock) {
|
||||
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
|
||||
auto db_path = temp_dir.GetPath().AppendASCII("database_test_locked.sqlite");
|
||||
|
||||
Database db({.exclusive_database_file_lock = true}, test::kTestTag);
|
||||
Database db(DatabaseOptions().set_exclusive_database_file_lock(true),
|
||||
test::kTestTag);
|
||||
|
||||
EXPECT_CHECK_DEATH_WITH(
|
||||
{ std::ignore = db.Open(db_path); },
|
||||
@ -2298,10 +2297,9 @@ class SQLDatabaseTestExclusiveMode : public testing::Test,
|
||||
}
|
||||
|
||||
DatabaseOptions GetDBOptions() {
|
||||
DatabaseOptions options;
|
||||
options.wal_mode = IsWALEnabled();
|
||||
options.exclusive_locking = true;
|
||||
return options;
|
||||
return DatabaseOptions()
|
||||
.set_wal_mode(IsWALEnabled())
|
||||
.set_exclusive_locking(true);
|
||||
}
|
||||
|
||||
bool IsWALEnabled() { return GetParam(); }
|
||||
|
@ -278,9 +278,9 @@ DEFINE_PROTO_FUZZER(const sql_fuzzers::RecoveryFuzzerTestCase& fuzzer_input) {
|
||||
std::cout << test_case;
|
||||
}
|
||||
|
||||
sql::DatabaseOptions database_options;
|
||||
database_options.wal_mode = test_case.wal_mode();
|
||||
sql::Database database(database_options, sql::test::kTestTag);
|
||||
sql::Database database(
|
||||
sql::DatabaseOptions().set_wal_mode(test_case.wal_mode()),
|
||||
sql::test::kTestTag);
|
||||
CHECK(database.Open(env.db_path()));
|
||||
|
||||
// Bootstrap the database with SQL queries derived from `fuzzer_input`.
|
||||
|
@ -74,10 +74,7 @@ Recovery::Recovery(Database* database, Strategy strategy)
|
||||
: strategy_(strategy),
|
||||
db_(database),
|
||||
recover_db_(
|
||||
sql::DatabaseOptions{
|
||||
.page_size = database ? database->page_size() : 0,
|
||||
.cache_size = 0,
|
||||
},
|
||||
DatabaseOptions().set_page_size(database ? database->page_size() : 0),
|
||||
"Recovery") {
|
||||
CHECK(db_);
|
||||
CHECK(db_->is_open());
|
||||
|
@ -47,8 +47,8 @@ namespace sql {
|
||||
|
||||
namespace {
|
||||
|
||||
using sql::test::ExecuteWithResult;
|
||||
using sql::test::ExecuteWithResults;
|
||||
using test::ExecuteWithResult;
|
||||
using test::ExecuteWithResults;
|
||||
|
||||
constexpr char kRecoveryResultHistogramName[] = "Sql.Recovery.Result";
|
||||
constexpr char kRecoveryResultCodeHistogramName[] = "Sql.Recovery.ResultCode";
|
||||
@ -68,7 +68,7 @@ class SqlRecoveryTest : public testing::Test,
|
||||
public testing::WithParamInterface<bool> {
|
||||
public:
|
||||
SqlRecoveryTest()
|
||||
: db_(DatabaseOptions{.wal_mode = ShouldEnableWal()}, test::kTestTag) {
|
||||
: db_(DatabaseOptions().set_wal_mode(ShouldEnableWal()), test::kTestTag) {
|
||||
scoped_feature_list_.InitWithFeatureStates(
|
||||
{{features::kEnableWALModeByDefault, ShouldEnableWal()}});
|
||||
}
|
||||
@ -160,7 +160,7 @@ TEST_P(SqlRecoveryTest, RecoverCorruptIndex) {
|
||||
ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(8, 8)"));
|
||||
|
||||
db_.Close();
|
||||
ASSERT_TRUE(sql::test::CorruptIndexRootPage(db_path_, "rows_index"));
|
||||
ASSERT_TRUE(test::CorruptIndexRootPage(db_path_, "rows_index"));
|
||||
ASSERT_TRUE(Reopen());
|
||||
|
||||
int error = SQLITE_OK;
|
||||
@ -238,7 +238,7 @@ TEST_P(SqlRecoveryTest, RecoverCorruptTable) {
|
||||
<< "Page overflow relies on specific size";
|
||||
large_buffer.resize(kDbPageSize * 2);
|
||||
std::ranges::fill(large_buffer, '8');
|
||||
sql::Statement insert(db_.GetUniqueStatement(
|
||||
Statement insert(db_.GetUniqueStatement(
|
||||
"INSERT INTO rows(indexed,unindexed,filler) VALUES(8,8,?)"));
|
||||
insert.BindBlob(0, large_buffer);
|
||||
ASSERT_TRUE(insert.Run());
|
||||
@ -259,7 +259,7 @@ TEST_P(SqlRecoveryTest, RecoverCorruptTable) {
|
||||
}
|
||||
|
||||
{
|
||||
sql::test::ScopedErrorExpecter expecter;
|
||||
test::ScopedErrorExpecter expecter;
|
||||
expecter.ExpectError(SQLITE_CORRUPT);
|
||||
ASSERT_FALSE(Reopen());
|
||||
EXPECT_TRUE(expecter.SawExpectedErrors());
|
||||
@ -630,7 +630,8 @@ TEST_P(SqlRecoveryTest, RecoverIfPossibleWithPerDatabaseUma) {
|
||||
|
||||
TEST_P(SqlRecoveryTest, RecoverDatabaseWithView) {
|
||||
db_.Close();
|
||||
sql::Database db({.enable_views_discouraged = true}, test::kTestTag);
|
||||
Database db(DatabaseOptions().set_enable_views_discouraged(true),
|
||||
test::kTestTag);
|
||||
ASSERT_TRUE(db.Open(db_path_));
|
||||
|
||||
ASSERT_TRUE(db.Execute(
|
||||
@ -685,7 +686,7 @@ TEST_P(SqlRecoveryTest, RecoverDatabaseDelete) {
|
||||
ASSERT_TRUE(OverwriteDatabaseHeader());
|
||||
|
||||
{
|
||||
sql::test::ScopedErrorExpecter expecter;
|
||||
test::ScopedErrorExpecter expecter;
|
||||
expecter.ExpectError(SQLITE_NOTADB);
|
||||
|
||||
// Reopen() here because it will see SQLITE_NOTADB.
|
||||
@ -727,13 +728,13 @@ TEST_P(SqlRecoveryTest, BeginRecoverDatabase) {
|
||||
ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(8, 8)"));
|
||||
|
||||
db_.Close();
|
||||
ASSERT_TRUE(sql::test::CorruptIndexRootPage(db_path_, "rows_index"));
|
||||
ASSERT_TRUE(test::CorruptIndexRootPage(db_path_, "rows_index"));
|
||||
ASSERT_TRUE(Reopen());
|
||||
|
||||
static const char kIndexedCountSql[] =
|
||||
"SELECT SUM(indexed) FROM rows INDEXED BY rows_index";
|
||||
{
|
||||
sql::test::ScopedErrorExpecter expecter;
|
||||
test::ScopedErrorExpecter expecter;
|
||||
expecter.ExpectError(SQLITE_CORRUPT);
|
||||
EXPECT_EQ("", ExecuteWithResult(&db_, kIndexedCountSql))
|
||||
<< "Index should still be corrupted after recovery rollback";
|
||||
@ -760,7 +761,7 @@ TEST_P(SqlRecoveryTest, AttachFailure) {
|
||||
ASSERT_TRUE(OverwriteDatabaseHeader());
|
||||
|
||||
{
|
||||
sql::test::ScopedErrorExpecter expecter;
|
||||
test::ScopedErrorExpecter expecter;
|
||||
expecter.ExpectError(SQLITE_NOTADB);
|
||||
|
||||
// Reopen() here because it will see SQLITE_NOTADB.
|
||||
@ -797,7 +798,8 @@ void TestPageSize(const base::FilePath& db_prefix,
|
||||
const base::FilePath db_path = db_prefix.InsertBeforeExtensionASCII(
|
||||
base::NumberToString(initial_page_size));
|
||||
Database::Delete(db_path);
|
||||
Database db({.page_size = initial_page_size}, test::kTestTag);
|
||||
Database db{DatabaseOptions().set_page_size(initial_page_size),
|
||||
test::kTestTag};
|
||||
ASSERT_TRUE(db.Open(db_path));
|
||||
ASSERT_TRUE(db.Execute(kCreateSql));
|
||||
ASSERT_TRUE(db.Execute(kInsertSql1));
|
||||
@ -807,7 +809,8 @@ void TestPageSize(const base::FilePath& db_prefix,
|
||||
db.Close();
|
||||
|
||||
// Re-open the database while setting a new |options.page_size| in the object.
|
||||
Database recover_db({.page_size = final_page_size}, test::kTestTag);
|
||||
Database recover_db(DatabaseOptions().set_page_size(final_page_size),
|
||||
test::kTestTag);
|
||||
ASSERT_TRUE(recover_db.Open(db_path));
|
||||
// Recovery will use the page size set in the database object, which may not
|
||||
// match the file's page size.
|
||||
@ -819,8 +822,7 @@ void TestPageSize(const base::FilePath& db_prefix,
|
||||
recover_db.Close();
|
||||
|
||||
// Make sure the page size is read from the file.
|
||||
Database recovered_db({.page_size = DatabaseOptions::kDefaultPageSize},
|
||||
test::kTestTag);
|
||||
Database recovered_db(test::kTestTag);
|
||||
ASSERT_TRUE(recovered_db.Open(db_path));
|
||||
ASSERT_EQ(expected_final_page_size,
|
||||
ExecuteWithResult(&recovered_db, "PRAGMA page_size"));
|
||||
@ -901,7 +903,7 @@ TEST_P(SqlRecoveryTest, PRE_RecoverFormerlyWalDbAfterCrash) {
|
||||
temp_dir_.GetPath().AppendASCII("recovery_wal_test.sqlite");
|
||||
|
||||
// Open the DB in WAL mode to set journal_mode="wal".
|
||||
Database wal_db{{.wal_mode = true}, test::kTestTag};
|
||||
Database wal_db{DatabaseOptions().set_wal_mode(true), test::kTestTag};
|
||||
ASSERT_TRUE(wal_db.Open(wal_db_path));
|
||||
|
||||
EXPECT_TRUE(wal_db.UseWALMode());
|
||||
@ -916,7 +918,7 @@ TEST_P(SqlRecoveryTest, RecoverFormerlyWalDbAfterCrash) {
|
||||
base::FilePath wal_db_path =
|
||||
temp_dir_.GetPath().AppendASCII("recovery_wal_test.sqlite");
|
||||
|
||||
Database non_wal_db{{.wal_mode = false}, test::kTestTag};
|
||||
Database non_wal_db{DatabaseOptions().set_wal_mode(false), test::kTestTag};
|
||||
ASSERT_TRUE(non_wal_db.Open(wal_db_path));
|
||||
|
||||
auto run_recovery = base::BindLambdaForTesting([&]() {
|
||||
|
@ -157,7 +157,7 @@ bool CorruptSizeInHeader(const base::FilePath& db_path) {
|
||||
// This function doesn't reliably work if connections to the DB are still
|
||||
// open. The database is opened in excusive mode. Open will fail if any
|
||||
// other connection exists on the database.
|
||||
sql::Database db({.wal_mode = true}, kTestTag);
|
||||
Database db(DatabaseOptions().set_wal_mode(true), kTestTag);
|
||||
if (!db.Open(db_path))
|
||||
return false;
|
||||
int wal_log_size = 0;
|
||||
@ -196,7 +196,7 @@ bool CorruptSizeInHeader(const base::FilePath& db_path) {
|
||||
|
||||
bool CorruptSizeInHeaderWithLock(const base::FilePath& db_path) {
|
||||
base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
sql::Database db(sql::test::kTestTag);
|
||||
Database db(kTestTag);
|
||||
if (!db.Open(db_path))
|
||||
return false;
|
||||
|
||||
@ -214,7 +214,7 @@ bool CorruptIndexRootPage(const base::FilePath& db_path,
|
||||
if (!page_size.has_value())
|
||||
return false;
|
||||
|
||||
sql::Database db(sql::test::kTestTag);
|
||||
Database db(kTestTag);
|
||||
if (!db.Open(db_path))
|
||||
return false;
|
||||
|
||||
@ -233,27 +233,27 @@ bool CorruptIndexRootPage(const base::FilePath& db_path,
|
||||
return file.WriteAndCheck(page_offset, page_buffer);
|
||||
}
|
||||
|
||||
size_t CountSQLTables(sql::Database* db) {
|
||||
size_t CountSQLTables(Database* db) {
|
||||
return CountSQLItemsOfType(db, "table");
|
||||
}
|
||||
|
||||
size_t CountSQLIndices(sql::Database* db) {
|
||||
size_t CountSQLIndices(Database* db) {
|
||||
return CountSQLItemsOfType(db, "index");
|
||||
}
|
||||
|
||||
size_t CountTableColumns(sql::Database* db, const char* table) {
|
||||
size_t CountTableColumns(Database* db, const char* table) {
|
||||
// TODO(shess): sql::Database::QuoteForSQL() would make sense.
|
||||
std::string quoted_table;
|
||||
{
|
||||
static const char kQuoteSQL[] = "SELECT quote(?)";
|
||||
sql::Statement s(db->GetUniqueStatement(kQuoteSQL));
|
||||
Statement s(db->GetUniqueStatement(kQuoteSQL));
|
||||
s.BindCString(0, table);
|
||||
EXPECT_TRUE(s.Step());
|
||||
quoted_table = s.ColumnString(0);
|
||||
}
|
||||
|
||||
std::string sql = "PRAGMA table_info(" + quoted_table + ")";
|
||||
sql::Statement s(db->GetUniqueStatement(sql));
|
||||
Statement s(db->GetUniqueStatement(sql));
|
||||
size_t rows = 0;
|
||||
while (s.Step()) {
|
||||
++rows;
|
||||
@ -262,13 +262,13 @@ size_t CountTableColumns(sql::Database* db, const char* table) {
|
||||
return rows;
|
||||
}
|
||||
|
||||
bool CountTableRows(sql::Database* db, const char* table, size_t* count) {
|
||||
bool CountTableRows(Database* db, const char* table, size_t* count) {
|
||||
// TODO(shess): Table should probably be quoted with [] or "". See
|
||||
// http://www.sqlite.org/lang_keywords.html . Meanwhile, odd names
|
||||
// will throw an error.
|
||||
std::string sql = "SELECT COUNT(*) FROM ";
|
||||
sql += table;
|
||||
sql::Statement s(db->GetUniqueStatement(sql));
|
||||
Statement s(db->GetUniqueStatement(sql));
|
||||
if (!s.Step())
|
||||
return false;
|
||||
|
||||
@ -285,7 +285,7 @@ bool CreateDatabaseFromSQL(const base::FilePath& db_path,
|
||||
if (!base::ReadFileToString(sql_path, &sql))
|
||||
return false;
|
||||
|
||||
sql::Database db(sql::test::kTestTag);
|
||||
Database db(kTestTag);
|
||||
if (!db.Open(db_path))
|
||||
return false;
|
||||
|
||||
@ -298,23 +298,23 @@ bool CreateDatabaseFromSQL(const base::FilePath& db_path,
|
||||
return db.Execute(sql);
|
||||
}
|
||||
|
||||
std::string IntegrityCheck(sql::Database& db) {
|
||||
std::string IntegrityCheck(Database& db) {
|
||||
std::vector<std::string> messages;
|
||||
EXPECT_TRUE(db.FullIntegrityCheck(&messages));
|
||||
|
||||
return base::JoinString(messages, "\n");
|
||||
}
|
||||
|
||||
std::string ExecuteWithResult(sql::Database* db, const base::cstring_view sql) {
|
||||
sql::Statement s(db->GetUniqueStatement(sql));
|
||||
std::string ExecuteWithResult(Database* db, const base::cstring_view sql) {
|
||||
Statement s(db->GetUniqueStatement(sql));
|
||||
return s.Step() ? s.ColumnString(0) : std::string();
|
||||
}
|
||||
|
||||
std::string ExecuteWithResults(sql::Database* db,
|
||||
std::string ExecuteWithResults(Database* db,
|
||||
const base::cstring_view sql,
|
||||
const base::cstring_view column_sep,
|
||||
const base::cstring_view row_sep) {
|
||||
sql::Statement s(db->GetUniqueStatement(sql));
|
||||
Statement s(db->GetUniqueStatement(sql));
|
||||
std::string ret;
|
||||
while (s.Step()) {
|
||||
if (!ret.empty())
|
||||
@ -328,14 +328,14 @@ std::string ExecuteWithResults(sql::Database* db,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int GetPageCount(sql::Database* db) {
|
||||
sql::Statement statement(db->GetUniqueStatement("PRAGMA page_count"));
|
||||
int GetPageCount(Database* db) {
|
||||
Statement statement(db->GetUniqueStatement("PRAGMA page_count"));
|
||||
CHECK(statement.Step());
|
||||
return statement.ColumnInt(0);
|
||||
}
|
||||
|
||||
// static
|
||||
ColumnInfo ColumnInfo::Create(sql::Database* db,
|
||||
ColumnInfo ColumnInfo::Create(Database* db,
|
||||
const std::string& db_name,
|
||||
const std::string& table_name,
|
||||
const std::string& column_name) {
|
||||
|
@ -1052,15 +1052,13 @@ QuotaError QuotaDatabase::EnsureOpened() {
|
||||
return QuotaError::kDatabaseError;
|
||||
}
|
||||
|
||||
sql::DatabaseOptions options{
|
||||
// The quota database is a critical storage component. If it's corrupted,
|
||||
// all client-side storage APIs fail, because they don't know where their
|
||||
// data is stored.
|
||||
.flush_to_media = true,
|
||||
};
|
||||
|
||||
db_ = std::make_unique<sql::Database>(std::move(options),
|
||||
sql::Database::Tag("Quota"));
|
||||
db_ = std::make_unique<sql::Database>(
|
||||
sql::DatabaseOptions()
|
||||
// The quota database is a critical storage component. If it's
|
||||
// corrupted, all client-side storage APIs fail, because they don't
|
||||
// know where their data is stored.
|
||||
.set_flush_to_media(true),
|
||||
sql::Database::Tag("Quota"));
|
||||
meta_table_ = std::make_unique<sql::MetaTable>();
|
||||
|
||||
db_->set_error_callback(base::BindRepeating(&QuotaDatabase::OnSqliteError,
|
||||
|
Reference in New Issue
Block a user