Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /sql /meta_table.cc
blob: 75335f2c6b31e8e240e8a13af1d0751eae733eec [file] [log] [blame] [edit]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include"sql/meta_table.h"
#include<cstdint>
#include<string>
#include<string_view>
#include"base/check.h"
#include"base/check_op.h"
#include"sql/database.h"
#include"sql/statement.h"
#include"sql/statement_id.h"
#include"sql/transaction.h"
namespace sql{
namespace{
// Keys understood directly by sql:MetaTable.
constexprchar kVersionKey[]="version";
constexprchar kCompatibleVersionKey[]="last_compatible_version";
constexprchar kMmapStatusKey[]="mmap_status";
boolPrepareSetStatement(std::string_view key,
Database& db,
Statement& insert_statement){
insert_statement.Assign(db.GetCachedStatement(
SQL_FROM_HERE,"INSERT OR REPLACE INTO meta(key,value) VALUES(?,?)"));
if(!insert_statement.is_valid()){
returnfalse;
}
insert_statement.BindString(0, key);
returntrue;
}
boolPrepareGetStatement(std::string_view key,
Database& db,
Statement& select_statement){
select_statement.Assign(db.GetCachedStatement(
SQL_FROM_HERE,"SELECT value FROM meta WHERE key=?"));
if(!select_statement.is_valid())
returnfalse;
select_statement.BindString(0, key);
return select_statement.Step();
}
}// namespace
MetaTable::MetaTable()=default;
MetaTable::~MetaTable()=default;
// static
constexprint64_tMetaTable::kMmapFailure;
constexprint64_tMetaTable::kMmapSuccess;
// static
boolMetaTable::DoesTableExist(sql::Database* db){
DCHECK(db);
return db->DoesTableExist("meta");
}
// static
boolMetaTable::DeleteTableForTesting(sql::Database* db){
DCHECK(db);
return db->Execute("DROP TABLE IF EXISTS meta");
}
// static
boolMetaTable::GetMmapStatus(Database* db,int64_t* status){
DCHECK(db);
DCHECK(status);
// It is fine for the status to be missing entirely, but any error prevents
// memory-mapping.
Statement select;
if(!PrepareGetStatement(kMmapStatusKey,*db, select)){
*status=0;
returntrue;
}
*status= select.ColumnInt64(0);
return select.Succeeded();
}
// static
boolMetaTable::SetMmapStatus(Database* db,int64_t status){
DCHECK(db);
DCHECK(status== kMmapFailure|| status== kMmapSuccess|| status>=0);
Statement insert;
if(!PrepareSetStatement(kMmapStatusKey,*db, insert)){
returnfalse;
}
insert.BindInt64(1, status);
return insert.Run();
}
// static
RazeIfIncompatibleResultMetaTable::RazeIfIncompatible(
Database* db,
int lowest_supported_version,
int current_version){
DCHECK(db);
if(!DoesTableExist(db)){
returnRazeIfIncompatibleResult::kCompatible;
}
sql::Statement select;
if(!PrepareGetStatement(kVersionKey,*db, select)){
returnRazeIfIncompatibleResult::kFailed;
}
int64_t on_disk_schema_version= select.ColumnInt64(0);
if(!PrepareGetStatement(kCompatibleVersionKey,*db, select)){
returnRazeIfIncompatibleResult::kFailed;
}
int64_t on_disk_compatible_version= select.ColumnInt(0);
select.Clear();// Clear potential automatic transaction for Raze().
if((lowest_supported_version!= kNoLowestSupportedVersion&&
lowest_supported_version> on_disk_schema_version)||
(current_version< on_disk_compatible_version)){
return db->Raze()?RazeIfIncompatibleResult::kRazedSuccessfully
:RazeIfIncompatibleResult::kFailed;
}
returnRazeIfIncompatibleResult::kCompatible;
}
boolMetaTable::Init(Database* db,int version,int compatible_version){
DCHECK(!db_&& db);
db_= db;
// If values stored are nullptr or missing entirely, 0 will be reported.
// Require new clients to start with a greater initial version.
DCHECK_GT(version,0);
DCHECK_GT(compatible_version,0);
// Make sure the table is created and populated atomically.
sql::Transaction transaction(db_);
if(!transaction.Begin())
returnfalse;
if(!DoesTableExist(db)){
if(!db_->Execute("CREATE TABLE meta"
"(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value "
"LONGVARCHAR)")){
returnfalse;
}
// Newly-created databases start out with mmap'ed I/O, but have no place to
// store the setting. Set here so that later opens don't need to validate.
if(!SetMmapStatus(db_, kMmapSuccess)){
returnfalse;
}
// Note: there is no index over the meta table. We currently only have a
// couple of keys, so it doesn't matter. If we start storing more stuff in
// there, we should create an index.
// If setting either version number fails, return early to avoid likely
// crashes or incorrect behavior with respect to migrations.
if(!SetVersionNumber(version)||
!SetCompatibleVersionNumber(compatible_version)){
returnfalse;
}
}
return transaction.Commit();
}
voidMetaTable::Reset(){
db_=nullptr;
}
boolMetaTable::SetVersionNumber(int version){
DCHECK_GT(version,0);
returnSetValue(kVersionKey, version);
}
intMetaTable::GetVersionNumber(){
int64_t version=0;
returnGetValue(kVersionKey,&version)? version:0;
}
boolMetaTable::SetCompatibleVersionNumber(int version){
DCHECK_GT(version,0);
returnSetValue(kCompatibleVersionKey, version);
}
intMetaTable::GetCompatibleVersionNumber(){
int version=0;
returnGetValue(kCompatibleVersionKey,&version)? version:0;
}
boolMetaTable::SetValue(std::string_view key,const std::string& value){
DCHECK(db_);
Statement insert;
PrepareSetStatement(key,*db_, insert);
insert.BindString(1, value);
return insert.Run();
}
boolMetaTable::SetValue(std::string_view key,int64_t value){
DCHECK(db_);
Statement insert;
PrepareSetStatement(key,*db_, insert);
insert.BindInt64(1, value);
return insert.Run();
}
boolMetaTable::GetValue(std::string_view key, std::string* value){
DCHECK(value);
DCHECK(db_);
Statement select;
if(!PrepareGetStatement(key,*db_, select))
returnfalse;
*value= select.ColumnString(0);
returntrue;
}
boolMetaTable::GetValue(std::string_view key,int* value){
DCHECK(value);
DCHECK(db_);
Statement select;
if(!PrepareGetStatement(key,*db_, select))
returnfalse;
*value= select.ColumnInt64(0);
returntrue;
}
boolMetaTable::GetValue(std::string_view key,int64_t* value){
DCHECK(value);
DCHECK(db_);
Statement select;
if(!PrepareGetStatement(key,*db_, select))
returnfalse;
*value= select.ColumnInt64(0);
returntrue;
}
boolMetaTable::DeleteKey(std::string_view key){
DCHECK(db_);
Statement delete_statement(
db_->GetUniqueStatement("DELETE FROM meta WHERE key=?"));
delete_statement.BindString(0, key);
return delete_statement.Run();
}
}// namespace sql

[8]ページ先頭

©2009-2025 Movatter.jp