// 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 <memory>
#include <tuple>

#include "base/check.h"
#include "base/dcheck_is_on.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "base/sequence_checker.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/scoped_blocking_call.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"
#include "base/types/pass_key.h"
#include "build/build_config.h"
#include "sql/database_memory_dump_provider.h"
#include "sql/initialization.h"
#include "sql/meta_table.h"
#include "sql/sql_features.h"
#include "sql/sqlite_result_code.h"
#include "sql/sqlite_result_code_values.h"
#include "sql/statement.h"
#include "sql/vfs_wrapper.h"
#include "third_party/sqlite/sqlite3.h"

namespace sql {

namespace {

bool enable_mmap_by_default_ = true;

// 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;

class ScopedBusyTimeout {
 public:
  explicit ScopedBusyTimeout(sqlite3* db) : db_(db) {}
  ~ScopedBusyTimeout() { sqlite3_busy_timeout(db_, 0); }

  int SetTimeout(base::TimeDelta timeout) {
    DCHECK_LT(timeout.InMilliseconds(), INT_MAX);
    return sqlite3_busy_timeout(db_,
                                static_cast<int>(timeout.InMilliseconds()));
  }

 private:
  raw_ptr<sqlite3> db_;
};

// Helper to "safely" enable writable_schema.  No error checking
// 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(sqlite3* db) : db_(db) {
    sqlite3_exec(db_, "PRAGMA writable_schema=1", nullptr, nullptr, nullptr);
  }
  ~ScopedWritableSchema() {
    sqlite3_exec(db_, "PRAGMA writable_schema=0", nullptr, nullptr, nullptr);
  }

 private:
  raw_ptr<sqlite3> 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(base::StringPiece 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 base::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
}

}  // namespace

// 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"));
}

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::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.
    absl::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));
  }
  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);
}

// DatabaseOptions::explicit_locking needs to be set to false for historical
// reasons.
Database::Database() : Database({.exclusive_locking = false}) {}

Database::Database(DatabaseOptions options)
    : options_(options), mmap_disabled_(!enable_mmap_by_default_) {
  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();
}

// static
void Database::DisableMmapByDefault() {
  enable_mmap_by_default_ = false;
}

bool Database::Open(const base::FilePath& path) {
  std::string path_string = AsUTF8ForSQL(path);
  TRACE_EVENT1("sql", "Database::Open", "path", path_string);

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

  return OpenInternal(path_string, OpenMode::kRetryOnPoision);
}

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

  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  in_memory_ = true;
  return OpenInternal(kSqliteOpenInMemoryPath, OpenMode::kInMemory);
}

bool Database::OpenTemporary(base::PassKey<Recovery>) {
  TRACE_EVENT0("sql", "Database::OpenTemporary");

  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return OpenInternal(std::string(), OpenMode::kTemporary);
}

void Database::CloseInternal(bool forced) {
  TRACE_EVENT0("sql", "Database::CloseInternal");
  // 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 (db_) {
    // 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.
    absl::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_));
    }

    auto sqlite_result_code = ToSqliteResultCode(sqlite3_close(db_));

    DCHECK_NE(sqlite_result_code, SqliteResultCode::kBusy)
        << "sqlite3_close() called while prepared statements are still alive";
    DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
        << "sqlite3_close() failed in an unexpected way: " << GetErrorMessage();

    // The reset must happen after the DCHECKs above. GetErrorMessage() needs a
    // valid `db_` value.
    db_ = nullptr;
  }
}

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

  CloseInternal(false);
}

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

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

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

  // 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.
  //
  // On Windows 7, base::PreReadFile() falls back to a synchronous read, and
  // blocks until the entire file is read into memory. This is a minor factor at
  // this point, because Chrome has very limited support for Windows 7.
  constexpr int kPreReadSize = 128 * 1024 * 1024;  // 128 MB
  base::PreReadFile(DbPath(), /*is_executable=*/false, kPreReadSize);
}

// 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) {
  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 {
  if (!is_open())
    return base::FilePath();

  const char* path = sqlite3_db_filename(db_, "main");
  if (!path)
    return base::FilePath();
  const base::StringPiece 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();
  return base::FilePath();
#endif
}

