blob: 5778fd0d7daf930b06698e2c632a985e4d254148 [file] [log] [blame]
[email protected]98b6f8b12012-02-10 13:31:591// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]e5ffd0e42009-09-11 21:30:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f0a54b22011-07-19 18:40:215#include "sql/statement.h"
[email protected]e5ffd0e42009-09-11 21:30:566
avi0b519202015-12-21 07:25:197#include <stddef.h>
8#include <stdint.h>
9
[email protected]e5ffd0e42009-09-11 21:30:5610#include "base/logging.h"
[email protected]a4bbc1f92013-06-11 07:28:1911#include "base/strings/string_util.h"
[email protected]906265872013-06-07 22:40:4512#include "base/strings/utf_string_conversions.h"
[email protected]e33cba42010-08-18 23:37:0313#include "third_party/sqlite/sqlite3.h"
[email protected]e5ffd0e42009-09-11 21:30:5614
15namespace sql {
16
17// This empty constructor initializes our reference with an empty one so that
18// we don't have to NULL-check the ref_ to see if the statement is valid: we
19// only have to check the ref's validity bit.
20Statement::Statement()
[email protected]41a97c812013-02-07 02:35:3821 : ref_(new Connection::StatementRef(NULL, NULL, false)),
[email protected]097723d2013-10-25 20:09:3222 stepped_(false),
[email protected]e5ffd0e42009-09-11 21:30:5623 succeeded_(false) {
24}
25
26Statement::Statement(scoped_refptr<Connection::StatementRef> ref)
27 : ref_(ref),
[email protected]097723d2013-10-25 20:09:3228 stepped_(false),
[email protected]e5ffd0e42009-09-11 21:30:5629 succeeded_(false) {
30}
31
32Statement::~Statement() {
33 // Free the resources associated with this statement. We assume there's only
34 // one statement active for a given sqlite3_stmt at any time, so this won't
35 // mess with anything.
[email protected]389e0a42012-04-25 21:36:4136 Reset(true);
[email protected]e5ffd0e42009-09-11 21:30:5637}
38
39void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) {
[email protected]389e0a42012-04-25 21:36:4140 Reset(true);
[email protected]e5ffd0e42009-09-11 21:30:5641 ref_ = ref;
42}
43
[email protected]85fc27b02012-02-17 02:15:0944void Statement::Clear() {
[email protected]41a97c812013-02-07 02:35:3845 Assign(new Connection::StatementRef(NULL, NULL, false));
[email protected]85fc27b02012-02-17 02:15:0946 succeeded_ = false;
47}
48
[email protected]eff1fa522011-12-12 23:50:5949bool Statement::CheckValid() const {
[email protected]41a97c812013-02-07 02:35:3850 // Allow operations to fail silently if a statement was invalidated
51 // because the database was closed by an error handler.
52 DLOG_IF(FATAL, !ref_->was_valid())
53 << "Cannot call mutating statements on an invalid statement.";
[email protected]eff1fa522011-12-12 23:50:5954 return is_valid();
55}
56
shess58b8df82015-06-03 00:19:3257int Statement::StepInternal(bool timer_flag) {
[email protected]35f7e5392012-07-27 19:54:5058 ref_->AssertIOAllowed();
[email protected]eff1fa522011-12-12 23:50:5959 if (!CheckValid())
shess58b8df82015-06-03 00:19:3260 return SQLITE_ERROR;
[email protected]eff1fa522011-12-12 23:50:5961
shess58b8df82015-06-03 00:19:3262 const bool was_stepped = stepped_;
[email protected]097723d2013-10-25 20:09:3263 stepped_ = true;
shess58b8df82015-06-03 00:19:3264 int ret = SQLITE_ERROR;
65 if (!ref_->connection()) {
66 ret = sqlite3_step(ref_->stmt());
67 } else {
68 if (!timer_flag) {
69 ret = sqlite3_step(ref_->stmt());
70 } else {
71 const base::TimeTicks before = ref_->connection()->Now();
72 ret = sqlite3_step(ref_->stmt());
73 const base::TimeTicks after = ref_->connection()->Now();
74 const bool read_only = !!sqlite3_stmt_readonly(ref_->stmt());
75 ref_->connection()->RecordTimeAndChanges(after - before, read_only);
76 }
77
78 if (!was_stepped)
79 ref_->connection()->RecordOneEvent(Connection::EVENT_STATEMENT_RUN);
80
81 if (ret == SQLITE_ROW)
82 ref_->connection()->RecordOneEvent(Connection::EVENT_STATEMENT_ROWS);
83 }
84 return CheckError(ret);
85}
86
87bool Statement::Run() {
88 DCHECK(!stepped_);
89 return StepInternal(true) == SQLITE_DONE;
90}
91
92bool Statement::RunWithoutTimers() {
93 DCHECK(!stepped_);
94 return StepInternal(false) == SQLITE_DONE;
[email protected]e5ffd0e42009-09-11 21:30:5695}
96
97bool Statement::Step() {
shess58b8df82015-06-03 00:19:3298 return StepInternal(true) == SQLITE_ROW;
[email protected]e5ffd0e42009-09-11 21:30:5699}
100
[email protected]389e0a42012-04-25 21:36:41101void Statement::Reset(bool clear_bound_vars) {
[email protected]35f7e5392012-07-27 19:54:50102 ref_->AssertIOAllowed();
[email protected]faa604e2009-09-25 22:38:59103 if (is_valid()) {
[email protected]389e0a42012-04-25 21:36:41104 if (clear_bound_vars)
105 sqlite3_clear_bindings(ref_->stmt());
shess58b8df82015-06-03 00:19:32106
107 // StepInternal() cannot track success because statements may be reset
108 // before reaching SQLITE_DONE. Don't call CheckError() because
109 // sqlite3_reset() returns the last step error, which StepInternal() already
110 // checked.
111 const int rc =sqlite3_reset(ref_->stmt());
112 if (rc == SQLITE_OK && ref_->connection())
113 ref_->connection()->RecordOneEvent(Connection::EVENT_STATEMENT_SUCCESS);
[email protected]faa604e2009-09-25 22:38:59114 }
[email protected]eff1fa522011-12-12 23:50:59115
shess7dbd4dee2015-10-06 17:39:16116 // Potentially release dirty cache pages if an autocommit statement made
117 // changes.
118 if (ref_->connection())
119 ref_->connection()->ReleaseCacheMemoryIfNeeded(false);
120
[email protected]e5ffd0e42009-09-11 21:30:56121 succeeded_ = false;
[email protected]097723d2013-10-25 20:09:32122 stepped_ = false;
[email protected]e5ffd0e42009-09-11 21:30:56123}
124
125bool Statement::Succeeded() const {
126 if (!is_valid())
127 return false;
[email protected]eff1fa522011-12-12 23:50:59128
[email protected]e5ffd0e42009-09-11 21:30:56129 return succeeded_;
130}
131
132bool Statement::BindNull(int col) {
[email protected]097723d2013-10-25 20:09:32133 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59134 if (!is_valid())
135 return false;
136
137 return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
[email protected]e5ffd0e42009-09-11 21:30:56138}
139
[email protected]765b44502009-10-02 05:01:42140bool Statement::BindBool(int col, bool val) {
141 return BindInt(col, val ? 1 : 0);
142}
143
[email protected]e5ffd0e42009-09-11 21:30:56144bool Statement::BindInt(int col, int val) {
[email protected]097723d2013-10-25 20:09:32145 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59146 if (!is_valid())
147 return false;
148
149 return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56150}
151
tfarina720d4f32015-05-11 22:31:26152bool Statement::BindInt64(int col, int64_t val) {
[email protected]097723d2013-10-25 20:09:32153 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59154 if (!is_valid())
155 return false;
156
157 return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56158}
159
160bool Statement::BindDouble(int col, double val) {
[email protected]097723d2013-10-25 20:09:32161 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59162 if (!is_valid())
163 return false;
164
165 return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56166}
167
168bool Statement::BindCString(int col, const char* val) {
[email protected]097723d2013-10-25 20:09:32169 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59170 if (!is_valid())
171 return false;
172
173 return CheckOk(
174 sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56175}
176
177bool Statement::BindString(int col, const std::string& val) {
[email protected]097723d2013-10-25 20:09:32178 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59179 if (!is_valid())
180 return false;
181
182 return CheckOk(sqlite3_bind_text(ref_->stmt(),
183 col + 1,
184 val.data(),
185 val.size(),
186 SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56187}
188
[email protected]fcf75d42013-12-03 20:11:26189bool Statement::BindString16(int col, const base::string16& value) {
[email protected]6c3bf032013-12-25 19:37:03190 return BindString(col, base::UTF16ToUTF8(value));
[email protected]5eea1162010-05-11 17:14:16191}
192
[email protected]e5ffd0e42009-09-11 21:30:56193bool Statement::BindBlob(int col, const void* val, int val_len) {
[email protected]097723d2013-10-25 20:09:32194 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59195 if (!is_valid())
196 return false;
197
198 return CheckOk(
199 sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56200}
201
202int Statement::ColumnCount() const {
[email protected]eff1fa522011-12-12 23:50:59203 if (!is_valid())
[email protected]e5ffd0e42009-09-11 21:30:56204 return 0;
[email protected]eff1fa522011-12-12 23:50:59205
[email protected]e5ffd0e42009-09-11 21:30:56206 return sqlite3_column_count(ref_->stmt());
207}
208
[email protected]765b44502009-10-02 05:01:42209ColType Statement::ColumnType(int col) const {
210 // Verify that our enum matches sqlite's values.
mostynbddbabe72015-01-06 00:20:50211 static_assert(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, "integer no match");
212 static_assert(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, "float no match");
213 static_assert(COLUMN_TYPE_TEXT == SQLITE_TEXT, "integer no match");
214 static_assert(COLUMN_TYPE_BLOB == SQLITE_BLOB, "blob no match");
215 static_assert(COLUMN_TYPE_NULL == SQLITE_NULL, "null no match");
[email protected]765b44502009-10-02 05:01:42216
217 return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
218}
219
[email protected]98b6f8b12012-02-10 13:31:59220ColType Statement::DeclaredColumnType(int col) const {
brettw8e2106d2015-08-11 19:30:22221 std::string column_type = base::ToLowerASCII(
222 sqlite3_column_decltype(ref_->stmt(), col));
[email protected]98b6f8b12012-02-10 13:31:59223
224 if (column_type == "integer")
225 return COLUMN_TYPE_INTEGER;
226 else if (column_type == "float")
227 return COLUMN_TYPE_FLOAT;
228 else if (column_type == "text")
229 return COLUMN_TYPE_TEXT;
230 else if (column_type == "blob")
231 return COLUMN_TYPE_BLOB;
232
233 return COLUMN_TYPE_NULL;
234}
235
[email protected]765b44502009-10-02 05:01:42236bool Statement::ColumnBool(int col) const {
237 return !!ColumnInt(col);
238}
239
[email protected]e5ffd0e42009-09-11 21:30:56240int Statement::ColumnInt(int col) const {
[email protected]eff1fa522011-12-12 23:50:59241 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56242 return 0;
[email protected]eff1fa522011-12-12 23:50:59243
[email protected]e5ffd0e42009-09-11 21:30:56244 return sqlite3_column_int(ref_->stmt(), col);
245}
246
tfarina720d4f32015-05-11 22:31:26247int64_t Statement::ColumnInt64(int col) const {
[email protected]eff1fa522011-12-12 23:50:59248 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56249 return 0;
[email protected]eff1fa522011-12-12 23:50:59250
[email protected]e5ffd0e42009-09-11 21:30:56251 return sqlite3_column_int64(ref_->stmt(), col);
252}
253
254double Statement::ColumnDouble(int col) const {
[email protected]eff1fa522011-12-12 23:50:59255 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56256 return 0;
[email protected]eff1fa522011-12-12 23:50:59257
[email protected]e5ffd0e42009-09-11 21:30:56258 return sqlite3_column_double(ref_->stmt(), col);
259}
260
261std::string Statement::ColumnString(int col) const {
[email protected]eff1fa522011-12-12 23:50:59262 if (!CheckValid())
[email protected]007b3f82013-04-09 08:46:45263 return std::string();
[email protected]eff1fa522011-12-12 23:50:59264
[email protected]e5ffd0e42009-09-11 21:30:56265 const char* str = reinterpret_cast<const char*>(
266 sqlite3_column_text(ref_->stmt(), col));
267 int len = sqlite3_column_bytes(ref_->stmt(), col);
268
269 std::string result;
270 if (str && len > 0)
271 result.assign(str, len);
272 return result;
273}
274
[email protected]fcf75d42013-12-03 20:11:26275base::string16 Statement::ColumnString16(int col) const {
[email protected]eff1fa522011-12-12 23:50:59276 if (!CheckValid())
[email protected]fcf75d42013-12-03 20:11:26277 return base::string16();
[email protected]eff1fa522011-12-12 23:50:59278
[email protected]5eea1162010-05-11 17:14:16279 std::string s = ColumnString(col);
[email protected]6c3bf032013-12-25 19:37:03280 return !s.empty() ? base::UTF8ToUTF16(s) : base::string16();
[email protected]5eea1162010-05-11 17:14:16281}
282
[email protected]1ed78a32009-09-15 20:24:17283int Statement::ColumnByteLength(int col) const {
[email protected]eff1fa522011-12-12 23:50:59284 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56285 return 0;
[email protected]eff1fa522011-12-12 23:50:59286
[email protected]e5ffd0e42009-09-11 21:30:56287 return sqlite3_column_bytes(ref_->stmt(), col);
288}
289
[email protected]1ed78a32009-09-15 20:24:17290const void* Statement::ColumnBlob(int col) const {
[email protected]eff1fa522011-12-12 23:50:59291 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56292 return NULL;
[email protected]e5ffd0e42009-09-11 21:30:56293
294 return sqlite3_column_blob(ref_->stmt(), col);
295}
296
vabrb194fc562016-07-13 08:46:37297bool Statement::ColumnBlobAsString(int col, std::string* blob) const {
[email protected]eff1fa522011-12-12 23:50:59298 if (!CheckValid())
[email protected]5eea1162010-05-11 17:14:16299 return false;
[email protected]eff1fa522011-12-12 23:50:59300
[email protected]5eea1162010-05-11 17:14:16301 const void* p = ColumnBlob(col);
302 size_t len = ColumnByteLength(col);
303 blob->resize(len);
304 if (blob->size() != len) {
305 return false;
306 }
307 blob->assign(reinterpret_cast<const char*>(p), len);
308 return true;
309}
310
[email protected]fcf75d42013-12-03 20:11:26311bool Statement::ColumnBlobAsString16(int col, base::string16* val) const {
[email protected]98b6f8b12012-02-10 13:31:59312 if (!CheckValid())
313 return false;
314
315 const void* data = ColumnBlob(col);
[email protected]fcf75d42013-12-03 20:11:26316 size_t len = ColumnByteLength(col) / sizeof(base::char16);
[email protected]98b6f8b12012-02-10 13:31:59317 val->resize(len);
318 if (val->size() != len)
319 return false;
[email protected]fcf75d42013-12-03 20:11:26320 val->assign(reinterpret_cast<const base::char16*>(data), len);
[email protected]98b6f8b12012-02-10 13:31:59321 return true;
322}
323
[email protected]eff1fa522011-12-12 23:50:59324bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
[email protected]e5ffd0e42009-09-11 21:30:56325 val->clear();
[email protected]eff1fa522011-12-12 23:50:59326
327 if (!CheckValid())
328 return false;
[email protected]e5ffd0e42009-09-11 21:30:56329
330 const void* data = sqlite3_column_blob(ref_->stmt(), col);
331 int len = sqlite3_column_bytes(ref_->stmt(), col);
332 if (data && len > 0) {
333 val->resize(len);
334 memcpy(&(*val)[0], data, len);
335 }
[email protected]eff1fa522011-12-12 23:50:59336 return true;
[email protected]e5ffd0e42009-09-11 21:30:56337}
338
[email protected]eff1fa522011-12-12 23:50:59339bool Statement::ColumnBlobAsVector(
[email protected]1ed78a32009-09-15 20:24:17340 int col,
341 std::vector<unsigned char>* val) const {
[email protected]eff1fa522011-12-12 23:50:59342 return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
[email protected]1ed78a32009-09-15 20:24:17343}
344
[email protected]faa604e2009-09-25 22:38:59345const char* Statement::GetSQLStatement() {
346 return sqlite3_sql(ref_->stmt());
347}
[email protected]e5ffd0e42009-09-11 21:30:56348
[email protected]eff1fa522011-12-12 23:50:59349bool Statement::CheckOk(int err) const {
[email protected]bed29d942011-12-22 19:25:51350 // Binding to a non-existent variable is evidence of a serious error.
351 // TODO(gbillock,shess): make this invalidate the statement so it
352 // can't wreak havoc.
353 if (err == SQLITE_RANGE)
354 DLOG(FATAL) << "Bind value out of range";
[email protected]eff1fa522011-12-12 23:50:59355 return err == SQLITE_OK;
356}
357
[email protected]faa604e2009-09-25 22:38:59358int Statement::CheckError(int err) {
359 // Please don't add DCHECKs here, OnSqliteError() already has them.
360 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
[email protected]71318802013-06-03 00:20:05361 if (!succeeded_ && ref_.get() && ref_->connection())
[email protected]2f496b42013-09-26 18:36:58362 return ref_->connection()->OnSqliteError(err, this, NULL);
[email protected]e5ffd0e42009-09-11 21:30:56363 return err;
364}
365
366} // namespace sql