// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sql/statement.h"

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

#include "base/containers/span.h"
#include "base/dcheck_is_on.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/sequence_checker.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "sql/sqlite_result_code.h"
#include "sql/sqlite_result_code_values.h"
#include "third_party/sqlite/sqlite3.h"

namespace sql {

// This empty constructor initializes our reference with an empty one so that
// we don't have to null-check the ref_ to see if the statement is valid: we
// only have to check the ref's validity bit.
Statement::Statement()
    : ref_(base::MakeRefCounted<Database::StatementRef>(nullptr,
                                                        nullptr,
                                                        false)) {}

Statement::Statement(scoped_refptr<Database::StatementRef> ref)
    : ref_(std::move(ref)) {}

Statement::~Statement() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Free the resources associated with this statement. We assume there's only
  // one statement active for a given sqlite3_stmt at any time, so this won't
  // mess with anything.
  Reset(true);
}

void Statement::Assign(scoped_refptr<Database::StatementRef> ref) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  Reset(true);
  ref_ = std::move(ref);
}

void Statement::Clear() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  Assign(base::MakeRefCounted<Database::StatementRef>(nullptr, nullptr, false));
  succeeded_ = false;
}

bool Statement::CheckValid() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Allow operations to fail silently if a statement was invalidated
  // because the database was closed by an error handler.
  DLOG_IF(FATAL, !ref_->was_valid())
      << "Cannot call mutating statements on an invalid statement.";
  return is_valid();
}

SqliteResultCode Statement::StepInternal() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!CheckValid())
    return SqliteResultCode::kError;

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

  auto sqlite_result_code = ToSqliteResultCode(sqlite3_step(ref_->stmt()));
  return CheckSqliteResultCode(sqlite_result_code);
}

bool Statement::Run() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << "Run() must be called exactly once";
  run_called_ = true;
  DCHECK(!step_called_) << "Run() must not be mixed with Step()";
#endif  // DCHECK_IS_ON()
  return StepInternal() == SqliteResultCode::kDone;
}

bool Statement::Step() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << "Run() must not be mixed with Step()";
  step_called_ = true;
#endif  // DCHECK_IS_ON()
  return StepInternal() == SqliteResultCode::kRow;
}

void Statement::Reset(bool clear_bound_vars) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
  ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
  if (is_valid()) {
    if (clear_bound_vars)
      sqlite3_clear_bindings(ref_->stmt());

    // StepInternal() cannot track success because statements may be reset
    // before reaching SQLITE_DONE.  Don't call CheckError() because
    // sqlite3_reset() returns the last step error, which StepInternal() already
    // checked.
    sqlite3_reset(ref_->stmt());
  }

  // Potentially release dirty cache pages if an autocommit statement made
  // changes.
  if (ref_->database())
    ref_->database()->ReleaseCacheMemoryIfNeeded(false);

  succeeded_ = false;
#if DCHECK_IS_ON()
  run_called_ = false;
  step_called_ = false;
#endif  // DCHECK_IS_ON()
}

bool Statement::Succeeded() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return is_valid() && succeeded_;
}

void Statement::BindNull(int param_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";
  int sqlite_result_code = sqlite3_bind_null(ref_->stmt(), param_index + 1);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

void Statement::BindBool(int param_index, bool val) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return BindInt64(param_index, val ? 1 : 0);
}

void Statement::BindInt(int param_index, int val) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";
  int sqlite_result_code = sqlite3_bind_int(ref_->stmt(), param_index + 1, val);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

void Statement::BindInt64(int param_index, int64_t val) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";
  int sqlite_result_code =
      sqlite3_bind_int64(ref_->stmt(), param_index + 1, val);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

void Statement::BindDouble(int param_index, double val) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";
  int sqlite_result_code =
      sqlite3_bind_double(ref_->stmt(), param_index + 1, val);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

void Statement::BindTime(int param_index, base::Time val) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";
  int64_t int_value = val.ToDeltaSinceWindowsEpoch().InMicroseconds();
  int sqlite_result_code =
      sqlite3_bind_int64(ref_->stmt(), param_index + 1, int_value);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

void Statement::BindCString(int param_index, const char* val) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  DCHECK(val);
  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";

  // If the string length is more than SQLITE_MAX_LENGTH (or the per-database
  // SQLITE_LIMIT_LENGTH limit), sqlite3_bind_text() fails with SQLITE_TOOBIG.
  //
  // We're not currently handling this error. SQLITE_MAX_LENGTH is set to the
  // default (1 billion bytes) in Chrome's SQLite build, so this is an unlilely
  // issue.

  int sqlite_result_code = sqlite3_bind_text(ref_->stmt(), param_index + 1, val,
                                             -1, SQLITE_TRANSIENT);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

