| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sql/statement.h" | 5 #include "sql/statement.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "third_party/sqlite/sqlite3.h" | 10 #include "third_party/sqlite/sqlite3.h" |
| 11 | 11 |
| 12 namespace sql { | 12 namespace sql { |
| 13 | 13 |
| 14 // This empty constructor initializes our reference with an empty one so that | 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 | 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. | 16 // only have to check the ref's validity bit. |
| 17 Statement::Statement() | 17 Statement::Statement() |
| 18 : ref_(new Connection::StatementRef(NULL, NULL, false)), | 18 : ref_(new Connection::StatementRef(NULL, NULL, false)), |
| 19 stepped_(false), |
| 19 succeeded_(false) { | 20 succeeded_(false) { |
| 20 } | 21 } |
| 21 | 22 |
| 22 Statement::Statement(scoped_refptr<Connection::StatementRef> ref) | 23 Statement::Statement(scoped_refptr<Connection::StatementRef> ref) |
| 23 : ref_(ref), | 24 : ref_(ref), |
| 25 stepped_(false), |
| 24 succeeded_(false) { | 26 succeeded_(false) { |
| 25 } | 27 } |
| 26 | 28 |
| 27 Statement::~Statement() { | 29 Statement::~Statement() { |
| 28 // Free the resources associated with this statement. We assume there's only | 30 // 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 | 31 // one statement active for a given sqlite3_stmt at any time, so this won't |
| 30 // mess with anything. | 32 // mess with anything. |
| 31 Reset(true); | 33 Reset(true); |
| 32 } | 34 } |
| 33 | 35 |
| 34 void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) { | 36 void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) { |
| 35 Reset(true); | 37 Reset(true); |
| 36 ref_ = ref; | 38 ref_ = ref; |
| 37 } | 39 } |
| 38 | 40 |
| 39 void Statement::Clear() { | 41 void Statement::Clear() { |
| 40 Assign(new Connection::StatementRef(NULL, NULL, false)); | 42 Assign(new Connection::StatementRef(NULL, NULL, false)); |
| 41 succeeded_ = false; | 43 succeeded_ = false; |
| 42 } | 44 } |
| 43 | 45 |
| 44 bool Statement::CheckValid() const { | 46 bool Statement::CheckValid() const { |
| 45 // Allow operations to fail silently if a statement was invalidated | 47 // Allow operations to fail silently if a statement was invalidated |
| 46 // because the database was closed by an error handler. | 48 // because the database was closed by an error handler. |
| 47 DLOG_IF(FATAL, !ref_->was_valid()) | 49 DLOG_IF(FATAL, !ref_->was_valid()) |
| 48 << "Cannot call mutating statements on an invalid statement."; | 50 << "Cannot call mutating statements on an invalid statement."; |
| 49 return is_valid(); | 51 return is_valid(); |
| 50 } | 52 } |
| 51 | 53 |
| 52 bool Statement::Run() { | 54 bool Statement::Run() { |
| 55 DCHECK(!stepped_); |
| 53 ref_->AssertIOAllowed(); | 56 ref_->AssertIOAllowed(); |
| 54 if (!CheckValid()) | 57 if (!CheckValid()) |
| 55 return false; | 58 return false; |
| 56 | 59 |
| 60 stepped_ = true; |
| 57 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE; | 61 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE; |
| 58 } | 62 } |
| 59 | 63 |
| 60 bool Statement::Step() { | 64 bool Statement::Step() { |
| 61 ref_->AssertIOAllowed(); | 65 ref_->AssertIOAllowed(); |
| 62 if (!CheckValid()) | 66 if (!CheckValid()) |
| 63 return false; | 67 return false; |
| 64 | 68 |
| 69 stepped_ = true; |
| 65 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW; | 70 return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW; |
| 66 } | 71 } |
| 67 | 72 |
| 68 void Statement::Reset(bool clear_bound_vars) { | 73 void Statement::Reset(bool clear_bound_vars) { |
| 69 ref_->AssertIOAllowed(); | 74 ref_->AssertIOAllowed(); |
| 70 if (is_valid()) { | 75 if (is_valid()) { |
| 71 // We don't call CheckError() here because sqlite3_reset() returns | 76 // We don't call CheckError() here because sqlite3_reset() returns |
| 72 // the last error that Step() caused thereby generating a second | 77 // the last error that Step() caused thereby generating a second |
| 73 // spurious error callback. | 78 // spurious error callback. |
| 74 if (clear_bound_vars) | 79 if (clear_bound_vars) |
| 75 sqlite3_clear_bindings(ref_->stmt()); | 80 sqlite3_clear_bindings(ref_->stmt()); |
| 76 sqlite3_reset(ref_->stmt()); | 81 sqlite3_reset(ref_->stmt()); |
| 77 } | 82 } |
| 78 | 83 |
| 79 succeeded_ = false; | 84 succeeded_ = false; |
| 85 stepped_ = false; |
| 80 } | 86 } |
| 81 | 87 |
| 82 bool Statement::Succeeded() const { | 88 bool Statement::Succeeded() const { |
| 83 if (!is_valid()) | 89 if (!is_valid()) |
| 84 return false; | 90 return false; |
| 85 | 91 |
| 86 return succeeded_; | 92 return succeeded_; |
| 87 } | 93 } |
| 88 | 94 |
| 89 bool Statement::BindNull(int col) { | 95 bool Statement::BindNull(int col) { |
| 96 DCHECK(!stepped_); |
| 90 if (!is_valid()) | 97 if (!is_valid()) |
| 91 return false; | 98 return false; |
| 92 | 99 |
| 93 return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1)); | 100 return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1)); |
| 94 } | 101 } |
| 95 | 102 |
| 96 bool Statement::BindBool(int col, bool val) { | 103 bool Statement::BindBool(int col, bool val) { |
| 97 return BindInt(col, val ? 1 : 0); | 104 return BindInt(col, val ? 1 : 0); |
| 98 } | 105 } |
| 99 | 106 |
| 100 bool Statement::BindInt(int col, int val) { | 107 bool Statement::BindInt(int col, int val) { |
| 108 DCHECK(!stepped_); |
| 101 if (!is_valid()) | 109 if (!is_valid()) |
| 102 return false; | 110 return false; |
| 103 | 111 |
| 104 return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val)); | 112 return CheckOk(sqlite3_bind_int(ref_->stmt(), col + 1, val)); |
| 105 } | 113 } |
| 106 | 114 |
| 107 bool Statement::BindInt64(int col, int64 val) { | 115 bool Statement::BindInt64(int col, int64 val) { |
| 116 DCHECK(!stepped_); |
| 108 if (!is_valid()) | 117 if (!is_valid()) |
| 109 return false; | 118 return false; |
| 110 | 119 |
| 111 return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val)); | 120 return CheckOk(sqlite3_bind_int64(ref_->stmt(), col + 1, val)); |
| 112 } | 121 } |
| 113 | 122 |
| 114 bool Statement::BindDouble(int col, double val) { | 123 bool Statement::BindDouble(int col, double val) { |
| 124 DCHECK(!stepped_); |
| 115 if (!is_valid()) | 125 if (!is_valid()) |
| 116 return false; | 126 return false; |
| 117 | 127 |
| 118 return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val)); | 128 return CheckOk(sqlite3_bind_double(ref_->stmt(), col + 1, val)); |
| 119 } | 129 } |
| 120 | 130 |
| 121 bool Statement::BindCString(int col, const char* val) { | 131 bool Statement::BindCString(int col, const char* val) { |
| 132 DCHECK(!stepped_); |
| 122 if (!is_valid()) | 133 if (!is_valid()) |
| 123 return false; | 134 return false; |
| 124 | 135 |
| 125 return CheckOk( | 136 return CheckOk( |
| 126 sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT)); | 137 sqlite3_bind_text(ref_->stmt(), col + 1, val, -1, SQLITE_TRANSIENT)); |
| 127 } | 138 } |
| 128 | 139 |
| 129 bool Statement::BindString(int col, const std::string& val) { | 140 bool Statement::BindString(int col, const std::string& val) { |
| 141 DCHECK(!stepped_); |
| 130 if (!is_valid()) | 142 if (!is_valid()) |
| 131 return false; | 143 return false; |
| 132 | 144 |
| 133 return CheckOk(sqlite3_bind_text(ref_->stmt(), | 145 return CheckOk(sqlite3_bind_text(ref_->stmt(), |
| 134 col + 1, | 146 col + 1, |
| 135 val.data(), | 147 val.data(), |
| 136 val.size(), | 148 val.size(), |
| 137 SQLITE_TRANSIENT)); | 149 SQLITE_TRANSIENT)); |
| 138 } | 150 } |
| 139 | 151 |
| 140 bool Statement::BindString16(int col, const string16& value) { | 152 bool Statement::BindString16(int col, const string16& value) { |
| 141 return BindString(col, UTF16ToUTF8(value)); | 153 return BindString(col, UTF16ToUTF8(value)); |
| 142 } | 154 } |
| 143 | 155 |
| 144 bool Statement::BindBlob(int col, const void* val, int val_len) { | 156 bool Statement::BindBlob(int col, const void* val, int val_len) { |
| 157 DCHECK(!stepped_); |
| 145 if (!is_valid()) | 158 if (!is_valid()) |
| 146 return false; | 159 return false; |
| 147 | 160 |
| 148 return CheckOk( | 161 return CheckOk( |
| 149 sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT)); | 162 sqlite3_bind_blob(ref_->stmt(), col + 1, val, val_len, SQLITE_TRANSIENT)); |
| 150 } | 163 } |
| 151 | 164 |
| 152 int Statement::ColumnCount() const { | 165 int Statement::ColumnCount() const { |
| 153 if (!is_valid()) | 166 if (!is_valid()) |
| 154 return 0; | 167 return 0; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 | 320 |
| 308 int Statement::CheckError(int err) { | 321 int Statement::CheckError(int err) { |
| 309 // Please don't add DCHECKs here, OnSqliteError() already has them. | 322 // Please don't add DCHECKs here, OnSqliteError() already has them. |
| 310 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE); | 323 succeeded_ = (err == SQLITE_OK || err == SQLITE_ROW || err == SQLITE_DONE); |
| 311 if (!succeeded_ && ref_.get() && ref_->connection()) | 324 if (!succeeded_ && ref_.get() && ref_->connection()) |
| 312 return ref_->connection()->OnSqliteError(err, this, NULL); | 325 return ref_->connection()->OnSqliteError(err, this, NULL); |
| 313 return err; | 326 return err; |
| 314 } | 327 } |
| 315 | 328 |
| 316 } // namespace sql | 329 } // namespace sql |
| OLD | NEW |