| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 "base/utf_string_conversions.h" | |
| 9 #include "third_party/sqlite/sqlite3.h" | |
| 10 | |
| 11 namespace 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. | |
| 16 Statement::Statement() | |
| 17 : ref_(new Connection::StatementRef), | |
| 18 succeeded_(false) { | |
| 19 } | |
| 20 | |
| 21 Statement::Statement(scoped_refptr<Connection::StatementRef> ref) | |
| 22 : ref_(ref), | |
| 23 succeeded_(false) { | |
| 24 } | |
| 25 | |
| 26 Statement::~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 | |
| 33 void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) { | |
| 34 Reset(); | |
| 35 ref_ = ref; | |
| 36 } | |
| 37 | |
| 38 bool Statement::Run() { | |
| 39 if (!is_valid()) | |
| 40 return false; | |
| 41 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE; | |
| 42 } | |
| 43 | |
| 44 bool Statement::Step() { | |
| 45 if (!is_valid()) | |
| 46 return false; | |
| 47 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW; | |
| 48 } | |
| 49 | |
| 50 void Statement::Reset() { | |
| 51 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 } | |
| 58 succeeded_ = false; | |
| 59 } | |
| 60 | |
| 61 bool Statement::Succeeded() const { | |
| 62 if (!is_valid()) | |
| 63 return false; | |
| 64 return succeeded_; | |
| 65 } | |
| 66 | |
| 67 bool Statement::BindNull(int col) { | |
| 68 if (is_valid()) { | |
| 69 int err = CheckError(sqlite3_bind_null(ref_->stmt(), col + 1)); | |
| 70 return err == SQLITE_OK; | |
| 71 } | |
| 72 return false; | |
| 73 } | |
| 74 | |
| 75 bool Statement::BindBool(int col, bool val) { | |
| 76 return BindInt(col, val ? 1 : 0); | |
| 77 } | |
| 78 | |
| 79 bool Statement::BindInt(int col, int val) { | |
| 80 if (is_valid()) { | |
| 81 int err = CheckError(sqlite3_bind_int(ref_->stmt(), col + 1, val)); | |
| 82 return err == SQLITE_OK; | |
| 83 } | |
| 84 return false; | |
| 85 } | |
| 86 | |
| 87 bool Statement::BindInt64(int col, int64 val) { | |
| 88 if (is_valid()) { | |
| 89 int err = CheckError(sqlite3_bind_int64(ref_->stmt(), col + 1, val)); | |
| 90 return err == SQLITE_OK; | |
| 91 } | |
| 92 return false; | |
| 93 } | |
| 94 | |
| 95 bool Statement::BindDouble(int col, double val) { | |
| 96 if (is_valid()) { | |
| 97 int err = CheckError(sqlite3_bind_double(ref_->stmt(), col + 1, val)); | |
| 98 return err == SQLITE_OK; | |
| 99 } | |
| 100 return false; | |
| 101 } | |
| 102 | |
| 103 bool 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)); | |
| 107 return err == SQLITE_OK; | |
| 108 } | |
| 109 return false; | |
| 110 } | |
| 111 | |
| 112 bool 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)); | |
| 116 return err == SQLITE_OK; | |
| 117 } | |
| 118 return false; | |
| 119 } | |
| 120 | |
| 121 bool Statement::BindString16(int col, const string16& value) { | |
| 122 return BindString(col, UTF16ToUTF8(value)); | |
| 123 } | |
| 124 | |
| 125 bool 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)); | |
| 129 return err == SQLITE_OK; | |
| 130 } | |
| 131 return false; | |
| 132 } | |
| 133 | |
| 134 int Statement::ColumnCount() const { | |
| 135 if (!is_valid()) { | |
| 136 NOTREACHED(); | |
| 137 return 0; | |
| 138 } | |
| 139 return sqlite3_column_count(ref_->stmt()); | |
| 140 } | |
| 141 | |
| 142 ColType 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 | |
| 153 bool Statement::ColumnBool(int col) const { | |
| 154 return !!ColumnInt(col); | |
| 155 } | |
| 156 | |
| 157 int 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 | |
| 165 int64 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 | |
| 173 double 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 | |
| 181 std::string Statement::ColumnString(int col) const { | |
| 182 if (!is_valid()) { | |
| 183 NOTREACHED(); | |
| 184 return ""; | |
| 185 } | |
| 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 | |
| 196 string16 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 | |
| 205 int Statement::ColumnByteLength(int col) const { | |
| 206 if (!is_valid()) { | |
| 207 NOTREACHED(); | |
| 208 return 0; | |
| 209 } | |
| 210 return sqlite3_column_bytes(ref_->stmt(), col); | |
| 211 } | |
| 212 | |
| 213 const void* Statement::ColumnBlob(int col) const { | |
| 214 if (!is_valid()) { | |
| 215 NOTREACHED(); | |
| 216 return NULL; | |
| 217 } | |
| 218 | |
| 219 return sqlite3_column_blob(ref_->stmt(), col); | |
| 220 } | |
| 221 | |
| 222 bool 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 | |
| 237 void Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const { | |
| 238 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 | |
| 252 void Statement::ColumnBlobAsVector( | |
| 253 int col, | |
| 254 std::vector<unsigned char>* val) const { | |
| 255 ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val)); | |
| 256 } | |
| 257 | |
| 258 const char* Statement::GetSQLStatement() { | |
| 259 return sqlite3_sql(ref_->stmt()); | |
| 260 } | |
| 261 | |
| 262 int 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); | |
| 267 return err; | |
| 268 } | |
| 269 | |
| 270 } // namespace sql | |
| OLD | NEW |