blob: d143524314dd1324966dec946d72fc606681b6e1 [file] [log] [blame]
[email protected]e5ffd0e42009-09-11 21:30:561// Copyright (c) 2009 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 "app/sql/statement.h"
6
7#include "base/logging.h"
8#include "third_party/sqlite/preprocessed/sqlite3.h"
9
10namespace sql {
11
12// This empty constructor initializes our reference with an empty one so that
13// we don't have to NULL-check the ref_ to see if the statement is valid: we
14// only have to check the ref's validity bit.
15Statement::Statement()
16 : ref_(new Connection::StatementRef),
17 succeeded_(false) {
18}
19
20Statement::Statement(scoped_refptr<Connection::StatementRef> ref)
21 : ref_(ref),
22 succeeded_(false) {
23}
24
25Statement::~Statement() {
26 // Free the resources associated with this statement. We assume there's only
27 // one statement active for a given sqlite3_stmt at any time, so this won't
28 // mess with anything.
29 Reset();
30}
31
32void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) {
[email protected]35f2094c2009-12-29 22:46:5533 Reset();
[email protected]e5ffd0e42009-09-11 21:30:5634 ref_ = ref;
35}
36
37bool Statement::Run() {
38 if (!is_valid())
39 return false;
40 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE;
41}
42
43bool Statement::Step() {
44 if (!is_valid())
45 return false;
46 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW;
47}
48
49void Statement::Reset() {
[email protected]faa604e2009-09-25 22:38:5950 if (is_valid()) {
51 // We don't call CheckError() here because sqlite3_reset() returns
52 // the last error that Step() caused thereby generating a second
53 // spurious error callback.
54 sqlite3_clear_bindings(ref_->stmt());
55 sqlite3_reset(ref_->stmt());
56 }
[email protected]e5ffd0e42009-09-11 21:30:5657 succeeded_ = false;
58}
59
60bool Statement::Succeeded() const {
61 if (!is_valid())
62 return false;
63 return succeeded_;
64}
65
66bool Statement::BindNull(int col) {
67 if (is_valid()) {
68 int err = CheckError(sqlite3_bind_null(ref_->stmt(), col + 1));
[email protected]e5ffd0e42009-09-11 21:30:5669 return err == SQLITE_OK;
70 }
71 return false;
72}
73
[email protected]765b44502009-10-02 05:01:4274bool Statement::BindBool(int col, bool val) {
75 return BindInt(col, val ? 1 : 0);
76}
77
[email protected]e5ffd0e42009-09-11 21:30:5678bool Statement::BindInt(int col, int val) {
79 if (is_valid()) {
80 int err = CheckError(sqlite3_bind_int(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:5681 return err == SQLITE_OK;
82 }
83 return false;
84}
85
86bool Statement::BindInt64(int col, int64 val) {
87 if (is_valid()) {
88 int err = CheckError(sqlite3_bind_int64(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:5689 return err == SQLITE_OK;
90 }
91 return false;
92}
93
94bool Statement::BindDouble(int col, double val) {
95 if (is_valid()) {
96 int err = CheckError(sqlite3_bind_double(ref_->stmt(), col + 1, val));
[email protected]e5ffd0e42009-09-11 21:30:5697 return err == SQLITE_OK;
98 }
99 return false;
100}
101
102bool Statement::BindCString(int col, const char* val) {
103 if (is_valid()) {
104 int err = CheckError(sqlite3_bind_text(ref_->stmt(), col + 1, val, -1,
105 SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56106 return err == SQLITE_OK;
107 }
108 return false;
109}
110
111bool Statement::BindString(int col, const std::string& val) {
112 if (is_valid()) {
113 int err = CheckError(sqlite3_bind_text(ref_->stmt(), col + 1, val.data(),
114 val.size(), SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56115 return err == SQLITE_OK;
116 }
117 return false;
118}
119
120bool Statement::BindBlob(int col, const void* val, int val_len) {
121 if (is_valid()) {
122 int err = CheckError(sqlite3_bind_blob(ref_->stmt(), col + 1,
123 val, val_len, SQLITE_TRANSIENT));
[email protected]e5ffd0e42009-09-11 21:30:56124 return err == SQLITE_OK;
125 }
126 return false;
127}
128
129int Statement::ColumnCount() const {
130 if (!is_valid()) {
131 NOTREACHED();
132 return 0;
133 }
134 return sqlite3_column_count(ref_->stmt());
135}
136
[email protected]765b44502009-10-02 05:01:42137ColType Statement::ColumnType(int col) const {
138 // Verify that our enum matches sqlite's values.
139 COMPILE_ASSERT(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, integer_no_match);
140 COMPILE_ASSERT(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, float_no_match);
141 COMPILE_ASSERT(COLUMN_TYPE_TEXT == SQLITE_TEXT, integer_no_match);
142 COMPILE_ASSERT(COLUMN_TYPE_BLOB == SQLITE_BLOB, blob_no_match);
143 COMPILE_ASSERT(COLUMN_TYPE_NULL == SQLITE_NULL, null_no_match);
144
145 return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
146}
147
148bool Statement::ColumnBool(int col) const {
149 return !!ColumnInt(col);
150}
151
[email protected]e5ffd0e42009-09-11 21:30:56152int Statement::ColumnInt(int col) const {
153 if (!is_valid()) {
154 NOTREACHED();
155 return 0;
156 }
157 return sqlite3_column_int(ref_->stmt(), col);
158}
159
160int64 Statement::ColumnInt64(int col) const {
161 if (!is_valid()) {
162 NOTREACHED();
163 return 0;
164 }
165 return sqlite3_column_int64(ref_->stmt(), col);
166}
167
168double Statement::ColumnDouble(int col) const {
169 if (!is_valid()) {
170 NOTREACHED();
171 return 0;
172 }
173 return sqlite3_column_double(ref_->stmt(), col);
174}
175
176std::string Statement::ColumnString(int col) const {
177 if (!is_valid()) {
178 NOTREACHED();
179 return 0;
180 }
181 const char* str = reinterpret_cast<const char*>(
182 sqlite3_column_text(ref_->stmt(), col));
183 int len = sqlite3_column_bytes(ref_->stmt(), col);
184
185 std::string result;
186 if (str && len > 0)
187 result.assign(str, len);
188 return result;
189}
190
[email protected]1ed78a32009-09-15 20:24:17191int Statement::ColumnByteLength(int col) const {
[email protected]e5ffd0e42009-09-11 21:30:56192 if (!is_valid()) {
193 NOTREACHED();
194 return 0;
195 }
196 return sqlite3_column_bytes(ref_->stmt(), col);
197}
198
[email protected]1ed78a32009-09-15 20:24:17199const void* Statement::ColumnBlob(int col) const {
[email protected]e5ffd0e42009-09-11 21:30:56200 if (!is_valid()) {
201 NOTREACHED();
202 return NULL;
203 }
204
205 return sqlite3_column_blob(ref_->stmt(), col);
206}
207
[email protected]1ed78a32009-09-15 20:24:17208void Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const {
[email protected]e5ffd0e42009-09-11 21:30:56209 val->clear();
210 if (!is_valid()) {
211 NOTREACHED();
212 return;
213 }
214
215 const void* data = sqlite3_column_blob(ref_->stmt(), col);
216 int len = sqlite3_column_bytes(ref_->stmt(), col);
217 if (data && len > 0) {
218 val->resize(len);
219 memcpy(&(*val)[0], data, len);
220 }
221}
222
[email protected]1ed78a32009-09-15 20:24:17223void Statement::ColumnBlobAsVector(
224 int col,
225 std::vector<unsigned char>* val) const {
226 ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
227}
228
[email protected]faa604e2009-09-25 22:38:59229const char* Statement::GetSQLStatement() {
230 return sqlite3_sql(ref_->stmt());
231}
[email protected]e5ffd0e42009-09-11 21:30:56232
[email protected]faa604e2009-09-25 22:38:59233int Statement::CheckError(int err) {
234 // Please don't add DCHECKs here, OnSqliteError() already has them.
235 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE);
236 if (!succeeded_ && is_valid())
237 return ref_->connection()->OnSqliteError(err, this);
[email protected]e5ffd0e42009-09-11 21:30:56238 return err;
239}
240
241} // namespace sql