// 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/database.h"

#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include <algorithm>
#include <cinttypes>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include "base/check.h"
#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/dcheck_is_on.h"
#include "base/feature.h"
#include "base/feature_list.h"
#include "base/files/drive_info.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/notimplemented.h"
#include "base/notreached.h"
#include "base/sequence_checker.h"
#include "base/strings/cstring_view.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"  // IWYU pragma: keep
#include "base/threading/scoped_blocking_call.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
#include "base/tracing/protos/chrome_track_event.pbzero.h"  // IWYU pragma: keep
#include "base/types/pass_key.h"
#include "build/build_config.h"
#include "sql/database_memory_dump_provider.h"
#include "sql/initialization.h"
#include "sql/internal_api_token.h"
#include "sql/meta_table.h"
#include "sql/sqlite_result_code.h"
#include "sql/sqlite_result_code_values.h"
#include "sql/statement.h"
#include "sql/statement_id.h"
#include "sql/streaming_blob_handle.h"
#include "sql/transaction.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#include "third_party/perfetto/include/perfetto/tracing/string_helpers.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_proto.h"
#include "third_party/perfetto/include/perfetto/tracing/track.h"
#include "third_party/sqlite/sqlite3.h"

#if BUILDFLAG(IS_WIN)
#include "base/strings/escape.h"
#include "base/strings/utf_string_conversions.h"
#endif

namespace sql {

namespace {

// Features to evaluate the hypothesis that preloading sql::Database causes
// memory contention (using Browser.MainThreadsCongestion as a proxy) for
// minimal gains.
//
// Context: We previously validated that preloading the main DLL causes memory
// contention, and the benefits don't outweigh this downside on fixed SSDs.
//
// When enabled, the "preload" option is ignored unconditionally.
BASE_FEATURE(kInhibitSQLPreload, base::FEATURE_DISABLED_BY_DEFAULT);
//
// When enabled, the "preload" option is ignored *only if the database is on a
// fixed SSD*.
BASE_FEATURE(kInhibitSQLPreloadOnFixedSSD, base::FEATURE_DISABLED_BY_DEFAULT);

// When enabled, the call to ReleaseCacheMemoryIfNeeded are ignored.
BASE_FEATURE(kInhibitSQLReleaseCacheMemoryIfNeeded,
             base::FEATURE_DISABLED_BY_DEFAULT);

// Returns true if `path` is on a drive that has no seek penalty and isn't
// removable, or if that information cannot be obtained (most drives are fixed
// and have no seek penalty, so `true` is the result that is most likely to be
// correct).
bool FilePathIsFixedSSD(const base::FilePath& path) {
  std::optional<base::DriveInfo> drive_info = base::GetFileDriveInfo(path);
  if (!drive_info) {
    return true;
  }

  return !drive_info->has_seek_penalty.value_or(false)
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
    BUILDFLAG(IS_CHROMEOS)
         && !drive_info->is_removable.value_or(false)
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
         && !drive_info->is_usb.value_or(false)
#endif
      ;
}

// The name of the main database associated with a sqlite3* connection.
//
// SQLite has the ability to ATTACH multiple databases to the same connection.
// As a consequence, some SQLite APIs require the connection-specific database
// name. This is the right name to be passed to such APIs.
static constexpr char kSqliteMainDatabaseName[] = "main";

// Magic path value telling sqlite3_open_v2() to open an in-memory database.
static constexpr char kSqliteOpenInMemoryPath[] = ":memory:";

// Spin for up to a second waiting for the lock to clear when setting
// up the database.
// TODO(shess): Better story on this.  http://crbug.com/56559
const int kBusyTimeoutSeconds = 1;

constexpr int kPrepareFlags = SQLITE_PREPARE_NO_VTAB;

// RAII-style wrapper that enables `writable_schema` until it goes out of scope.
// No error checking on the PRAGMA statements because it is reasonable to just
// forge ahead in case of an error. If turning it on fails, then most likely
// nothing will work, whereas if turning it off fails, it only matters if some
// code attempts to continue working with the database and tries to modify the
// sqlite_schema table (none of our code does this).
class ScopedWritableSchema {
 public:
  explicit ScopedWritableSchema(base::WeakPtr<Database> db)
      : db_(std::move(db)) {
    CHECK(db_->is_open());
    std::ignore = db_->Execute("PRAGMA writable_schema=1");
  }
  ~ScopedWritableSchema() {
    // Database invalidates its WeakPtrs before closing the SQLite connection.
    if (db_) {
      CHECK(db_->is_open());
      std::ignore = db_->Execute("PRAGMA writable_schema=0");
    }
  }

 private:
  const base::WeakPtr<Database> db_;
};

// Raze() helper that uses SQLite's online backup API.
//
// Returns the SQLite error code produced by sqlite3_backup_step(). SQLITE_DONE
// signals success. SQLITE_OK will never be returned.
//
// The implementation is tailored for the Raze() use case. In particular, the
// SQLite API use and and error handling is optimized for 1-page databases.
SqliteResultCode BackupDatabaseForRaze(sqlite3* source_db,
                                       sqlite3* destination_db) {
  DCHECK(source_db);
  DCHECK(destination_db);
  DCHECK_NE(source_db, destination_db);

  // https://www.sqlite.org/backup.html has a high-level overview of SQLite's
  // backup support. https://www.sqlite.org/c3ref/backup_finish.html describes
  // the API.
  static constexpr char kMainDatabaseName[] = "main";
  sqlite3_backup* backup = sqlite3_backup_init(
      destination_db, kMainDatabaseName, source_db, kMainDatabaseName);
  if (!backup) {
    // sqlite3_backup_init() fails if a transaction is ongoing. In particular,
    // SQL statements that return multiple rows keep a read transaction open
    // until all the Step() calls are executed.
    return ToSqliteResultCode(chrome_sqlite3_extended_errcode(destination_db));
  }

  constexpr int kUnlimitedPageCount = -1;  // Back up entire database.
  auto sqlite_result_code =
      ToSqliteResultCode(sqlite3_backup_step(backup, kUnlimitedPageCount));
  DCHECK_NE(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_backup_step() returned SQLITE_OK (instead of SQLITE_DONE) "
      << "when asked to back up the entire database";

#if DCHECK_IS_ON()
  if (sqlite_result_code == SqliteResultCode::kDone) {
    // If successful, exactly one page should have been backed up.
    DCHECK_EQ(sqlite3_backup_pagecount(backup), 1)
        << __func__ << " was intended to be used with 1-page databases";
  }
#endif  // DCHECK_IS_ON()

  // sqlite3_backup_finish() releases the sqlite3_backup object.
  //
  // It returns an error code only if the backup encountered a permanent error.
  // We use the the sqlite3_backup_step() result instead, because it also tells
  // us about temporary errors, like SQLITE_BUSY.
  //
  // We pass the sqlite3_backup_finish() result code through
  // ToSqliteResultCode() to catch codes that should never occur, like
  // SQLITE_MISUSE.
  std::ignore = ToSqliteResultCode(sqlite3_backup_finish(backup));

  return sqlite_result_code;
}

bool ValidAttachmentPoint(std::string_view attachment_point) {
  // SQLite could handle a much wider character set, with appropriate quoting.
  //
  // Chrome's constraint is easy to remember, and sufficient for the few
  // existing use cases. ATTACH is a discouraged feature, so no new use cases
  // are expected.
  return std::ranges::all_of(attachment_point,
                             [](char ch) { return base::IsAsciiLower(ch); });
}

std::string AsUTF8ForSQL(const base::FilePath& path) {
#if BUILDFLAG(IS_WIN)
  return base::WideToUTF8(path.value());
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  return path.value();
#endif
}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// LINT.IfChange(OpenDatabaseFailedReason)
enum class OpenDatabaseFailedReason {
  kAlreadyOpened = 0,
  kIncorrectPath = 1,
  kSqliteOpenFailed = 2,
  kLockingModeFailed = 3,
  kMetadataLoadingFailed = 4,
  kPageSizeFailed = 5,
  kPragmaSynchronousFailed = 6,
  kPragmaJournalFailed = 7,
  kMaxValue = kPragmaJournalFailed
};

// LINT.ThenChange(//tools/metrics/histograms/metadata/sql/enums.xml)
// Reports the reason for a failure in Database::Open(...).
void RecordOpenDatabaseFailureReason(const std::string& histogram_tag,
                                     OpenDatabaseFailedReason reason) {
  base::UmaHistogramEnumeration(
      base::StrCat({"Sql.Database.Open.FailureReason.", histogram_tag}),
      reason);
}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// LINT.IfChange(RazeDatabaseFailedReason)
enum class RazeDatabaseFailedReason {
  kPoisoned = 0,
  kPendingTransaction = 1,
  kCantOpenInMemory = 2,
  kAutoVacuumFailed = 3,
  kSchemaFailed = 4,
  kLocked = 5,
  kTruncateFailed = 6,
  kBackupFailed = 7,
  kPageSizeFailed = 8,
  kUnknownError = 9,
  kCheckpointFailed = 10,
  kMaxValue = kCheckpointFailed
};

// LINT.ThenChange(//tools/metrics/histograms/metadata/sql/enums.xml)
// Reports the reason for a failure in Database::Raze(...).
void RecordRazeDatabaseFailureReason(const std::string& histogram_tag,
                                     RazeDatabaseFailedReason reason) {
  base::UmaHistogramEnumeration(
      base::StrCat({"Sql.Database.Raze.FailureReason.", histogram_tag}),
      reason);
}

// Creates a collapsible global track to hold all Database tracing tracks.
perfetto::NamedTrack GetSqlGroupTrack() {
  static const base::NoDestructor<
      base::trace_event::TrackRegistration<perfetto::NamedTrack>>
      sql_group_track_(perfetto::NamedTrack("Sql Databases"));
  return sql_group_track_->track();
}

}  // namespace

DatabaseOptions::DatabaseOptions() = default;
DatabaseOptions::DatabaseOptions(const DatabaseOptions&) = default;
DatabaseOptions::DatabaseOptions(DatabaseOptions&&) = default;
DatabaseOptions& DatabaseOptions::operator=(const DatabaseOptions&) = default;
DatabaseOptions& DatabaseOptions::operator=(DatabaseOptions&&) = default;
DatabaseOptions::~DatabaseOptions() = default;

// static
Database::ScopedErrorExpecterCallback* Database::current_expecter_cb_ = nullptr;

// static
bool Database::IsExpectedSqliteError(int sqlite_error_code) {
  DCHECK_NE(sqlite_error_code, SQLITE_OK)
      << __func__ << " received non-error result code";
  DCHECK_NE(sqlite_error_code, SQLITE_DONE)
      << __func__ << " received non-error result code";
  DCHECK_NE(sqlite_error_code, SQLITE_ROW)
      << __func__ << " received non-error result code";

  if (!current_expecter_cb_) {
    return false;
  }
  return current_expecter_cb_->Run(sqlite_error_code);
}

// static
void Database::SetScopedErrorExpecter(
    Database::ScopedErrorExpecterCallback* cb,
    base::PassKey<test::ScopedErrorExpecter>) {
  CHECK(!current_expecter_cb_);
  current_expecter_cb_ = cb;
}

// static
void Database::ResetScopedErrorExpecter(
    base::PassKey<test::ScopedErrorExpecter>) {
  CHECK(current_expecter_cb_);
  current_expecter_cb_ = nullptr;
}

// static
base::FilePath Database::JournalPath(const base::FilePath& db_path) {
  return base::FilePath(db_path.value() + FILE_PATH_LITERAL("-journal"));
}

// static
base::FilePath Database::WriteAheadLogPath(const base::FilePath& db_path) {
  return base::FilePath(db_path.value() + FILE_PATH_LITERAL("-wal"));
}

// static
base::FilePath Database::SharedMemoryFilePath(const base::FilePath& db_path) {
  return base::FilePath(db_path.value() + FILE_PATH_LITERAL("-shm"));
}

// static
int Database::WalCommitHook(void* db_ptr,
                            sqlite3* db_handle,
                            const char* db_name,
                            int pages) {
  Database* self = reinterpret_cast<Database*>(db_ptr);
  DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_);
  CHECK_EQ(db_handle, self->db_.get());

  // SAFETY: `db_name` is the terminated name of the database as provided by
  // SQLite.
  self->OnWalDataCommit(UNSAFE_BUFFERS(base::cstring_view(db_name)), pages);

