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

#ifndef SQL_STATEMENT_H_
#define SQL_STATEMENT_H_

#include <stdint.h>

#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/dcheck_is_on.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "sql/database.h"

namespace base {
class RefCountedMemory;
}  // namespace base

namespace sql {

enum class SqliteResultCode : int;

// Possible return values from ColumnType in a statement. These should match
// the values in sqlite3.h.
enum class ColumnType {
  kInteger = 1,
  kFloat = 2,
  kText = 3,
  kBlob = 4,
  kNull = 5,
};

// Compiles and executes SQL statements.
//
// This class is not thread-safe. An instance must be accessed from a single
// sequence. This is enforced in DCHECK-enabled builds.
//
// Normal usage:
//   sql::Statement s(connection_.GetUniqueStatement(...));
//   s.BindInt(0, a);
//   if (s.Step())
//     return s.ColumnString(0);
//
//   If there are errors getting the statement, the statement will be inert; no
//   mutating or database-access methods will work. If you need to check for
//   validity, use:
//   if (!s.is_valid())
//     return false;
//
// Step() and Run() just return true to signal success. If you want to handle
// specific errors such as database corruption, install an error handler in
// in the connection object using set_error_delegate().
class COMPONENT_EXPORT(SQL) Statement {
 public:
  // Utility function that returns what //sql code encodes the 'time' value as
  // in a database when using BindTime
  static int64_t TimeToSqlValue(base::Time time);

  // Creates an uninitialized statement. The statement will be invalid until
  // you initialize it via Assign.
  Statement();

  explicit Statement(scoped_refptr<Database::StatementRef> ref);

  Statement(const Statement&) = delete;
  Statement& operator=(const Statement&) = delete;

  Statement(Statement&&) = delete;
  Statement& operator=(Statement&&) = delete;

  ~Statement();

  // Initializes this object with the given statement, which may or may not
  // be valid. Use is_valid() to check if it's OK.
  void Assign(scoped_refptr<Database::StatementRef> ref);

  // Resets the statement to an uninitialized state corresponding to
  // the default constructor, releasing the StatementRef.
  void Clear();

  // Returns true if the statement can be executed. All functions can still
  // be used if the statement is invalid, but they will return failure or some
  // default value. This is because the statement can become invalid in the
  // middle of executing a command if there is a serious error and the database
  // has to be reset.
  bool is_valid() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

    return ref_->is_valid();
  }

  // Running -------------------------------------------------------------------

  // Executes the statement, returning true on success. This is like Step but
  // for when there is no output, like an INSERT statement.
  bool Run();

  // Executes the statement, returning true if there is a row of data returned.
  // You can keep calling Step() until it returns false to iterate through all
  // the rows in your result set.
  //
  // When Step returns false, the result is either that there is no more data
  // or there is an error. This makes it most convenient for loop usage. If you
  // need to disambiguate these cases, use Succeeded().
  //
  // Typical example:
  //   while (s.Step()) {
  //     ...
  //   }
  //   return s.Succeeded();
  bool Step();

  // Resets the statement to its initial condition. This includes any current
  // result row, and also the bound variables if the |clear_bound_vars| is true.
  void Reset(bool clear_bound_vars);

  // Returns true if the last executed thing in this statement succeeded. If
  // there was no last executed thing or the statement is invalid, this will
  // return false.
  bool Succeeded() const;

  // Binding -------------------------------------------------------------------

  // These all take a 0-based parameter index and return true on success.
  // strings there may be out of memory.
  void BindNull(int param_index);
  void BindBool(int param_index, bool val);
  void BindInt(int param_index, int val);
  void BindInt(int param_index,
               int64_t val) = delete;  // Call BindInt64() instead.
  void BindInt64(int param_index, int64_t val);
  void BindDouble(int param_index, double val);
  void BindCString(int param_index, const char* val);
  void BindString(int param_index, std::string_view val);

  // If you need to store (potentially invalid) UTF-16 strings losslessly,
  // store them as BLOBs instead. `BindBlob()` has an overload for this purpose.
  void BindString16(int param_index, std::u16string_view value);

