Home | History | Annotate | Download | only in sql
      1 // Copyright (c) 2011 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/connection.h"
      6 
      7 #include <string.h>
      8 
      9 #include "app/sql/statement.h"
     10 #include "base/file_path.h"
     11 #include "base/logging.h"
     12 #include "base/string_util.h"
     13 #include "base/utf_string_conversions.h"
     14 #ifdef ANDROID
     15 #include "sqlite3.h"
     16 #else
     17 #include "third_party/sqlite/sqlite3.h"
     18 #endif
     19 
     20 namespace {
     21 
     22 // Spin for up to a second waiting for the lock to clear when setting
     23 // up the database.
     24 // TODO(shess): Better story on this.  http://crbug.com/56559
     25 const base::TimeDelta kBusyTimeout = base::TimeDelta::FromSeconds(1);
     26 
     27 class ScopedBusyTimeout {
     28  public:
     29   explicit ScopedBusyTimeout(sqlite3* db)
     30       : db_(db) {
     31   }
     32   ~ScopedBusyTimeout() {
     33     sqlite3_busy_timeout(db_, 0);
     34   }
     35 
     36   int SetTimeout(base::TimeDelta timeout) {
     37     DCHECK_LT(timeout.InMilliseconds(), INT_MAX);
     38     return sqlite3_busy_timeout(db_,
     39                                 static_cast<int>(timeout.InMilliseconds()));
     40   }
     41 
     42  private:
     43   sqlite3* db_;
     44 };
     45 
     46 }  // namespace
     47 
     48 namespace sql {
     49 
     50 bool StatementID::operator<(const StatementID& other) const {
     51   if (number_ != other.number_)
     52     return number_ < other.number_;
     53   return strcmp(str_, other.str_) < 0;
     54 }
     55 
     56 ErrorDelegate::ErrorDelegate() {
     57 }
     58 
     59 ErrorDelegate::~ErrorDelegate() {
     60 }
     61 
     62 Connection::StatementRef::StatementRef()
     63     : connection_(NULL),
     64       stmt_(NULL) {
     65 }
     66 
     67 Connection::StatementRef::StatementRef(Connection* connection,
     68                                        sqlite3_stmt* stmt)
     69     : connection_(connection),
     70       stmt_(stmt) {
     71   connection_->StatementRefCreated(this);
     72 }
     73 
     74 Connection::StatementRef::~StatementRef() {
     75   if (connection_)
     76     connection_->StatementRefDeleted(this);
     77   Close();
     78 }
     79 
     80 void Connection::StatementRef::Close() {
     81   if (stmt_) {
     82     sqlite3_finalize(stmt_);
     83     stmt_ = NULL;
     84   }
     85   connection_ = NULL;  // The connection may be getting deleted.
     86 }
     87 
     88 Connection::Connection()
     89     : db_(NULL),
     90       page_size_(0),
     91       cache_size_(0),
     92       exclusive_locking_(false),
     93       transaction_nesting_(0),
     94       needs_rollback_(false) {
     95 }
     96 
     97 Connection::~Connection() {
     98   Close();
     99 }
    100 
    101 bool Connection::Open(const FilePath& path) {
    102 #if defined(OS_WIN)
    103   return OpenInternal(WideToUTF8(path.value()));
    104 #elif defined(OS_POSIX)
    105   return OpenInternal(path.value());
    106 #endif
    107 }
    108 
    109 bool Connection::OpenInMemory() {
    110   return OpenInternal(":memory:");
    111 }
    112 
    113 void Connection::Close() {
    114   statement_cache_.clear();
    115   DCHECK(open_statements_.empty());
    116   if (db_) {
    117     sqlite3_close(db_);
    118     db_ = NULL;
    119   }
    120 }
    121 
    122 void Connection::Preload() {
    123   if (!db_) {
    124     NOTREACHED();
    125     return;
    126   }
    127 
    128   // A statement must be open for the preload command to work. If the meta
    129   // table doesn't exist, it probably means this is a new database and there
    130   // is nothing to preload (so it's OK we do nothing).
    131   if (!DoesTableExist("meta"))
    132     return;
    133   Statement dummy(GetUniqueStatement("SELECT * FROM meta"));
    134   if (!dummy || !dummy.Step())
    135     return;
    136 
    137 #if !defined(USE_SYSTEM_SQLITE)
    138   // This function is only defined in Chromium's version of sqlite.
    139   // Do not call it when using system sqlite.
    140   sqlite3_preload(db_);
    141 #endif
    142 }
    143 
    144 bool Connection::BeginTransaction() {
    145   if (needs_rollback_) {
    146     DCHECK_GT(transaction_nesting_, 0);
    147 
    148     // When we're going to rollback, fail on this begin and don't actually
    149     // mark us as entering the nested transaction.
    150     return false;
    151   }
    152 
    153   bool success = true;
    154   if (!transaction_nesting_) {
    155     needs_rollback_ = false;
    156 
    157     Statement begin(GetCachedStatement(SQL_FROM_HERE, "BEGIN TRANSACTION"));
    158     if (!begin || !begin.Run())
    159       return false;
    160   }
    161   transaction_nesting_++;
    162   return success;
    163 }
    164 
    165 void Connection::RollbackTransaction() {
    166   if (!transaction_nesting_) {
    167     NOTREACHED() << "Rolling back a nonexistent transaction";
    168     return;
    169   }
    170 
    171   transaction_nesting_--;
    172 
    173   if (transaction_nesting_ > 0) {
    174     // Mark the outermost transaction as needing rollback.
    175     needs_rollback_ = true;
    176     return;
    177   }
    178 
    179   DoRollback();
    180 }
    181 
    182 bool Connection::CommitTransaction() {
    183   if (!transaction_nesting_) {
    184     NOTREACHED() << "Rolling back a nonexistent transaction";
    185     return false;
    186   }
    187   transaction_nesting_--;
    188 
    189   if (transaction_nesting_ > 0) {
    190     // Mark any nested transactions as failing after we've already got one.
    191     return !needs_rollback_;
    192   }
    193 
    194   if (needs_rollback_) {
    195     DoRollback();
    196     return false;
    197   }
    198 
    199   Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT"));
    200   if (!commit)
    201     return false;
    202   return commit.Run();
    203 }
    204 
    205 bool Connection::Execute(const char* sql) {
    206   if (!db_)
    207     return false;
    208   return sqlite3_exec(db_, sql, NULL, NULL, NULL) == SQLITE_OK;
    209 }
    210 
    211 bool Connection::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) {
    212   if (!db_)
    213     return false;
    214 
    215   ScopedBusyTimeout busy_timeout(db_);
    216   busy_timeout.SetTimeout(timeout);
    217   return sqlite3_exec(db_, sql, NULL, NULL, NULL) == SQLITE_OK;
    218 }
    219 
    220 bool Connection::HasCachedStatement(const StatementID& id) const {
    221   return statement_cache_.find(id) != statement_cache_.end();
    222 }
    223 
    224 scoped_refptr<Connection::StatementRef> Connection::GetCachedStatement(
    225     const StatementID& id,
    226     const char* sql) {
    227   CachedStatementMap::iterator i = statement_cache_.find(id);
    228   if (i != statement_cache_.end()) {
    229     // Statement is in the cache. It should still be active (we're the only
    230     // one invalidating cached statements, and we'll remove it from the cache
    231     // if we do that. Make sure we reset it before giving out the cached one in
    232     // case it still has some stuff bound.
    233     DCHECK(i->second->is_valid());
    234     sqlite3_reset(i->second->stmt());
    235     return i->second;
    236   }
    237 
    238   scoped_refptr<StatementRef> statement = GetUniqueStatement(sql);
    239   if (statement->is_valid())
    240     statement_cache_[id] = statement;  // Only cache valid statements.
    241   return statement;
    242 }
    243 
    244 scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement(
    245     const char* sql) {
    246   if (!db_)
    247     return new StatementRef(this, NULL);  // Return inactive statement.
    248 
    249   sqlite3_stmt* stmt = NULL;
    250   if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) {
    251     // Treat this as non-fatal, it can occur in a number of valid cases, and
    252     // callers should be doing their own error handling.
    253     DLOG(WARNING) << "SQL compile error " << GetErrorMessage();
    254     return new StatementRef(this, NULL);
    255   }
    256   return new StatementRef(this, stmt);
    257 }
    258 
    259 bool Connection::DoesTableExist(const char* table_name) const {
    260   // GetUniqueStatement can't be const since statements may modify the
    261   // database, but we know ours doesn't modify it, so the cast is safe.
    262   Statement statement(const_cast<Connection*>(this)->GetUniqueStatement(
    263       "SELECT name FROM sqlite_master "
    264       "WHERE type='table' AND name=?"));
    265   if (!statement)
    266     return false;
    267   statement.BindString(0, table_name);
    268   return statement.Step();  // Table exists if any row was returned.
    269 }
    270 
    271 bool Connection::DoesColumnExist(const char* table_name,
    272                                  const char* column_name) const {
    273   std::string sql("PRAGMA TABLE_INFO(");
    274   sql.append(table_name);
    275   sql.append(")");
    276 
    277   // Our SQL is non-mutating, so this cast is OK.
    278   Statement statement(const_cast<Connection*>(this)->GetUniqueStatement(
    279       sql.c_str()));
    280   if (!statement)
    281     return false;
    282 
    283   while (statement.Step()) {
    284     if (!statement.ColumnString(1).compare(column_name))
    285       return true;
    286   }
    287   return false;
    288 }
    289 
    290 int64 Connection::GetLastInsertRowId() const {
    291   if (!db_) {
    292     NOTREACHED();
    293     return 0;
    294   }
    295   return sqlite3_last_insert_rowid(db_);
    296 }
    297 
    298 int Connection::GetLastChangeCount() const {
    299   if (!db_) {
    300     NOTREACHED();
    301     return 0;
    302   }
    303   return sqlite3_changes(db_);
    304 }
    305 
    306 int Connection::GetErrorCode() const {
    307   if (!db_)
    308     return SQLITE_ERROR;
    309   return sqlite3_errcode(db_);
    310 }
    311 
    312 int Connection::GetLastErrno() const {
    313   if (!db_)
    314     return -1;
    315 
    316   int err = 0;
    317   if (SQLITE_OK != sqlite3_file_control(db_, NULL, SQLITE_LAST_ERRNO, &err))
    318     return -2;
    319 
    320   return err;
    321 }
    322 
    323 const char* Connection::GetErrorMessage() const {
    324   if (!db_)
    325     return "sql::Connection has no connection.";
    326   return sqlite3_errmsg(db_);
    327 }
    328 
    329 bool Connection::OpenInternal(const std::string& file_name) {
    330   if (db_) {
    331     NOTREACHED() << "sql::Connection is already open.";
    332     return false;
    333   }
    334 
    335   int err = sqlite3_open(file_name.c_str(), &db_);
    336   if (err != SQLITE_OK) {
    337     OnSqliteError(err, NULL);
    338     db_ = NULL;
    339     return false;
    340   }
    341 
    342   // Enable extended result codes to provide more color on I/O errors.
    343   // Not having extended result codes is not a fatal problem, as
    344   // Chromium code does not attempt to handle I/O errors anyhow.  The
    345   // current implementation always returns SQLITE_OK, the DCHECK is to
    346   // quickly notify someone if SQLite changes.
    347   err = sqlite3_extended_result_codes(db_, 1);
    348   DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes";
    349 
    350   // If indicated, lock up the database before doing anything else, so
    351   // that the following code doesn't have to deal with locking.
    352   // TODO(shess): This code is brittle.  Find the cases where code
    353   // doesn't request |exclusive_locking_| and audit that it does the
    354   // right thing with SQLITE_BUSY, and that it doesn't make
    355   // assumptions about who might change things in the database.
    356   // http://crbug.com/56559
    357   if (exclusive_locking_) {
    358     // TODO(shess): This should probably be a full CHECK().  Code
    359     // which requests exclusive locking but doesn't get it is almost
    360     // certain to be ill-tested.
    361     if (!Execute("PRAGMA locking_mode=EXCLUSIVE"))
    362       NOTREACHED() << "Could not set locking mode: " << GetErrorMessage();
    363   }
    364 
    365   if (page_size_ != 0) {
    366     // Enforce SQLite restrictions on |page_size_|.
    367     DCHECK(!(page_size_ & (page_size_ - 1)))
    368         << " page_size_ " << page_size_ << " is not a power of two.";
    369     static const int kSqliteMaxPageSize = 32768;  // from sqliteLimit.h
    370     DCHECK_LE(page_size_, kSqliteMaxPageSize);
    371     const std::string sql = StringPrintf("PRAGMA page_size=%d", page_size_);
    372     if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout))
    373       NOTREACHED() << "Could not set page size: " << GetErrorMessage();
    374   }
    375 
    376   if (cache_size_ != 0) {
    377     const std::string sql = StringPrintf("PRAGMA cache_size=%d", cache_size_);
    378     if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout))
    379       NOTREACHED() << "Could not set cache size: " << GetErrorMessage();
    380   }
    381 
    382   return true;
    383 }
    384 
    385 void Connection::DoRollback() {
    386   Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK"));
    387   if (rollback)
    388     rollback.Run();
    389 }
    390 
    391 void Connection::StatementRefCreated(StatementRef* ref) {
    392   DCHECK(open_statements_.find(ref) == open_statements_.end());
    393   open_statements_.insert(ref);
    394 }
    395 
    396 void Connection::StatementRefDeleted(StatementRef* ref) {
    397   StatementRefSet::iterator i = open_statements_.find(ref);
    398   if (i == open_statements_.end())
    399     NOTREACHED();
    400   else
    401     open_statements_.erase(i);
    402 }
    403 
    404 void Connection::ClearCache() {
    405   statement_cache_.clear();
    406 
    407   // The cache clear will get most statements. There may be still be references
    408   // to some statements that are held by others (including one-shot statements).
    409   // This will deactivate them so they can't be used again.
    410   for (StatementRefSet::iterator i = open_statements_.begin();
    411        i != open_statements_.end(); ++i)
    412     (*i)->Close();
    413 }
    414 
    415 int Connection::OnSqliteError(int err, sql::Statement *stmt) {
    416   if (error_delegate_.get())
    417     return error_delegate_->OnError(err, this, stmt);
    418   // The default handling is to assert on debug and to ignore on release.
    419   NOTREACHED() << GetErrorMessage();
    420   return err;
    421 }
    422 
    423 }  // namespace sql
    424