  // Unconditionally return SQLITE_OK as per the recommendation in
  // https://www.sqlite.org/c3ref/wal_hook.html and the default implementation
  // in SQLite.
  return SQLITE_OK;
}

void Database::OnWalDataCommit(base::cstring_view db_name, int pages) {
  // The default number of frames to accumulate in the log file before
  // checkpointing the database in WAL mode.
  static constexpr int kDefaultWalAutoCheckpoint = 1000;

  if (options_.wal_commit_callback_ && db_name == kSqliteMainDatabaseName) {
    // The creator has specified their own callback and this is the main
    // database.
    options_.wal_commit_callback_.Run(pages);
  } else if (pages >= kDefaultWalAutoCheckpoint) {
    // Perform the default behavior of checkpointing if more than 1000 pages are
    // in the log.
    (void)WalCheckpointImpl(db_name, /*is_auto_checkpoint=*/true,
                            /*truncate=*/false);
  }
}

int Database::WalCheckpointImpl(base::cstring_view db_name,
                                bool is_auto_checkpoint,
                                bool truncate) {
  // The number of frames in the write-ahead log after the checkpoint completes.
  int log_frame_count = 0;

  // The number of frames in the write-ahead log that were copied into the
  // database file; i.e., the subset of `log_frame_count` that made it into the
  // database. If this is equal to `log_frame_count`, then all entries in the
  // log were added to the database; otherwise, a concurrent reader prevented
  // such and the log will continue to grow as new data is written to the
  // database. Once all frames are checkpointed, the next write will rewind the
  // log and start it fresh. This is one reason why WAL mode works best when the
  // database is opened for exclusive access -- checkpoints will never be
  // prevented from transferring all frames on success.
  int checkpointed_frame_count = 0;

  TRACE_EVENT_BEGIN("sql", "Checkpoint", "is_auto_checkpoint",
                    is_auto_checkpoint);
  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

  base::ElapsedTimer timer;
  const int result = sqlite3_wal_checkpoint_v2(
      db_, db_name.c_str(),
      truncate ? SQLITE_CHECKPOINT_TRUNCATE : SQLITE_CHECKPOINT_PASSIVE,
      /*pnLog=*/&log_frame_count,
      /*pnCkpt=*/&checkpointed_frame_count);
  RecordTimingHistogram(is_auto_checkpoint
                            ? "Sql.Database.AutoCheckpoint.Time."
                            : "Sql.Database.ManualCheckpoint.Time.",
                        timer.Elapsed());
  TRACE_EVENT_END("sql", "result", result, "log_frame_count", log_frame_count,
                  "checkpointed_frame_count", checkpointed_frame_count);
  scoped_blocking_call.reset();

  // Expected result codes, among others:
  // - SQLITE_BUSY if the lock could not be acquired due to use by another
  //   connection. Not possible if the database is in exclusive mode.
  // - SQLITE_LOCKED if a b-tree transaction is open, i.e. the database is in
  //   use by *this* connection, which can be due to an active database
  //   transaction, prepared statement, or open blob handle.
  // - SQLITE_READONLY if the db is in read-only mode.
  UmaHistogramSqliteResult(
      base::StrCat({"Sql.Database.", (is_auto_checkpoint ? "Auto" : "Manual"),
                    "Checkpoint.Result.", histogram_tag()}),
      result);

  if (checkpointed_frame_count > 0) {
    base::UmaHistogramCounts10000(
        base::StrCat({"Sql.Database.", (is_auto_checkpoint ? "Auto" : "Manual"),
                      "Checkpoint.FrameCount.", histogram_tag()}),
        checkpointed_frame_count);
  }

  return result;
}

base::WeakPtr<Database> Database::GetWeakPtr(InternalApiToken) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!is_open()) {
    return nullptr;
  }
  return weak_factory_.GetWeakPtr();
}

Database::StatementRef::StatementRef(Database* database,
                                     sqlite3_stmt* stmt,
                                     bool was_valid)
    : database_(database), stmt_(stmt), was_valid_(was_valid) {
  DCHECK_EQ(database == nullptr, stmt == nullptr);
  if (database) {
    database_->StatementRefCreated(this);
  }
}

Database::StatementRef::~StatementRef() {
  if (database_) {
    database_->StatementRefDeleted(this);
  }
  Close(false);
}

void Database::StatementRef::Reset(bool clear_bound_variables) {
  if (clear_bound_variables) {
    std::ignore = ToSqliteResultCode(sqlite3_clear_bindings(stmt()));
    bound_blobs_.clear();
  }

  // ToSqliteResultCode() is called to ensure that sqlite3_reset() doesn't
  // return a concerning code, such as SQLITE_MISUSE. The processed error code
  // is ignored because sqlite3_reset() returns an error code if the last
  // sqlite3_step() failed, and that error was already reported when we ran
  // sqlite3_step(), via Statement::Run() or Statement::Step().
  std::ignore = ToSqliteResultCode(sqlite3_reset(stmt()));
}

base::span<const uint8_t> Database::StatementRef::TakeBlobMemory(
    int param_index,
    scoped_refptr<base::RefCountedMemory> blob) {
  auto inserted = bound_blobs_.emplace(param_index, std::move(blob));
  CHECK(inserted.second) << "Parameter unexpectedly bound twice: "
                         << param_index;
  return *inserted.first->second;
}

void Database::StatementRef::ClearBlobMemory(int param_index) {
  bound_blobs_.erase(param_index);
}

void Database::StatementRef::Close(bool forced) {
  if (stmt_) {
    // Call to InitScopedBlockingCall() cannot go at the beginning of the
    // function because Close() is called unconditionally from destructor to
    // clean database_. And if this is inactive statement this won't cause any
    // disk access and destructor most probably will be called on thread not
    // allowing disk access.
    // TODO(paivanof@gmail.com): This should move to the beginning
    // of the function. http://crbug.com/136655.
    std::optional<base::ScopedBlockingCall> scoped_blocking_call;
    InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

    // `stmt_` references memory loaned from the sqlite3 library. Stop
    // referencing it from the raw_ptr<> before returning it. This avoids the
    // raw_ptr<> becoming dangling.
    sqlite3_stmt* statement = stmt_;
    stmt_ = nullptr;

    // sqlite3_finalize()'s result code is ignored because it reports the same
    // error as the most recent sqlite3_step(). The result code is passed
    // through ToSqliteResultCode() to catch issues like SQLITE_MISUSE.
    std::ignore = ToSqliteResultCode(sqlite3_finalize(statement));

    bound_blobs_.clear();
  }
  database_ = nullptr;  // The Database may be getting deleted.

  // Forced close is expected to happen from a statement error
  // handler.  In that case maintain the sense of |was_valid_| which
  // previously held for this ref.
  was_valid_ = was_valid_ && forced;
}

static_assert(DatabaseOptions::kDefaultPageSize == SQLITE_DEFAULT_PAGE_SIZE,
              "DatabaseOptions::kDefaultPageSize must match the value "
              "configured into SQLite");

DatabaseDiagnostics::DatabaseDiagnostics() = default;
DatabaseDiagnostics::~DatabaseDiagnostics() = default;

void DatabaseDiagnostics::WriteIntoTrace(
    perfetto::TracedProto<TraceProto> context) const {
  context->set_reported_sqlite_error_code(reported_sqlite_error_code);
  context->set_error_code(error_code);
  context->set_last_errno(last_errno);
  context->set_sql_statement(sql_statement);
  context->set_version(version);
  for (const auto& sql : schema_sql_rows) {
    context->add_schema_sql_rows(sql);
  }
  for (const auto& name : schema_other_row_names) {
    context->add_schema_other_row_names(name);
  }
  context->set_has_valid_header(has_valid_header);
  context->set_has_valid_schema(has_valid_schema);
  context->set_error_message(error_message);
}

Database::Database(Database::Tag tag) : Database(DatabaseOptions{}, tag) {}

Database::Database(DatabaseOptions options, Database::Tag tag)
    : options_(options),
      mmap_disabled_(!options.mmap_enabled_),
      histogram_tag_(tag.value),
      tracing_track_(
          perfetto::NamedTrack::FromPointer(perfetto::StaticString(tag.value),
                                            this,
                                            GetSqlGroupTrack())) {
  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_)
      << "mmap_alt_status requires views";

  // It's valid to construct a database on a sequence and then pass it to a
  // different sequence before usage.
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

Database::~Database() {
  Close();
}

bool Database::Open(const base::FilePath& path) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  std::string path_string = AsUTF8ForSQL(path);
  TRACE_EVENT1("sql", "Database::Open", "path", path_string);

  DCHECK(!path.empty());
  DCHECK_NE(path_string, kSqliteOpenInMemoryPath)
      << "Path conflicts with SQLite magic identifier";

  absl::Cleanup report_success = [this, open_timer = base::ElapsedTimer()] {
    RecordTimingHistogram("Sql.Database.DatabaseOpenTime.",
                          open_timer.Elapsed());
  };

  // Preload the database before opening it to ensure it's working with the
  // exclusive mode.
  if (options_.preload_) {
    PreloadInternal(path);
  }

  {
    ScopedOpenErrorReporter reporter(this,
                                     "Sql.Database.Open.FirstAttempt.Error");
    if (OpenInternal(path_string)) {
      return true;
    }
  }
  // OpenInternal() may have run the error callback before returning false. If
  // the error callback poisoned `this`, the database may have been recovered or
  // razed, so a second attempt may succeed.
  if (poisoned_) {
    Close();
    {
      ScopedOpenErrorReporter reporter(this,
                                       "Sql.Database.Open.SecondAttempt.Error");
      return OpenInternal(path_string);
    }
  }
  // Otherwise, do not attempt to reopen.
  return false;
}

bool Database::OpenInMemory() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::OpenInMemory");

  in_memory_ = true;
  return OpenInternal(kSqliteOpenInMemoryPath);
}

void Database::DetachFromSequence() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(!weak_factory_.HasWeakPtrs());
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

void Database::CloseInternal(bool forced) {
  TRACE_EVENT0("sql", "Database::CloseInternal");

  CHECK_EQ(outstanding_blob_count_, 0U)
      << "All StreamingBlobHandles should be destroyed before closing "
         "sql::Database";

  // TODO(shess): Calling "PRAGMA journal_mode = DELETE" at this point
  // will delete the -journal file.  For ChromiumOS or other more
  // embedded systems, this is probably not appropriate, whereas on
  // desktop it might make some sense.

  // sqlite3_close() needs all prepared statements to be finalized.

  // Release cached statements.
  statement_cache_.clear();

  // With cached statements released, in-use statements will remain.
  // Closing the database while statements are in use is an API
  // violation, except for forced close (which happens from within a
  // statement's error handler).
  DCHECK(forced || open_statements_.empty());

  // Deactivate any outstanding statements so sqlite3_close() works.
  for (StatementRef* statement_ref : open_statements_) {
    statement_ref->Close(forced);
  }
  open_statements_.clear();

  if (is_open()) {
    // Call to InitScopedBlockingCall() cannot go at the beginning of the
    // function because Close() must be called from destructor to clean
    // statement_cache_, it won't cause any disk access and it most probably
    // will happen on thread not allowing disk access.
    // TODO(paivanof@gmail.com): This should move to the beginning
    // of the function. http://crbug.com/136655.
    std::optional<base::ScopedBlockingCall> scoped_blocking_call;
    InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

    // Resetting acquires a lock to ensure no dump is happening on the database
    // at the same time. Unregister takes ownership of provider and it is safe
    // since the db is reset. memory_dump_provider_ could be null if db_ was
    // poisoned.
    if (memory_dump_provider_) {
      memory_dump_provider_->ResetDatabase();
      base::trace_event::MemoryDumpManager::GetInstance()
          ->UnregisterAndDeleteDumpProviderSoon(
              std::move(memory_dump_provider_));
    }

    // Invalidate any `WeakPtr`s held by scoping helpers.
    weak_factory_.InvalidateWeakPtrs();

    sqlite3* raw_db = db_;
    db_ = nullptr;
    auto sqlite_result_code = ToSqliteResultCode(sqlite3_close(raw_db));

    CHECK_NE(sqlite_result_code, SqliteResultCode::kBusy,
             base::NotFatalUntil::M141)
        << "sqlite3_close() called while resources (statements, blobs, etc) "
           "are still alive";
    DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
        << "sqlite3_close() failed in an unexpected way: "
        << sqlite3_errmsg(raw_db);

    // Closing a SQLite database connection implicitly rolls back transactions.
    // (See https://www.sqlite.org/c3ref/close.html for details.) Callers need
    // not call `RollbackAllTransactions()`, but we still must account for the
    // implicit rollback in our internal bookkeeping.
    transaction_nesting_ = 0;
  }
}

