blob: d92be010fd4420cb2e7eef83e37bfa00dfc1dfa6 [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]c0714df2012-02-10 20:19:288#include "base/string_util.h"
[email protected]5eea1162010-05-11 17:14:169#include "base/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]e5ffd0e42009-09-11 21:30:5619 succeeded_(false) {
20}
21
22Statement::Statement(scoped_refptr<Connection::StatementRef> ref)
23 : ref_(ref),
24 succeeded_(false) {
25}
26
27Statement::~Statement() {
28 // Free the resources associated with this statement. We assume there's only
29 // one statement active for a given sqlite3_stmt at any time, so this won't
30 // mess with anything.
[email protected]389e0a42012-04-25 21:36:4131 Reset(true);
[email protected]e5ffd0e42009-09-11 21:30:5632}
33
34void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) {
[email protected]389e0a42012-04-25 21:36:4135 Reset(true);
[email protected]e5ffd0e42009-09-11 21:30:5636 ref_ = ref;
37}
38
[email protected]85fc27b02012-02-17 02:15:0939void Statement::Clear() {
[email protected]41a97c812013-02-07 02:35:3840 Assign(new Connection::StatementRef(NULL, NULL, false));
[email protected]85fc27b02012-02-17 02:15:0941 succeeded_ = false;
42}
43
[email protected]eff1fa522011-12-12 23:50:5944bool Statement::CheckValid() const {
[email protected]41a97c812013-02-07 02:35:3845 // Allow operations to fail silently if a statement was invalidated
46 // because the database was closed by an error handler.
47 DLOG_IF(FATAL, !ref_->was_valid())
48 << "Cannot call mutating statements on an invalid statement.";
[email protected]eff1fa522011-12-12 23:50:5949 return is_valid();
50}
51
52bool Statement::Run() {
[email protected]35f7e5392012-07-27 19:54:5053 ref_->AssertIOAllowed();
[email protected]eff1fa522011-12-12 23:50:5954 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:5655 return false;
[email protected]eff1fa522011-12-12 23:50:5956
[email protected]e5ffd0e42009-09-11 21:30:5657 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE;
58}
59
60bool Statement::Step() {
[email protected]35f7e5392012-07-27 19:54:5061 ref_->AssertIOAllowed();
[email protected]eff1fa522011-12-12 23:50:5962 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:5663 return false;
[email protected]eff1fa522011-12-12 23:50:5964
[email protected]e5ffd0e42009-09-11 21:30:5665 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW;
66}
67
[email protected]389e0a42012-04-25 21:36:4168void Statement::Reset(bool clear_bound_vars) {
[email protected]35f7e5392012-07-27 19:54:5069 ref_->AssertIOAllowed();
[email protected]faa604e2009-09-25 22:38:5970 if (is_valid()) {
71 // We don't call CheckError() here because sqlite3_reset() returns
72 // the last error that Step() caused thereby generating a second
73 // spurious error callback.
[email protected]389e0a42012-04-25 21:36:4174 if (clear_bound_vars)
75 sqlite3_clear_bindings(ref_->stmt());
[email protected]faa604e2009-09-25 22:38:5976 sqlite3_reset(ref_->stmt());
77 }
[email protected]eff1fa522011-12-12 23:50:5978
[email protected]e5ffd0e42009-09-11 21:30:5679 succeeded_ = false;
80}
81
82bool Statement::Succeeded() const {
83 if (!is_valid())
84 return false;
[email protected]eff1fa522011-12-12 23:50:5985
[email protected]e5ffd0e42009-09-11 21:30:5686 return succeeded_;
87}
88
89bool Statement::BindNull(int col) {
[email protected]eff1fa522011-12-12 23:50:5990 if (!is_valid())
91 return false;
92
93 return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
[email protected]e5ffd0e42009-09-11 21:30:5694}
95
[email protected]765b44502009-10-02 05:01:4296bool Statement::BindBool(int col, bool val) {
97 return BindInt(col, val ? 1 : 0);
98}
99
[email protected]e5ffd0e42009-09-11 21:30:56100bool Statement::BindInt(int col, int val) {
[email protected]eff1fa522011-12-12 23:50:59101 if (!is_valid())
102 return false;
103
104 return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56105}
106
107bool Statement::BindInt64(int col, int64 val) {
[email protected]eff1fa522011-12-12 23:50:59108 if (!is_valid())
109 return false;
110
111 return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56112}
113
114bool Statement::BindDouble(int col, double val) {
[email protected]eff1fa522011-12-12 23:50:59115 if (!is_valid())
116 return false;
117
118 return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:56119}
120
121bool Statement::BindCString(int col, const char* val) {
[email protected]eff1fa522011-12-12 23:50:59122 if (!is_valid())
123 return false;
124
125 return CheckOk(
126 sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56127}
128
129bool Statement::BindString(int col, const std::string& val) {
[email protected]eff1fa522011-12-12 23:50:59130 if (!is_valid())
131 return false;
132
133 return CheckOk(sqlite3_bind_text(ref_->stmt(),
134 col + 1,
135 val.data(),
136 val.size(),
137 SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56138}
139
[email protected]5eea1162010-05-11 17:14:16140bool Statement::BindString16(int col, const string16& value) {
141 return BindString(col, UTF16ToUTF8(value));
142}
143
[email protected]e5ffd0e42009-09-11 21:30:56144bool Statement::BindBlob(int col, const void* val, int val_len) {
[email protected]eff1fa522011-12-12 23:50:59145 if (!is_valid())
146 return false;
147
148 return CheckOk(
149 sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56150}
151
152int Statement::ColumnCount() const {
[email protected]eff1fa522011-12-12 23:50:59153 if (!is_valid())
[email protected]e5ffd0e42009-09-11 21:30:56154 return 0;
[email protected]eff1fa522011-12-12 23:50:59155
[email protected]e5ffd0e42009-09-11 21:30:56156 return sqlite3_column_count(ref_->stmt());
157}
158
[email protected]765b44502009-10-02 05:01:42159ColType Statement::ColumnType(int col) const {
160 // Verify that our enum matches sqlite's values.
161 COMPILE_ASSERT(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, integer_no_match);
162 COMPILE_ASSERT(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, float_no_match);
163 COMPILE_ASSERT(COLUMN_TYPE_TEXT == SQLITE_TEXT, integer_no_match);
164 COMPILE_ASSERT(COLUMN_TYPE_BLOB == SQLITE_BLOB, blob_no_match);
165 COMPILE_ASSERT(COLUMN_TYPE_NULL == SQLITE_NULL, null_no_match);
166
167 return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
168}
169
[email protected]98b6f8b12012-02-10 13:31:59170ColType Statement::DeclaredColumnType(int col) const {
171 std::string column_type(sqlite3_column_decltype(ref_->stmt(), col));
[email protected]c0714df2012-02-10 20:19:28172 StringToLowerASCII(&column_type);
[email protected]98b6f8b12012-02-10 13:31:59173
174 if (column_type == "integer")
175 return COLUMN_TYPE_INTEGER;
176 else if (column_type == "float")
177 return COLUMN_TYPE_FLOAT;
178 else if (column_type == "text")
179 return COLUMN_TYPE_TEXT;
180 else if (column_type == "blob")
181 return COLUMN_TYPE_BLOB;
182
183 return COLUMN_TYPE_NULL;
184}
185
[email protected]765b44502009-10-02 05:01:42186bool Statement::ColumnBool(int col) const {
187 return !!ColumnInt(col);
188}
189
[email protected]e5ffd0e42009-09-11 21:30:56190int Statement::ColumnInt(int col) const {
[email protected]eff1fa522011-12-12 23:50:59191 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56192 return 0;
[email protected]eff1fa522011-12-12 23:50:59193
[email protected]e5ffd0e42009-09-11 21:30:56194 return sqlite3_column_int(ref_->stmt(), col);
195}
196
197int64 Statement::ColumnInt64(int col) const {
[email protected]eff1fa522011-12-12 23:50:59198 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56199 return 0;
[email protected]eff1fa522011-12-12 23:50:59200
[email protected]e5ffd0e42009-09-11 21:30:56201 return sqlite3_column_int64(ref_->stmt(), col);
202}
203
204double Statement::ColumnDouble(int col) const {
[email protected]eff1fa522011-12-12 23:50:59205 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56206 return 0;
[email protected]eff1fa522011-12-12 23:50:59207
[email protected]e5ffd0e42009-09-11 21:30:56208 return sqlite3_column_double(ref_->stmt(), col);
209}
210
211std::string Statement::ColumnString(int col) const {
[email protected]eff1fa522011-12-12 23:50:59212 if (!CheckValid())
[email protected]3ddbd1452010-03-16 20:34:05213 return "";
[email protected]eff1fa522011-12-12 23:50:59214
[email protected]e5ffd0e42009-09-11 21:30:56215 const char* str = reinterpret_cast<const char*>(
216 sqlite3_column_text(ref_->stmt(), col));
217 int len = sqlite3_column_bytes(ref_->stmt(), col);
218
219 std::string result;
220 if (str && len > 0)
221 result.assign(str, len);
222 return result;
223}
224
[email protected]5eea1162010-05-11 17:14:16225string16 Statement::ColumnString16(int col) const {
[email protected]eff1fa522011-12-12 23:50:59226 if (!CheckValid())
[email protected]5eea1162010-05-11 17:14:16227 return string16();
[email protected]eff1fa522011-12-12 23:50:59228
[email protected]5eea1162010-05-11 17:14:16229 std::string s = ColumnString(col);
230 return !s.empty() ? UTF8ToUTF16(s) : string16();
231}
232
[email protected]1ed78a32009-09-15 20:24:17233int Statement::ColumnByteLength(int col) const {
[email protected]eff1fa522011-12-12 23:50:59234 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56235 return 0;
[email protected]eff1fa522011-12-12 23:50:59236
[email protected]e5ffd0e42009-09-11 21:30:56237 return sqlite3_column_bytes(ref_->stmt(), col);
238}
239
[email protected]1ed78a32009-09-15 20:24:17240const void* Statement::ColumnBlob(int col) const {
[email protected]eff1fa522011-12-12 23:50:59241 if (!CheckValid())
[email protected]e5ffd0e42009-09-11 21:30:56242 return NULL;
[email protected]e5ffd0e42009-09-11 21:30:56243
244 return sqlite3_column_blob(ref_->stmt(), col);
245}
246
[email protected]5eea1162010-05-11 17:14:16247bool Statement::ColumnBlobAsString(int col, std::string* blob) {
[email protected]eff1fa522011-12-12 23:50:59248 if (!CheckValid())
[email protected]5eea1162010-05-11 17:14:16249 return false;
[email protected]eff1fa522011-12-12 23:50:59250
[email protected]5eea1162010-05-11 17:14:16251 const void* p = ColumnBlob(col);
252 size_t len = ColumnByteLength(col);
253 blob->resize(len);
254 if (blob->size() != len) {
255 return false;
256 }
257 blob->assign(reinterpret_cast<const char*>(p), len);
258 return true;
259}
260
[email protected]98b6f8b12012-02-10 13:31:59261bool Statement::ColumnBlobAsString16(int col, string16* val) const {
262 if (!CheckValid())
263 return false;
264
265 const void* data = ColumnBlob(col);
266 size_t len = ColumnByteLength(col) / sizeof(char16);
267 val->resize(len);
268 if (val->size() != len)
269 return false;
270 val->assign(reinterpret_cast<const char16*>(data), len);
271 return true;
272}
273
[email protected]eff1fa522011-12-12 23:50:59274bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
[email protected]e5ffd0e42009-09-11 21:30:56275 val->clear();
[email protected]eff1fa522011-12-12 23:50:59276
277 if (!CheckValid())
278 return false;
[email protected]e5ffd0e42009-09-11 21:30:56279
280 const void* data = sqlite3_column_blob(ref_->stmt(), col);
281 int len = sqlite3_column_bytes(ref_->stmt(), col);
282 if (data && len > 0) {
283 val->resize(len);
284 memcpy(&(*val)[0], data, len);
285 }
[email protected]eff1fa522011-12-12 23:50:59286 return true;
[email protected]e5ffd0e42009-09-11 21:30:56287}
288
[email protected]eff1fa522011-12-12 23:50:59289bool Statement::ColumnBlobAsVector(
[email protected]1ed78a32009-09-15 20:24:17290 int col,
291 std::vector<unsigned char>* val) const {
[email protected]eff1fa522011-12-12 23:50:59292 return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
[email protected]1ed78a32009-09-15 20:24:17293}
294
[email protected]faa604e2009-09-25 22:38:59295const char* Statement::GetSQLStatement() {
296 return sqlite3_sql(ref_->stmt());
297}
[email protected]e5ffd0e42009-09-11 21:30:56298
[email protected]eff1fa522011-12-12 23:50:59299bool Statement::CheckOk(int err) const {
[email protected]bed29d942011-12-22 19:25:51300 // Binding to a non-existent variable is evidence of a serious error.
301 // TODO(gbillock,shess): make this invalidate the statement so it
302 // can't wreak havoc.
303 if (err == SQLITE_RANGE)
304 DLOG(FATAL) << "Bind value out of range";
[email protected]eff1fa522011-12-12 23:50:59305 return err == SQLITE_OK;
306}
307
[email protected]faa604e2009-09-25 22:38:59308int Statement::CheckError(int err) {
309 // Please don't add DCHECKs here, OnSqliteError() already has them.
310 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
[email protected]41a97c812013-02-07 02:35:38311 if (!succeeded_ && ref_ && ref_->connection())
[email protected]faa604e2009-09-25 22:38:59312 return ref_->connection()->OnSqliteError(err, this);
[email protected]e5ffd0e42009-09-11 21:30:56313 return err;
314}
315
316} // namespace sql