Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: node
Fetching contributors…

Cannot retrieve contributors at this time

file 133 lines (107 sloc) 3.535 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
// Copyright (c) 2011 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 "base/file_util.h"
#include "base/scoped_temp_dir.h"
#include "sql/connection.h"
#include "sql/statement.h"
#include "sql/transaction.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"

class SQLTransactionTest : public testing::Test {
 public:
  SQLTransactionTest() {}

  void SetUp() {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    ASSERT_TRUE(db_.Open(
        temp_dir_.path().AppendASCII("SQLTransactionTest.db")));

    ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
  }

  void TearDown() {
    db_.Close();
  }

  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:
  ScopedTempDir temp_dir_;
  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());
}
Something went wrong with that request. Please try again.