  // Binds a blob to the statement.
  void BindBlob(int param_index, scoped_refptr<base::RefCountedMemory> blob);

  // Convenience overloads for `BindBlob()`.
  void BindBlob(int param_index, std::string blob);
  void BindBlob(int param_index, std::u16string blob);
  void BindBlob(int param_index, std::vector<uint8_t> blob);
  void BindBlob(int param_index, base::span<const uint8_t> value);

  // Reserves `size` bytes of space for a blob. The actual bytes should be set
  // via a `StreamingBlobHandle`. This method will assert if `size` is too big
  // for the database, which by default means > 1GB.
  void BindBlobForStreaming(int param_index, uint64_t size);

  // Serializes a `base::Time` in full fidelity (the number of microseconds
  // since the Windows epic in UTC). This form of binding is preferred over
  // `t.ToInternalValue()` or `t.ToDeltaSinceWindowsEpoch().InMicroseconds()`.
  //
  // Legacy serializations of `base::Time` via other ways, such as `ToTimeT()`
  // or `InMillisecondsSinceUnixEpoch()`, require a database migration to be
  // converted to this (recommended) serialization method.
  void BindTime(int param_index, base::Time time);

  // Serializes a `base::TimeDelta` in full fidelity (a number of microseconds).
  // This form of binding is preferred over `d.ToInternalValue()` or
  // `d.InMicroseconds()`.
  void BindTimeDelta(int param_index, base::TimeDelta delta);

  // Retrieving ----------------------------------------------------------------

  // Returns the number of output columns in the result.
  int ColumnCount() const;

  // Returns the type associated with the given column.
  //
  // Watch out: the type may be undefined if you've done something to cause a
  // "type conversion." This means requesting the value of a column of a type
  // where that type is not the native type. For safety, call ColumnType only
  // on a column before getting the value out in any way.
  ColumnType GetColumnType(int col);

  // Returns the value at `column_index` (zero-based) in the current result set
  // produced by a successful call to `Step()`. `column_index` must be less than
  // the number of columns in the result set. Must only be called following a
  // successful call to `Step()`.
  bool ColumnBool(int column_index);
  int ColumnInt(int column_index);
  int64_t ColumnInt64(int column_index);
  double ColumnDouble(int column_index);
  std::string ColumnString(int column_index);

  // If you need to store and retrieve (potentially invalid) UTF-16 strings
  // losslessly, store them as BLOBs instead. They may be retrieved with
  // `ColumnBlobAsString16()`.
  std::u16string ColumnString16(int column_index);

  // Returns a string view pointing to a buffer containing the string data.
  //
  // This can be used to avoid allocating a temporary string when the value is
  // immediately passed to a function accepting a string view. Otherwise, the
  // string view's contents should be copied to a caller-owned buffer
  // immediately. Any method call on the `Statement` may invalidate the string
  // view.
  //
  // The string view will be empty (and may have a null data) if the underlying
  // string is empty. Code that needs to distinguish between empty strings and
  // NULL should call `GetColumnType()` before calling `ColumnStringView()`.
  std::string_view ColumnStringView(int column_index);

  // Conforms with base::Time serialization recommendations.
  //
  // This is equivalent to the following snippets, which should be replaced.
  // * base::Time::FromInternalValue(ColumnInt64(col))
  // * base::Time::FromDeltaSinceWindowsEpoch(
  //       base::Microseconds(ColumnInt64(col)))
  //
  // TODO(crbug.com/40176243): Migrate all time serialization to this method,
  // and then remove the migration details above.
  base::Time ColumnTime(int column_index);

  // Conforms with base::TimeDelta deserialization recommendations.
  //
  // This is equivalent to the following snippets, which should be replaced.
  // * base::TimeDelta::FromInternalValue(ColumnInt64(column_index))
  //
  // TODO(crbug.com/40251269): Migrate all TimeDelta serialization to this
  // method and remove the migration details above.
  base::TimeDelta ColumnTimeDelta(int column_index);

