blob: 4f5e17f1684bdf221616e3db272f73a05096bef3 [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
54bool Statement::Run() {
[email protected]097723d2013-10-25 20:09:3255 DCHECK(!stepped_);
[email protected]35f7e5392012-07-27 19:54:5056 ref_->AssertIOAllowed();
[email protected]eff1fa522011-12-12 23:50:5957 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:5658 return false;
[email protected]eff1fa522011-12-12 23:50:5959
[email protected]097723d2013-10-25 20:09:3260 stepped_ = true;
[email protected]e5ffd0e42009-09-11 21:30:5661 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE;
62}
63
64bool Statement::Step() {
[email protected]35f7e5392012-07-27 19:54:5065 ref_->AssertIOAllowed();
[email protected]eff1fa522011-12-12 23:50:5966 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:5667 return false;
[email protected]eff1fa522011-12-12 23:50:5968
[email protected]097723d2013-10-25 20:09:3269 stepped_ = true;
[email protected]e5ffd0e42009-09-11 21:30:5670 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW;
71}
72
[email protected]389e0a42012-04-25 21:36:4173void Statement::Reset(bool clear_bound_vars) {
[email protected]35f7e5392012-07-27 19:54:5074 ref_->AssertIOAllowed();
[email protected]faa604e2009-09-25 22:38:5975 if (is_valid()) {
76 // We don't call CheckError() here because sqlite3_reset() returns
77 // the last error that Step() caused thereby generating a second
78 // spurious error callback.
[email protected]389e0a42012-04-25 21:36:4179 if (clear_bound_vars)
80 sqlite3_clear_bindings(ref_->stmt());
[email protected]faa604e2009-09-25 22:38:5981 sqlite3_reset(ref_->stmt());
82 }
[email protected]eff1fa522011-12-12 23:50:5983
[email protected]e5ffd0e42009-09-11 21:30:5684 succeeded_ = false;
[email protected]097723d2013-10-25 20:09:3285 stepped_ = false;
[email protected]e5ffd0e42009-09-11 21:30:5686}
87
88bool Statement::Succeeded() const {
89 if (!is_valid())
90 return false;
[email protected]eff1fa522011-12-12 23:50:5991
[email protected]e5ffd0e42009-09-11 21:30:5692 return succeeded_;
93}
94
95bool Statement::BindNull(int col) {
[email protected]097723d2013-10-25 20:09:3296 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:5997 if (!is_valid())
98 return false;
99
100 return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
[email protected]e5ffd0e42009-09-11 21:30:56101}
102
[email protected]765b44502009-10-02 05:01:42103bool Statement::BindBool(int col, bool val) {
104 return BindInt(col, val ? 1 : 0);
105}
106
[email protected]e5ffd0e42009-09-11 21:30:56107bool Statement::BindInt(int col, int val) {
[email protected]097723d2013-10-25 20:09:32108 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59109 if (!is_valid())
110 return false;
111
112 return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56113}
114
115bool Statement::BindInt64(int col, int64 val) {
[email protected]097723d2013-10-25 20:09:32116 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59117 if (!is_valid())
118 return false;
119
120 return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56121}
122
123bool Statement::BindDouble(int col, double val) {
[email protected]097723d2013-10-25 20:09:32124 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59125 if (!is_valid())
126 return false;
127
128 return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56129}
130
131bool Statement::BindCString(int col, const char* val) {
[email protected]097723d2013-10-25 20:09:32132 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59133 if (!is_valid())
134 return false;
135
136 return CheckOk(
137 sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56138}
139
140bool Statement::BindString(int col, const std::string& val) {
[email protected]097723d2013-10-25 20:09:32141 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59142 if (!is_valid())
143 return false;
144
145 return CheckOk(sqlite3_bind_text(ref_->stmt(),
146 col + 1,
147 val.data(),
148 val.size(),
149 SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56150}
151
[email protected]5eea1162010-05-11 17:14:16152bool Statement::BindString16(int col, const string16& value) {
153 return BindString(col, UTF16ToUTF8(value));
154}
155
[email protected]e5ffd0e42009-09-11 21:30:56156bool Statement::BindBlob(int col, const void* val, int val_len) {
[email protected]097723d2013-10-25 20:09:32157 DCHECK(!stepped_);
[email protected]eff1fa522011-12-12 23:50:59158 if (!is_valid())
159 return false;
160
161 return CheckOk(
162 sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56163}
164
165int Statement::ColumnCount() const {
[email protected]eff1fa522011-12-12 23:50:59166 if (!is_valid())
[email protected]e5ffd0e42009-09-11 21:30:56167 return 0;
[email protected]eff1fa522011-12-12 23:50:59168
[email protected]e5ffd0e42009-09-11 21:30:56169 return sqlite3_column_count(ref_->stmt());
170}
171
[email protected]765b44502009-10-02 05:01:42172ColType Statement::ColumnType(int col) const {
173 // Verify that our enum matches sqlite's values.
174 COMPILE_ASSERT(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, integer_no_match);
175 COMPILE_ASSERT(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, float_no_match);
176 COMPILE_ASSERT(COLUMN_TYPE_TEXT == SQLITE_TEXT, integer_no_match);
177 COMPILE_ASSERT(COLUMN_TYPE_BLOB == SQLITE_BLOB, blob_no_match);
178 COMPILE_ASSERT(COLUMN_TYPE_NULL == SQLITE_NULL, null_no_match);
179
180 return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
181}
182
[email protected]98b6f8b12012-02-10 13:31:59183ColType Statement::DeclaredColumnType(int col) const {
184 std::string column_type(sqlite3_column_decltype(ref_->stmt(), col));
[email protected]c0714df2012-02-10 20:19:28185 StringToLowerASCII(&column_type);
[email protected]98b6f8b12012-02-10 13:31:59186
187 if (column_type == "integer")
188 return COLUMN_TYPE_INTEGER;
189 else if (column_type == "float")
190 return COLUMN_TYPE_FLOAT;
191 else if (column_type == "text")
192 return COLUMN_TYPE_TEXT;
193 else if (column_type == "blob")
194 return COLUMN_TYPE_BLOB;
195
196 return COLUMN_TYPE_NULL;
197}
198
[email protected]765b44502009-10-02 05:01:42199bool Statement::ColumnBool(int col) const {
200 return !!ColumnInt(col);
201}
202
[email protected]e5ffd0e42009-09-11 21:30:56203int Statement::ColumnInt(int col) const {
[email protected]eff1fa522011-12-12 23:50:59204 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56205 return 0;
[email protected]eff1fa522011-12-12 23:50:59206
[email protected]e5ffd0e42009-09-11 21:30:56207 return sqlite3_column_int(ref_->stmt(), col);
208}
209
210int64 Statement::ColumnInt64(int col) const {
[email protected]eff1fa522011-12-12 23:50:59211 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56212 return 0;
[email protected]eff1fa522011-12-12 23:50:59213
[email protected]e5ffd0e42009-09-11 21:30:56214 return sqlite3_column_int64(ref_->stmt(), col);
215}
216
217double Statement::ColumnDouble(int col) const {
[email protected]eff1fa522011-12-12 23:50:59218 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56219 return 0;
[email protected]eff1fa522011-12-12 23:50:59220
[email protected]e5ffd0e42009-09-11 21:30:56221 return sqlite3_column_double(ref_->stmt(), col);
222}
223
224std::string Statement::ColumnString(int col) const {
[email protected]eff1fa522011-12-12 23:50:59225 if (!CheckValid())
[email protected]007b3f82013-04-09 08:46:45226 return std::string();
[email protected]eff1fa522011-12-12 23:50:59227
[email protected]e5ffd0e42009-09-11 21:30:56228 const char* str = reinterpret_cast<const char*>(
229 sqlite3_column_text(ref_->stmt(), col));
230 int len = sqlite3_column_bytes(ref_->stmt(), col);
231
232 std::string result;
233 if (str && len > 0)
234 result.assign(str, len);
235 return result;
236}
237
[email protected]5eea1162010-05-11 17:14:16238string16 Statement::ColumnString16(int col) const {
[email protected]eff1fa522011-12-12 23:50:59239 if (!CheckValid())
[email protected]5eea1162010-05-11 17:14:16240 return string16();
[email protected]eff1fa522011-12-12 23:50:59241
[email protected]5eea1162010-05-11 17:14:16242 std::string s = ColumnString(col);
243 return !s.empty() ? UTF8ToUTF16(s) : string16();
244}
245
[email protected]1ed78a32009-09-15 20:24:17246int Statement::ColumnByteLength(int col) const {
[email protected]eff1fa522011-12-12 23:50:59247 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56248 return 0;
[email protected]eff1fa522011-12-12 23:50:59249
[email protected]e5ffd0e42009-09-11 21:30:56250 return sqlite3_column_bytes(ref_->stmt(), col);
251}
252
[email protected]1ed78a32009-09-15 20:24:17253const void* Statement::ColumnBlob(int col) const {
[email protected]eff1fa522011-12-12 23:50:59254 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56255 return NULL;
[email protected]e5ffd0e42009-09-11 21:30:56256
257 return sqlite3_column_blob(ref_->stmt(), col);
258}
259
[email protected]5eea1162010-05-11 17:14:16260bool Statement::ColumnBlobAsString(int col, std::string* blob) {
[email protected]eff1fa522011-12-12 23:50:59261 if (!CheckValid())
[email protected]5eea1162010-05-11 17:14:16262 return false;
[email protected]eff1fa522011-12-12 23:50:59263
[email protected]5eea1162010-05-11 17:14:16264 const void* p = ColumnBlob(col);
265 size_t len = ColumnByteLength(col);
266 blob->resize(len);
267 if (blob->size() != len) {
268 return false;
269 }
270 blob->assign(reinterpret_cast<const char*>(p), len);
271 return true;
272}
273
[email protected]98b6f8b12012-02-10 13:31:59274bool Statement::ColumnBlobAsString16(int col, string16* val) const {
275 if (!CheckValid())
276 return false;
277
278 const void* data = ColumnBlob(col);
279 size_t len = ColumnByteLength(col) / sizeof(char16);
280 val->resize(len);
281 if (val->size() != len)
282 return false;
283 val->assign(reinterpret_cast<const char16*>(data), len);
284 return true;
285}
286
[email protected]eff1fa522011-12-12 23:50:59287bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
[email protected]e5ffd0e42009-09-11 21:30:56288 val->clear();
[email protected]eff1fa522011-12-12 23:50:59289
290 if (!CheckValid())
291 return false;
[email protected]e5ffd0e42009-09-11 21:30:56292
293 const void* data = sqlite3_column_blob(ref_->stmt(), col);
294 int len = sqlite3_column_bytes(ref_->stmt(), col);
295 if (data && len > 0) {
296 val->resize(len);
297 memcpy(&(*val)[0], data, len);
298 }
[email protected]eff1fa522011-12-12 23:50:59299 return true;
[email protected]e5ffd0e42009-09-11 21:30:56300}
301
[email protected]eff1fa522011-12-12 23:50:59302bool Statement::ColumnBlobAsVector(
[email protected]1ed78a32009-09-15 20:24:17303 int col,
304 std::vector<unsigned char>* val) const {
[email protected]eff1fa522011-12-12 23:50:59305 return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
[email protected]1ed78a32009-09-15 20:24:17306}
307
[email protected]faa604e2009-09-25 22:38:59308const char* Statement::GetSQLStatement() {
309 return sqlite3_sql(ref_->stmt());
310}
[email protected]e5ffd0e42009-09-11 21:30:56311
[email protected]eff1fa522011-12-12 23:50:59312bool Statement::CheckOk(int err) const {
[email protected]bed29d942011-12-22 19:25:51313 // Binding to a non-existent variable is evidence of a serious error.
314 // TODO(gbillock,shess): make this invalidate the statement so it
315 // can't wreak havoc.
316 if (err == SQLITE_RANGE)
317 DLOG(FATAL) << "Bind value out of range";
[email protected]eff1fa522011-12-12 23:50:59318 return err == SQLITE_OK;
319}
320
[email protected]faa604e2009-09-25 22:38:59321int Statement::CheckError(int err) {
322 // Please don't add DCHECKs here, OnSqliteError() already has them.
323 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
[email protected]71318802013-06-03 00:20:05324 if (!succeeded_ && ref_.get() && ref_->connection())
[email protected]2f496b42013-09-26 18:36:58325 return ref_->connection()->OnSqliteError(err, this, NULL);
[email protected]e5ffd0e42009-09-11 21:30:56326 return err;
327}
328
329} // namespace sql