bool Database::is_open() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return static_cast<bool>(db_) && !poisoned_;
}

void Database::Close() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::Close");
  // If the database was already closed by RazeAndPoison(), then no
  // need to close again.  Clear the |poisoned_| bit so that incorrect
  // API calls are caught.
  if (poisoned_) {
    poisoned_ = false;
    return;
  }

  CloseInternal(false);
}

// SQLite keeps unused pages associated with a database in a cache.  It asks
// the cache for pages by an id, and if the page is present and the database is
// unchanged, it considers the content of the page valid and doesn't read it
// from disk.  When memory-mapped I/O is enabled, on read SQLite uses page
// structures created from the memory map data before consulting the cache.  On
// write SQLite creates a new in-memory page structure, copies the data from the
// memory map, and later writes it, releasing the updated page back to the
// cache.
//
// This means that in memory-mapped mode, the contents of the cached pages are
// not re-used for reads, but they are re-used for writes if the re-written page
// is still in the cache. The implementation of sqlite3_db_release_memory() as
// of SQLite 3.8.7.4 frees all pages from pcaches associated with the
// database, so it should free these pages.
//
// Unfortunately, the zero page is also freed.  That page is never accessed
// using memory-mapped I/O, and the cached copy can be re-used after verifying
// the file change counter on disk.  Also, fresh pages from cache receive some
// pager-level initialization before they can be used.  Since the information
// involved will immediately be accessed in various ways, it is unclear if the
// additional overhead is material, or just moving processor cache effects
// around.
//
// TODO(shess): It would be better to release the pages immediately when they
// are no longer needed.  This would basically happen after SQLite commits a
// transaction.  I had implemented a pcache wrapper to do this, but it involved
// layering violations, and it had to be setup before any other sqlite call,
// which was brittle.  Also, for large files it would actually make sense to
// maintain the existing pcache behavior for blocks past the memory-mapped
// segment.  I think drh would accept a reasonable implementation of the overall
// concept for upstreaming to SQLite core.
//
// TODO(shess): Another possibility would be to set the cache size small, which
// would keep the zero page around, plus some pre-initialized pages, and SQLite
// can manage things.  The downside is that updates larger than the cache would
// spill to the journal.  That could be compensated by setting cache_spill to
// false.  The downside then is that it allows open-ended use of memory for
// large transactions.
void Database::ReleaseCacheMemoryIfNeeded(bool implicit_change_performed) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (base::FeatureList::IsEnabled(kInhibitSQLReleaseCacheMemoryIfNeeded)) {
    return;
  }

  if (!options_.release_memory_after_writes_) {
    return;
  }

  TRACE_EVENT0("sql", "Database::ReleaseCacheMemoryIfNeeded");
  // The database could have been closed during a transaction as part of error
  // recovery.
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return;
  }

  // If memory-mapping is not enabled, the page cache helps performance.
  if (!mmap_enabled_) {
    return;
  }

  // On caller request, force the change comparison to fail.  Done before the
  // transaction-nesting test so that the signal can carry to transaction
  // commit.
  if (implicit_change_performed) {
    --total_changes_at_last_release_;
  }

  // Cached pages may be re-used within the same transaction.
  DCHECK_GE(transaction_nesting_, 0);
  if (transaction_nesting_) {
    return;
  }

  // If no changes have been made, skip flushing.  This allows the first page of
  // the database to remain in cache across multiple reads.
  const int64_t total_changes = sqlite3_total_changes64(db_);
  if (total_changes == total_changes_at_last_release_) {
    return;
  }

  total_changes_at_last_release_ = total_changes;

  // Passing the result code through ToSqliteResultCode() to catch issues such
  // as SQLITE_MISUSE.
  std::ignore = ToSqliteResultCode(sqlite3_db_release_memory(db_));
}

base::FilePath Database::DbPath() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!is_open()) {
    return base::FilePath();
  }

  const char* path = sqlite3_db_filename(db_, "main");
  if (!path) {
    return base::FilePath();
  }
  const std::string_view db_path(path);
#if BUILDFLAG(IS_WIN)
  return base::FilePath(base::UTF8ToWide(db_path));
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  return base::FilePath(db_path);
#else
  NOTREACHED();
#endif
}

std::string Database::CollectErrorInfo(int sqlite_error_code,
                                       Statement* stmt,
                                       DatabaseDiagnostics* diagnostics) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::CollectErrorInfo");
  DCHECK_NE(sqlite_error_code, SQLITE_OK)
      << __func__ << " received non-error result code";
  DCHECK_NE(sqlite_error_code, SQLITE_DONE)
      << __func__ << " received non-error result code";
  DCHECK_NE(sqlite_error_code, SQLITE_ROW)
      << __func__ << " received non-error result code";

  // Buffer for accumulating debugging info about the error.  Place
  // more-relevant information earlier, in case things overflow the
  // fixed-size reporting buffer.
  std::string debug_info;

  // The error message from the failed operation.
  int error_code = GetErrorCode();
  base::StringAppendF(&debug_info, "db error: %d/%s\n", error_code,
                      GetErrorMessage());
  if (diagnostics) {
    diagnostics->error_code = error_code;
    diagnostics->error_message = GetErrorMessage();
  }

  // TODO(shess): |error| and |GetErrorCode()| should always be the same, but
  // reading code does not entirely convince me.  Remove if they turn out to be
  // the same.
  if (sqlite_error_code != GetErrorCode()) {
    base::StringAppendF(&debug_info, "reported error: %d\n", sqlite_error_code);
  }

// System error information.  Interpretation of Windows errors is different
// from posix.
#if BUILDFLAG(IS_WIN)
  int last_errno = GetLastErrno();
  base::StringAppendF(&debug_info, "LastError: %d\n", last_errno);
  if (diagnostics) {
    diagnostics->last_errno = last_errno;
  }
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
  int last_errno = GetLastErrno();
  base::StringAppendF(&debug_info, "errno: %d\n", last_errno);
  if (diagnostics) {
    diagnostics->last_errno = last_errno;
  }
#else
  NOTREACHED();  // Add appropriate log info.
#endif

  if (stmt) {
    std::string sql_string = stmt->GetSQLStatement();
    base::StringAppendF(&debug_info, "statement: %s\n", sql_string.c_str());
    if (diagnostics) {
      diagnostics->sql_statement = sql_string;
    }
  } else {
    base::StringAppendF(&debug_info, "statement: NULL\n");
  }

  // SQLITE_ERROR often indicates some sort of mismatch between the statement
  // and the schema, possibly due to a failed schema migration.
  if (sqlite_error_code == SQLITE_ERROR) {
    static constexpr char kVersionSql[] =
        "SELECT value FROM meta WHERE key='version'";
    sqlite3_stmt* sqlite_statement;
    // When the number of bytes passed to sqlite3_prepare_v3() includes the null
    // terminator, SQLite avoids a buffer copy.
    int rc = sqlite3_prepare_v3(db_, kVersionSql, sizeof(kVersionSql),
                                SQLITE_PREPARE_NO_VTAB, &sqlite_statement,
                                /* pzTail= */ nullptr);
    if (rc == SQLITE_OK) {
      rc = sqlite3_step(sqlite_statement);
      if (rc == SQLITE_ROW) {
        int version = sqlite3_column_int(sqlite_statement, 0);
        base::StringAppendF(&debug_info, "version: %d\n", version);
        if (diagnostics) {
          diagnostics->version = version;
        }
      } else if (rc == SQLITE_DONE) {
        debug_info += "version: none\n";
      } else {
        base::StringAppendF(&debug_info, "version: error %d\n", rc);
      }
      sqlite3_finalize(sqlite_statement);
    } else {
      base::StringAppendF(&debug_info, "version: prepare error %d\n", rc);
    }

    // Get all the SQL from sqlite_schema.
    debug_info += "schema:\n";
    static constexpr char kSchemaSql[] =
        "SELECT sql FROM sqlite_schema WHERE sql IS NOT NULL ORDER BY ROWID";
    rc = sqlite3_prepare_v3(db_, kSchemaSql, sizeof(kSchemaSql),
                            SQLITE_PREPARE_NO_VTAB, &sqlite_statement,
                            /* pzTail= */ nullptr);
    if (rc == SQLITE_OK) {
      while ((rc = sqlite3_step(sqlite_statement)) == SQLITE_ROW) {
        std::string text;
        base::StringAppendF(&text, "%s",
                            reinterpret_cast<const char*>(
                                sqlite3_column_text(sqlite_statement, 0)));
        debug_info += text + "\n";
        if (diagnostics) {
          diagnostics->schema_sql_rows.push_back(text);
        }
      }

      if (rc != SQLITE_DONE) {
        base::StringAppendF(&debug_info, "error %d\n", rc);
      }
      sqlite3_finalize(sqlite_statement);
    } else {
      base::StringAppendF(&debug_info, "prepare error %d\n", rc);
    }

    // Automatically generated indices have a NULL 'sql' column. For those rows,
    // we log the name column instead.
    debug_info += "schema rows with only name:\n";
    static constexpr char kSchemaOtherRowNamesSql[] =
        "SELECT name FROM sqlite_schema WHERE sql IS NULL ORDER BY ROWID";
    rc = sqlite3_prepare_v3(db_, kSchemaOtherRowNamesSql,
                            sizeof(kSchemaOtherRowNamesSql),
                            SQLITE_PREPARE_NO_VTAB, &sqlite_statement,
                            /* pzTail= */ nullptr);
    if (rc == SQLITE_OK) {
      while ((rc = sqlite3_step(sqlite_statement)) == SQLITE_ROW) {
        std::string text;
        base::StringAppendF(&text, "%s",
                            reinterpret_cast<const char*>(
                                sqlite3_column_text(sqlite_statement, 0)));
        debug_info += text + "\n";
        if (diagnostics) {
          diagnostics->schema_other_row_names.push_back(text);
        }
      }

      if (rc != SQLITE_DONE) {
        base::StringAppendF(&debug_info, "error %d\n", rc);
      }
      sqlite3_finalize(sqlite_statement);
    } else {
      base::StringAppendF(&debug_info, "prepare error %d\n", rc);
    }
  }

  return debug_info;
}

// TODO(shess): Since this is only called in an error situation, it might be
// prudent to rewrite in terms of SQLite API calls, and mark the function const.
std::string Database::CollectCorruptionInfo() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::CollectCorruptionInfo");
  // If the file cannot be accessed it is unlikely that an integrity check will
  // turn up actionable information.
  const base::FilePath db_path = DbPath();
  std::optional<int64_t> db_size = GetFileSize(db_path);
  if (db_size && *db_size < 0) {
    return std::string();
  }

  // Buffer for accumulating debugging info about the error.  Place
  // more-relevant information earlier, in case things overflow the
  // fixed-size reporting buffer.
  std::string debug_info;
  base::StringAppendF(&debug_info, "SQLITE_CORRUPT, db size %" PRId64 "\n",
                      *db_size);

  // Only check files up to 8M to keep things from blocking too long.
  const int64_t kMaxIntegrityCheckSize = 8192 * 1024;
  if (*db_size > kMaxIntegrityCheckSize) {
    debug_info += "integrity_check skipped due to size\n";
  } else {
    std::vector<std::string> messages;

    // TODO(shess): FullIntegrityCheck() splits into a vector while this joins
    // into a string.  Probably should be refactored.
    const base::TimeTicks before = base::TimeTicks::Now();
    FullIntegrityCheck(&messages);
    base::StringAppendF(
        &debug_info, "integrity_check %" PRId64 " ms, %" PRIuS " records:\n",
        (base::TimeTicks::Now() - before).InMilliseconds(), messages.size());

    // SQLite returns up to 100 messages by default, trim deeper to
    // keep close to the 2000-character size limit for dumping.
    const size_t kMaxMessages = 20;
    for (size_t i = 0; i < kMaxMessages && i < messages.size(); ++i) {
      base::StringAppendF(&debug_info, "%s\n", messages[i].c_str());
    }
  }

  return debug_info;
}

