1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "sql/statement.h"
6
7#include "base/logging.h"
8#include "base/strings/string_util.h"
9#include "base/strings/utf_string_conversions.h"
10#include "third_party/sqlite/sqlite3.h"
11
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()
18    : ref_(new Connection::StatementRef(NULL, NULL, false)),
19      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.
31  Reset(true);
32}
33
34void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) {
35  Reset(true);
36  ref_ = ref;
37}
38
39void Statement::Clear() {
40  Assign(new Connection::StatementRef(NULL, NULL, false));
41  succeeded_ = false;
42}
43
44bool Statement::CheckValid() const {
45  // 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.";
49  return is_valid();
50}
51
52bool Statement::Run() {
53  ref_->AssertIOAllowed();
54  if (!CheckValid())
55    return false;
56
57  return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE;
58}
59
60bool Statement::Step() {
61  ref_->AssertIOAllowed();
62  if (!CheckValid())
63    return false;
64
65  return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW;
66}
67
68void Statement::Reset(bool clear_bound_vars) {
69  ref_->AssertIOAllowed();
70  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.
74    if (clear_bound_vars)
75      sqlite3_clear_bindings(ref_->stmt());
76    sqlite3_reset(ref_->stmt());
77  }
78
79  succeeded_ = false;
80}
81
82bool Statement::Succeeded() const {
83  if (!is_valid())
84    return false;
85
86  return succeeded_;
87}
88
89bool Statement::BindNull(int col) {
90  if (!is_valid())
91    return false;
92
93  return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
94}
95
96bool Statement::BindBool(int col, bool val) {
97  return BindInt(col, val ? 1 : 0);
98}
99
100bool Statement::BindInt(int col, int val) {
101  if (!is_valid())
102    return false;
103
104  return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val));
105}
106
107bool Statement::BindInt64(int col, int64 val) {
108  if (!is_valid())
109    return false;
110
111  return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
112}
113
114bool Statement::BindDouble(int col, double val) {
115  if (!is_valid())
116    return false;
117
118  return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val));
119}
120
121bool Statement::BindCString(int col, const char* val) {
122  if (!is_valid())
123    return false;
124
125  return CheckOk(
126      sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT));
127}
128
129bool Statement::BindString(int col, const std::string& val) {
130  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));
138}
139
140bool Statement::BindString16(int col, const string16& value) {
141  return BindString(col, UTF16ToUTF8(value));
142}
143
144bool Statement::BindBlob(int col, const void* val, int val_len) {
145  if (!is_valid())
146    return false;
147
148  return CheckOk(
149      sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT));
150}
151
152int Statement::ColumnCount() const {
153  if (!is_valid())
154    return 0;
155
156  return sqlite3_column_count(ref_->stmt());
157}
158
159ColType 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
170ColType Statement::DeclaredColumnType(int col) const {
171  std::string column_type(sqlite3_column_decltype(ref_->stmt(), col));
172  StringToLowerASCII(&column_type);
173
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
186bool Statement::ColumnBool(int col) const {
187  return !!ColumnInt(col);
188}
189
190int Statement::ColumnInt(int col) const {
191  if (!CheckValid())
192    return 0;
193
194  return sqlite3_column_int(ref_->stmt(), col);
195}
196
197int64 Statement::ColumnInt64(int col) const {
198  if (!CheckValid())
199    return 0;
200
201  return sqlite3_column_int64(ref_->stmt(), col);
202}
203
204double Statement::ColumnDouble(int col) const {
205  if (!CheckValid())
206    return 0;
207
208  return sqlite3_column_double(ref_->stmt(), col);
209}
210
211std::string Statement::ColumnString(int col) const {
212  if (!CheckValid())
213    return std::string();
214
215  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
225string16 Statement::ColumnString16(int col) const {
226  if (!CheckValid())
227    return string16();
228
229  std::string s = ColumnString(col);
230  return !s.empty() ? UTF8ToUTF16(s) : string16();
231}
232
233int Statement::ColumnByteLength(int col) const {
234  if (!CheckValid())
235    return 0;
236
237  return sqlite3_column_bytes(ref_->stmt(), col);
238}
239
240const void* Statement::ColumnBlob(int col) const {
241  if (!CheckValid())
242    return NULL;
243
244  return sqlite3_column_blob(ref_->stmt(), col);
245}
246
247bool Statement::ColumnBlobAsString(int col, std::string* blob) {
248  if (!CheckValid())
249    return false;
250
251  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
261bool 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
274bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
275  val->clear();
276
277  if (!CheckValid())
278    return false;
279
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  }
286  return true;
287}
288
289bool Statement::ColumnBlobAsVector(
290    int col,
291    std::vector<unsigned char>* val) const {
292  return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
293}
294
295const char* Statement::GetSQLStatement() {
296  return sqlite3_sql(ref_->stmt());
297}
298
299bool Statement::CheckOk(int err) const {
300  // 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";
305  return err == SQLITE_OK;
306}
307
308int 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);
311  if (!succeeded_ && ref_.get() && ref_->connection())
312    return ref_->connection()->OnSqliteError(err, this);
313  return err;
314}
315
316}  // namespace sql
317