1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sql/statement.h"
10 #include "base/logging.h"
11 #include "base/numerics/safe_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "third_party/sqlite/sqlite3.h"
18 // This empty constructor initializes our reference with an empty one so that
19 // we don't have to null-check the ref_ to see if the statement is valid: we
20 // only have to check the ref's validity bit.
21 Statement::Statement()
22 : ref_(base::MakeRefCounted<Database::StatementRef>(nullptr,
28 Statement::Statement(scoped_refptr<Database::StatementRef> ref)
29 : ref_(std::move(ref)), stepped_(false), succeeded_(false) {}
31 Statement::~Statement() {
32 // Free the resources associated with this statement. We assume there's only
33 // one statement active for a given sqlite3_stmt at any time, so this won't
34 // mess with anything.
38 void Statement::Assign(scoped_refptr<Database::StatementRef> ref) {
40 ref_ = std::move(ref);
43 void Statement::Clear() {
44 Assign(base::MakeRefCounted<Database::StatementRef>(nullptr, nullptr, false));
48 bool Statement::CheckValid() const {
49 // Allow operations to fail silently if a statement was invalidated
50 // because the database was closed by an error handler.
51 DLOG_IF(FATAL, !ref_->was_valid())
52 << "Cannot call mutating statements on an invalid statement.";
56 int Statement::StepInternal() {
60 base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
61 ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
64 int ret = sqlite3_step(ref_->stmt());
65 return CheckError(ret);
68 bool Statement::Run() {
70 return StepInternal() == SQLITE_DONE;
73 bool Statement::Step() {
74 return StepInternal() == SQLITE_ROW;
77 void Statement::Reset(bool clear_bound_vars) {
78 base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
79 ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
82 sqlite3_clear_bindings(ref_->stmt());
84 // StepInternal() cannot track success because statements may be reset
85 // before reaching SQLITE_DONE. Don't call CheckError() because
86 // sqlite3_reset() returns the last step error, which StepInternal() already
88 sqlite3_reset(ref_->stmt());
91 // Potentially release dirty cache pages if an autocommit statement made
94 ref_->database()->ReleaseCacheMemoryIfNeeded(false);
100 bool Statement::Succeeded() const {
101 return is_valid() && succeeded_;
104 bool Statement::BindNull(int col) {
107 return is_valid() && CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
110 bool Statement::BindBool(int col, bool val) {
111 return BindInt(col, val ? 1 : 0);
114 bool Statement::BindInt(int col, int val) {
117 return is_valid() && CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
120 bool Statement::BindInt64(int col, int64_t val) {
123 return is_valid() && CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
126 bool Statement::BindDouble(int col, double val) {
129 return is_valid() && CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
132 bool Statement::BindCString(int col, const char* val) {
135 return is_valid() && CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val, -1,
139 bool Statement::BindString(int col, const std::string& val) {
143 CheckOk(sqlite3_bind_text(ref_->stmt(), col + 1, val.data(),
144 base::checked_cast<int>(val.size()),
148 bool Statement::BindString16(int col, const base::string16& value) {
149 return BindString(col, base::UTF16ToUTF8(value));
152 bool Statement::BindBlob(int col, const void* val, int val_len) {
155 return is_valid() && CheckOk(sqlite3_bind_blob(ref_->stmt(), col + 1, val,
156 val_len, SQLITE_TRANSIENT));
159 int Statement::ColumnCount() const {
162 return sqlite3_column_count(ref_->stmt());
165 // Verify that our enum matches sqlite's values.
166 static_assert(static_cast<int>(ColumnType::kInteger) == SQLITE_INTEGER,
168 static_assert(static_cast<int>(ColumnType::kFloat) == SQLITE_FLOAT,
170 static_assert(static_cast<int>(ColumnType::kText) == SQLITE_TEXT,
172 static_assert(static_cast<int>(ColumnType::kBlob) == SQLITE_BLOB,
174 static_assert(static_cast<int>(ColumnType::kNull) == SQLITE_NULL,
177 ColumnType Statement::GetColumnType(int col) const {
178 return static_cast<enum ColumnType>(sqlite3_column_type(ref_->stmt(), col));
181 bool Statement::ColumnBool(int col) const {
182 return static_cast<bool>(ColumnInt(col));
185 int Statement::ColumnInt(int col) const {
188 return sqlite3_column_int(ref_->stmt(), col);
191 int64_t Statement::ColumnInt64(int col) const {
194 return sqlite3_column_int64(ref_->stmt(), col);
197 double Statement::ColumnDouble(int col) const {
200 return sqlite3_column_double(ref_->stmt(), col);
203 std::string Statement::ColumnString(int col) const {
205 return std::string();
207 const char* str = reinterpret_cast<const char*>(
208 sqlite3_column_text(ref_->stmt(), col));
209 int len = sqlite3_column_bytes(ref_->stmt(), col);
213 result.assign(str, len);
217 base::string16 Statement::ColumnString16(int col) const {
219 return base::string16();
221 std::string s = ColumnString(col);
222 return !s.empty() ? base::UTF8ToUTF16(s) : base::string16();
225 int Statement::ColumnByteLength(int col) const {
228 return sqlite3_column_bytes(ref_->stmt(), col);
231 const void* Statement::ColumnBlob(int col) const {
235 return sqlite3_column_blob(ref_->stmt(), col);
238 bool Statement::ColumnBlobAsString(int col, std::string* blob) const {
242 const void* p = ColumnBlob(col);
243 size_t len = ColumnByteLength(col);
245 if (blob->size() != len) {
248 blob->assign(reinterpret_cast<const char*>(p), len);
252 bool Statement::ColumnBlobAsString16(int col, base::string16* val) const {
256 const void* data = ColumnBlob(col);
257 size_t len = ColumnByteLength(col) / sizeof(base::char16);
259 if (val->size() != len)
261 val->assign(reinterpret_cast<const base::char16*>(data), len);
265 bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
271 const void* data = sqlite3_column_blob(ref_->stmt(), col);
272 int len = sqlite3_column_bytes(ref_->stmt(), col);
273 if (data && len > 0) {
275 memcpy(&(*val)[0], data, len);
280 bool Statement::ColumnBlobAsVector(
282 std::vector<unsigned char>* val) const {
283 return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
286 const char* Statement::GetSQLStatement() {
287 return sqlite3_sql(ref_->stmt());
290 bool Statement::CheckOk(int err) const {
291 // Binding to a non-existent variable is evidence of a serious error.
292 // TODO(gbillock,shess): make this invalidate the statement so it
293 // can't wreak havoc.
294 DCHECK_NE(err, SQLITE_RANGE) << "Bind value out of range";
295 return err == SQLITE_OK;
298 int Statement::CheckError(int err) {
299 // Please don't add DCHECKs here, OnSqliteError() already has them.
300 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
301 if (!succeeded_ && ref_.get() && ref_->database())
302 return ref_->database()->OnSqliteError(err, this, nullptr);