sqlite3_file* Database::GetSqliteVfsFile() {
  CHECK(db_) << "Database not opened";

  // sqlite3_file_control() accepts a null pointer to mean the "main" database
  // attached to a connection. https://www.sqlite.org/c3ref/file_control.html
  constexpr const char* kMainDatabaseName = nullptr;

  sqlite3_file* result = nullptr;
  auto sqlite_result_code = ToSqliteResultCode(sqlite3_file_control(
      db_, kMainDatabaseName, SQLITE_FCNTL_FILE_POINTER, &result));

  // SQLITE_FCNTL_FILE_POINTER is handled directly by SQLite, not by the VFS. It
  // is only supposed to fail with SQLITE_ERROR if the database name is not
  // recognized. However, "main" should always be recognized.
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_file_control(SQLITE_FCNTL_FILE_POINTER) failed";

  // SQLite does not return null when called on an in-memory or temporary
  // database. Instead, it returns returns a VFS file object with a null
  // pMethods member.
  DCHECK(result)
      << "sqlite3_file_control() succeded but returned a null sqlite3_file*";
  if (!result->pMethods) {
    // If this assumption fails, sql::Database will still function correctly,
    // but will miss some configuration optimizations. The DCHECK is here to
    // alert us (via test failures and ASAN canary builds) of such cases.
    DCHECK_EQ(DbPath().AsUTF8Unsafe(), "")
        << "sqlite3_file_control() returned a sqlite3_file* with null pMethods "
        << "in a case when it shouldn't have.";

    return nullptr;
  }

  return result;
}

void Database::RecordTimingHistogram(std::string_view name_prefix,
                                     base::TimeDelta timing) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  base::UmaHistogramCustomMicrosecondsTimes(
      base::StrCat({name_prefix, histogram_tag()}), timing,
      base::Microseconds(0), base::Minutes(1), 100);
}

const perfetto::NamedTrack& Database::GetTracingNamedTrack() const {
  return tracing_track_;
}

void Database::TrimMemory() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::TrimMemory");

  if (!db_) {
    return;
  }

  // Passing the result code through ToSqliteResultCode() to catch issues such
  // as SQLITE_MISUSE.
  std::ignore = ToSqliteResultCode(sqlite3_db_release_memory(db_));

  // It is tempting to use sqlite3_release_memory() here as well. However, the
  // API is documented to be a no-op unless SQLite is built with
  // SQLITE_ENABLE_MEMORY_MANAGEMENT. We do not use this option, because it is
  // incompatible with per-database page cache pools. Behind the scenes,
  // SQLITE_ENABLE_MEMORY_MANAGEMENT causes SQLite to use a global page cache
  // pool, and sqlite3_release_memory() releases unused pages from this global
  // pool.
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
#error "This method assumes SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined"
#endif  // defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
}

// Create an in-memory database with the existing database's page
// size, then backup that database over the existing database.
bool Database::RazeInternal() {
  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

  if (!db_) {
    DCHECK(poisoned_) << "Cannot raze null db";
    RecordRazeDatabaseFailureReason(histogram_tag_,
                                    RazeDatabaseFailedReason::kPoisoned);
    return false;
  }

  DCHECK_GE(transaction_nesting_, 0);
  if (transaction_nesting_ > 0) {
    RecordRazeDatabaseFailureReason(
        histogram_tag_, RazeDatabaseFailedReason::kPendingTransaction);
    return false;
  }

  Database null_db(
      DatabaseOptions()
          .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.";
    RecordRazeDatabaseFailureReason(
        histogram_tag_, RazeDatabaseFailedReason::kCantOpenInMemory);
    return false;
  }

#if BUILDFLAG(IS_ANDROID)
  // Android compiles with SQLITE_DEFAULT_AUTOVACUUM.  Unfortunately,
  // in-memory databases do not respect this define.
  // TODO(shess): Figure out a way to set this without using platform
  // specific code.  AFAICT from sqlite3.c, the only way to do it
  // would be to create an actual filesystem database, which is
  // unfortunate.
  if (!null_db.Execute("PRAGMA auto_vacuum = 1")) {
    RecordRazeDatabaseFailureReason(
        histogram_tag_, RazeDatabaseFailedReason::kAutoVacuumFailed);
    return false;
  }
#endif

  // The page size doesn't take effect until a database has pages, and
  // at this point the null database has none.  Changing the schema
  // version will create the first page.  This will not affect the
  // schema version in the resulting database, as SQLite's backup
  // implementation propagates the schema version from the original
  // database to the new version of the database, incremented by one
  // so that other readers see the schema change and act accordingly.
  if (!null_db.Execute("PRAGMA schema_version = 1")) {
    RecordRazeDatabaseFailureReason(histogram_tag_,
                                    RazeDatabaseFailedReason::kSchemaFailed);
    return false;
  }

  // SQLite tracks the expected number of database pages in the first
  // page, and if it does not match the total retrieved from a
  // filesystem call, treats the database as corrupt.  This situation
  // breaks almost all SQLite calls.  "PRAGMA writable_schema" can be
  // used to hint to SQLite to soldier on in that case, specifically
  // for purposes of recovery.  [See SQLITE_CORRUPT_BKPT case in
  // sqlite3.c lockBtree().]
  // TODO(shess): With this, "PRAGMA auto_vacuum" and "PRAGMA
  // page_size" can be used to query such a database.
  ScopedWritableSchema writable_schema(weak_factory_.GetWeakPtr());

#if BUILDFLAG(IS_WIN)
  // On Windows, truncate silently fails when applied to memory-mapped files.
  // Disable memory-mapping so that the truncate succeeds.  Note that other
  // Database connections may have memory-mapped the file, so this may not
  // entirely prevent the problem.
  // [Source: <https://sqlite.org/mmap.html> plus experiments.]
  std::ignore = Execute("PRAGMA mmap_size = 0");
#endif

  SqliteResultCode sqlite_result_code =
      BackupDatabaseForRaze(null_db.db(InternalApiToken()), db_);

  // The destination database was locked.
  if (sqlite_result_code == SqliteResultCode::kBusy) {
    RecordRazeDatabaseFailureReason(histogram_tag_,
                                    RazeDatabaseFailedReason::kLocked);
    return false;
  }

  // SQLITE_NOTADB can happen if page 1 of db_ exists, but is not
  // formatted correctly.  SQLITE_IOERR_SHORT_READ can happen if db_
  // isn't even big enough for one page.  Either way, reach in and
  // truncate it before trying again.
  // TODO(shess): Maybe it would be worthwhile to just truncate from
  // the get-go?
  if (sqlite_result_code == SqliteResultCode::kNotADatabase ||
      sqlite_result_code == SqliteResultCode::kIoShortRead) {
    sqlite3_file* file = GetSqliteVfsFile();
    if (!file || file->pMethods->xTruncate(file, 0) != SQLITE_OK) {
      DLOG(FATAL) << "Failed to truncate file.";
      RecordRazeDatabaseFailureReason(
          histogram_tag_, RazeDatabaseFailedReason::kTruncateFailed);
      return false;
    }

    sqlite_result_code =
        BackupDatabaseForRaze(null_db.db(InternalApiToken()), db_);
    if (sqlite_result_code != SqliteResultCode::kDone) {
      RecordRazeDatabaseFailureReason(histogram_tag_,
                                      RazeDatabaseFailedReason::kBackupFailed);
      return false;
    }
  }

  // Page size of |db_| and |null_db| differ.
  if (sqlite_result_code == SqliteResultCode::kReadOnly) {
    // Enter TRUNCATE mode to change page size.
    // TODO(shuagga@microsoft.com): Need a guarantee here that there is no other
    // 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_)});
    if (!Execute(page_size_sql)) {
      RecordRazeDatabaseFailureReason(
          histogram_tag_, RazeDatabaseFailedReason::kPageSizeFailed);
      return false;
    }
    // Page size isn't changed until the database is vacuumed.
    std::ignore = Execute("VACUUM");
    // Re-enter WAL mode.
    if (UseWALMode()) {
      std::ignore = Execute("PRAGMA journal_mode=WAL;");
    }

    sqlite_result_code =
        BackupDatabaseForRaze(null_db.db(InternalApiToken()), db_);
    if (sqlite_result_code != SqliteResultCode::kDone) {
      RecordRazeDatabaseFailureReason(histogram_tag_,
                                      RazeDatabaseFailedReason::kBackupFailed);

      return false;
    }
  }

  if (sqlite_result_code != SqliteResultCode::kDone) {
    NOTIMPLEMENTED() << "Unhandled sqlite3_backup_step() error: "
                     << sqlite_result_code;
    RecordRazeDatabaseFailureReason(histogram_tag_,
                                    RazeDatabaseFailedReason::kUnknownError);
    base::UmaHistogramSparse(
        base::StrCat(
            {"Sql.Database.Raze.UnhandledErrorCode.", histogram_tag()}),
        static_cast<int>(sqlite_result_code));
    return false;
  }

  // Checkpoint to propagate transactions to the database file and empty the WAL
  // file.
  // The database can still contain old data if the Checkpoint fails so fail the
  // Raze.
  if (!CheckpointDatabase()) {
    RecordRazeDatabaseFailureReason(
        histogram_tag_, RazeDatabaseFailedReason::kCheckpointFailed);
    return false;
  }

  return true;
}

bool Database::Raze() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::Raze");

  base::ElapsedTimer raze_timer;
  bool result = RazeInternal();
  RecordTimingHistogram("Sql.Database.RazeTime.", raze_timer.Elapsed());

  return result;
}

bool Database::RazeAndPoison() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::RazeAndPoison");

  if (!db_) {
    DCHECK(poisoned_) << "Cannot raze null db";
    return false;
  }

  // Raze() cannot run in a transaction.
  RollbackAllTransactions();

  bool result = Raze();

  CloseInternal(true);

  // Mark the database so that future API calls fail appropriately,
  // but don't DCHECK (because after calling this function they are
  // expected to fail).
  poisoned_ = true;

  return result;
}

void Database::Poison() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::Poison");

  if (!db_) {
    DCHECK(poisoned_) << "Cannot poison null db";
    return;
  }

  CloseInternal(true);

  // Mark the database so that future API calls fail appropriately,
  // but don't DCHECK (because after calling this function they are
  // expected to fail).
  poisoned_ = true;
}

// TODO(shess): To the extent possible, figure out the optimal
// ordering for these deletes which will prevent other Database connections
// from seeing odd behavior.  For instance, it may be necessary to
// manually lock the main database file in a SQLite-compatible fashion
// (to prevent other processes from opening it), then delete the
// journal files, then delete the main database file.  Another option
// might be to lock the main database file and poison the header with
// junk to prevent other processes from opening it successfully (like
// Gears "SQLite poison 3" trick).
//
// static
bool Database::Delete(const base::FilePath& path) {
  TRACE_EVENT1("sql", "Database::Delete", "path", path.MaybeAsASCII());

  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  base::FilePath journal_path = Database::JournalPath(path);
  base::FilePath wal_path = Database::WriteAheadLogPath(path);

  std::string journal_str = AsUTF8ForSQL(journal_path);
  std::string wal_str = AsUTF8ForSQL(wal_path);
  std::string path_str = AsUTF8ForSQL(path);

  EnsureSqliteInitialized();

  sqlite3_vfs* vfs = sqlite3_vfs_find(nullptr);
  CHECK(vfs);
  CHECK(vfs->xDelete);
  CHECK(vfs->xAccess);

  vfs->xDelete(vfs, journal_str.c_str(), 0);
  vfs->xDelete(vfs, wal_str.c_str(), 0);
  vfs->xDelete(vfs, path_str.c_str(), 0);

  int journal_exists = 0;
  vfs->xAccess(vfs, journal_str.c_str(), SQLITE_ACCESS_EXISTS, &journal_exists);

  int wal_exists = 0;
  vfs->xAccess(vfs, wal_str.c_str(), SQLITE_ACCESS_EXISTS, &wal_exists);

  int path_exists = 0;
  vfs->xAccess(vfs, path_str.c_str(), SQLITE_ACCESS_EXISTS, &path_exists);

  return !journal_exists && !wal_exists && !path_exists;
}

bool Database::CloseAndDelete() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(is_open());
  if (UseWALMode()) {
    sqlite3_db_config(db_, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1, nullptr);
  }
  const base::FilePath path = DbPath();
  Close();
  return Delete(path);
}

bool Database::BeginTransaction(InternalApiToken) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::BeginTransaction");

  if (needs_rollback_) {
    DCHECK_GT(transaction_nesting_, 0);

    // When we're going to rollback, fail on this begin and don't actually
    // mark us as entering the nested transaction.
    return false;
  }

  DCHECK_GE(transaction_nesting_, 0);
  if (!transaction_nesting_) {
    needs_rollback_ = false;

    // Create and cache the "COMMIT" and "ROLLBACK" statements right away. If
    // they can't be created, the transaction cannot be allowed to begin or else
    // it would be impossible to terminate.
    if (!GetCachedStatement(commit_statement_id_, "COMMIT")->is_valid() ||
        !GetCachedStatement(rollback_statement_id_, "ROLLBACK")->is_valid()) {
      return false;
    }

    Statement begin(GetCachedStatement(SQL_FROM_HERE, "BEGIN TRANSACTION"));
    if (!begin.is_valid() || !begin.Run()) {
      return false;
    }
  }
  ++transaction_nesting_;
  return true;
}

