summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-02 05:01:42 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-02 05:01:42 +0000
commit765b445022c7f2a24bc862b45d48ece4ca9a77e1 (patch)
tree9f351b1203bbfd02fae7018a1f11e2f15b6eeacb /app
parenteb6f2c542d7405788d668a762282b66655836e1d (diff)
downloadchromium_src-765b445022c7f2a24bc862b45d48ece4ca9a77e1.zip
chromium_src-765b445022c7f2a24bc862b45d48ece4ca9a77e1.tar.gz
chromium_src-765b445022c7f2a24bc862b45d48ece4ca9a77e1.tar.bz2
Convert history to use new sql wrappers. Enhance wrappers in several ways to
support the needs of history. BUG=none TEST=covered by unit tests Review URL: http://codereview.chromium.org/246053 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27832 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r--app/sql/connection.cc58
-rw-r--r--app/sql/connection.h37
-rw-r--r--app/sql/connection_unittest.cc2
-rw-r--r--app/sql/statement.cc19
-rw-r--r--app/sql/statement.h20
-rw-r--r--app/sql/statement_unittest.cc4
-rw-r--r--app/sql/transaction_unittest.cc2
7 files changed, 102 insertions, 40 deletions
diff --git a/app/sql/connection.cc b/app/sql/connection.cc
index 886f781..ac1c545 100644
--- a/app/sql/connection.cc
+++ b/app/sql/connection.cc
@@ -59,36 +59,16 @@ Connection::~Connection() {
Close();
}
-bool Connection::Init(const FilePath& path) {
+bool Connection::Open(const FilePath& path) {
#if defined(OS_WIN)
- // We want the default encoding to always be UTF-8, so we use the
- // 8-bit version of open().
- int err = sqlite3_open(WideToUTF8(path.value()).c_str(), &db_);
+ return OpenInternal(WideToUTF8(path.value()));
#elif defined(OS_POSIX)
- int err = sqlite3_open(path.value().c_str(), &db_);
+ return OpenInternal(path.value());
#endif
+}
- if (err != SQLITE_OK) {
- db_ = NULL;
- return false;
- }
-
- if (page_size_ != 0) {
- if (!Execute(StringPrintf("PRAGMA page_size=%d", page_size_).c_str()))
- NOTREACHED() << "Could not set page size";
- }
-
- if (cache_size_ != 0) {
- if (!Execute(StringPrintf("PRAGMA cache_size=%d", cache_size_).c_str()))
- NOTREACHED() << "Could not set page size";
- }
-
- if (exclusive_locking_) {
- if (!Execute("PRAGMA locking_mode=EXCLUSIVE"))
- NOTREACHED() << "Could not set locking mode.";
- }
-
- return true;
+bool Connection::OpenInMemory() {
+ return OpenInternal(":memory:");
}
void Connection::Close() {
@@ -283,6 +263,32 @@ const char* Connection::GetErrorMessage() const {
return sqlite3_errmsg(db_);
}
+bool Connection::OpenInternal(const std::string& file_name) {
+ int err = sqlite3_open(file_name.c_str(), &db_);
+ if (err != SQLITE_OK) {
+ OnSqliteError(err, NULL);
+ db_ = NULL;
+ return false;
+ }
+
+ if (page_size_ != 0) {
+ if (!Execute(StringPrintf("PRAGMA page_size=%d", page_size_).c_str()))
+ NOTREACHED() << "Could not set page size";
+ }
+
+ if (cache_size_ != 0) {
+ if (!Execute(StringPrintf("PRAGMA cache_size=%d", cache_size_).c_str()))
+ NOTREACHED() << "Could not set page size";
+ }
+
+ if (exclusive_locking_) {
+ if (!Execute("PRAGMA locking_mode=EXCLUSIVE"))
+ NOTREACHED() << "Could not set locking mode.";
+ }
+
+ return true;
+}
+
void Connection::DoRollback() {
Statement rollback(GetCachedStatement(SQL_FROM_HERE, "ROLLBACK"));
if (rollback)
diff --git a/app/sql/connection.h b/app/sql/connection.h
index 904d614..e87baa8 100644
--- a/app/sql/connection.h
+++ b/app/sql/connection.h
@@ -79,8 +79,12 @@ class ErrorDelegate : public base::RefCounted<ErrorDelegate> {
virtual ~ErrorDelegate() {}
// |error| is an sqlite result code as seen in sqlite\preprocessed\sqlite3.h
// |connection| is db connection where the error happened and |stmt| is
- // our best guess at the statement that triggered the error. Do not store
+ // our best guess at the statement that triggered the error. Do not store
// these pointers.
+ //
+ // |stmt| MAY BE NULL if there is no statement causing the problem (i.e. on
+ // initialization).
+ //
// If the error condition has been fixed an the original statement succesfuly
// re-tried then returning SQLITE_OK is appropiate; otherwise is recomended
// that you return the original |error| or the appropiae error code.
@@ -92,14 +96,14 @@ class Connection {
class StatementRef; // Forward declaration, see real one below.
public:
- // The database is opened by calling Init(). Any uncommitted transactions
- // will be rolled back when this object is deleted.
+ // The database is opened by calling Open[InMemory](). Any uncommitted
+ // transactions will be rolled back when this object is deleted.
Connection();
~Connection();
// Pre-init configuration ----------------------------------------------------
- // Sets the page size that will be used when creating a new adtabase. This
+ // Sets the page size that will be used when creating a new database. This
// must be called before Init(), and will only have an effect on new
// databases.
//
@@ -110,7 +114,7 @@ class Connection {
// Sets the number of pages that will be cached in memory by sqlite. The
// total cache size in bytes will be page_size * cache_size. This must be
- // called before Init() to have an effect.
+ // called before Open() to have an effect.
void set_cache_size(int cache_size) { cache_size_ = cache_size; }
// Call to put the database in exclusive locking mode. There is no "back to
@@ -122,11 +126,11 @@ class Connection {
// transaction, which means there may be less time spent initializing the
// next transaction because it doesn't have to re-aquire locks.
//
- // This must be called before Init() to have an effect.
+ // This must be called before Open() to have an effect.
void set_exclusive_locking() { exclusive_locking_ = true; }
// Sets the object that will handle errors. Recomended that it should be set
- // before calling Init(). If not set, the default is to ignore errors on
+ // before calling Open(). If not set, the default is to ignore errors on
// release and assert on debug builds.
void set_error_delegate(ErrorDelegate* delegate) {
error_delegate_ = delegate;
@@ -135,8 +139,16 @@ class Connection {
// Initialization ------------------------------------------------------------
// Initializes the SQL connection for the given file, returning true if the
- // file could be opened.
- bool Init(const FilePath& path);
+ // file could be opened. You can call this or InitInMemory to initialize.
+ bool Open(const FilePath& path);
+
+ // Initializes the SQL connection for a temporary in-memory database. There
+ // will be no associated file on disk, and the initial database will be
+ // empty. You must call this or Init to open the database.
+ bool OpenInMemory();
+
+ // Returns trie if the database has been successfully opened.
+ bool is_open() const { return !!db_; }
// Closes the database. This is automatically performed on destruction for
// you, but this allows you to close the database early. You must not call
@@ -225,7 +237,7 @@ class Connection {
// Info querying -------------------------------------------------------------
// Returns true if the given table exists.
- bool DoesTableExist( const char* table_name) const;
+ bool DoesTableExist(const char* table_name) const;
// Returns true if a column with the given name exists in the given table.
bool DoesColumnExist(const char* table_name, const char* column_name) const;
@@ -253,6 +265,11 @@ class Connection {
// (they should go through Statement).
friend class Statement;
+ // Internal initialize function used by both Init and InitInMemory. The file
+ // name is always 8 bits since we want to use the 8-bit version of
+ // sqlite3_open. The string can also be sqlite's special ":memory:" string.
+ bool OpenInternal(const std::string& file_name);
+
// A StatementRef is a refcounted wrapper around a sqlite statement pointer.
// Refcounting allows us to give these statements out to sql::Statement
// objects while also optionally maintaining a cache of compiled statements
diff --git a/app/sql/connection_unittest.cc b/app/sql/connection_unittest.cc
index 70c9ffc..a36fca7 100644
--- a/app/sql/connection_unittest.cc
+++ b/app/sql/connection_unittest.cc
@@ -18,7 +18,7 @@ class SQLConnectionTest : public testing::Test {
ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path_));
path_ = path_.AppendASCII("SQLConnectionTest.db");
file_util::Delete(path_, false);
- ASSERT_TRUE(db_.Init(path_));
+ ASSERT_TRUE(db_.Open(path_));
}
void TearDown() {
diff --git a/app/sql/statement.cc b/app/sql/statement.cc
index 3cadb6e..7abc225 100644
--- a/app/sql/statement.cc
+++ b/app/sql/statement.cc
@@ -70,6 +70,10 @@ bool Statement::BindNull(int col) {
return false;
}
+bool Statement::BindBool(int col, bool val) {
+ return BindInt(col, val ? 1 : 0);
+}
+
bool Statement::BindInt(int col, int val) {
if (is_valid()) {
int err = CheckError(sqlite3_bind_int(ref_->stmt(), col + 1, val));
@@ -129,6 +133,21 @@ int Statement::ColumnCount() const {
return sqlite3_column_count(ref_->stmt());
}
+ColType Statement::ColumnType(int col) const {
+ // Verify that our enum matches sqlite's values.
+ COMPILE_ASSERT(COLUMN_TYPE_INTEGER == SQLITE_INTEGER, integer_no_match);
+ COMPILE_ASSERT(COLUMN_TYPE_FLOAT == SQLITE_FLOAT, float_no_match);
+ COMPILE_ASSERT(COLUMN_TYPE_TEXT == SQLITE_TEXT, integer_no_match);
+ COMPILE_ASSERT(COLUMN_TYPE_BLOB == SQLITE_BLOB, blob_no_match);
+ COMPILE_ASSERT(COLUMN_TYPE_NULL == SQLITE_NULL, null_no_match);
+
+ return static_cast<ColType>(sqlite3_column_type(ref_->stmt(), col));
+}
+
+bool Statement::ColumnBool(int col) const {
+ return !!ColumnInt(col);
+}
+
int Statement::ColumnInt(int col) const {
if (!is_valid()) {
NOTREACHED();
diff --git a/app/sql/statement.h b/app/sql/statement.h
index 6211d34..8ee6ef5 100644
--- a/app/sql/statement.h
+++ b/app/sql/statement.h
@@ -14,6 +14,16 @@
namespace sql {
+// Possible return values from ColumnType in a statement. These should match
+// the values in sqlite3.h.
+enum ColType {
+ COLUMN_TYPE_INTEGER = 1,
+ COLUMN_TYPE_FLOAT = 2,
+ COLUMN_TYPE_TEXT = 3,
+ COLUMN_TYPE_BLOB = 4,
+ COLUMN_TYPE_NULL = 5,
+};
+
// Normal usage:
// sql::Statement s = connection_.GetUniqueStatement(...);
// if (!s) // You should check for errors before using the statement.
@@ -88,6 +98,7 @@ class Statement {
// The main thing you may want to check is when binding large blobs or
// strings there may be out of memory.
bool BindNull(int col);
+ bool BindBool(int col, bool val);
bool BindInt(int col, int val);
bool BindInt64(int col, int64 val);
bool BindDouble(int col, double val);
@@ -100,7 +111,16 @@ class Statement {
// Returns the number of output columns in the result.
int ColumnCount() const;
+ // Returns the type associated with the given column.
+ //
+ // Watch out: the type may be undefined if you've done something to cause a
+ // "type conversion." This means requesting the value of a column of a type
+ // where that type is not the native type. For safety, call ColumnType only
+ // on a column before getting the value out in any way.
+ ColType ColumnType(int col) const;
+
// These all take a 0-based argument index.
+ bool ColumnBool(int col) const;
int ColumnInt(int col) const;
int64 ColumnInt64(int col) const;
double ColumnDouble(int col) const;
diff --git a/app/sql/statement_unittest.cc b/app/sql/statement_unittest.cc
index 5f04880..90f421c 100644
--- a/app/sql/statement_unittest.cc
+++ b/app/sql/statement_unittest.cc
@@ -19,7 +19,7 @@ class StatementErrorHandler : public sql::ErrorDelegate {
virtual int OnError(int error, sql::Connection* connection,
sql::Statement* stmt) {
error_ = error;
- const char* sql_txt = stmt->GetSQLStatement();
+ const char* sql_txt = stmt ? stmt->GetSQLStatement() : NULL;
sql_text_ = sql_txt ? sql_txt : "no statement available";
return error;
}
@@ -46,7 +46,7 @@ class SQLStatementTest : public testing::Test {
ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path_));
path_ = path_.AppendASCII("SQLStatementTest.db");
file_util::Delete(path_, false);
- ASSERT_TRUE(db_.Init(path_));
+ ASSERT_TRUE(db_.Open(path_));
// The |error_handler_| will be called if any sqlite statement operation
// returns an error code.
db_.set_error_delegate(error_handler_);
diff --git a/app/sql/transaction_unittest.cc b/app/sql/transaction_unittest.cc
index 0da79e3..55b77b9 100644
--- a/app/sql/transaction_unittest.cc
+++ b/app/sql/transaction_unittest.cc
@@ -19,7 +19,7 @@ class SQLTransactionTest : public testing::Test {
ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path_));
path_ = path_.AppendASCII("SQLStatementTest.db");
file_util::Delete(path_, false);
- ASSERT_TRUE(db_.Init(path_));
+ ASSERT_TRUE(db_.Open(path_));
ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
}