diff options
author | shess <shess@chromium.org> | 2015-04-08 18:59:47 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-09 02:00:21 +0000 |
commit | 92a2ab1f1d0cdff39e6d506c4cb6a80038baeeb3 (patch) | |
tree | 10caf28af8322af472fd341379c676935e685c20 | |
parent | 9afe19122a83f762baded7003b25ff22205fd533 (diff) | |
download | chromium_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.cc | 23 | ||||
-rw-r--r-- | sql/connection.h | 6 | ||||
-rw-r--r-- | sql/connection_unittest.cc | 43 |
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) { |