Home | History | Annotate | Download | only in sql
      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       succeeded_(false) {
     20 }
     21 
     22 Statement::Statement(scoped_refptr<Connection::StatementRef> ref)
     23     : ref_(ref),
     24       succeeded_(false) {
     25 }
     26 
     27 Statement::~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 
     34 void Statement::Assign(scoped_refptr<Connection::StatementRef> ref) {
     35   Reset(true);
     36   ref_ = ref;
     37 }
     38 
     39 void Statement::Clear() {
     40   Assign(new Connection::StatementRef(NULL, NULL, false));
     41   succeeded_ = false;
     42 }
     43 
     44 bool 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 
     52 bool Statement::Run() {
     53   ref_->AssertIOAllowed();
     54   if (!CheckValid())
     55     return false;
     56 
     57   return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_DONE;
     58 }
     59 
     60 bool Statement::Step() {
     61   ref_->AssertIOAllowed();
     62   if (!CheckValid())
     63     return false;
     64 
     65   return CheckError(sqlite3_step(ref_->stmt())) == SQLITE_ROW;
     66 }
     67 
     68 void 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 
     82 bool Statement::Succeeded() const {
     83   if (!is_valid())
     84     return false;
     85 
     86   return succeeded_;
     87 }
     88 
     89 bool Statement::BindNull(int col) {
     90   if (!is_valid())
     91     return false;
     92 
     93   return CheckOk(sqlite3_bind_null(ref_->stmt(), col + 1));
     94 }
     95 
     96 bool Statement::BindBool(int col, bool val) {
     97   return BindInt(col, val ? 1 : 0);
     98 }
     99 
    100 bool 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 
    107 bool 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 
    114 bool 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 
    121 bool 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 
    129 bool 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 
    140 bool Statement::BindString16(int col, const string16& value) {
    141   return BindString(col, UTF16ToUTF8(value));
    142 }
    143 
    144 bool 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 
    152 int Statement::ColumnCount() const {
    153   if (!is_valid())
    154     return 0;
    155 
    156   return sqlite3_column_count(ref_->stmt());
    157 }
    158 
    159 ColType 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 
    170 ColType 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 
    186 bool Statement::ColumnBool(int col) const {
    187   return !!ColumnInt(col);
    188 }
    189 
    190 int Statement::ColumnInt(int col) const {
    191   if (!CheckValid())
    192     return 0;
    193 
    194   return sqlite3_column_int(ref_->stmt(), col);
    195 }
    196 
    197 int64 Statement::ColumnInt64(int col) const {
    198   if (!CheckValid())
    199     return 0;
    200 
    201   return sqlite3_column_int64(ref_->stmt(), col);
    202 }
    203 
    204 double Statement::ColumnDouble(int col) const {
    205   if (!CheckValid())
    206     return 0;
    207 
    208   return sqlite3_column_double(ref_->stmt(), col);
    209 }
    210 
    211 std::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 
    225 string16 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 
    233 int Statement::ColumnByteLength(int col) const {
    234   if (!CheckValid())
    235     return 0;
    236 
    237   return sqlite3_column_bytes(ref_->stmt(), col);
    238 }
    239 
    240 const void* Statement::ColumnBlob(int col) const {
    241   if (!CheckValid())
    242     return NULL;
    243 
    244   return sqlite3_column_blob(ref_->stmt(), col);
    245 }
    246 
    247 bool 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 
    261 bool 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 
    274 bool 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 
    289 bool Statement::ColumnBlobAsVector(
    290     int col,
    291     std::vector<unsigned char>* val) const {
    292   return ColumnBlobAsVector(col, reinterpret_cast< std::vector<char>* >(val));
    293 }
    294 
    295 const char* Statement::GetSQLStatement() {
    296   return sqlite3_sql(ref_->stmt());
    297 }
    298 
    299 bool 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 
    308 int 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