void Statement::BindString(int param_index, base::StringPiece value) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";

  // base::StringPiece::data() may return null for empty pieces. In particular,
  // this may happen when the StringPiece is created from the default
  // constructor.
  //
  // However, sqlite3_bind_text() always interprets a nullptr data argument as a
  // NULL value, instead of an empty BLOB value.
  static constexpr char kEmptyPlaceholder[] = {0x00};
  const char* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder;

  // If the string length is more than SQLITE_MAX_LENGTH (or the per-database
  // SQLITE_LIMIT_LENGTH limit), sqlite3_bind_text() fails with SQLITE_TOOBIG.
  //
  // We're not currently handling this error. SQLITE_MAX_LENGTH is set to the
  // default (1 billion bytes) in Chrome's SQLite build, so this is an unlilely
  // issue.

  int sqlite_result_code = sqlite3_bind_text(
      ref_->stmt(), param_index + 1, data, value.size(), SQLITE_TRANSIENT);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

void Statement::BindString16(int param_index, base::StringPiece16 value) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return BindString(param_index, base::UTF16ToUTF8(value));
}

void Statement::BindBlob(int param_index, base::span<const uint8_t> value) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " must not be called after Run()";
  DCHECK(!step_called_) << __func__ << " must not be called after Step()";
#endif  // DCHECK_IS_ON()

  if (!is_valid())
    return;

  DCHECK_GE(param_index, 0);
  DCHECK_LT(param_index, sqlite3_bind_parameter_count(ref_->stmt()))
      << "Invalid parameter index";

  // span::data() may return null for empty spans. In particular, this may
  // happen when the span is created out of a std::vector, because
  // std::vector::data() may (or may not) return null for empty vectors.
  //
  // However, sqlite3_bind_blob() always interprets a nullptr data argument as a
  // NULL value, instead of an empty BLOB value.
  //
  // While the difference between NULL and an empty BLOB may not matter in some
  // cases, it may also cause subtle bugs in other cases. So, we cannot pass
  // span.data() directly to sqlite3_bind_blob().
  static constexpr uint8_t kEmptyPlaceholder[] = {0x00};
  const uint8_t* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder;

  // If the string length is more than SQLITE_MAX_LENGTH (or the per-database
  // SQLITE_LIMIT_LENGTH limit), sqlite3_bind_text() fails with SQLITE_TOOBIG.
  //
  // We're not currently handling this error. SQLITE_MAX_LENGTH is set to the
  // default (1 billion bytes) in Chrome's SQLite build, so this is an unlilely
  // issue.

  int sqlite_result_code = sqlite3_bind_blob(
      ref_->stmt(), param_index + 1, data, value.size(), SQLITE_TRANSIENT);
  DCHECK_EQ(sqlite_result_code, SQLITE_OK);
}

int Statement::ColumnCount() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!is_valid())
    return 0;
  return sqlite3_column_count(ref_->stmt());
}

// Verify that our enum matches sqlite's values.
static_assert(static_cast<int>(ColumnType::kInteger) == SQLITE_INTEGER,
              "INTEGER mismatch");
static_assert(static_cast<int>(ColumnType::kFloat) == SQLITE_FLOAT,
              "FLOAT mismatch");
static_assert(static_cast<int>(ColumnType::kText) == SQLITE_TEXT,
              "TEXT mismatch");
static_assert(static_cast<int>(ColumnType::kBlob) == SQLITE_BLOB,
              "BLOB mismatch");
static_assert(static_cast<int>(ColumnType::kNull) == SQLITE_NULL,
              "NULL mismatch");

ColumnType Statement::GetColumnType(int col) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  return static_cast<enum ColumnType>(sqlite3_column_type(ref_->stmt(), col));
}

bool Statement::ColumnBool(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return static_cast<bool>(ColumnInt64(column_index));
}

int Statement::ColumnInt(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return 0;
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  return sqlite3_column_int(ref_->stmt(), column_index);
}

int64_t Statement::ColumnInt64(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return 0;
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  return sqlite3_column_int64(ref_->stmt(), column_index);
}

double Statement::ColumnDouble(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return 0;
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  return sqlite3_column_double(ref_->stmt(), column_index);
}

