summaryrefslogtreecommitdiffstats
path: root/app/sql/transaction_unittest.cc
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-11 21:30:56 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-11 21:30:56 +0000
commite5ffd0e471417e75ddcd5af20c3254c0ec2f1f5d (patch)
tree60e8d7c1de4ee33cc063cfa98a168e8fe9fcf27b /app/sql/transaction_unittest.cc
parent92c3dc6b3fffbaf9fa2fa409120ca051bf317234 (diff)
downloadchromium_src-e5ffd0e471417e75ddcd5af20c3254c0ec2f1f5d.zip
chromium_src-e5ffd0e471417e75ddcd5af20c3254c0ec2f1f5d.tar.gz
chromium_src-e5ffd0e471417e75ddcd5af20c3254c0ec2f1f5d.tar.bz2
Add a new wrapper for sqlite. This is mostly a large cleanup of the existing
one, combined with the statement cache in a nice way. It is designed to entirely wrap sqlite so that we can catch corrupt errors in the future and "do something" when we get them without having to change all the calling code. There is also a new meta_table file which is almost exactly like the old one but which uses the new sql interface. This patch changes Chrome's history TextDatabase to use this new wrapper as a proof of concept, because this usage is relatively well-confined. Review URL: http://codereview.chromium.org/199047 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26022 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app/sql/transaction_unittest.cc')
-rw-r--r--app/sql/transaction_unittest.cc139
1 files changed, 139 insertions, 0 deletions
diff --git a/app/sql/transaction_unittest.cc b/app/sql/transaction_unittest.cc
new file mode 100644
index 0000000..0da79e3
--- /dev/null
+++ b/app/sql/transaction_unittest.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2009 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 "app/sql/statement.h"
+#include "app/sql/transaction.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/sqlite/preprocessed/sqlite3.h"
+
+class SQLTransactionTest : public testing::Test {
+ public:
+ SQLTransactionTest() {}
+
+ void SetUp() {
+ 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().Execute("CREATE TABLE foo (a, b)"));
+ }
+
+ void TearDown() {
+ db_.Close();
+
+ // If this fails something is going on with cleanup and later tests may
+ // fail, so we want to identify problems right away.
+ ASSERT_TRUE(file_util::Delete(path_, false));
+ }
+
+ sql::Connection& db() { return db_; }
+
+ // Returns the number of rows in table "foo".
+ int CountFoo() {
+ sql::Statement count(db().GetUniqueStatement("SELECT count(*) FROM foo"));
+ count.Step();
+ return count.ColumnInt(0);
+ }
+
+ private:
+ FilePath path_;
+ sql::Connection db_;
+};
+
+TEST_F(SQLTransactionTest, Commit) {
+ {
+ sql::Transaction t(&db());
+ EXPECT_FALSE(t.is_open());
+ EXPECT_TRUE(t.Begin());
+ EXPECT_TRUE(t.is_open());
+
+ EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+
+ t.Commit();
+ EXPECT_FALSE(t.is_open());
+ }
+
+ EXPECT_EQ(1, CountFoo());
+}
+
+TEST_F(SQLTransactionTest, Rollback) {
+ // Test some basic initialization, and that rollback runs when you exit the
+ // scope.
+ {
+ sql::Transaction t(&db());
+ EXPECT_FALSE(t.is_open());
+ EXPECT_TRUE(t.Begin());
+ EXPECT_TRUE(t.is_open());
+
+ EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ }
+
+ // Nothing should have been committed since it was implicitly rolled back.
+ EXPECT_EQ(0, CountFoo());
+
+ // Test explicit rollback.
+ sql::Transaction t2(&db());
+ EXPECT_FALSE(t2.is_open());
+ EXPECT_TRUE(t2.Begin());
+
+ EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ t2.Rollback();
+ EXPECT_FALSE(t2.is_open());
+
+ // Nothing should have been committed since it was explicitly rolled back.
+ EXPECT_EQ(0, CountFoo());
+}
+
+// Rolling back any part of a transaction should roll back all of them.
+TEST_F(SQLTransactionTest, NestedRollback) {
+ EXPECT_EQ(0, db().transaction_nesting());
+
+ // Outermost transaction.
+ {
+ sql::Transaction outer(&db());
+ EXPECT_TRUE(outer.Begin());
+ EXPECT_EQ(1, db().transaction_nesting());
+
+ // The first inner one gets committed.
+ {
+ sql::Transaction inner1(&db());
+ EXPECT_TRUE(inner1.Begin());
+ EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ EXPECT_EQ(2, db().transaction_nesting());
+
+ inner1.Commit();
+ EXPECT_EQ(1, db().transaction_nesting());
+ }
+
+ // One row should have gotten inserted.
+ EXPECT_EQ(1, CountFoo());
+
+ // The second inner one gets rolled back.
+ {
+ sql::Transaction inner2(&db());
+ EXPECT_TRUE(inner2.Begin());
+ EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ EXPECT_EQ(2, db().transaction_nesting());
+
+ inner2.Rollback();
+ EXPECT_EQ(1, db().transaction_nesting());
+ }
+
+ // A third inner one will fail in Begin since one has already been rolled
+ // back.
+ EXPECT_EQ(1, db().transaction_nesting());
+ {
+ sql::Transaction inner3(&db());
+ EXPECT_FALSE(inner3.Begin());
+ EXPECT_EQ(1, db().transaction_nesting());
+ }
+ }
+ EXPECT_EQ(0, db().transaction_nesting());
+ EXPECT_EQ(0, CountFoo());
+}