blob: 8f75693d730884270d3f7a4de19b03a568767660 [file] [log] [blame]
[email protected]f0a54b22011-07-19 18:40:211// Copyright (c) 2011 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]5eea1162010-05-11 17:14:168#include "base/utf_string_conversions.h"
[email protected]e33cba42010-08-18 23:37:039#include "third_party/sqlite/sqlite3.h"
[email protected]e5ffd0e42009-09-11 21:30:5610
11namespace sql {
12
13// This empty constructor initializes our reference with an empty one so that
14// we don't have to NULL-check the ref_ to see if the statement is valid: we
15// only have to check the ref's validity bit.
16Statement::Statement()
17 : ref_(new Connection::StatementRef),
18 succeeded_(false) {
19}
20
21Statement::Statement(scoped_refptr<Connection::StatementRef> ref)
22 : ref_(ref),
23 succeeded_(false) {
24}
25
26Statement::~Statement() {
27 // Free the resources associated with this statement. We assume there's only
28 // one statement active for a given sqlite3_stmt at any time, so this won't
29 // mess with anything.
30 Reset();
31}
32
33void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) {
[email protected]35f2094c2009-12-29 22:46:5534 Reset();
[email protected]e5ffd0e42009-09-11 21:30:5635 ref_ = ref;
36}
37
38bool Statement::Run() {
39 if (!is_valid())
40 return false;
41 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE;
42}
43
44bool Statement::Step() {
45 if (!is_valid())
46 return false;
47 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW;
48}
49
50void Statement::Reset() {
[email protected]faa604e2009-09-25 22:38:5951 if (is_valid()) {
52 // We don't call CheckError() here because sqlite3_reset() returns
53 // the last error that Step() caused thereby generating a second
54 // spurious error callback.
55 sqlite3_clear_bindings(ref_->stmt());
56 sqlite3_reset(ref_->stmt());
57 }
[email protected]e5ffd0e42009-09-11 21:30:5658 succeeded_ = false;
59}
60
61bool Statement::Succeeded() const {
62 if (!is_valid())
63 return false;
64 return succeeded_;
65}
66
67bool Statement::BindNull(int col) {
68 if (is_valid()) {
69 int err = CheckError(sqlite3_bind_null(ref_->stmt(), col + 1));
[email protected]e5ffd0e42009-09-11 21:30:5670 return err == SQLITE_OK;
71 }
72 return false;
73}
74
[email protected]765b44502009-10-02 05:01:4275bool Statement::BindBool(int col, bool val) {
76 return BindInt(col, val ? 1 : 0);
77}
78
[email protected]e5ffd0e42009-09-11 21:30:5679bool Statement::BindInt(int col, int val) {
80 if (is_valid()) {
81 int err = CheckError(sqlite3_bind_int(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:5682 return err == SQLITE_OK;
83 }
84 return false;
85}
86
87bool Statement::BindInt64(int col, int64 val) {
88 if (is_valid()) {
89 int err = CheckError(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:5690 return err == SQLITE_OK;
91 }
92 return false;
93}
94
95bool Statement::BindDouble(int col, double val) {
96 if (is_valid()) {
97 int err = CheckError(sqlite3_bind_double(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:5698 return err == SQLITE_OK;
99 }
100 return false;
101}
102
103bool Statement::BindCString(int col, const char* val) {
104 if (is_valid()) {
105 int err = CheckError(sqlite3_bind_text(ref_->stmt(), col + 1, val, -1,
106 SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56107 return err == SQLITE_OK;
108 }
109 return false;
110}
111
112bool Statement::BindString(int col, const std::string& val) {
113 if (is_valid()) {
114 int err = CheckError(sqlite3_bind_text(ref_->stmt(), col + 1, val.data(),
115 val.size(), SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56116 return err == SQLITE_OK;
117 }
118 return false;
119}
120
[email protected]5eea1162010-05-11 17:14:16121bool Statement::BindString16(int col, const string16& value) {
122 return BindString(col, UTF16ToUTF8(value));
123}
124
[email protected]e5ffd0e42009-09-11 21:30:56125bool Statement::BindBlob(int col, const void* val, int val_len) {
126 if (is_valid()) {
127 int err = CheckError(sqlite3_bind_blob(ref_->stmt(), col + 1,
128 val, val_len, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56129 return err == SQLITE_OK;
130 }
131 return false;
132}
133
134int Statement::ColumnCount() const {
135 if (!is_valid()) {
136 NOTREACHED();
137 return 0;
138 }
139 return sqlite3_column_count(ref_->stmt());
140}
141
[email protected]765b44502009-10-02 05:01:42142ColType Statement::ColumnType(int col) const {
143 // Verify that our enum matches sqlite's values.
144 COMPILE_ASSERT(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, integer_no_match);
145 COMPILE_ASSERT(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, float_no_match);
146 COMPILE_ASSERT(COLUMN_TYPE_TEXT == SQLITE_TEXT, integer_no_match);
147 COMPILE_ASSERT(COLUMN_TYPE_BLOB == SQLITE_BLOB, blob_no_match);
148 COMPILE_ASSERT(COLUMN_TYPE_NULL == SQLITE_NULL, null_no_match);
149
150 return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
151}
152
153bool Statement::ColumnBool(int col) const {
154 return !!ColumnInt(col);
155}
156
[email protected]e5ffd0e42009-09-11 21:30:56157int Statement::ColumnInt(int col) const {
158 if (!is_valid()) {
159 NOTREACHED();
160 return 0;
161 }
162 return sqlite3_column_int(ref_->stmt(), col);
163}
164
165int64 Statement::ColumnInt64(int col) const {
166 if (!is_valid()) {
167 NOTREACHED();
168 return 0;
169 }
170 return sqlite3_column_int64(ref_->stmt(), col);
171}
172
173double Statement::ColumnDouble(int col) const {
174 if (!is_valid()) {
175 NOTREACHED();
176 return 0;
177 }
178 return sqlite3_column_double(ref_->stmt(), col);
179}
180
181std::string Statement::ColumnString(int col) const {
182 if (!is_valid()) {
183 NOTREACHED();
[email protected]3ddbd1452010-03-16 20:34:05184 return "";
[email protected]e5ffd0e42009-09-11 21:30:56185 }
186 const char* str = reinterpret_cast<const char*>(
187 sqlite3_column_text(ref_->stmt(), col));
188 int len = sqlite3_column_bytes(ref_->stmt(), col);
189
190 std::string result;
191 if (str && len > 0)
192 result.assign(str, len);
193 return result;
194}
195
[email protected]5eea1162010-05-11 17:14:16196string16 Statement::ColumnString16(int col) const {
197 if (!is_valid()) {
198 NOTREACHED();
199 return string16();
200 }
201 std::string s = ColumnString(col);
202 return !s.empty() ? UTF8ToUTF16(s) : string16();
203}
204
[email protected]1ed78a32009-09-15 20:24:17205int Statement::ColumnByteLength(int col) const {
[email protected]e5ffd0e42009-09-11 21:30:56206 if (!is_valid()) {
207 NOTREACHED();
208 return 0;
209 }
210 return sqlite3_column_bytes(ref_->stmt(), col);
211}
212
[email protected]1ed78a32009-09-15 20:24:17213const void* Statement::ColumnBlob(int col) const {
[email protected]e5ffd0e42009-09-11 21:30:56214 if (!is_valid()) {
215 NOTREACHED();
216 return NULL;
217 }
218
219 return sqlite3_column_blob(ref_->stmt(), col);
220}
221
[email protected]5eea1162010-05-11 17:14:16222bool Statement::ColumnBlobAsString(int col, std::string* blob) {
223 if (!is_valid()) {
224 NOTREACHED();
225 return false;
226 }
227 const void* p = ColumnBlob(col);
228 size_t len = ColumnByteLength(col);
229 blob->resize(len);
230 if (blob->size() != len) {
231 return false;
232 }
233 blob->assign(reinterpret_cast<const char*>(p), len);
234 return true;
235}
236
[email protected]1ed78a32009-09-15 20:24:17237void Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
[email protected]e5ffd0e42009-09-11 21:30:56238 val->clear();
239 if (!is_valid()) {
240 NOTREACHED();
241 return;
242 }
243
244 const void* data = sqlite3_column_blob(ref_->stmt(), col);
245 int len = sqlite3_column_bytes(ref_->stmt(), col);
246 if (data && len > 0) {
247 val->resize(len);
248 memcpy(&(*val)[0], data, len);
249 }
250}
251
[email protected]1ed78a32009-09-15 20:24:17252void Statement::ColumnBlobAsVector(
253 int col,
254 std::vector<unsigned char>* val) const {
255 ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
256}
257
[email protected]faa604e2009-09-25 22:38:59258const char* Statement::GetSQLStatement() {
259 return sqlite3_sql(ref_->stmt());
260}
[email protected]e5ffd0e42009-09-11 21:30:56261
[email protected]faa604e2009-09-25 22:38:59262int Statement::CheckError(int err) {
263 // Please don't add DCHECKs here, OnSqliteError() already has them.
264 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
265 if (!succeeded_ && is_valid())
266 return ref_->connection()->OnSqliteError(err, this);
[email protected]e5ffd0e42009-09-11 21:30:56267 return err;
268}
269
270} // namespace sql