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 12 namespace 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. 17 Statement::Statement() 18 : ref_(new Connection::StatementRef(NULL, NULL, false)), 19 stepped_(false), 20 succeeded_(false) { 21 } 22 23 Statement::Statement(scoped_refptr<Connection::StatementRef> ref) 24 : ref_(ref), 25 stepped_(false), 26 succeeded_(false) { 27 } 28 29 Statement::~Statement() { 30 // Free the resources associated with this statement. We assume there's only 31 // one statement active for a given sqlite3_stmt at any time, so this won't 32 // mess with anything. 33 Reset(true); 34 } 35 36 void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) { 37 Reset(true); 38 ref_ = ref; 39 } 40 41 void Statement::Clear() { 42 Assign(new Connection::StatementRef(NULL, NULL, false)); 43 succeeded_ = false; 44 } 45 46 bool Statement::CheckValid() const { 47 // Allow operations to fail silently if a statement was invalidated 48 // because the database was closed by an error handler. 49 DLOG_IF(FATAL, !ref_->was_valid()) 50 << "Cannot call mutating statements on an invalid statement."; 51 return is_valid(); 52 } 53 54 bool Statement::Run() { 55 DCHECK(!stepped_); 56 ref_->AssertIOAllowed(); 57 if (!CheckValid()) 58 return false; 59 60 stepped_ = true; 61 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE; 62 } 63 64 bool Statement::Step() { 65 ref_->AssertIOAllowed(); 66 if (!CheckValid()) 67 return false; 68 69 stepped_ = true; 70 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW; 71 } 72 73 void Statement::Reset(bool clear_bound_vars) { 74 ref_->AssertIOAllowed(); 75 if (is_valid()) { 76 // We don't call CheckError() here because sqlite3_reset() returns 77 // the last error that Step() caused thereby generating a second 78 // spurious error callback. 79 if (clear_bound_vars) 80 sqlite3_clear_bindings(ref_->stmt()); 81 sqlite3_reset(ref_->stmt()); 82 } 83 84 succeeded_ = false; 85 stepped_ = false; 86 } 87 88 bool Statement::Succeeded() const { 89 if (!is_valid()) 90 return false; 91 92 return succeeded_; 93 } 94 95 bool Statement::BindNull(int col) { 96 DCHECK(!stepped_); 97 if (!is_valid()) 98 return false; 99 100 return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1)); 101 } 102 103 bool Statement::BindBool(int col, bool val) { 104 return BindInt(col, val ? 1 : 0); 105 } 106 107 bool Statement::BindInt(int col, int val) { 108 DCHECK(!stepped_); 109 if (!is_valid()) 110 return false; 111 112 return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val)); 113 } 114 115 bool Statement::BindInt64(int col, int64 val) { 116 DCHECK(!stepped_); 117 if (!is_valid()) 118 return false; 119 120 return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val)); 121 } 122 123 bool Statement::BindDouble(int col, double val) { 124 DCHECK(!stepped_); 125 if (!is_valid()) 126 return false; 127 128 return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val)); 129 } 130 131 bool Statement::BindCString(int col, const char* val) { 132 DCHECK(!stepped_); 133 if (!is_valid()) 134 return false; 135 136 return CheckOk( 137 sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT)); 138 } 139 140 bool Statement::BindString(int col, const std::string& val) { 141 DCHECK(!stepped_); 142 if (!is_valid()) 143 return false; 144 145 return CheckOk(sqlite3_bind_text(ref_->stmt(), 146 col + 1, 147 val.data(), 148 val.size(), 149 SQLITE_TRANSIENT)); 150 } 151 152 bool Statement::BindString16(int col, const base::string16& value) { 153 return BindString(col, base::UTF16ToUTF8(value)); 154 } 155 156 bool Statement::BindBlob(int col, const void* val, int val_len) { 157 DCHECK(!stepped_); 158 if (!is_valid()) 159 return false; 160 161 return CheckOk( 162 sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT)); 163 } 164 165 int Statement::ColumnCount() const { 166 if (!is_valid()) 167 return 0; 168 169 return sqlite3_column_count(ref_->stmt()); 170 } 171 172 ColType Statement::ColumnType(int col) const { 173 // Verify that our enum matches sqlite's values. 174 COMPILE_ASSERT(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, integer_no_match); 175 COMPILE_ASSERT(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, float_no_match); 176 COMPILE_ASSERT(COLUMN_TYPE_TEXT == SQLITE_TEXT, integer_no_match); 177 COMPILE_ASSERT(COLUMN_TYPE_BLOB == SQLITE_BLOB, blob_no_match); 178 COMPILE_ASSERT(COLUMN_TYPE_NULL == SQLITE_NULL, null_no_match); 179 180 return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col)); 181 } 182 183 ColType Statement::DeclaredColumnType(int col) const { 184 std::string column_type(sqlite3_column_decltype(ref_->stmt(), col)); 185 StringToLowerASCII(&column_type); 186 187 if (column_type == "integer") 188 return COLUMN_TYPE_INTEGER; 189 else if (column_type == "float") 190 return COLUMN_TYPE_FLOAT; 191 else if (column_type == "text") 192 return COLUMN_TYPE_TEXT; 193 else if (column_type == "blob") 194 return COLUMN_TYPE_BLOB; 195 196 return COLUMN_TYPE_NULL; 197 } 198 199 bool Statement::ColumnBool(int col) const { 200 return !!ColumnInt(col); 201 } 202 203 int Statement::ColumnInt(int col) const { 204 if (!CheckValid()) 205 return 0; 206 207 return sqlite3_column_int(ref_->stmt(), col); 208 } 209 210 int64 Statement::ColumnInt64(int col) const { 211 if (!CheckValid()) 212 return 0; 213 214 return sqlite3_column_int64(ref_->stmt(), col); 215 } 216 217 double Statement::ColumnDouble(int col) const { 218 if (!CheckValid()) 219 return 0; 220 221 return sqlite3_column_double(ref_->stmt(), col); 222 } 223 224 std::string Statement::ColumnString(int col) const { 225 if (!CheckValid()) 226 return std::string(); 227 228 const char* str = reinterpret_cast<const char*>( 229 sqlite3_column_text(ref_->stmt(), col)); 230 int len = sqlite3_column_bytes(ref_->stmt(), col); 231 232 std::string result; 233 if (str && len > 0) 234 result.assign(str, len); 235 return result; 236 } 237 238 base::string16 Statement::ColumnString16(int col) const { 239 if (!CheckValid()) 240 return base::string16(); 241 242 std::string s = ColumnString(col); 243 return !s.empty() ? base::UTF8ToUTF16(s) : base::string16(); 244 } 245 246 int Statement::ColumnByteLength(int col) const { 247 if (!CheckValid()) 248 return 0; 249 250 return sqlite3_column_bytes(ref_->stmt(), col); 251 } 252 253 const void* Statement::ColumnBlob(int col) const { 254 if (!CheckValid()) 255 return NULL; 256 257 return sqlite3_column_blob(ref_->stmt(), col); 258 } 259 260 bool Statement::ColumnBlobAsString(int col, std::string* blob) { 261 if (!CheckValid()) 262 return false; 263 264 const void* p = ColumnBlob(col); 265 size_t len = ColumnByteLength(col); 266 blob->resize(len); 267 if (blob->size() != len) { 268 return false; 269 } 270 blob->assign(reinterpret_cast<const char*>(p), len); 271 return true; 272 } 273 274 bool Statement::ColumnBlobAsString16(int col, base::string16* val) const { 275 if (!CheckValid()) 276 return false; 277 278 const void* data = ColumnBlob(col); 279 size_t len = ColumnByteLength(col) / sizeof(base::char16); 280 val->resize(len); 281 if (val->size() != len) 282 return false; 283 val->assign(reinterpret_cast<const base::char16*>(data), len); 284 return true; 285 } 286 287 bool Statement::ColumnBlobAsVector(int col, std::vector<char>* val) const { 288 val->clear(); 289 290 if (!CheckValid()) 291 return false; 292 293 const void* data = sqlite3_column_blob(ref_->stmt(), col); 294 int len = sqlite3_column_bytes(ref_->stmt(), col); 295 if (data && len > 0) { 296 val->resize(len); 297 memcpy(&(*val)[0], data, len); 298 } 299 return true; 300 } 301 302 bool Statement::ColumnBlobAsVector( 303 int col, 304 std::vector<unsigned char>* val) const { 305 return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val)); 306 } 307 308 const char* Statement::GetSQLStatement() { 309 return sqlite3_sql(ref_->stmt()); 310 } 311 312 bool Statement::CheckOk(int err) const { 313 // Binding to a non-existent variable is evidence of a serious error. 314 // TODO(gbillock,shess): make this invalidate the statement so it 315 // can't wreak havoc. 316 if (err == SQLITE_RANGE) 317 DLOG(FATAL) << "Bind value out of range"; 318 return err == SQLITE_OK; 319 } 320 321 int Statement::CheckError(int err) { 322 // Please don't add DCHECKs here, OnSqliteError() already has them. 323 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE); 324 if (!succeeded_ && ref_.get() && ref_->connection()) 325 return ref_->connection()->OnSqliteError(err, this, NULL); 326 return err; 327 } 328 329 } // namespace sql 330