Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2086)

Unified Diff: app/sql/connection.cc

Issue 7353026: Move app/sql/* files to sql/ directory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « app/sql/connection.h ('k') | app/sql/connection_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: app/sql/connection.cc
diff --git a/app/sql/connection.cc b/app/sql/connection.cc
deleted file mode 100644
index 09eea458d6a8187cea337e61efb3de5118c95429..0000000000000000000000000000000000000000
--- a/app/sql/connection.cc
+++ /dev/null
@@ -1,420 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "app/sql/connection.h"
-
-#include <string.h>
-
-#include "app/sql/statement.h"
-#include "base/file_path.h"
-#include "base/logging.h"
-#include "base/stringprintf.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "third_party/sqlite/sqlite3.h"
-
-namespace {
-
-// Spin for up to a second waiting for the lock to clear when setting
-// up the database.
-// TODO(shess): Better story on this. http://crbug.com/56559
-const base::TimeDelta kBusyTimeout = base::TimeDelta::FromSeconds(1);
-
-class ScopedBusyTimeout {
- public:
- explicit ScopedBusyTimeout(sqlite3* db)
- : db_(db) {
- }
- ~ScopedBusyTimeout() {
- sqlite3_busy_timeout(db_, 0);
- }
-
- int SetTimeout(base::TimeDelta timeout) {
- DCHECK_LT(timeout.InMilliseconds(), INT_MAX);
- return sqlite3_busy_timeout(db_,
- static_cast<int>(timeout.InMilliseconds()));
- }
-
- private:
- sqlite3* db_;
-};
-
-} // namespace
-
-namespace sql {
-
-bool StatementID::operator<(const StatementID& other) const {
- if (number_ != other.number_)
- return number_ < other.number_;
- return strcmp(str_, other.str_) < 0;
-}
-
-ErrorDelegate::ErrorDelegate() {
-}
-
-ErrorDelegate::~ErrorDelegate() {
-}
-
-Connection::StatementRef::StatementRef()
- : connection_(NULL),
- stmt_(NULL) {
-}
-
-Connection::StatementRef::StatementRef(Connection* connection,
- sqlite3_stmt* stmt)
- : connection_(connection),
- stmt_(stmt) {
- connection_->StatementRefCreated(this);
-}
-
-Connection::StatementRef::~StatementRef() {
- if (connection_)
- connection_->StatementRefDeleted(this);
- Close();
-}
-
-void Connection::StatementRef::Close() {
- if (stmt_) {
- sqlite3_finalize(stmt_);
- stmt_ = NULL;
- }
- connection_ = NULL; // The connection may be getting deleted.
-}
-
-Connection::Connection()
- : db_(NULL),
- page_size_(0),
- cache_size_(0),
- exclusive_locking_(false),
- transaction_nesting_(0),
- needs_rollback_(false) {
-}
-
-Connection::~Connection() {
- Close();
-}
-
-bool Connection::Open(const FilePath& path) {
-#if defined(OS_WIN)
- return OpenInternal(WideToUTF8(path.value()));
-#elif defined(OS_POSIX)
- return OpenInternal(path.value());
-#endif
-}
-
-bool Connection::OpenInMemory() {
- return OpenInternal(":memory:");
-}
-
-void Connection::Close() {
- statement_cache_.clear();
- DCHECK(open_statements_.empty());
- if (db_) {
- sqlite3_close(db_);
- db_ = NULL;
- }
-}
-
-void Connection::Preload() {
- if (!db_) {
- NOTREACHED();
- return;
- }
-
- // A statement must be open for the preload command to work. If the meta
- // table doesn't exist, it probably means this is a new database and there
- // is nothing to preload (so it's OK we do nothing).
- if (!DoesTableExist("meta"))
- return;
- Statement dummy(GetUniqueStatement("SELECT * FROM meta"));
- if (!dummy || !dummy.Step())
- return;
-
-#if !defined(USE_SYSTEM_SQLITE)
- // This function is only defined in Chromium's version of sqlite.
- // Do not call it when using system sqlite.
- sqlite3_preload(db_);
-#endif
-}
-
-bool Connection::BeginTransaction() {
- if (needs_rollback_) {
- DCHECK_GT(transaction_nesting_, 0);
-
- // When we're going to rollback, fail on this begin and don't actually
- // mark us as entering the nested transaction.
- return false;
- }
-
- bool success = true;
- if (!transaction_nesting_) {
- needs_rollback_ = false;
-
- Statement begin(GetCachedStatement(SQL_FROM_HERE, "BEGIN TRANSACTION"));
- if (!begin || !begin.Run())
- return false;
- }
- transaction_nesting_++;
- return success;
-}
-
-void Connection::RollbackTransaction() {
- if (!transaction_nesting_) {
- NOTREACHED() << "Rolling back a nonexistent transaction";
- return;
- }
-
- transaction_nesting_--;
-
- if (transaction_nesting_ > 0) {
- // Mark the outermost transaction as needing rollback.
- needs_rollback_ = true;
- return;
- }
-
- DoRollback();
-}
-
-bool Connection::CommitTransaction() {
- if (!transaction_nesting_) {
- NOTREACHED() << "Rolling back a nonexistent transaction";
- return false;
- }
- transaction_nesting_--;
-
- if (transaction_nesting_ > 0) {
- // Mark any nested transactions as failing after we've already got one.
- return !needs_rollback_;
- }
-
- if (needs_rollback_) {
- DoRollback();
- return false;
- }
-
- Statement commit(GetCachedStatement(SQL_FROM_HERE, "COMMIT"));
- if (!commit)
- return false;
- return commit.Run();
-}
-
-bool Connection::Execute(const char* sql) {
- if (!db_)
- return false;
- return sqlite3_exec(db_, sql, NULL, NULL, NULL) == SQLITE_OK;
-}
-
-bool Connection::ExecuteWithTimeout(const char* sql, base::TimeDelta timeout) {
- if (!db_)
- return false;
-
- ScopedBusyTimeout busy_timeout(db_);
- busy_timeout.SetTimeout(timeout);
- return sqlite3_exec(db_, sql, NULL, NULL, NULL) == SQLITE_OK;
-}
-
-bool Connection::HasCachedStatement(const StatementID& id) const {
- return statement_cache_.find(id) != statement_cache_.end();
-}
-
-scoped_refptr<Connection::StatementRef> Connection::GetCachedStatement(
- const StatementID& id,
- const char* sql) {
- CachedStatementMap::iterator i = statement_cache_.find(id);
- if (i != statement_cache_.end()) {
- // Statement is in the cache. It should still be active (we're the only
- // one invalidating cached statements, and we'll remove it from the cache
- // if we do that. Make sure we reset it before giving out the cached one in
- // case it still has some stuff bound.
- DCHECK(i->second->is_valid());
- sqlite3_reset(i->second->stmt());
- return i->second;
- }
-
- scoped_refptr<StatementRef> statement = GetUniqueStatement(sql);
- if (statement->is_valid())
- statement_cache_[id] = statement; // Only cache valid statements.
- return statement;
-}
-
-scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement(
- const char* sql) {
- if (!db_)
- return new StatementRef(this, NULL); // Return inactive statement.
-
- sqlite3_stmt* stmt = NULL;
- if (sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL) != SQLITE_OK) {
- // Treat this as non-fatal, it can occur in a number of valid cases, and
- // callers should be doing their own error handling.
- DLOG(WARNING) << "SQL compile error " << GetErrorMessage();
- return new StatementRef(this, NULL);
- }
- return new StatementRef(this, stmt);
-}
-
-bool Connection::DoesTableExist(const char* table_name) const {
- // GetUniqueStatement can't be const since statements may modify the
- // database, but we know ours doesn't modify it, so the cast is safe.
- Statement statement(const_cast<Connection*>(this)->GetUniqueStatement(
- "SELECT name FROM sqlite_master "
- "WHERE type='table' AND name=?"));
- if (!statement)
- return false;
- statement.BindString(0, table_name);
- return statement.Step(); // Table exists if any row was returned.
-}
-
-bool Connection::DoesColumnExist(const char* table_name,
- const char* column_name) const {
- std::string sql("PRAGMA TABLE_INFO(");
- sql.append(table_name);
- sql.append(")");
-
- // Our SQL is non-mutating, so this cast is OK.
- Statement statement(const_cast<Connection*>(this)->GetUniqueStatement(
- sql.c_str()));
- if (!statement)
- return false;
-
- while (statement.Step()) {
- if (!statement.ColumnString(1).compare(column_name))
- return true;
- }
- return false;
-}
-
-int64 Connection::GetLastInsertRowId() const {
- if (!db_) {
- NOTREACHED();
- return 0;
- }
- return sqlite3_last_insert_rowid(db_);
-}
-
-int Connection::GetLastChangeCount() const {
- if (!db_) {
- NOTREACHED();
- return 0;
- }
- return sqlite3_changes(db_);
-}
-
-int Connection::GetErrorCode() const {
- if (!db_)
- return SQLITE_ERROR;
- return sqlite3_errcode(db_);
-}
-
-int Connection::GetLastErrno() const {
- if (!db_)
- return -1;
-
- int err = 0;
- if (SQLITE_OK != sqlite3_file_control(db_, NULL, SQLITE_LAST_ERRNO, &err))
- return -2;
-
- return err;
-}
-
-const char* Connection::GetErrorMessage() const {
- if (!db_)
- return "sql::Connection has no connection.";
- return sqlite3_errmsg(db_);
-}
-
-bool Connection::OpenInternal(const std::string& file_name) {
- if (db_) {
- NOTREACHED() << "sql::Connection is already open.";
- return false;
- }
-
- int err = sqlite3_open(file_name.c_str(), &db_);
- if (err != SQLITE_OK) {
- OnSqliteError(err, NULL);
- db_ = NULL;
- return false;
- }
-
- // Enable extended result codes to provide more color on I/O errors.
- // Not having extended result codes is not a fatal problem, as
- // Chromium code does not attempt to handle I/O errors anyhow. The
- // current implementation always returns SQLITE_OK, the DCHECK is to
- // quickly notify someone if SQLite changes.
- err = sqlite3_extended_result_codes(db_, 1);
- DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes";
-
- // If indicated, lock up the database before doing anything else, so
- // that the following code doesn't have to deal with locking.
- // TODO(shess): This code is brittle. Find the cases where code
- // doesn't request |exclusive_locking_| and audit that it does the
- // right thing with SQLITE_BUSY, and that it doesn't make
- // assumptions about who might change things in the database.
- // http://crbug.com/56559
- if (exclusive_locking_) {
- // TODO(shess): This should probably be a full CHECK(). Code
- // which requests exclusive locking but doesn't get it is almost
- // certain to be ill-tested.
- if (!Execute("PRAGMA locking_mode=EXCLUSIVE"))
- NOTREACHED() << "Could not set locking mode: " << GetErrorMessage();
- }
-
- if (page_size_ != 0) {
- // Enforce SQLite restrictions on |page_size_|.
- DCHECK(!(page_size_ & (page_size_ - 1)))
- << " page_size_ " << page_size_ << " is not a power of two.";
- static const int kSqliteMaxPageSize = 32768; // from sqliteLimit.h
- DCHECK_LE(page_size_, kSqliteMaxPageSize);
- const std::string sql = StringPrintf("PRAGMA page_size=%d", page_size_);
- if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout))
- NOTREACHED() << "Could not set page size: " << GetErrorMessage();
- }
-
- if (cache_size_ != 0) {
- const std::string sql = StringPrintf("PRAGMA cache_size=%d", cache_size_);
- if (!ExecuteWithTimeout(sql.c_str(), kBusyTimeout))
- NOTREACHED() << "Could not set cache size: " << GetErrorMessage();
- }
-
- return true;
-}
-
-void Connection::DoRollback() {
- Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK"));
- if (rollback)
- rollback.Run();
-}
-
-void Connection::StatementRefCreated(StatementRef* ref) {
- DCHECK(open_statements_.find(ref) == open_statements_.end());
- open_statements_.insert(ref);
-}
-
-void Connection::StatementRefDeleted(StatementRef* ref) {
- StatementRefSet::iterator i = open_statements_.find(ref);
- if (i == open_statements_.end())
- NOTREACHED();
- else
- open_statements_.erase(i);
-}
-
-void Connection::ClearCache() {
- statement_cache_.clear();
-
- // The cache clear will get most statements. There may be still be references
- // to some statements that are held by others (including one-shot statements).
- // This will deactivate them so they can't be used again.
- for (StatementRefSet::iterator i = open_statements_.begin();
- i != open_statements_.end(); ++i)
- (*i)->Close();
-}
-
-int Connection::OnSqliteError(int err, sql::Statement *stmt) {
- if (error_delegate_.get())
- return error_delegate_->OnError(err, this, stmt);
- // The default handling is to assert on debug and to ignore on release.
- NOTREACHED() << GetErrorMessage();
- return err;
-}
-
-} // namespace sql
« no previous file with comments | « app/sql/connection.h ('k') | app/sql/connection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698