summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshess <shess@chromium.org>2015-04-08 18:59:47 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-09 02:00:21 +0000
commit92a2ab1f1d0cdff39e6d506c4cb6a80038baeeb3 (patch)
tree10caf28af8322af472fd341379c676935e685c20
parent9afe19122a83f762baded7003b25ff22205fd533 (diff)
downloadchromium_src-92a2ab1f1d0cdff39e6d506c4cb6a80038baeeb3.zip
chromium_src-92a2ab1f1d0cdff39e6d506c4cb6a80038baeeb3.tar.gz
chromium_src-92a2ab1f1d0cdff39e6d506c4cb6a80038baeeb3.tar.bz2
[sql] Change DoesStuffExist() to work with ScopedErrorIgnorer.
This not working was preventing certain corruption-testing tests from being written. Also modified Does{Table,Index,Column}Exist() to reflect that these names are _not_ case sensitive. It is not possible to have distinct tables [Foo] and [foo]. BUG=none Review URL: https://codereview.chromium.org/1069313004 Cr-Commit-Position: refs/heads/master@{#324337}
-rw-r--r--sql/connection.cc23
-rw-r--r--sql/connection.h6
-rw-r--r--sql/connection_unittest.cc43
3 files changed, 58 insertions, 14 deletions
diff --git a/sql/connection.cc b/sql/connection.cc
index cc7e69d..bfe8bb7 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -725,7 +725,8 @@ scoped_refptr<Connection::StatementRef> Connection::GetUniqueStatement(
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
// This is evidence of a syntax error in the incoming SQL.
- DLOG(FATAL) << "SQL compile error " << GetErrorMessage();
+ DLOG_IF(FATAL, !ShouldIgnoreSqliteError(rc))
+ << "SQL compile error " << GetErrorMessage();
// It could also be database corruption.
OnSqliteError(rc, NULL, sql);
@@ -744,7 +745,8 @@ scoped_refptr<Connection::StatementRef> Connection::GetUntrackedStatement(
int rc = sqlite3_prepare_v2(db_, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
// This is evidence of a syntax error in the incoming SQL.
- DLOG(FATAL) << "SQL compile error " << GetErrorMessage();
+ DLOG_IF(FATAL, !ShouldIgnoreSqliteError(rc))
+ << "SQL compile error " << GetErrorMessage();
return new StatementRef(NULL, NULL, false);
}
return new StatementRef(NULL, stmt, true);
@@ -798,8 +800,15 @@ bool Connection::DoesIndexExist(const char* index_name) const {
bool Connection::DoesTableOrIndexExist(
const char* name, const char* type) const {
- const char* kSql = "SELECT name FROM sqlite_master WHERE type=? AND name=?";
+ const char* kSql =
+ "SELECT name FROM sqlite_master WHERE type=? AND name=? COLLATE NOCASE";
Statement statement(GetUntrackedStatement(kSql));
+
+ // This can happen if the database is corrupt and the error is being ignored
+ // for testing purposes.
+ if (!statement.is_valid())
+ return false;
+
statement.BindString(0, type);
statement.BindString(1, name);
@@ -813,8 +822,14 @@ bool Connection::DoesColumnExist(const char* table_name,
sql.append(")");
Statement statement(GetUntrackedStatement(sql.c_str()));
+
+ // This can happen if the database is corrupt and the error is being ignored
+ // for testing purposes.
+ if (!statement.is_valid())
+ return false;
+
while (statement.Step()) {
- if (!statement.ColumnString(1).compare(column_name))
+ if (!base::strcasecmp(statement.ColumnString(1).c_str(), column_name))
return true;
}
return false;
diff --git a/sql/connection.h b/sql/connection.h
index 5bbdb97..2f6c71f 100644
--- a/sql/connection.h
+++ b/sql/connection.h
@@ -361,10 +361,10 @@ class SQL_EXPORT Connection {
// Info querying -------------------------------------------------------------
- // Returns true if the given table exists.
+ // Returns true if the given table (or index) exists. Instead of
+ // test-then-create, callers should almost always prefer "CREATE TABLE IF NOT
+ // EXISTS" or "CREATE INDEX IF NOT EXISTS".
bool DoesTableExist(const char* table_name) const;
-
- // Returns true if the given index exists.
bool DoesIndexExist(const char* index_name) const;
// Returns true if a column with the given name exists in the given table.
diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc
index 07c9fa7..3cb2e37 100644
--- a/sql/connection_unittest.cc
+++ b/sql/connection_unittest.cc
@@ -176,10 +176,9 @@ TEST_F(SQLConnectionTest, DoesStuffExist) {
// Test DoesTableExist.
EXPECT_FALSE(db().DoesTableExist("foo"));
ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db().Execute("CREATE INDEX foo_a ON foo (a)"));
EXPECT_TRUE(db().DoesTableExist("foo"));
-
- // Should be case sensitive.
- EXPECT_FALSE(db().DoesTableExist("FOO"));
+ EXPECT_TRUE(db().DoesIndexExist("foo_a"));
// Test DoesColumnExist.
EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
@@ -187,6 +186,10 @@ TEST_F(SQLConnectionTest, DoesStuffExist) {
// Testing for a column on a nonexistent table.
EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
+
+ // Names are not case sensitive.
+ EXPECT_TRUE(db().DoesTableExist("FOO"));
+ EXPECT_TRUE(db().DoesColumnExist("FOO", "A"));
}
TEST_F(SQLConnectionTest, GetLastInsertRowId) {
@@ -221,10 +224,36 @@ TEST_F(SQLConnectionTest, ScopedIgnoreError) {
ASSERT_TRUE(db().Execute(kCreateSql));
ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
- sql::ScopedErrorIgnorer ignore_errors;
- ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
- ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
- ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ {
+ sql::ScopedErrorIgnorer ignore_errors;
+ ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
+ ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ }
+}
+
+// Test that clients of GetUntrackedStatement() can test corruption-handling
+// with ScopedErrorIgnorer.
+TEST_F(SQLConnectionTest, ScopedIgnoreUntracked) {
+ const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
+ ASSERT_TRUE(db().Execute(kCreateSql));
+ ASSERT_FALSE(db().DoesTableExist("bar"));
+ ASSERT_TRUE(db().DoesTableExist("foo"));
+ ASSERT_TRUE(db().DoesColumnExist("foo", "id"));
+ db().Close();
+
+ // Corrupt the database so that nothing works, including PRAGMAs.
+ ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path()));
+
+ {
+ sql::ScopedErrorIgnorer ignore_errors;
+ ignore_errors.IgnoreError(SQLITE_CORRUPT);
+ ASSERT_TRUE(db().Open(db_path()));
+ ASSERT_FALSE(db().DoesTableExist("bar"));
+ ASSERT_FALSE(db().DoesTableExist("foo"));
+ ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
+ ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
+ }
}
TEST_F(SQLConnectionTest, ErrorCallback) {