void Database::RollbackTransaction(InternalApiToken) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::RollbackTransaction");

  DCHECK_GE(transaction_nesting_, 0);
  if (!transaction_nesting_) {
    DCHECK(poisoned_) << "Rolling back a nonexistent transaction";
    return;
  }

  DCHECK_GT(transaction_nesting_, 0);
  --transaction_nesting_;

  if (transaction_nesting_ > 0) {
    // Mark the outermost transaction as needing rollback.
    needs_rollback_ = true;
    return;
  }

  DoRollback();
}

bool Database::CommitTransaction(InternalApiToken) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::CommitTransaction");

  DCHECK_GE(transaction_nesting_, 0);
  if (!transaction_nesting_) {
    DCHECK(poisoned_) << "Committing a nonexistent transaction";
    return false;
  }

  DCHECK_GT(transaction_nesting_, 0);
  --transaction_nesting_;

  if (transaction_nesting_ > 0) {
    // Mark any nested transactions as failing after we've already got one.
    return !needs_rollback_;
  }

  if (needs_rollback_) {
    DoRollback();
    return false;
  }

  Statement commit(GetCachedStatement(commit_statement_id_, "COMMIT"));
  // A valid "COMMIT" statement was cached by `BeginTransaction`. That statement
  // is mandatory for keeping SQLite and the application in sync.
  CHECK(commit.is_valid(), base::NotFatalUntil::M155);

  bool succeeded = commit.Run();
  if (!is_open()) {
    // The statement `commit` failed and the error callback closed the database.
    return false;
  }

  // The commit can fail with error code like SQLITE_BUSY or SQLITE_ERROR. In
  // these cases, the transaction is not rollback and is kept alive. The call
  // to sqlite3_get_autocommit(...) can be used to know if there is still a
  // pending transaction or if the connection is back to normal with the
  // autocommit mode (no pending transaction).
  if (!succeeded && sqlite3_get_autocommit(db_) == 0) {
    // In modern SQLite (post 3.7.11), rollback is design to be robust and
    // reliable and it will bring back the connection in a clean state.
    DoRollback();
    return false;
  }

  // Release dirty cache pages after the transaction closes.
  ReleaseCacheMemoryIfNeeded(false);

  // There should be no pending transactions.
  CHECK_NE(sqlite3_get_autocommit(db_), 0);

  return succeeded;
}

bool Database::BeginTransactionDeprecated() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!is_open()) {
    return false;
  }
  return BeginTransaction(InternalApiToken());
}

bool Database::CommitTransactionDeprecated() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!is_open()) {
    return false;
  }
  return CommitTransaction(InternalApiToken());
}

void Database::RollbackTransactionDeprecated() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!is_open()) {
    return;
  }
  RollbackTransaction(InternalApiToken());
}

void Database::RollbackAllTransactions() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::RollbackAllTransactions");

  DCHECK_GE(transaction_nesting_, 0);
  if (transaction_nesting_ > 0) {
    transaction_nesting_ = 0;
    DoRollback();
  }
}

bool Database::AttachDatabase(const base::FilePath& other_db_path,
                              std::string_view attachment_point) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::AttachDatabase");

  DCHECK(ValidAttachmentPoint(attachment_point));

  Statement statement(GetUniqueStatement("ATTACH ? AS ?"));
#if BUILDFLAG(IS_WIN)
  statement.BindString16(0, base::AsStringPiece16(other_db_path.value()));
#else
  statement.BindString(0, other_db_path.value());
#endif
  statement.BindString(1, attachment_point);
  return statement.Run();
}

bool Database::DetachDatabase(std::string_view attachment_point) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT0("sql", "Database::DetachDatabase");

  DCHECK(ValidAttachmentPoint(attachment_point));

  Statement statement(GetUniqueStatement("DETACH ?"));
  statement.BindString(0, attachment_point);
  return statement.Run();
}

// TODO(crbug.com/40779018): Change this to execute exactly one statement.
SqliteResultCode Database::ExecuteAndReturnResultCode(
    base::cstring_view initial_sql) {
  TRACE_EVENT0("sql", "Database::ExecuteAndReturnErrorCode");

  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return SqliteResultCode::kError;
  }

  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
  const char* sql = initial_sql.c_str();

  SqliteResultCode sqlite_result_code = SqliteResultCode::kOk;
  while ((sqlite_result_code == SqliteResultCode::kOk) && *sql) {
    sqlite3_stmt* sqlite_statement;
    const char* leftover_sql;
    sqlite_result_code = ToSqliteResultCode(
        sqlite3_prepare_v3(db_, sql, /* nByte= */ -1, kPrepareFlags,
                           &sqlite_statement, &leftover_sql));

#if DCHECK_IS_ON()
    // Report SQL compilation errors. On developer machines, the errors are most
    // likely caused by invalid SQL in an under-development feature. In
    // production, SQL compilation errors are caused by database schema
    // corruption.
    //
    // DCHECK would not be appropriate here, because on-disk data is always
    // subject to corruption, so Chrome cannot assume that the database schema
    // will remain intact.
    if (sqlite_result_code == SqliteResultCode::kError) {
      DLOG(ERROR) << "SQL compilation error: " << GetErrorMessage()
                  << ". Statement: " << sql;
    }
#endif  // DCHECK_IS_ON()

    // Stop if compiling the SQL statement fails.
    if (sqlite_result_code != SqliteResultCode::kOk) {
      DCHECK_NE(sqlite_result_code, SqliteResultCode::kDone)
          << "sqlite3_prepare_v3() returned unexpected non-error result code";
      DCHECK_NE(sqlite_result_code, SqliteResultCode::kRow)
          << "sqlite3_prepare_v3() returned unexpected non-error result code";
      break;
    }

    sql = leftover_sql;

    // This happens if |sql| originally only contained comments or whitespace.
    // TODO(shess): Audit to see if this can become a DCHECK().  Having
    // extraneous comments and whitespace in the SQL statements increases
    // runtime cost and can easily be shifted out to the C++ layer.
    if (!sqlite_statement) {
      continue;
    }

    while (true) {
      sqlite_result_code = ToSqliteResultCode(sqlite3_step(sqlite_statement));
      if (sqlite_result_code != SqliteResultCode::kRow) {
        break;
      }

      // TODO(shess): Audit to see if this can become a DCHECK.  I think PRAGMA
      // is the only legitimate case for this. Previously recorded histograms
      // show significant use of this code path.
    }

    // sqlite3_finalize() returns SQLITE_OK if the most recent sqlite3_step()
    // returned SQLITE_DONE or SQLITE_ROW, otherwise the error code.
    sqlite_result_code = ToSqliteResultCode(sqlite3_finalize(sqlite_statement));
    DCHECK_NE(sqlite_result_code, SqliteResultCode::kDone)
        << "sqlite3_finalize() returned unexpected non-error result code";
    DCHECK_NE(sqlite_result_code, SqliteResultCode::kRow)
        << "sqlite3_finalize() returned unexpected non-error result code";

    // sqlite3_exec() does this, presumably to avoid spinning the parser for
    // trailing whitespace.
    // TODO(shess): Audit to see if this can become a DCHECK.
    while (base::IsAsciiWhitespace(*sql)) {
      UNSAFE_TODO(sql++);
    }
  }

  // Most calls to Execute() modify the database.  The main exceptions would be
  // calls such as CREATE TABLE IF NOT EXISTS which could modify the database
  // but sometimes don't.
  ReleaseCacheMemoryIfNeeded(true);

  DCHECK_NE(sqlite_result_code, SqliteResultCode::kDone)
      << __func__ << " about to return unexpected non-error result code";
  DCHECK_NE(sqlite_result_code, SqliteResultCode::kRow)
      << __func__ << " about to return unexpected non-error result code";
  return sqlite_result_code;
}

bool Database::Execute(base::cstring_view sql) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  TRACE_EVENT0("sql", "Database::Execute");

  return ExecuteWithTimeout(sql, base::TimeDelta());
}

bool Database::ExecuteWithTimeout(base::cstring_view sql,
                                  base::TimeDelta timeout) {
  TRACE_EVENT1("sql", "Database::ExecuteWithTimeout", "query", sql);

  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return false;
  }

  // Passing zero or a negative value to sqlite3_busy_timeout() would clear any
  // busy handlers defined prior to this point.
  if (timeout.is_positive()) {
    DCHECK_LT(timeout.InMilliseconds(), INT_MAX);
    sqlite3_busy_timeout(db_, static_cast<int>(timeout.InMilliseconds()));
  }
  SqliteResultCode sqlite_result_code = ExecuteAndReturnResultCode(sql);
  sqlite3_busy_timeout(db_, 0);
  if (sqlite_result_code != SqliteResultCode::kOk) {
    MaybeReportErrorDuringOpen(sqlite_result_code);
    OnSqliteError(ToSqliteErrorCode(sqlite_result_code), nullptr, sql.c_str());
    // At this point, `this` may have been modified or even deleted as a result
    // of the caller-provided error callback.
  }
  return sqlite_result_code == SqliteResultCode::kOk;
}

bool Database::ExecuteScriptForTesting(base::cstring_view sql_script) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return false;
  }

  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

  const char* sql = sql_script.c_str();
  while (*sql) {
    sqlite3_stmt* sqlite_statement;
    auto sqlite_result_code = ToSqliteResultCode(sqlite3_prepare_v3(
        db_, sql, /*nByte=*/-1, kPrepareFlags, &sqlite_statement, &sql));
    if (sqlite_result_code != SqliteResultCode::kOk) {
      return false;
    }

    if (!sqlite_statement) {
      // Trailing comment or whitespace after the last semicolon.
      return true;
    }

    // TODO(pwnall): Investigate restricting ExecuteScriptForTesting() to
    //               statements that don't produce any result rows.
    do {
      sqlite_result_code = ToSqliteResultCode(sqlite3_step(sqlite_statement));
    } while (sqlite_result_code == SqliteResultCode::kRow);

    // sqlite3_finalize() returns SQLITE_OK if the most recent sqlite3_step()
    // returned SQLITE_DONE or SQLITE_ROW, otherwise the error code.
    sqlite_result_code = ToSqliteResultCode(sqlite3_finalize(sqlite_statement));
    if (sqlite_result_code != SqliteResultCode::kOk) {
      return false;
    }
  }

  return true;
}

scoped_refptr<Database::StatementRef> Database::GetCachedStatement(
    StatementID id,
    base::cstring_view sql) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto it = statement_cache_.find(id);
  if (it != statement_cache_.end()) {
    StatementRef& statement = *it->second;
    // Statement is in the cache. It should still be valid. We're the only
    // entity invalidating cached statements, and we remove them from the cache
    // when we do that.
    DCHECK(statement.is_valid());
    DCHECK_EQ(UNSAFE_TODO(base::cstring_view(sqlite3_sql(statement.stmt()))),
              sql)
        << "GetCachedStatement used with same ID but different SQL";

    // Reset the statement so it can be reused.
    statement.Reset(/*clear_bound_variables=*/true);
    return it->second;
  }

  scoped_refptr<StatementRef> statement = GetUniqueStatement(sql);
  if (statement->is_valid()) {
    statement_cache_[id] = statement;  // Only cache valid statements.
    DCHECK_EQ(std::string(sqlite3_sql(statement->stmt())), std::string(sql))
        << "Input SQL does not match SQLite's normalized version";
  }
  return statement;
}

scoped_refptr<Database::StatementRef> Database::GetUniqueStatement(
    base::cstring_view sql) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return GetStatementImpl(sql, /*is_readonly=*/false);
}

scoped_refptr<Database::StatementRef> Database::GetReadonlyStatement(
    base::cstring_view sql) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return GetStatementImpl(sql, /*is_readonly=*/true);
}