std::string Database::CollectErrorInfo(int sqlite_error_code,
                                       Statement* stmt,
                                       DatabaseDiagnostics* diagnostics) const {
  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",
                            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",
                            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() {
  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();
  int64_t db_size = -1;
  if (!base::GetFileSize(db_path, &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;
}

bool Database::GetMmapAltStatus(int64_t* status) {
  TRACE_EVENT0("sql", "Database::GetMmapAltStatus");

  // The [meta] version uses a missing table as a signal for a fresh database.
  // That will not work for the view, which would not exist in either a new or
  // an existing database.  A new database _should_ be only one page long, so
  // just don't bother optimizing this case (start at offset 0).
  // TODO(shess): Could the [meta] case also get simpler, then?
  if (!DoesViewExist("MmapStatus")) {
    *status = 0;
    return true;
  }

  const char* kMmapStatusSql = "SELECT * FROM MmapStatus";
  Statement s(GetUniqueStatement(kMmapStatusSql));
  if (s.Step())
    *status = s.ColumnInt64(0);
  return s.Succeeded();
}

bool Database::SetMmapAltStatus(int64_t status) {
  if (!BeginTransaction())
    return false;

  // View may not exist on first run.
  if (!Execute("DROP VIEW IF EXISTS MmapStatus")) {
    RollbackTransaction();
    return false;
  }

  // Views live in the schema, so they cannot be parameterized.  For an integer
  // value, this construct should be safe from SQL injection, if the value
  // becomes more complicated use "SELECT quote(?)" to generate a safe quoted
  // value.
  const std::string create_view_sql = base::StringPrintf(
      "CREATE VIEW MmapStatus (value) AS SELECT %" PRId64, status);
  if (!Execute(create_view_sql.c_str())) {
    RollbackTransaction();
    return false;
  }

  return CommitTransaction();
}

size_t Database::ComputeMmapSizeForOpen() {
  TRACE_EVENT0("sql", "Database::ComputeMmapSizeForOpen");

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

  // 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.
  const size_t kMmapEverything = 256 * 1024 * 1024;

  // Progress information is tracked in the [meta] table for databases which use
  // sql::MetaTable, otherwise it is tracked in a special view.
  // TODO(pwnall): Migrate all databases to using a meta table.
  int64_t mmap_ofs = 0;
  if (options_.mmap_alt_status_discouraged) {
    if (!GetMmapAltStatus(&mmap_ofs))
      return 0;
  } else {
    // If [meta] doesn't exist, yet, it's a new database, assume the best.
    // sql::MetaTable::Init() will preload kMmapSuccess.
    if (!MetaTable::DoesTableExist(this))
      return kMmapEverything;

    if (!MetaTable::GetMmapStatus(this, &mmap_ofs))
      return 0;
  }

  // Database read failed in the past, don't memory map.
  if (mmap_ofs == MetaTable::kMmapFailure)
    return 0;

  if (mmap_ofs != MetaTable::kMmapSuccess) {
    // Continue reading from previous offset.
    DCHECK_GE(mmap_ofs, 0);

    // GetSqliteVfsFile() returns null for in-memory and temporary databases.
    // This is fine, we don't want to enable memory-mapping in those cases
    // anyway.
    //
    // First, memory-mapping is a no-op for in-memory databases.
    //
    // Second, temporary databases are only used for corruption recovery, which
    // occurs in response to I/O errors. An environment with heightened I/O
    // errors translates into a higher risk of mmap-induced Chrome crashes.
    sqlite3_int64 db_size = 0;
    sqlite3_file* file = GetSqliteVfsFile();
    if (!file || file->pMethods->xFileSize(file, &db_size) != SQLITE_OK)
      return 0;

    // Read more of the database looking for errors.  The VFS interface is used
    // to assure that the reads are valid for SQLite.  |g_reads_allowed| is used
    // to limit checking to 20MB per run of Chromium.
    //
    // Read the data left, or |g_reads_allowed|, whichever is smaller.
    // |g_reads_allowed| limits the total amount of I/O to spend verifying data
    // in a single Chromium run.
    sqlite3_int64 amount = db_size - mmap_ofs;
    if (amount < 0)
      amount = 0;
    if (amount > 0) {
      static base::NoDestructor<base::Lock> lock;
      base::AutoLock auto_lock(*lock);
      static sqlite3_int64 g_reads_allowed = 20 * 1024 * 1024;
      if (g_reads_allowed < amount)
        amount = g_reads_allowed;
      g_reads_allowed -= amount;
    }

    // |amount| can be <= 0 if |g_reads_allowed| ran out of quota, or if the
    // database was truncated after a previous pass.
    if (amount <= 0 && mmap_ofs < db_size) {
      DCHECK_EQ(0, amount);
    } else {
      static const int kPageSize = 4096;
      char buf[kPageSize];
      while (amount > 0) {
        int rc = file->pMethods->xRead(file, buf, sizeof(buf), mmap_ofs);
        if (rc == SQLITE_OK) {
          mmap_ofs += sizeof(buf);
          amount -= sizeof(buf);
        } else if (rc == SQLITE_IOERR_SHORT_READ) {
          // Reached EOF for a database with page size < |kPageSize|.
          mmap_ofs = db_size;
          break;
        } else {
          // TODO(shess): Consider calling OnSqliteError().
          mmap_ofs = MetaTable::kMmapFailure;
          break;
        }
      }

      // Log these events after update to distinguish meta update failure.
      if (mmap_ofs >= db_size) {
        mmap_ofs = MetaTable::kMmapSuccess;
      } else {
        DCHECK(mmap_ofs > 0 || mmap_ofs == MetaTable::kMmapFailure);
      }

      if (options_.mmap_alt_status_discouraged) {
        if (!SetMmapAltStatus(mmap_ofs))
          return 0;
      } else {
        if (!MetaTable::SetMmapStatus(this, mmap_ofs))
          return 0;
      }
    }
  }

  if (mmap_ofs == MetaTable::kMmapFailure)
    return 0;
  if (mmap_ofs == MetaTable::kMmapSuccess)
    return kMmapEverything;
  return mmap_ofs;
}

int Database::SqlitePrepareFlags() const {
  return options_.enable_virtual_tables_discouraged ? 0
                                                    : SQLITE_PREPARE_NO_VTAB;
}

sqlite3_file* Database::GetSqliteVfsFile() {
  DCHECK(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::TrimMemory() {
  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::Raze() {
  TRACE_EVENT0("sql", "Database::Raze");

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

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

  DCHECK_GE(transaction_nesting_, 0);
  if (transaction_nesting_ > 0) {
    DLOG(DCHECK) << "Cannot raze within a transaction";
    return false;
  }

  sql::Database null_db(sql::DatabaseOptions{
      .exclusive_locking = true,
      .page_size = options_.page_size,
      .cache_size = 0,
      .enable_foreign_keys_discouraged =
          options_.enable_foreign_keys_discouraged,
      .enable_views_discouraged = options_.enable_views_discouraged,
      .enable_virtual_tables_discouraged =
          options_.enable_virtual_tables_discouraged,
  });
  if (!null_db.OpenInMemory()) {
    DLOG(DCHECK) << "Unable to open in-memory database.";
    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"))
    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"))
    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(db_);

#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_, db_);

  // The destination database was locked.
  if (sqlite_result_code == SqliteResultCode::kBusy)
    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(DCHECK) << "Failed to truncate file.";
      return false;
    }

    sqlite_result_code = BackupDatabaseForRaze(null_db.db_, db_);
    if (sqlite_result_code != SqliteResultCode::kDone)
      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.c_str())) {
      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_, db_);
    if (sqlite_result_code != SqliteResultCode::kDone)
      return false;
  }

  if (sqlite_result_code != SqliteResultCode::kDone) {
    NOTIMPLEMENTED() << "Unhandled sqlite3_backup_step() error: "
                     << 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.
  return CheckpointDatabase();
}

bool Database::RazeAndClose() {
  TRACE_EVENT0("sql", "Database::RazeAndClose");

  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() {
  TRACE_EVENT0("sql", "Database::Poison");

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

  RollbackAllTransactions();
  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);

  // We only work with the VFS implementations listed below. If you're trying to
  // use this code with any other VFS, you're not in a good place.
  CHECK(strncmp(vfs->zName, "unix", 4) == 0 ||
        strncmp(vfs->zName, "win32", 5) == 0 ||
        strcmp(vfs->zName, "storage_service") == 0);

  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::BeginTransaction() {
  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;
  }

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

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

void Database::RollbackTransaction() {
  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() {
  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(SQL_FROM_HERE, "COMMIT"));

  bool succeeded = commit.Run();

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

  return succeeded;
}

void Database::RollbackAllTransactions() {
  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,
                              base::StringPiece attachment_point,
                              InternalApiToken) {
  TRACE_EVENT0("sql", "Database::AttachDatabase");

  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(ValidAttachmentPoint(attachment_point));

  Statement statement(GetUniqueStatement("ATTACH ? AS ?"));
#if OS_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(base::StringPiece attachment_point,
                              InternalApiToken) {
  TRACE_EVENT0("sql", "Database::DetachDatabase");

  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(ValidAttachmentPoint(attachment_point));

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

// TODO(crbug.com/1230443): Change this to execute exactly one statement.
SqliteResultCode Database::ExecuteAndReturnResultCode(const char* sql) {
  TRACE_EVENT0("sql", "Database::ExecuteAndReturnErrorCode");

  DCHECK(sql);

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

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

  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, SqlitePrepareFlags(),
                           &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)) {
      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(const char* sql) {
  TRACE_EVENT1("sql", "Database::Execute", "query", TRACE_STR_COPY(sql));

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

  SqliteResultCode sqlite_result_code = ExecuteAndReturnResultCode(sql);
  if (sqlite_result_code != SqliteResultCode::kOk)
    OnSqliteError(ToSqliteErrorCode(sqlite_result_code), nullptr, sql);

  return sqlite_result_code == SqliteResultCode::kOk;
}

bool Database::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) {
  TRACE_EVENT0("sql", "Database::ExecuteWithTimeout");

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

  ScopedBusyTimeout busy_timeout(db_);
  busy_timeout.SetTimeout(timeout);
  return Execute(sql);
}

bool Database::ExecuteScriptForTesting(const char* sql_script) {
  DCHECK(sql_script);
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return false;
  }

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

  while (*sql_script) {
    sqlite3_stmt* sqlite_statement;
    auto sqlite_result_code = ToSqliteResultCode(
        sqlite3_prepare_v3(db_, sql_script, /*nByte=*/-1, SqlitePrepareFlags(),
                           &sqlite_statement, &sql_script));
    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,
    const char* sql) {
  auto it = statement_cache_.find(id);
  if (it != statement_cache_.end()) {
    // 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(it->second->is_valid());
    DCHECK_EQ(std::string(sqlite3_sql(it->second->stmt())), std::string(sql))
        << "GetCachedStatement used with same ID but different SQL";

    // Reset the statement so it can be reused.
    //
    // 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(it->second->stmt()));
    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(
    const char* sql) {
  return GetStatementImpl(sql, /*is_readonly=*/false);
}

scoped_refptr<Database::StatementRef> Database::GetReadonlyStatement(
    const char* sql) {
  return GetStatementImpl(sql, /*is_readonly=*/true);
}

scoped_refptr<Database::StatementRef> Database::GetStatementImpl(
    const char* sql,
    bool is_readonly) {
  DCHECK(sql);

  // Return inactive statement.
  if (!db_)
    return base::MakeRefCounted<StatementRef>(nullptr, nullptr, poisoned_);

  absl::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, /* nByte= */ -1, SqlitePrepareFlags(),
                         &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);
    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, sql + strlen(sql))
      << "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::string Database::GetSchema() {
  // The ORDER BY should not be necessary, but relying on organic
  // order for something like this is questionable.
  static const 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.ColumnString(0);
    schema += '|';
    schema += statement.ColumnString(1);
    schema += '|';
    schema += statement.ColumnString(2);
    schema += '|';
    schema += statement.ColumnString(3);
    schema += '\n';
  }

  return schema;
}

bool Database::IsSQLValid(const char* sql) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  absl::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, /* nByte= */ -1, SqlitePrepareFlags(),
                         &sqlite_statement, unused_sql_ptr));
  if (sqlite_result_code != SqliteResultCode::kOk)
    return false;

#if DCHECK_IS_ON()
  DCHECK_EQ(unused_sql, sql + strlen(sql))
      << "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(base::StringPiece index_name) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return DoesSchemaItemExist(index_name, "index");
}

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

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

bool Database::DoesSchemaItemExist(base::StringPiece name,
                                   base::StringPiece type) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  static const 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(const char* table_name,
                               const char* column_name) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // 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, column_name, /* pzDataType= */ nullptr,
      /* pzCollSeq= */ nullptr, /* pNotNull= */ nullptr,
      /* pPrimaryKey= */ nullptr, /* pAutoinc= */ nullptr));
  return sqlite_result_code == SqliteResultCode::kOk;
}

