Home | History | Annotate | Line # | Download | only in sqlite
      1 // Copyright 2011 Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 // * Redistributions of source code must retain the above copyright
      9 //   notice, this list of conditions and the following disclaimer.
     10 // * Redistributions in binary form must reproduce the above copyright
     11 //   notice, this list of conditions and the following disclaimer in the
     12 //   documentation and/or other materials provided with the distribution.
     13 // * Neither the name of Google Inc. nor the names of its contributors
     14 //   may be used to endorse or promote products derived from this software
     15 //   without specific prior written permission.
     16 //
     17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 #include "utils/sqlite/transaction.hpp"
     30 
     31 #include <atf-c++.hpp>
     32 
     33 #include "utils/format/macros.hpp"
     34 #include "utils/sqlite/database.hpp"
     35 #include "utils/sqlite/exceptions.hpp"
     36 #include "utils/sqlite/statement.ipp"
     37 
     38 namespace sqlite = utils::sqlite;
     39 
     40 
     41 namespace {
     42 
     43 
     44 /// Ensures that a table has a single specific value in a column.
     45 ///
     46 /// \param db The SQLite database.
     47 /// \param table_name The table to be checked.
     48 /// \param column_name The column to be checked.
     49 /// \param exp_value The value expected to be found in the column.
     50 ///
     51 /// \return True if the column contains a single value and it matches exp_value;
     52 /// false if not.  If the query fails, the calling test is marked as bad.
     53 static bool
     54 check_in_table(sqlite::database& db, const char* table_name,
     55                const char* column_name, int exp_value)
     56 {
     57     sqlite::statement stmt = db.create_statement(
     58         F("SELECT * FROM %s WHERE %s == %s") % table_name % column_name %
     59         exp_value);
     60     if (!stmt.step())
     61         return false;
     62     if (stmt.step())
     63         ATF_FAIL("More than one value found in table");
     64     return true;
     65 }
     66 
     67 
     68 }  // anonymous namespace
     69 
     70 
     71 ATF_TEST_CASE_WITHOUT_HEAD(automatic_rollback);
     72 ATF_TEST_CASE_BODY(automatic_rollback)
     73 {
     74     sqlite::database db = sqlite::database::in_memory();
     75     db.exec("CREATE TABLE t (col INTEGER PRIMARY KEY)");
     76     db.exec("INSERT INTO t VALUES (3)");
     77     {
     78         sqlite::transaction tx = db.begin_transaction();
     79         db.exec("INSERT INTO t VALUES (5)");
     80     }
     81     ATF_REQUIRE( check_in_table(db, "t", "col", 3));
     82     ATF_REQUIRE(!check_in_table(db, "t", "col", 5));
     83 }
     84 
     85 
     86 ATF_TEST_CASE_WITHOUT_HEAD(explicit_commit);
     87 ATF_TEST_CASE_BODY(explicit_commit)
     88 {
     89     sqlite::database db = sqlite::database::in_memory();
     90     db.exec("CREATE TABLE t (col INTEGER PRIMARY KEY)");
     91     db.exec("INSERT INTO t VALUES (3)");
     92     {
     93         sqlite::transaction tx = db.begin_transaction();
     94         db.exec("INSERT INTO t VALUES (5)");
     95         tx.commit();
     96     }
     97     ATF_REQUIRE(check_in_table(db, "t", "col", 3));
     98     ATF_REQUIRE(check_in_table(db, "t", "col", 5));
     99 }
    100 
    101 
    102 ATF_TEST_CASE_WITHOUT_HEAD(explicit_rollback);
    103 ATF_TEST_CASE_BODY(explicit_rollback)
    104 {
    105     sqlite::database db = sqlite::database::in_memory();
    106     db.exec("CREATE TABLE t (col INTEGER PRIMARY KEY)");
    107     db.exec("INSERT INTO t VALUES (3)");
    108     {
    109         sqlite::transaction tx = db.begin_transaction();
    110         db.exec("INSERT INTO t VALUES (5)");
    111         tx.rollback();
    112     }
    113     ATF_REQUIRE( check_in_table(db, "t", "col", 3));
    114     ATF_REQUIRE(!check_in_table(db, "t", "col", 5));
    115 }
    116 
    117 
    118 ATF_TEST_CASE_WITHOUT_HEAD(nested_fail);
    119 ATF_TEST_CASE_BODY(nested_fail)
    120 {
    121     sqlite::database db = sqlite::database::in_memory();
    122     {
    123         sqlite::transaction tx = db.begin_transaction();
    124         ATF_REQUIRE_THROW(sqlite::error, db.begin_transaction());
    125     }
    126 }
    127 
    128 
    129 ATF_INIT_TEST_CASES(tcs)
    130 {
    131     ATF_ADD_TEST_CASE(tcs, automatic_rollback);
    132     ATF_ADD_TEST_CASE(tcs, explicit_commit);
    133     ATF_ADD_TEST_CASE(tcs, explicit_rollback);
    134     ATF_ADD_TEST_CASE(tcs, nested_fail);
    135 }
    136