scoped_refptr<Database::StatementRef> Database::GetStatementImpl(
    base::cstring_view sql,
    bool is_readonly) {
  // Return inactive statement.
  if (!db_) {
    return base::MakeRefCounted<StatementRef>(nullptr, nullptr, poisoned_);
  }

  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

#if DCHECK_IS_ON()
  const char* unused_sql = nullptr;
  const char** unused_sql_ptr = &unused_sql;
#else
  constexpr const char** unused_sql_ptr = nullptr;
#endif  // DCHECK_IS_ON()
  // TODO(pwnall): Cached statements (but not unique statements) should be
  //               prepared with prepFlags set to SQLITE_PREPARE_PERSISTENT.
  sqlite3_stmt* sqlite_statement;
  auto sqlite_result_code = ToSqliteResultCode(sqlite3_prepare_v3(
      db_, sql.c_str(), /* nByte= */ -1, kPrepareFlags,
      &sqlite_statement, unused_sql_ptr));

#if DCHECK_IS_ON()
  // Report SQL compilation errors. On developer machines, the errors are most
  // likely caused by invalid SQL in an under-development feature. In
  // production, SQL compilation errors are caused by database schema
  // corruption.
  //
  // DCHECK would not be appropriate here, because on-disk data is always
  // subject to corruption, so Chrome cannot assume that the database schema
  // will remain intact.
  if (sqlite_result_code == SqliteResultCode::kError) {
    DLOG(ERROR) << "SQL compilation error: " << GetErrorMessage()
                << ". Statement: " << sql;
  }
#endif  // DCHECK_IS_ON()

  if (sqlite_result_code != SqliteResultCode::kOk) {
    DCHECK_NE(sqlite_result_code, SqliteResultCode::kDone)
        << "sqlite3_prepare_v3() returned unexpected non-error result code";
    DCHECK_NE(sqlite_result_code, SqliteResultCode::kRow)
        << "sqlite3_prepare_v3() returned unexpected non-error result code";
    OnSqliteError(ToSqliteErrorCode(sqlite_result_code), nullptr, sql.c_str());
    return base::MakeRefCounted<StatementRef>(nullptr, nullptr, false);
  }

  // If readonly statement is expected and the statement is not readonly, return
  // an invalid statement and close the created statement.
  if (is_readonly && sqlite3_stmt_readonly(sqlite_statement) == 0) {
    DLOG(ERROR) << "Readonly SQL statement failed readonly test " << sql;
    // Make a `StatementRef` that will close the created statement.
    base::MakeRefCounted<StatementRef>(this, sqlite_statement, true);

    return base::MakeRefCounted<StatementRef>(nullptr, nullptr, false);
  }

#if DCHECK_IS_ON()
  DCHECK_EQ(unused_sql, UNSAFE_TODO(sql.c_str() + sql.size()))
      << "Unused text: " << std::string(unused_sql) << "\n"
      << "in prepared SQL statement: " << std::string(sql);
#endif  // DCHECK_IS_ON()

  DCHECK(sqlite_statement) << "No SQL statement in string: " << sql;

  return base::MakeRefCounted<StatementRef>(this, sqlite_statement, true);
}

std::optional<StreamingBlobHandle> Database::GetStreamingBlob(
    base::cstring_view table,
    base::cstring_view column,
    int64_t row_id,
    bool readonly) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return std::nullopt;
  }

  sqlite3_blob* blob_handle = nullptr;
  auto sqlite_result_code =
      sqlite3_blob_open(db_, kSqliteMainDatabaseName, table.c_str(),
                        column.c_str(), row_id, readonly ? 0 : 1, &blob_handle);
  if (sqlite_result_code != SQLITE_OK) {
    OnSqliteError(ToSqliteErrorCode(ToSqliteResultCode((sqlite_result_code))),
                  nullptr, "-- sqlite3_blob_open()");

    return std::nullopt;
  }

  CHECK(blob_handle);
  ++outstanding_blob_count_;
  return StreamingBlobHandle(base::PassKey<Database>(), blob_handle,
                             base::BindOnce(&Database::OnStreamingBlobClosed,
                                            weak_factory_.GetWeakPtr()));
}

void Database::OnStreamingBlobClosed(SqliteResultCode result,
                                     const char* error_source) {
  --outstanding_blob_count_;
  if (handling_error_nesting_ == 0 && !IsSqliteSuccessCode(result)) {
    OnSqliteError(ToSqliteErrorCode(result), nullptr, error_source);
  }
}

std::string Database::GetSchema() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // The ORDER BY should not be necessary, but relying on organic
  // order for something like this is questionable.
  static constexpr char kSql[] =
      "SELECT type, name, tbl_name, sql "
      "FROM sqlite_schema ORDER BY 1, 2, 3, 4";
  Statement statement(GetUniqueStatement(kSql));

  std::string schema;
  while (statement.Step()) {
    schema += statement.ColumnStringView(0);
    schema += '|';
    schema += statement.ColumnStringView(1);
    schema += '|';
    schema += statement.ColumnStringView(2);
    schema += '|';
    schema += statement.ColumnStringView(3);
    schema += '\n';
  }

  return schema;
}

bool Database::IsSQLValid(base::cstring_view sql) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return false;
  }

#if DCHECK_IS_ON()
  const char* unused_sql = nullptr;
  const char** unused_sql_ptr = &unused_sql;
#else
  constexpr const char** unused_sql_ptr = nullptr;
#endif  // DCHECK_IS_ON()

  sqlite3_stmt* sqlite_statement = nullptr;
  auto sqlite_result_code = ToSqliteResultCode(sqlite3_prepare_v3(
      db_, sql.c_str(), /* nByte= */ -1, kPrepareFlags,
      &sqlite_statement, unused_sql_ptr));
  if (sqlite_result_code != SqliteResultCode::kOk) {
    return false;
  }

#if DCHECK_IS_ON()
  DCHECK_EQ(unused_sql, UNSAFE_TODO(sql.c_str() + sql.size()))
      << "Unused text: " << std::string(unused_sql) << "\n"
      << "in SQL statement: " << std::string(sql);
#endif  // DCHECK_IS_ON()

  DCHECK(sqlite_statement) << "No SQL statement in string: " << sql;

  sqlite_result_code = ToSqliteResultCode(sqlite3_finalize(sqlite_statement));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_finalize() failed for valid statement";
  return true;
}

bool Database::DoesIndexExist(std::string_view index_name) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return DoesSchemaItemExist(index_name, "index");
}

bool Database::DoesTableExist(std::string_view table_name) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return DoesSchemaItemExist(table_name, "table");
}

bool Database::DoesViewExist(std::string_view view_name) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return DoesSchemaItemExist(view_name, "view");
}

bool Database::DoesSchemaItemExist(std::string_view name,
                                   std::string_view type) {
  static constexpr char kSql[] =
      "SELECT 1 FROM sqlite_schema WHERE type=? AND name=?";
  Statement statement(GetUniqueStatement(kSql));

  if (!statement.is_valid()) {
    // The database is corrupt.
    return false;
  }

  statement.BindString(0, type);
  statement.BindString(1, name);

  return statement.Step();  // Table exists if any row was returned.
}

bool Database::DoesColumnExist(base::cstring_view table_name,
                               base::cstring_view column_name) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return false;
  }

  // sqlite3_table_column_metadata uses out-params to return column definition
  // details, such as the column type and whether it allows NULL values. These
  // aren't needed to compute the current method's result, so we pass in nullptr
  // for all the out-params.
  auto sqlite_result_code = ToSqliteResultCode(sqlite3_table_column_metadata(
      db_, "main", table_name.c_str(), column_name.c_str(),
      /* pzDataType= */ nullptr,
      /* pzCollSeq= */ nullptr, /* pNotNull= */ nullptr,
      /* pPrimaryKey= */ nullptr, /* pAutoinc= */ nullptr));
  return sqlite_result_code == SqliteResultCode::kOk;
}

int64_t Database::GetLastInsertRowId() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return 0;
  }
  int64_t last_rowid = sqlite3_last_insert_rowid(db_);
  DCHECK(last_rowid != 0) << "No successful INSERT in a table with ROWID";
  return last_rowid;
}

int64_t Database::GetLastChangeCount() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return 0;
  }
  return sqlite3_changes64(db_);
}

int Database::GetMemoryUsage() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return 0;
  }

  // The following calls all set the high watermark to zero.
  // See https://www.sqlite.org/c3ref/c_dbstatus_options.html
  int high_watermark = 0;

  int cache_memory = 0, schema_memory = 0, statement_memory = 0;

  auto sqlite_result_code = ToSqliteResultCode(sqlite3_db_status(
      db_, SQLITE_DBSTATUS_CACHE_USED, &cache_memory, &high_watermark,
      /*resetFlg=*/0));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_status(SQLITE_DBSTATUS_CACHE_USED) failed";

#if DCHECK_IS_ON()
  int shared_cache_memory = 0;
  sqlite_result_code = ToSqliteResultCode(
      sqlite3_db_status(db_, SQLITE_DBSTATUS_CACHE_USED_SHARED,
                        &shared_cache_memory, &high_watermark, /*resetFlg=*/0));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_status(SQLITE_DBSTATUS_CACHE_USED_SHARED) failed";
  DCHECK_EQ(shared_cache_memory, cache_memory)
      << "Memory counting assumes that each database uses a private page cache";
#endif  // DCHECK_IS_ON()

  sqlite_result_code = ToSqliteResultCode(sqlite3_db_status(
      db_, SQLITE_DBSTATUS_SCHEMA_USED, &schema_memory, &high_watermark,
      /*resetFlg=*/0));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_status(SQLITE_DBSTATUS_SCHEMA_USED) failed";

  sqlite_result_code = ToSqliteResultCode(sqlite3_db_status(
      db_, SQLITE_DBSTATUS_STMT_USED, &statement_memory, &high_watermark,
      /*resetFlg=*/0));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_status(SQLITE_DBSTATUS_STMT_USED) failed";

  return cache_memory + schema_memory + statement_memory;
}

int Database::GetErrorCode() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    return SQLITE_ERROR;
  }
  return sqlite3_extended_errcode(db_);
}

int Database::GetLastErrno() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    return -1;
  }

  int err = 0;
  if (SQLITE_OK !=
      sqlite3_file_control(db_, nullptr, SQLITE_FCNTL_LAST_ERRNO, &err)) {
    return -2;
  }

  return err;
}

const char* Database::GetErrorMessage() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (!db_) {
    return "sql::Database is not opened.";
  }
  return sqlite3_errmsg(db_);
}

Database::ScopedOpenErrorReporter::ScopedOpenErrorReporter(
    Database* db,
    std::string_view histogram)
    : db_(db), histogram_(histogram) {
  db_->open_error_reporting_callback_ =
      base::BindRepeating(&Database::ScopedOpenErrorReporter::OnErrorDuringOpen,
                          base::Unretained(this));
}

Database::ScopedOpenErrorReporter::~ScopedOpenErrorReporter() {
  db_->open_error_reporting_callback_.Reset();
}

void Database::ScopedOpenErrorReporter::OnErrorDuringOpen(
    SqliteResultCode code) {
  // Use `base::UmaHistogramSparse` because sqlite result codes aren't
  // sequential. The large integers they represent make it so that the
  // non-sparse histograms end up with too many buckets.
  if (db_->histogram_tag().empty()) {
    base::UmaHistogramSparse(base::StrCat({histogram_, ".NoTag"}),
                             static_cast<int>(code));
  } else {
    base::UmaHistogramSparse(
        base::StrCat({histogram_, ".", db_->histogram_tag()}),
        static_cast<int>(code));
  }
}

void Database::MaybeReportErrorDuringOpen(SqliteResultCode code) {
  if (open_error_reporting_callback_) {
    open_error_reporting_callback_.Run(code);
  }
}