int64_t Database::GetLastInsertRowId() const {
  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() {
  if (!db_) {
    DCHECK(poisoned_) << "Illegal use of Database without a db";
    return 0;
  }
  return sqlite3_changes64(db_);
}

int Database::GetMemoryUsage() {
  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 {
  if (!db_)
    return SQLITE_ERROR;
  return sqlite3_extended_errcode(db_);
}

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

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

  return err;
}

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

bool Database::OpenInternal(const std::string& db_file_path,
                            Database::OpenMode mode) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  TRACE_EVENT1("sql", "Database::OpenInternal", "path", db_file_path);

  DCHECK(mode != OpenMode::kTemporary || db_file_path.empty())
      << "Temporary databases should be open with an empty file path";

  if (mode == OpenMode::kInMemory) {
    DCHECK_EQ(db_file_path, kSqliteOpenInMemoryPath)
        << "In-memory databases should be open with the magic :memory: path";
  } else {
    DCHECK_NE(db_file_path, kSqliteOpenInMemoryPath)
        << "Database file path conflicts with SQLite magic identifier";
  }

  if (db_) {
    DLOG(DCHECK) << "sql::Database is already open.";
    return false;
  }

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

  EnsureSqliteInitialized();

  // If |poisoned_| is set, it means an error handler called
  // RazeAndClose().  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.
  // TODO(shess): Revise is_open() to consider poisoned_, and review
  // to see if any non-testing code even depends on it.
  DCHECK(!poisoned_) << "sql::Database is already open.";
  poisoned_ = false;

  // Custom memory-mapping VFS which reads pages using regular I/O on first hit.
  sqlite3_vfs* vfs = VFSWrapper();
  const char* vfs_name = (vfs ? vfs->zName : nullptr);

  // 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_READWRITE | SQLITE_OPEN_CREATE |
                   SQLITE_OPEN_EXRESCODE | SQLITE_OPEN_PRIVATECACHE;
  auto sqlite_result_code = ToSqliteResultCode(
      sqlite3_open_v2(db_file_path.c_str(), &db_, open_flags, vfs_name));
  if (sqlite_result_code != SqliteResultCode::kOk) {
    OnSqliteError(ToSqliteErrorCode(sqlite_result_code), nullptr,
                  "-- sqlite3_open_v2()");
    bool was_poisoned = poisoned_;
    Close();

    if (was_poisoned && mode == OpenMode::kRetryOnPoision)
      return OpenInternal(db_file_path, OpenMode::kNone);
    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/1120969): 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"))
      return false;
  }

  // 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) {
    OnSqliteError(ToSqliteErrorCode(sqlite_result_code), nullptr,
                  "-- sqlite3_table_column_metadata()");

    // Retry or bail out if the error handler poisoned the handle.
    // TODO(shess): Move this handling to one place (see also sqlite3_open).
    //              Possibly a wrapper function?
    if (poisoned_) {
      Close();
      if (mode == OpenMode::kRetryOnPoision)
        return OpenInternal(db_file_path, OpenMode::kNone);
      return false;
    }
  }

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

  // 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);
  std::ignore = ExecuteWithTimeout(page_size_sql.c_str(), kBusyTimeout);

  // http://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()) {
    // Set the synchronous flag to NORMAL. This means that writers don't flush
    // the WAL file after every write. The WAL file is only flushed on a
    // checkpoint. In this case, transcations might lose durability on a power
    // loss (but still durable after an application crash).
    // TODO(shuagga@microsoft.com): Evaluate if this loss of durability is a
    // concern.
    std::ignore = Execute("PRAGMA synchronous=NORMAL");

    // 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).
    //
    // TODO(shuagga@microsoft.com): We should probably catch a failure here.
    std::ignore = Execute("PRAGMA journal_mode=WAL");
  } else {
    std::ignore = Execute("PRAGMA journal_mode=TRUNCATE");
  }

  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.c_str(), 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/1305778): 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);
    }
  }

  size_t mmap_size = mmap_disabled_ ? 0 : ComputeMmapSizeForOpen();

  // 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::string pragma_mmap_size_sql =
      base::StrCat({"PRAGMA mmap_size=", base::NumberToString(mmap_size)});
  std::ignore = Execute(pragma_mmap_size_sql.c_str());

  // 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_);
  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);

  return true;
}

