| Index: sql/connection_unittest.cc
|
| diff --git a/sql/connection_unittest.cc b/sql/connection_unittest.cc
|
| index 8cf32fb3f867f99c4e73e960decfe5822ff34240..e25efdb5b36a0106864600d16e6520c739092f49 100644
|
| --- a/sql/connection_unittest.cc
|
| +++ b/sql/connection_unittest.cc
|
| @@ -671,4 +671,97 @@ TEST_F(SQLConnectionTest, Delete) {
|
| EXPECT_FALSE(base::PathExists(journal));
|
| }
|
|
|
| +// Test that errors start happening once Poison() is called.
|
| +TEST_F(SQLConnectionTest, Poison) {
|
| + EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
|
| +
|
| + // Before the Poison() call, things generally work.
|
| + EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
|
| + EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
|
| + {
|
| + sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
|
| + ASSERT_TRUE(s.is_valid());
|
| + ASSERT_TRUE(s.Step());
|
| + }
|
| +
|
| + // Get a statement which is valid before and will exist across Poison().
|
| + sql::Statement valid_statement(
|
| + db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
|
| + ASSERT_TRUE(valid_statement.is_valid());
|
| + ASSERT_TRUE(valid_statement.Step());
|
| + valid_statement.Reset(true);
|
| +
|
| + db().Poison();
|
| +
|
| + // After the Poison() call, things fail.
|
| + EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
|
| + EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
|
| + {
|
| + sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
|
| + ASSERT_FALSE(s.is_valid());
|
| + ASSERT_FALSE(s.Step());
|
| + }
|
| +
|
| + // The existing statement has become invalid.
|
| + ASSERT_FALSE(valid_statement.is_valid());
|
| + ASSERT_FALSE(valid_statement.Step());
|
| +}
|
| +
|
| +// Test attaching and detaching databases from the connection.
|
| +TEST_F(SQLConnectionTest, Attach) {
|
| + EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
|
| +
|
| + // Create a database to attach to.
|
| + base::FilePath attach_path =
|
| + db_path().DirName().AppendASCII("SQLConnectionAttach.db");
|
| + const char kAttachmentPoint[] = "other";
|
| + {
|
| + sql::Connection other_db;
|
| + ASSERT_TRUE(other_db.Open(attach_path));
|
| + EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
|
| + EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
|
| + }
|
| +
|
| + // Cannot see the attached database, yet.
|
| + EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
|
| +
|
| + // Attach fails in a transaction.
|
| + EXPECT_TRUE(db().BeginTransaction());
|
| + {
|
| + sql::ScopedErrorIgnorer ignore_errors;
|
| + ignore_errors.IgnoreError(SQLITE_ERROR);
|
| + EXPECT_FALSE(db().AttachDatabase(attach_path, kAttachmentPoint));
|
| + ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
|
| + }
|
| +
|
| + // Attach succeeds when the transaction is closed.
|
| + db().RollbackTransaction();
|
| + EXPECT_TRUE(db().AttachDatabase(attach_path, kAttachmentPoint));
|
| + EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
|
| +
|
| + // Queries can touch both databases.
|
| + EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
|
| + {
|
| + sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
|
| + ASSERT_TRUE(s.Step());
|
| + EXPECT_EQ(1, s.ColumnInt(0));
|
| + }
|
| +
|
| + // Detach also fails in a transaction.
|
| + EXPECT_TRUE(db().BeginTransaction());
|
| + {
|
| + sql::ScopedErrorIgnorer ignore_errors;
|
| + ignore_errors.IgnoreError(SQLITE_ERROR);
|
| + EXPECT_FALSE(db().DetachDatabase(kAttachmentPoint));
|
| + EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
|
| + ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
|
| + }
|
| +
|
| + // Detach succeeds outside of a transaction.
|
| + db().RollbackTransaction();
|
| + EXPECT_TRUE(db().DetachDatabase(kAttachmentPoint));
|
| +
|
| + EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
|
| +}
|
| +
|
| } // namespace
|
|
|