  // Returns a span pointing to a buffer containing the blob data.
  //
  // The span's contents should be copied to a caller-owned buffer immediately.
  // Any method call on the Statement may invalidate the span.
  //
  // The span will be empty (and may have a null data) if the underlying blob is
  // empty. Code that needs to distinguish between empty blobs and NULL should
  // call GetColumnType() before calling ColumnBlob().
  //
  // If you need to store and retrieve potentially invalid UTF-16 strings
  // losslessly, store them as BLOBs. They may be retrieved with
  // `ColumnBlobAsString16()`.
  base::span<const uint8_t> ColumnBlob(int column_index);

  // These convenience methods convert BLOB column data to various C++ types.
  std::string ColumnBlobAsString(int column_index);
  std::vector<uint8_t> ColumnBlobAsVector(int column_index);

  // This will return false if the underlying blob does not have an even
  // number of bytes. Otherwise, it will return true and copy the contents of
  // the blob to `result`. It does no validation on the contents of the blob.
  std::optional<std::u16string> ColumnBlobAsString16(int column_index);

  // Diagnostics --------------------------------------------------------------

  // Returns the original text of a SQL statement WITHOUT any bound values.
  // Intended for logging in case of failures. Note that DOES NOT return any
  // bound values, because that would cause a privacy / PII issue for logging.
  std::string GetSQLStatement();

 private:
  friend class Database;

  // Checks SQLite result codes and handles any errors.
  //
  // Returns `sqlite_result_code`. This gives callers the convenience of writing
  // "return CheckSqliteResultCode(sqlite_result_code)" and gives the compiler
  // the opportunity of doing tail call optimization (TCO) on the code above.
  //
  // This method reports error codes to the associated Database, and updates
  // internal state to reflect whether the statement succeeded or not.
  SqliteResultCode CheckSqliteResultCode(SqliteResultCode sqlite_result_code);

  // Should be called by all mutating methods to check that the statement is
  // valid. Returns true if the statement is valid. DCHECKS and returns false
  // if it is not.
  // The reason for this is to handle two specific cases in which a Statement
  // may be invalid. The first case is that the programmer made an SQL error.
  // Those cases need to be DCHECKed so that we are guaranteed to find them
  // before release. The second case is that the computer has an error (probably
  // out of disk space) which is prohibiting the correct operation of the
  // database. Our testing apparatus should not exhibit this defect, but release
  // situations may. Therefore, the code is handling disjoint situations in
  // release and test. In test, we're ensuring correct SQL. In release, we're
  // ensuring that contracts are honored in error edge cases.
  bool CheckValid() const;

  // Crashes the process if `this` is not in a state that allows reading from
  // columns (i.e. `Step()` was called and succeeded), and specifically the
  // given column.
  void CheckCanReadColumn(int column_index) const;

  // Helper for Run() and Step(), calls sqlite3_step() and returns the checked
  // value from it.
  SqliteResultCode StepInternal();

  // Retrieve and log the count of VM steps required to execute the query.
  void ReportQueryExecutionMetrics() const;

  // Runs some basic sanity checks and frees memory previously associated with
  // `param_index`, if any. Should be called when a parameter is about to be
  // bound regardless of its type.
  void WillBindParameter(int param_index)
      VALID_CONTEXT_REQUIRED(sequence_checker_);

  // The actual sqlite statement. This may be unique to us, or it may be cached
  // by the Database, which is why it's ref-counted. This pointer is
  // guaranteed non-null.
  scoped_refptr<Database::StatementRef> ref_
      GUARDED_BY_CONTEXT(sequence_checker_);

  // The result code for the last `Run()` or `Step()`.
  std::optional<SqliteResultCode> last_sqlite_result_code_
      GUARDED_BY_CONTEXT(sequence_checker_);

#if DCHECK_IS_ON()
  // Used to DCHECK() that Bind*() is called before Step() or Run() are called.
  bool step_called_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
  bool run_called_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
#endif  // DCHECK_IS_ON()

  std::optional<base::TimeDelta> time_spent_stepping_ = std::nullopt;

  SEQUENCE_CHECKER(sequence_checker_);
};

}  // namespace sql

#endif  // SQL_STATEMENT_H_
