blob: 2a0faa7474253b297f55e3951ddd31542205a4a6 [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
7#include "base/logging.h"
[email protected]a4bbc1f92013-06-11 07:28:198#include "base/strings/string_util.h"
[email protected]906265872013-06-07 22:40:459#include "base/strings/utf_string_conversions.h"
[email protected]e33cba42010-08-18 23:37:0310#include "third_party/sqlite/sqlite3.h"
[email protected]e5ffd0e42009-09-11 21:30:5611
12namespace sql {
13
14// This empty constructor initializes our reference with an empty one so that
15// we don't have to NULL-check the ref_ to see if the statement is valid: we
16// only have to check the ref's validity bit.
17Statement::Statement()
[email protected]41a97c812013-02-07 02:35:3818 : ref_(new Connection::StatementRef(NULL, NULL, false)),
[email protected]097723d2013-10-25 20:09:3219 stepped_(false),
[email protected]e5ffd0e42009-09-11 21:30:5620 succeeded_(false) {
21}
22
23Statement::Statement(scoped_refptr<Connection::StatementRef> ref)
24 : ref_(ref),
[email protected]097723d2013-10-25 20:09:3225 stepped_(false),
[email protected]e5ffd0e42009-09-11 21:30:5626 succeeded_(false) {
27}
28
29Statement::~Statement() {
30 // Free the resources associated with this statement. We assume there's only
31 // one statement active for a given sqlite3_stmt at any time, so this won't
32 // mess with anything.
[email protected]389e0a42012-04-25 21:36:4133 Reset(true);
[email protected]e5ffd0e42009-09-11 21:30:5634}
35
36void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) {
[email protected]389e0a42012-04-25 21:36:4137 Reset(true);
[email protected]e5ffd0e42009-09-11 21:30:5638 ref_ = ref;
39}
40
[email protected]85fc27b02012-02-17 02:15:0941void Statement::Clear() {
[email protected]41a97c812013-02-07 02:35:3842 Assign(new Connection::StatementRef(NULL, NULL, false));
[email protected]85fc27b02012-02-17 02:15:0943 succeeded_ = false;
44}
45
[email protected]eff1fa522011-12-12 23:50:5946bool Statement::CheckValid() const {
[email protected]41a97c812013-02-07 02:35:3847 // Allow operations to fail silently if a statement was invalidated
48 // because the database was closed by an error handler.
49 DLOG_IF(FATAL, !ref_->was_valid())
50 << "Cannot call mutating statements on an invalid statement.";
[email protected]eff1fa522011-12-12 23:50:5951 return is_valid();
52}
53
shess58b8df82015-06-03 00:19:3254int Statement::StepInternal(bool timer_flag) {
[email protected]35f7e5392012-07-27 19:54:5055 ref_->AssertIOAllowed();
[email protected]eff1fa522011-12-12 23:50:5956 if (!CheckValid())
shess58b8df82015-06-03 00:19:3257 return SQLITE_ERROR;
[email protected]eff1fa522011-12-12 23:50:5958
shess58b8df82015-06-03 00:19:3259 const bool was_stepped = stepped_;
[email protected]097723d2013-10-25 20:09:3260 stepped_ = true;
shess58b8df82015-06-03 00:19:3261 int ret = SQLITE_ERROR;
62 if (!ref_->connection()) {
63 ret = sqlite3_step(ref_->stmt());
64 } else {
65 if (!timer_flag) {
66 ret = sqlite3_step(ref_->stmt());
67 } else {
68 const base::TimeTicks before = ref_->connection()->Now();
69 ret = sqlite3_step(ref_->stmt());
70 const base::TimeTicks after = ref_->connection()->Now();
71 const bool read_only = !!sqlite3_stmt_readonly(ref_->stmt());
72 ref_->connection()->RecordTimeAndChanges(after - before, read_only);
73 }
74
75 if (!was_stepped)
76 ref_->connection()->RecordOneEvent(Connection::EVENT_STATEMENT_RUN);
77
78 if (ret == SQLITE_ROW)
79 ref_->connection()->RecordOneEvent(Connection::EVENT_STATEMENT_ROWS);
80 }
81 return CheckError(ret);
82}
83
84bool Statement::Run() {
85 DCHECK(!stepped_);
86 return StepInternal(true) == SQLITE_DONE;
87}
88
89bool Statement::RunWithoutTimers() {
90 DCHECK(!stepped_);
91 return StepInternal(false) == SQLITE_DONE;
[email protected]e5ffd0e42009-09-11 21:30:5692}
93
94bool Statement::Step() {
shess58b8df82015-06-03 00:19:3295 return StepInternal(true) == SQLITE_ROW;
[email protected]e5ffd0e42009-09-11 21:30:5696}
97
[email protected]389e0a42012-04-25 21:36:4198void Statement::Reset(bool clear_bound_vars) {
[email protected]35f7e5392012-07-27 19:54:5099 ref_->AssertIOAllowed();
[email protected]faa604e2009-09-25 22:38:59100 if (is_valid()) {
[email protected]389e0a42012-04-25 21:36:41101 if (clear_bound_vars)
102 sqlite3_clear_bindings(ref_->stmt());
shess58b8df82015-06-03 00:19:32103
104 // StepInternal() cannot track success because statements may be reset
105 // before reaching SQLITE_DONE. Don't call CheckError() because
106 // sqlite3_reset() returns the last step error, which StepInternal() already
107 // checked.
108 const int rc =sqlite3_reset(ref_->stmt());
109 if (rc == SQLITE_OK && ref_->connection())
110 ref_->connection()->RecordOneEvent(Connection::EVENT_STATEMENT_SUCCESS);
[email protected]faa604e2009-09-25 22:38:59111 }
[email protected]eff1fa522011-12-12 23:50:59112
shess7dbd4dee2015-10-06 17:39:16113 // Potentially release dirty cache pages if an autocommit statement made
114 // changes.
115 if (ref_->connection())
116 ref_->connection()->ReleaseCacheMemoryIfNeeded(false);
117
[email protected]e5ffd0e42009-09-11 21:30:56118 succeeded_ = false;
[email protected]097723d2013-10-25 20:09:32119 stepped_ = false;
[email protected]e5ffd0e42009-09-11 21:30:56120}
121
122bool Statement::Succeeded() const {
123 if (!is_valid())
124 return false;
[email protected]eff1fa522011-12-12 23:50:59125
[email protected]e5ffd0e42009-09-11 21:30:56126 return succeeded_;
127}
128
129bool Statement::BindNull(int col) {
[email protected]097723d2013-10-25 20:09:32130 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59131 if (!is_valid())
132 return false;
133
134 return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
[email protected]e5ffd0e42009-09-11 21:30:56135}
136
[email protected]765b44502009-10-02 05:01:42137bool Statement::BindBool(int col, bool val) {
138 return BindInt(col, val ? 1 : 0);
139}
140
[email protected]e5ffd0e42009-09-11 21:30:56141bool Statement::BindInt(int col, int val) {
[email protected]097723d2013-10-25 20:09:32142 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59143 if (!is_valid())
144 return false;
145
146 return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56147}
148
tfarina720d4f32015-05-11 22:31:26149bool Statement::BindInt64(int col, int64_t val) {
[email protected]097723d2013-10-25 20:09:32150 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59151 if (!is_valid())
152 return false;
153
154 return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56155}
156
157bool Statement::BindDouble(int col, double val) {
[email protected]097723d2013-10-25 20:09:32158 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59159 if (!is_valid())
160 return false;
161
162 return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56163}
164
165bool Statement::BindCString(int col, const char* val) {
[email protected]097723d2013-10-25 20:09:32166 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59167 if (!is_valid())
168 return false;
169
170 return CheckOk(
171 sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56172}
173
174bool Statement::BindString(int col, const std::string& val) {
[email protected]097723d2013-10-25 20:09:32175 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59176 if (!is_valid())
177 return false;
178
179 return CheckOk(sqlite3_bind_text(ref_->stmt(),
180 col + 1,
181 val.data(),
182 val.size(),
183 SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56184}
185
[email protected]fcf75d42013-12-03 20:11:26186bool Statement::BindString16(int col, const base::string16& value) {
[email protected]6c3bf032013-12-25 19:37:03187 return BindString(col, base::UTF16ToUTF8(value));
[email protected]5eea1162010-05-11 17:14:16188}
189
[email protected]e5ffd0e42009-09-11 21:30:56190bool Statement::BindBlob(int col, const void* val, int val_len) {
[email protected]097723d2013-10-25 20:09:32191 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59192 if (!is_valid())
193 return false;
194
195 return CheckOk(
196 sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56197}
198
199int Statement::ColumnCount() const {
[email protected]eff1fa522011-12-12 23:50:59200 if (!is_valid())
[email protected]e5ffd0e42009-09-11 21:30:56201 return 0;
[email protected]eff1fa522011-12-12 23:50:59202
[email protected]e5ffd0e42009-09-11 21:30:56203 return sqlite3_column_count(ref_->stmt());
204}
205
[email protected]765b44502009-10-02 05:01:42206ColType Statement::ColumnType(int col) const {
207 // Verify that our enum matches sqlite's values.
mostynbddbabe72015-01-06 00:20:50208 static_assert(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, "integer no match");
209 static_assert(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, "float no match");
210 static_assert(COLUMN_TYPE_TEXT == SQLITE_TEXT, "integer no match");
211 static_assert(COLUMN_TYPE_BLOB == SQLITE_BLOB, "blob no match");
212 static_assert(COLUMN_TYPE_NULL == SQLITE_NULL, "null no match");
[email protected]765b44502009-10-02 05:01:42213
214 return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
215}
216
[email protected]98b6f8b12012-02-10 13:31:59217ColType Statement::DeclaredColumnType(int col) const {
brettw8e2106d2015-08-11 19:30:22218 std::string column_type = base::ToLowerASCII(
219 sqlite3_column_decltype(ref_->stmt(), col));
[email protected]98b6f8b12012-02-10 13:31:59220
221 if (column_type == "integer")
222 return COLUMN_TYPE_INTEGER;
223 else if (column_type == "float")
224 return COLUMN_TYPE_FLOAT;
225 else if (column_type == "text")
226 return COLUMN_TYPE_TEXT;
227 else if (column_type == "blob")
228 return COLUMN_TYPE_BLOB;
229
230 return COLUMN_TYPE_NULL;
231}
232
[email protected]765b44502009-10-02 05:01:42233bool Statement::ColumnBool(int col) const {
234 return !!ColumnInt(col);
235}
236
[email protected]e5ffd0e42009-09-11 21:30:56237int Statement::ColumnInt(int col) const {
[email protected]eff1fa522011-12-12 23:50:59238 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56239 return 0;
[email protected]eff1fa522011-12-12 23:50:59240
[email protected]e5ffd0e42009-09-11 21:30:56241 return sqlite3_column_int(ref_->stmt(), col);
242}
243
tfarina720d4f32015-05-11 22:31:26244int64_t Statement::ColumnInt64(int col) const {
[email protected]eff1fa522011-12-12 23:50:59245 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56246 return 0;
[email protected]eff1fa522011-12-12 23:50:59247
[email protected]e5ffd0e42009-09-11 21:30:56248 return sqlite3_column_int64(ref_->stmt(), col);
249}
250
251double Statement::ColumnDouble(int col) const {
[email protected]eff1fa522011-12-12 23:50:59252 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56253 return 0;
[email protected]eff1fa522011-12-12 23:50:59254
[email protected]e5ffd0e42009-09-11 21:30:56255 return sqlite3_column_double(ref_->stmt(), col);
256}
257
258std::string Statement::ColumnString(int col) const {
[email protected]eff1fa522011-12-12 23:50:59259 if (!CheckValid())
[email protected]007b3f82013-04-09 08:46:45260 return std::string();
[email protected]eff1fa522011-12-12 23:50:59261
[email protected]e5ffd0e42009-09-11 21:30:56262 const char* str = reinterpret_cast<const char*>(
263 sqlite3_column_text(ref_->stmt(), col));
264 int len = sqlite3_column_bytes(ref_->stmt(), col);
265
266 std::string result;
267 if (str && len > 0)
268 result.assign(str, len);
269 return result;
270}
271
[email protected]fcf75d42013-12-03 20:11:26272base::string16 Statement::ColumnString16(int col) const {
[email protected]eff1fa522011-12-12 23:50:59273 if (!CheckValid())
[email protected]fcf75d42013-12-03 20:11:26274 return base::string16();
[email protected]eff1fa522011-12-12 23:50:59275
[email protected]5eea1162010-05-11 17:14:16276 std::string s = ColumnString(col);
[email protected]6c3bf032013-12-25 19:37:03277 return !s.empty() ? base::UTF8ToUTF16(s) : base::string16();
[email protected]5eea1162010-05-11 17:14:16278}
279
[email protected]1ed78a32009-09-15 20:24:17280int Statement::ColumnByteLength(int col) const {
[email protected]eff1fa522011-12-12 23:50:59281 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56282 return 0;
[email protected]eff1fa522011-12-12 23:50:59283
[email protected]e5ffd0e42009-09-11 21:30:56284 return sqlite3_column_bytes(ref_->stmt(), col);
285}
286
[email protected]1ed78a32009-09-15 20:24:17287const void* Statement::ColumnBlob(int col) const {
[email protected]eff1fa522011-12-12 23:50:59288 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56289 return NULL;
[email protected]e5ffd0e42009-09-11 21:30:56290
291 return sqlite3_column_blob(ref_->stmt(), col);
292}
293
[email protected]5eea1162010-05-11 17:14:16294bool Statement::ColumnBlobAsString(int col, std::string* blob) {
[email protected]eff1fa522011-12-12 23:50:59295 if (!CheckValid())
[email protected]5eea1162010-05-11 17:14:16296 return false;
[email protected]eff1fa522011-12-12 23:50:59297
[email protected]5eea1162010-05-11 17:14:16298 const void* p = ColumnBlob(col);
299 size_t len = ColumnByteLength(col);
300 blob->resize(len);
301 if (blob->size() != len) {
302 return false;
303 }
304 blob->assign(reinterpret_cast<const char*>(p), len);
305 return true;
306}
307
[email protected]fcf75d42013-12-03 20:11:26308bool Statement::ColumnBlobAsString16(int col, base::string16* val) const {
[email protected]98b6f8b12012-02-10 13:31:59309 if (!CheckValid())
310 return false;
311
312 const void* data = ColumnBlob(col);
[email protected]fcf75d42013-12-03 20:11:26313 size_t len = ColumnByteLength(col) / sizeof(base::char16);
[email protected]98b6f8b12012-02-10 13:31:59314 val->resize(len);
315 if (val->size() != len)
316 return false;
[email protected]fcf75d42013-12-03 20:11:26317 val->assign(reinterpret_cast<const base::char16*>(data), len);
[email protected]98b6f8b12012-02-10 13:31:59318 return true;
319}
320
[email protected]eff1fa522011-12-12 23:50:59321bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
[email protected]e5ffd0e42009-09-11 21:30:56322 val->clear();
[email protected]eff1fa522011-12-12 23:50:59323
324 if (!CheckValid())
325 return false;
[email protected]e5ffd0e42009-09-11 21:30:56326
327 const void* data = sqlite3_column_blob(ref_->stmt(), col);
328 int len = sqlite3_column_bytes(ref_->stmt(), col);
329 if (data && len > 0) {
330 val->resize(len);
331 memcpy(&(*val)[0], data, len);
332 }
[email protected]eff1fa522011-12-12 23:50:59333 return true;
[email protected]e5ffd0e42009-09-11 21:30:56334}
335
[email protected]eff1fa522011-12-12 23:50:59336bool Statement::ColumnBlobAsVector(
[email protected]1ed78a32009-09-15 20:24:17337 int col,
338 std::vector<unsigned char>* val) const {
[email protected]eff1fa522011-12-12 23:50:59339 return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
[email protected]1ed78a32009-09-15 20:24:17340}
341
[email protected]faa604e2009-09-25 22:38:59342const char* Statement::GetSQLStatement() {
343 return sqlite3_sql(ref_->stmt());
344}
[email protected]e5ffd0e42009-09-11 21:30:56345
[email protected]eff1fa522011-12-12 23:50:59346bool Statement::CheckOk(int err) const {
[email protected]bed29d942011-12-22 19:25:51347 // Binding to a non-existent variable is evidence of a serious error.
348 // TODO(gbillock,shess): make this invalidate the statement so it
349 // can't wreak havoc.
350 if (err == SQLITE_RANGE)
351 DLOG(FATAL) << "Bind value out of range";
[email protected]eff1fa522011-12-12 23:50:59352 return err == SQLITE_OK;
353}
354
[email protected]faa604e2009-09-25 22:38:59355int Statement::CheckError(int err) {
356 // Please don't add DCHECKs here, OnSqliteError() already has them.
357 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
[email protected]71318802013-06-03 00:20:05358 if (!succeeded_ && ref_.get() && ref_->connection())
[email protected]2f496b42013-09-26 18:36:58359 return ref_->connection()->OnSqliteError(err, this, NULL);
[email protected]e5ffd0e42009-09-11 21:30:56360 return err;
361}
362
363} // namespace sql