void Database::ConfigureSqliteDatabaseObject() {
  // The use of SQLite's non-standard string quoting is not allowed in Chrome.
  //
  // Allowing double-quoted string literals is now considered a misfeature by
  // SQLite authors. See https://www.sqlite.org/quirks.html#dblquote
  auto sqlite_result_code = ToSqliteResultCode(
      sqlite3_db_config(db_, SQLITE_DBCONFIG_DQS_DDL, 0, nullptr));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_config(SQLITE_DBCONFIG_DQS_DDL) should not fail";
  sqlite_result_code = ToSqliteResultCode(
      sqlite3_db_config(db_, SQLITE_DBCONFIG_DQS_DML, 0, nullptr));
  DCHECK_EQ(sqlite_result_code, SqliteResultCode::kOk)
      << "sqlite3_db_config(SQLITE_DBCONFIG_DQS_DML) should not fail";

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

  // The use of triggers is discouraged for Chrome code. Thanks to this
  // configuration change, triggers are not executed. CREATE TRIGGER and DROP
  // TRIGGER still succeed.
  sqlite_result_code = ToSqliteResultCode(
      sqlite3_db_config(db_, SQLITE_DBCONFIG_ENABLE_TRIGGER, 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(SQL_FROM_HERE, "ROLLBACK"));

  rollback.Run();

  // The cache may have been accumulating dirty pages for commit.  Note that in
  // some cases sql::Transaction can fire rollback after a database is closed.
  if (is_open())
    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::set_histogram_tag(const std::string& tag) {
  DCHECK(!is_open());

  histogram_tag_ = tag;
}

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

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

  // 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()) {
    // 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);
    return;
  }
}

std::string Database::GetDiagnosticInfo(int sqlite_error_code,
                                        Statement* statement,
                                        DatabaseDiagnostics* diagnostics) {
  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),
                         SqlitePrepareFlags(), &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);
    base::StringPiece row_string(reinterpret_cast<const char*>(row), row_size);

    const std::vector<base::StringPiece> row_lines = base::SplitStringPiece(
        row_string, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    for (base::StringPiece 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::ReportMemoryUsage(base::trace_event::ProcessMemoryDump* pmd,
                                 const std::string& dump_name) {
  return memory_dump_provider_ &&
         memory_dump_provider_->ReportMemoryUsage(pmd, dump_name);
}

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() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
  InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);

  auto sqlite_result_code = ToSqliteResultCode(sqlite3_wal_checkpoint_v2(
      db_, kSqliteMainDatabaseName, SQLITE_CHECKPOINT_PASSIVE,
      /*pnLog=*/nullptr, /*pnCkpt=*/nullptr));

  return sqlite_result_code == SqliteResultCode::kOk;
}

}  // namespace sql
