• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "app/sql/connection.h"
6 #include "app/sql/statement.h"
7 #include "app/sql/transaction.h"
8 #include "base/file_util.h"
9 #include "base/memory/scoped_temp_dir.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/sqlite/sqlite3.h"
12 
13 class SQLTransactionTest : public testing::Test {
14  public:
SQLTransactionTest()15   SQLTransactionTest() {}
16 
SetUp()17   void SetUp() {
18     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
19     ASSERT_TRUE(db_.Open(
20         temp_dir_.path().AppendASCII("SQLTransactionTest.db")));
21 
22     ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
23   }
24 
TearDown()25   void TearDown() {
26     db_.Close();
27   }
28 
db()29   sql::Connection& db() { return db_; }
30 
31   // Returns the number of rows in table "foo".
CountFoo()32   int CountFoo() {
33     sql::Statement count(db().GetUniqueStatement("SELECT count(*) FROM foo"));
34     count.Step();
35     return count.ColumnInt(0);
36   }
37 
38  private:
39   ScopedTempDir temp_dir_;
40   sql::Connection db_;
41 };
42 
TEST_F(SQLTransactionTest,Commit)43 TEST_F(SQLTransactionTest, Commit) {
44   {
45     sql::Transaction t(&db());
46     EXPECT_FALSE(t.is_open());
47     EXPECT_TRUE(t.Begin());
48     EXPECT_TRUE(t.is_open());
49 
50     EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
51 
52     t.Commit();
53     EXPECT_FALSE(t.is_open());
54   }
55 
56   EXPECT_EQ(1, CountFoo());
57 }
58 
TEST_F(SQLTransactionTest,Rollback)59 TEST_F(SQLTransactionTest, Rollback) {
60   // Test some basic initialization, and that rollback runs when you exit the
61   // scope.
62   {
63     sql::Transaction t(&db());
64     EXPECT_FALSE(t.is_open());
65     EXPECT_TRUE(t.Begin());
66     EXPECT_TRUE(t.is_open());
67 
68     EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
69   }
70 
71   // Nothing should have been committed since it was implicitly rolled back.
72   EXPECT_EQ(0, CountFoo());
73 
74   // Test explicit rollback.
75   sql::Transaction t2(&db());
76   EXPECT_FALSE(t2.is_open());
77   EXPECT_TRUE(t2.Begin());
78 
79   EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
80   t2.Rollback();
81   EXPECT_FALSE(t2.is_open());
82 
83   // Nothing should have been committed since it was explicitly rolled back.
84   EXPECT_EQ(0, CountFoo());
85 }
86 
87 // Rolling back any part of a transaction should roll back all of them.
TEST_F(SQLTransactionTest,NestedRollback)88 TEST_F(SQLTransactionTest, NestedRollback) {
89   EXPECT_EQ(0, db().transaction_nesting());
90 
91   // Outermost transaction.
92   {
93     sql::Transaction outer(&db());
94     EXPECT_TRUE(outer.Begin());
95     EXPECT_EQ(1, db().transaction_nesting());
96 
97     // The first inner one gets committed.
98     {
99       sql::Transaction inner1(&db());
100       EXPECT_TRUE(inner1.Begin());
101       EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
102       EXPECT_EQ(2, db().transaction_nesting());
103 
104       inner1.Commit();
105       EXPECT_EQ(1, db().transaction_nesting());
106     }
107 
108     // One row should have gotten inserted.
109     EXPECT_EQ(1, CountFoo());
110 
111     // The second inner one gets rolled back.
112     {
113       sql::Transaction inner2(&db());
114       EXPECT_TRUE(inner2.Begin());
115       EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
116       EXPECT_EQ(2, db().transaction_nesting());
117 
118       inner2.Rollback();
119       EXPECT_EQ(1, db().transaction_nesting());
120     }
121 
122     // A third inner one will fail in Begin since one has already been rolled
123     // back.
124     EXPECT_EQ(1, db().transaction_nesting());
125     {
126       sql::Transaction inner3(&db());
127       EXPECT_FALSE(inner3.Begin());
128       EXPECT_EQ(1, db().transaction_nesting());
129     }
130   }
131   EXPECT_EQ(0, db().transaction_nesting());
132   EXPECT_EQ(0, CountFoo());
133 }
134