bool Database::OpenInternal(const std::string& db_file_path) {
  TRACE_EVENT1("sql", "Database::OpenInternal", "path", db_file_path);
  base::ElapsedTimer timer;

  if (is_open()) {
    DLOG(FATAL) << "sql::Database is already open.";
    RecordOpenDatabaseFailureReason(histogram_tag_,
                                    OpenDatabaseFailedReason::kAlreadyOpened);
    return false;
  }

  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

  EnsureSqliteInitialized();

  // If |poisoned_| is set, it means an error handler called
  // RazeAndPoison().  Until regular Close() is called, the caller
  // should be treating the database as open, but is_open() currently
  // only considers the sqlite3 handle's state.
  DCHECK(!poisoned_) << "sql::Database is already open.";
  poisoned_ = false;

  // The flags are documented at https://www.sqlite.org/c3ref/open.html.
  //
  // Chrome uses SQLITE_OPEN_PRIVATECACHE because SQLite is used by many
  // disparate features with their own databases, and having separate page
  // caches makes it easier to reason about each feature's performance in
  // isolation.
  //
  // SQLITE_OPEN_EXRESCODE enables the full range of SQLite error codes. See
  // https://www.sqlite.org/rescode.html for details.
  int open_flags = SQLITE_OPEN_EXRESCODE | SQLITE_OPEN_PRIVATECACHE;

  if (options_.read_only_) {
    open_flags |= (SQLITE_OPEN_READONLY);
  } else {
    open_flags |= (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
  }

  std::string uri_file_path = db_file_path;
  if (options_.exclusive_database_file_lock_) {
#if BUILDFLAG(IS_WIN)
    const bool in_memory = db_file_path == kSqliteOpenInMemoryPath;
    if (!in_memory) {
      // Do not allow query injection.
      if (db_file_path.contains('?')) {
        RecordOpenDatabaseFailureReason(
            histogram_tag_, OpenDatabaseFailedReason::kIncorrectPath);
        return false;
      }
      open_flags |= SQLITE_OPEN_URI;
      uri_file_path = base::StrCat(
          {"file:", base::EscapePath(db_file_path), "?exclusive=true"});
    }
#else
    NOTREACHED()
        << "exclusive_database_file_lock is only supported on Windows.";
#endif  // BUILDFLAG(IS_WIN)
  }

  sqlite3* db = nullptr;
  SqliteResultCode sqlite_result_code;
  {
    TRACE_EVENT1("sql", "Database::OpenInternal sqlite3_open_v2", "path",
                 db_file_path);
    base::ElapsedTimer library_call_timer;

    sqlite_result_code = ToSqliteResultCode(
        sqlite3_open_v2(uri_file_path.c_str(), &db, open_flags,
                        options_.vfs_name_discouraged_));

    // If SQLITE_OPEN_READWRITE is specified, the database must not be opened in
    // read-only mode. If it is, set the result code to
    // SqliteResultCode::kReadOnly to prevent subsequent statements from
    // executing and to disallow database use. This is crucial because on
    // Windows, SQLite attempts to open the database in read-only mode if the
    // initial read/write attempt fails. See the winOpen SQLite function for
    // details:
    // https://source.chromium.org/chromium/chromium/src/+/main:third_party/sqlite/src/src/os_win.c;l=5266-5269;drc=9bf5bea60709d4afa37a085b86de3651b0ddd5c9
    if (sqlite_result_code == SqliteResultCode::kOk && db) {
      const bool is_readonly =
          sqlite3_db_readonly(db, kSqliteMainDatabaseName) == 1;
      if (options_.read_only_) {
        DCHECK(is_readonly);
      } else if (is_readonly) {
        sqlite_result_code = SqliteResultCode::kReadOnly;
      }
    }

    RecordTimingHistogram("Sql.Database.Success.SqliteOpenTime.",
                          library_call_timer.Elapsed());
  }

  if (sqlite_result_code == SqliteResultCode::kOk) {
    db_ = db;
  } else {
    // sqlite3_open_v2() will usually create a database connection handle, even
    // if an error occurs (see https://www.sqlite.org/c3ref/open.html).
    if (db) {
      // Deallocate resources allocated during the failed open.
      // See https://www.sqlite.org/c3ref/close.html.
      sqlite3_close(db);
    }

    RecordOpenDatabaseFailureReason(
        histogram_tag_, OpenDatabaseFailedReason::kSqliteOpenFailed);
    MaybeReportErrorDuringOpen(sqlite_result_code);
    OnSqliteError(ToSqliteErrorCode(sqlite_result_code), nullptr,
                  "-- sqlite3_open_v2()");
    return false;
  }

  ConfigureSqliteDatabaseObject();

  // If indicated, enable shared mode ("NORMAL") on the database, so it can be
  // opened by multiple processes. This needs to happen before WAL mode is
  // enabled.
  //
  // TODO(crbug.com/40146017): Remove support for non-exclusive mode.
  static_assert(
      SQLITE_DEFAULT_LOCKING_MODE == 1,
      "Chrome assumes SQLite is configured to default to EXCLUSIVE locking");
  if (!options_.exclusive_locking_) {
    if (!Execute("PRAGMA locking_mode=NORMAL")) {
      RecordOpenDatabaseFailureReason(
          histogram_tag_, OpenDatabaseFailedReason::kLockingModeFailed);
      return false;
    }
  }

  if (!options_.read_only_) {
    // The sqlite3_open*() methods only perform I/O on the database file if a
    // hot journal is found. Force SQLite to parse the header and database
    // schema, so we can signal irrecoverable corruption early.
    //
    // sqlite3_table_column_metadata() causes SQLite to parse the database
    // schema. Since the schema is stored inside a table B-tree, parsing the
    // schema implies parsing the database header.
    //
    // sqlite3_table_column_metadata() can be used with a null database name,
    // but that will cause it to search for the table in all databases that are
    // ATTACHed to the connection. While Chrome features (almost) never use
    // ATTACHed databases, we prefer to be explicit here.
    //
    // sqlite3_table_column_metadata() can be used with a null column name, and
    // will report on the existence of the table with the given name. This is
    // sufficient for the purpose of getting SQLite to parse the database
    // schema. See https://www.sqlite.org/c3ref/table_column_metadata.html for
    // details.
    static constexpr char kSqliteSchemaTable[] = "sqlite_schema";
    sqlite_result_code = ToSqliteResultCode(sqlite3_table_column_metadata(
        db_, kSqliteMainDatabaseName, kSqliteSchemaTable,
        /*zColumnName=*/nullptr,
        /*pzDataType=*/nullptr, /*pzCollSeq=*/nullptr, /*pNotNull=*/nullptr,
        /*pPrimaryKey=*/nullptr, /*pAutoinc=*/nullptr));
    if (sqlite_result_code != SqliteResultCode::kOk) {
      MaybeReportErrorDuringOpen(sqlite_result_code);
      OnSqliteError(ToSqliteErrorCode(sqlite_result_code), nullptr,
                    "-- sqlite3_table_column_metadata()");
      RecordOpenDatabaseFailureReason(
          histogram_tag_, OpenDatabaseFailedReason::kMetadataLoadingFailed);
      return false;
    }
  }

  const base::TimeDelta kBusyTimeout = base::Seconds(kBusyTimeoutSeconds);

  if (options_.read_only_) {
    // This options isn't compatible with read-only mode.
    CHECK_EQ(options_.page_size_, DatabaseOptions::kDefaultPageSize);
  } else {
    // 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_);
    if (!ExecuteWithTimeout(page_size_sql, kBusyTimeout)) {
      RecordOpenDatabaseFailureReason(
          histogram_tag_, OpenDatabaseFailedReason::kPageSizeFailed);
      return false;
    }

    // Set the synchronous flag, which controls how aggressively SQLite writes
    // data to disk.
    //
    // If `no_sync_` is true, this is set to OFF. With synchronous=OFF, SQLite
    // hands data to the OS for writing but doesn't wait for it to complete.
    // This is very fast, but an OS crash or power failure can lead to database
    // corruption. Data is safe from an application crash.
    //
    // Otherwise, if WAL mode is enabled, this is set to NORMAL. In WAL mode,
    // synchronous=NORMAL means SQLite syncs at critical moments (like
    // checkpoints), but not for every individual transaction. An OS crash or
    // power failure may cause the loss of transactions that occurred since the
    // last checkpoint, but the database file itself will not be corrupted.
    //
    // If `no_sync_` is false and WAL mode is disabled, the synchronous flag is
    // not set, which means SQLite uses its default (FULL).
    // See https://www.sqlite.org/pragma.html#pragma_synchronous for more
    // details.
    if (options_.no_sync_ || UseWALMode()) {
      if (!Execute(options_.no_sync_
                       ? base::cstring_view("PRAGMA synchronous=OFF")
                       : base::cstring_view("PRAGMA synchronous=NORMAL"))) {
        RecordOpenDatabaseFailureReason(
            histogram_tag_, OpenDatabaseFailedReason::kPragmaSynchronousFailed);
        return false;
      }
    }

    // https://www.sqlite.org/pragma.html#pragma_journal_mode
    // WAL - Use a write-ahead log instead of a journal file.
    // DELETE (default) - delete -journal file to commit.
    // TRUNCATE - truncate -journal file to commit.
    // PERSIST - zero out header of -journal file to commit.
    // TRUNCATE should be faster than DELETE because it won't need directory
    // changes for each transaction.  PERSIST may break the spirit of using
    // secure_delete.
    //
    // Needs to be performed after setting exclusive locking mode. Otherwise can
    // fail if underlying VFS doesn't support shared memory.
    if (UseWALMode()) {
      // Opening the db in WAL mode can fail (eg if the underlying VFS doesn't
      // support shared memory and we are not in exclusive locking mode).
      if (!Execute("PRAGMA journal_mode=WAL")) {
        RecordOpenDatabaseFailureReason(
            histogram_tag_, OpenDatabaseFailedReason::kPragmaJournalFailed);
        return false;
      }

      // Register a WAL commit hook. This is used to report metrics and to call
      // the caller's `wal_commit_callback_` if they have provided one.
      sqlite3_wal_hook(db_, &Database::WalCommitHook, this);
    } else {
      // For speed, change the journal mode from the default DELETE to TRUNCATE.
      // Both modes will delete the rollback journal at the conclusion of every
      // transaction, but TRUNCATE is faster because it avoids touching the
      // journal's parent directory[0].
      //
      // PERSIST may be even faster because it zeroes out the journal's header
      // without fully deleting its contents. Chrome used PERSIST until 2015,
      // but switched to TRUNCATE to ensure that potentially-sensitive
      // information is deleted from disk[1].
      //
      // Per the SQLite docs[2], setting the journal mode has a sharp edge: the
      // operation may succeed without actually changing the mode! It only makes
      // sense to tolerate this successful failure because the default mode also
      // deletes the journal's contents.
      //
      // [0]: https://crbug.com/118470#c4
      // [1]: https://crbug.com/493008
      // [2]: https://www.sqlite.org/pragma.html#pragma_journal_mode
      if (!Execute("PRAGMA journal_mode=TRUNCATE")) {
        RecordOpenDatabaseFailureReason(
            histogram_tag_, OpenDatabaseFailedReason::kPragmaJournalFailed);
        return false;
      }
    }
  }

  CHECK(db_);

  if (options_.read_only_) {
    // These options are not compatible with read-only mode.
    CHECK(!options_.flush_to_media_);
    CHECK_EQ(options_.cache_size_, 0);
  } else {
    if (options_.flush_to_media_) {
      std::ignore = Execute("PRAGMA fullfsync=1");
    }

    if (options_.cache_size_ != 0) {
      const std::string cache_size_sql = base::StrCat(
          {"PRAGMA cache_size=", base::NumberToString(options_.cache_size_)});
      std::ignore = ExecuteWithTimeout(cache_size_sql, kBusyTimeout);
    }

    static_assert(SQLITE_SECURE_DELETE == 1,
                  "Chrome assumes secure_delete is on by default.");

    // When SQLite needs to grow a database file, it uses a configurable
    // increment. Larger values reduce filesystem fragmentation and mmap()
    // churn, as the database file is grown less often. Smaller values waste
    // less disk space.
    //
    // We currently set different values for small vs large files.
    //
    // TODO(crbug.com/40827336): Replace file size-based heuristic with a
    // DatabaseOptions member. Use the DatabaseOptions value for temporary
    // databases as well.
    sqlite3_file* file = GetSqliteVfsFile();

    // GetSqliteVfsFile() returns null for in-memory and temporary databases.
    // This is fine, because these databases start out empty, so the heuristic
    // below would never set a chunk size on them anyway.
    if (file) {
      sqlite3_int64 db_size = 0;
      sqlite_result_code =
          ToSqliteResultCode(file->pMethods->xFileSize(file, &db_size));
      if (sqlite_result_code == SqliteResultCode::kOk && db_size > 16 * 1024) {
        int chunk_size = 4 * 1024;
        if (db_size > 128 * 1024) {
          chunk_size = 32 * 1024;
        }

        sqlite3_file_control(db_, /*zDbName=*/nullptr, SQLITE_FCNTL_CHUNK_SIZE,
                             &chunk_size);
      }
    }
  }

  // How much to map if no errors are found. 50MB encompasses the 99th
  // percentile of Chrome databases in the wild, so this should be good.
  static constexpr size_t kMmapEverything = 256 * 1024 * 1024;
  size_t mmap_size =
      (mmap_disabled_ || !db_ || poisoned_) ? 0 : kMmapEverything;

  // We explicitly issue a "PRGAMA mmap_size=0" to disable memory-mapping. We
  // could skip executing the PRAGMA in that case, and use a static_assert to
  // ensure that SQLITE_DEFAULT_MMAP_SIZE > 0. We didn't choose this alternative
  // because would cost us a bit more logic, and the optimization would apply to
  // edge cases, such as in-memory databases.  More details at
  // https://www.sqlite.org/pragma.html#pragma_mmap_size.
  std::ignore = Execute(
      base::StrCat({"PRAGMA mmap_size=", base::NumberToString(mmap_size)}));

  // Determine if memory-mapping has actually been enabled.  The Execute() above
  // can succeed without changing the amount mapped.
  mmap_enabled_ = false;
  {
    Statement pragma_mmap_size(GetUniqueStatement("PRAGMA mmap_size"));
    if (pragma_mmap_size.Step() && pragma_mmap_size.ColumnInt64(0) > 0) {
      mmap_enabled_ = true;
    }
  }

  DCHECK(!memory_dump_provider_);
  // TODO(crbug.com/477762546): A raw pointer to the `sqlite3*` is given to
  // the dump provider, which will use it off of this instance's sequence.
  // SQLite must be in its "serialized" threading mode for this to be safe.
  memory_dump_provider_ =
      std::make_unique<DatabaseMemoryDumpProvider>(db_, histogram_tag_);
  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
      memory_dump_provider_.get(), "sql::Database", /*task_runner=*/nullptr);

  RecordTimingHistogram("Sql.Database.Success.OpenInternalTime.",
                        timer.Elapsed());

  return is_open();
}