base::Time Statement::ColumnTime(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return base::Time();
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  int64_t int_value = sqlite3_column_int64(ref_->stmt(), column_index);
  return base::Time::FromDeltaSinceWindowsEpoch(base::Microseconds(int_value));
}

std::string Statement::ColumnString(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return std::string();
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  const char* string_buffer = reinterpret_cast<const char*>(
      sqlite3_column_text(ref_->stmt(), column_index));
  int size = sqlite3_column_bytes(ref_->stmt(), column_index);

  std::string result;
  if (string_buffer && size > 0)
    result.assign(string_buffer, size);
  return result;
}

std::u16string Statement::ColumnString16(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return std::u16string();
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  std::string string = ColumnString(column_index);
  return string.empty() ? std::u16string() : base::UTF8ToUTF16(string);
}

base::span<const uint8_t> Statement::ColumnBlob(int column_index) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return base::span<const uint8_t>();
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  int result_size = sqlite3_column_bytes(ref_->stmt(), column_index);
  const void* result_buffer = sqlite3_column_blob(ref_->stmt(), column_index);
  DCHECK(result_size == 0 || result_buffer != nullptr)
      << "sqlite3_column_blob() returned a null buffer for a non-empty BLOB";

  return base::make_span(static_cast<const uint8_t*>(result_buffer),
                         result_size);
}

bool Statement::ColumnBlobAsString(int column_index, std::string* result) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return false;
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  const void* result_buffer = sqlite3_column_blob(ref_->stmt(), column_index);
  int size = sqlite3_column_bytes(ref_->stmt(), column_index);
  if (result_buffer && size > 0) {
    result->assign(reinterpret_cast<const char*>(result_buffer), size);
  } else {
    result->clear();
  }
  return true;
}

bool Statement::ColumnBlobAsVector(int column_index,
                                   std::vector<char>* result) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if DCHECK_IS_ON()
  DCHECK(!run_called_) << __func__ << " can be used after Step(), not Run()";
  DCHECK(step_called_) << __func__ << " can only be used after Step()";
#endif  // DCHECK_IS_ON()

  if (!CheckValid())
    return false;
  DCHECK_GE(column_index, 0);
  DCHECK_LT(column_index, sqlite3_data_count(ref_->stmt()))
      << "Invalid column index";

  const void* result_buffer = sqlite3_column_blob(ref_->stmt(), column_index);
  int size = sqlite3_column_bytes(ref_->stmt(), column_index);
  if (result_buffer && size > 0) {
    // Unlike std::string, std::vector does not have an assign() overload that
    // takes a buffer and a size.
    result->assign(static_cast<const char*>(result_buffer),
                   static_cast<const char*>(result_buffer) + size);
  } else {
    result->clear();
  }
  return true;
}

bool Statement::ColumnBlobAsVector(int column_index,
                                   std::vector<uint8_t>* result) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return ColumnBlobAsVector(column_index,
                            reinterpret_cast<std::vector<char>*>(result));
}

std::string Statement::GetSQLStatement() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // SQLite promises to keep the returned buffer alive until the statement is
  // finalized. We immediately copy the buffer contents into a std::string so we
  // don't need to worry about its lifetime. The performance overhead is
  // acceptable because this method should only be invoked for logging details
  // about SQLite errors.
  //
  // We use sqlite3_sql() instead of sqlite3_expanded_sql() because:
  //  - The returned SQL string matches the source code, making it easy to
  //    search.
  //  - This works with SQL statements that work with large data, such as BLOBS
  //    storing images.
  //  - The returned string is free of bound values, so it does not contain any
  //    PII that would raise privacy concerns around logging.
  //
  // Do not change this to use sqlite3_expanded_sql(). If that need ever arises
  // in the future, make a new function instead listing the above caveats.
  //
  // See https://www.sqlite.org/c3ref/expanded_sql.html for more details on the
  // difference between sqlite3_sql() and sqlite3_expanded_sql().
  return sqlite3_sql(ref_->stmt());
}

SqliteResultCode Statement::CheckSqliteResultCode(
    SqliteResultCode sqlite_result_code) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  succeeded_ = IsSqliteSuccessCode(sqlite_result_code);
  if (!succeeded_ && ref_.get() && ref_->database()) {
    auto sqlite_error_code = ToSqliteErrorCode(sqlite_result_code);
    ref_->database()->OnSqliteError(sqlite_error_code, this, nullptr);
  }
  return sqlite_result_code;
}

}  // namespace sql