void Database::PreloadInternal(const base::FilePath& path) {
  TRACE_EVENT0("sql", "Database::PreloadInternal");

  // TODO(crbug.com/40904059): Consider moving this to a DCHECK after fixing
  // or migrating callsites that call Preload(...) on in-memory databases.
  if (in_memory_) {
    return;
  }

  if (base::FeatureList::IsEnabled(kInhibitSQLPreload)) {
    return;
  }

  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  if (base::FeatureList::IsEnabled(kInhibitSQLPreloadOnFixedSSD) &&
      FilePathIsFixedSSD(path)) {
    return;
  }

  // Maximum number of bytes that will be prefetched from the database.
  //
  // This limit is very aggressive. The main trade-off involved is that having
  // SQLite block on reading from disk has a high impact on Chrome startup cost
  // for the databases that are on the critical path to startup. So, the limit
  // must exceed the expected sizes of databases on the critical path.
  static constexpr int kPreReadSize = 128 * 1024 * 1024;  // 128 MB
  base::PreReadFile(path, /*is_executable=*/false, /*sequential=*/false,
                    kPreReadSize);
}

void Database::ConfigureSqliteDatabaseObject() {
  auto sqlite_result_code = ToSqliteResultCode(
      sqlite3_db_config(db_, SQLITE_DBCONFIG_ENABLE_FKEY, 0, nullptr));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_config(SQLITE_DBCONFIG_ENABLE_FKEY) should not fail";

  sqlite_result_code = ToSqliteResultCode(
      sqlite3_db_config(db_, SQLITE_DBCONFIG_ENABLE_TRIGGER,
                        options_.enable_triggers_ ? 1 : 0, nullptr));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_config() should not fail";

  sqlite_result_code = ToSqliteResultCode(
      sqlite3_db_config(db_, SQLITE_DBCONFIG_ENABLE_VIEW,
                        options_.enable_views_discouraged_ ? 1 : 0, nullptr));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_config() should not fail";
}

void Database::DoRollback() {
  TRACE_EVENT0("sql", "Database::DoRollback");

  Statement rollback(GetCachedStatement(rollback_statement_id_, "ROLLBACK"));
  // A valid "ROLLBACK" statement was cached by `BeginTransaction`. That
  // statement is mandatory for keeping SQLite and the application in sync.
  CHECK(rollback.is_valid(), base::NotFatalUntil::M155);

  rollback.Run();

  // The cache may have been accumulating dirty pages for commit.
  ReleaseCacheMemoryIfNeeded(false);

  needs_rollback_ = false;
}

void Database::StatementRefCreated(StatementRef* ref) {
  DCHECK(!open_statements_.count(ref))
      << __func__ << " already called with this statement";
  open_statements_.insert(ref);
}

void Database::StatementRefDeleted(StatementRef* ref) {
  DCHECK(open_statements_.count(ref))
      << __func__ << " called with non-existing statement";
  open_statements_.erase(ref);
}

void Database::OnSqliteError(SqliteErrorCode sqlite_error_code,
                             sql::Statement* statement,
                             const char* sql_statement) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  TRACE_EVENT1("sql", "Database::OnSqliteError", "sqlite_error_code",
               sqlite_error_code);

  DCHECK_NE(statement != nullptr, sql_statement != nullptr)
      << __func__ << " should either get a Statement or a raw SQL string";

  ++handling_error_nesting_;

  // Use `base::UmaHistogramSparse` because sqlite result codes aren't
  // sequential. The large integers they represent make it so that the
  // non-sparse histograms end up with too many buckets.
  if (!histogram_tag().empty()) {
    base::UmaHistogramSparse(
        base::StrCat({"Sql.Database.Statement.Error.", histogram_tag()}),
        static_cast<int>(sqlite_error_code));
  }

  // Log errors for developers.
  //
  // This block is wrapped around a DCHECK_IS_ON() check so we don't waste CPU
  // cycles computing the strings that make up the log message in production.
#if DCHECK_IS_ON()
  std::string logged_statement;
  if (statement) {
    logged_statement = statement->GetSQLStatement();
  } else {
    logged_statement = sql_statement;
  }

  std::string database_id = histogram_tag_;
  if (database_id.empty()) {
    database_id = DbPath().BaseName().AsUTF8Unsafe();
  }

  // This logging block cannot be a DCHECK, because valid usage of sql::Database
  // can still encounter SQLite errors in production. For example, valid SQL
  // statements can fail when a database is corrupted.
  //
  // This logging block should not use LOG(ERROR) because many features built on
  // top of sql::Database can recover from most errors.
  DVLOG(1) << "SQLite error! This may indicate a programming error!\n"
           << "Database: " << database_id
           << " sqlite_error_code: " << sqlite_error_code
           << " errno: " << GetLastErrno()
           << "\nSQLite error description: " << GetErrorMessage()
           << "\nSQL statement: " << logged_statement;
#endif  // DCHECK_IS_ON()

  // Inform the error expecter that we've encountered the error.
  std::ignore = IsExpectedSqliteError(static_cast<int>(sqlite_error_code));

  if (!error_callback_.is_null()) {
    base::WeakPtr<Database> weak_this =
        weak_factory_lifetime_tracker_.GetWeakPtr();

    // Create an additional reference to the state in `error_callback_`, so the
    // state doesn't go away if the callback changes `error_callback_` by
    // calling set_error_callback() or reset_error_callback(). This avoids a
    // subtle source of use-after-frees. See https://crbug.com/254584.
    ErrorCallback error_callback_copy = error_callback_;
    error_callback_copy.Run(static_cast<int>(sqlite_error_code), statement);

    // Abort if `error_callback_` deleted this `Database` object.
    if (!weak_this) {
      return;
    }
  }

  --handling_error_nesting_;
}

std::string Database::GetDiagnosticInfo(int sqlite_error_code,
                                        Statement* statement,
                                        DatabaseDiagnostics* diagnostics) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  DCHECK_NE(sqlite_error_code, SQLITE_OK)
      << __func__ << " received non-error result code";
  DCHECK_NE(sqlite_error_code, SQLITE_DONE)
      << __func__ << " received non-error result code";
  DCHECK_NE(sqlite_error_code, SQLITE_ROW)
      << __func__ << " received non-error result code";

  // Prevent reentrant calls to the error callback.
  ErrorCallback original_callback = std::move(error_callback_);
  error_callback_.Reset();

  if (diagnostics) {
    diagnostics->reported_sqlite_error_code = sqlite_error_code;
  }

  // Trim extended error codes.
  const int primary_error_code = sqlite_error_code & 0xff;

  // CollectCorruptionInfo() is implemented in terms of sql::Database,
  // TODO(shess): Rewrite IntegrityCheckHelper() in terms of raw SQLite.
  std::string result =
      (primary_error_code == SQLITE_CORRUPT)
          ? CollectCorruptionInfo()
          : CollectErrorInfo(sqlite_error_code, statement, diagnostics);

  // The following queries must be executed after CollectErrorInfo() above, so
  // if they result in their own errors, they don't interfere with
  // CollectErrorInfo().
  const bool has_valid_header = Execute("PRAGMA auto_vacuum");
  const bool has_valid_schema = Execute("SELECT COUNT(*) FROM sqlite_schema");

  // Restore the original error callback.
  error_callback_ = std::move(original_callback);

  base::StringAppendF(&result, "Has valid header: %s\n",
                      (has_valid_header ? "Yes" : "No"));
  base::StringAppendF(&result, "Has valid schema: %s\n",
                      (has_valid_schema ? "Yes" : "No"));
  if (diagnostics) {
    diagnostics->has_valid_header = has_valid_header;
    diagnostics->has_valid_schema = has_valid_schema;
  }

  return result;
}

bool Database::FullIntegrityCheck(std::vector<std::string>* messages) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  messages->clear();

  // The PRAGMA below has the side effect of setting SQLITE_RecoveryMode, which
  // allows SQLite to process through certain cases of corruption.
  if (!Execute("PRAGMA writable_schema=ON")) {
    // The "PRAGMA integrity_check" statement executed below may return less
    // useful information. However, incomplete information is still better than
    // nothing, so we press on.
    messages->push_back("PRAGMA writable_schema=ON failed");
  }

  // We need to bypass sql::Statement and use raw SQLite C API calls here.
  //
  // "PRAGMA integrity_check" reports SQLITE_CORRUPT when the database is
  // corrupt. Reporting SQLITE_CORRUPT is undesirable in this case, because it
  // causes our sql::Statement infrastructure to call the database error
  // handler, which triggers feature-level error handling. However,
  // FullIntegrityCheck() callers presumably already know that the database is
  // corrupted, and are trying to collect diagnostic information for reporting.
  sqlite3_stmt* statement = nullptr;

  // https://www.sqlite.org/c3ref/prepare.html states that SQLite will perform
  // slightly better if sqlite_prepare_v3() receives a zero-terminated statement
  // string, and a statement size that includes the zero byte. Fortunately,
  // C++'s string literal and sizeof() operator do exactly that.
  constexpr char kIntegrityCheckSql[] = "PRAGMA integrity_check";
  const auto prepare_result_code = ToSqliteResultCode(
      sqlite3_prepare_v3(db_, kIntegrityCheckSql, sizeof(kIntegrityCheckSql),
                         kPrepareFlags, &statement, /*pzTail=*/nullptr));
  if (prepare_result_code != SqliteResultCode::kOk) {
    return false;
  }

  // "PRAGMA integrity_check" currently returns multiple lines as a single row.
  //
  // However, since https://www.sqlite.org/pragma.html#pragma_integrity_check
  // states that multiple records may be returned, the code below can handle
  // multiple records, each of which has multiple lines.
  std::vector<std::string> result_lines;

  while (ToSqliteResultCode(sqlite3_step(statement)) ==
         SqliteResultCode::kRow) {
    const uint8_t* row = chrome_sqlite3_column_text(statement, /*iCol=*/0);
    DCHECK(row) << "PRAGMA integrity_check should never return NULL rows";

    const int row_size = sqlite3_column_bytes(statement, /*iCol=*/0);
    std::string_view row_string(reinterpret_cast<const char*>(row), row_size);

    const std::vector<std::string_view> row_lines = base::SplitStringPiece(
        row_string, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    for (std::string_view row_line : row_lines) {
      result_lines.emplace_back(row_line);
    }
  }

  const auto finalize_result_code =
      ToSqliteResultCode(sqlite3_finalize(statement));
  // sqlite3_finalize() may return SQLITE_CORRUPT when the integrity check
  // discovers any problems. We still consider this case a success, as long as
  // the statement produced at least one diagnostic message.
  const bool success = (result_lines.size() > 0) ||
                       (finalize_result_code == SqliteResultCode::kOk);
  *messages = std::move(result_lines);

  // Best-effort attempt to undo the "PRAGMA writable_schema=ON" executed above.
  std::ignore = Execute("PRAGMA writable_schema=OFF");

  return success;
}

bool Database::UseWALMode() const {
#if BUILDFLAG(IS_FUCHSIA)
  // WAL mode is only enabled on Fuchsia for databases with exclusive
  // 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_;
#else
  return options_.wal_mode_;
#endif  // BUILDFLAG(IS_FUCHSIA)
}

bool Database::CheckpointDatabase(bool truncate) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return WalCheckpointImpl(kSqliteMainDatabaseName,
                           /*is_auto_checkpoint=*/false, truncate) == SQLITE_OK;
}

}  // namespace sql
