Web Wispers 1.2.2 C++ Unit Test Coverage
Current view: top level - tests/wispers/database - DatabaseTest.cc (source / functions) Hit Total Coverage
Test: Web Wispers 1.2.2 C++ Unit Tests Lines: 189 189 100.0 %
Date: 2012-04-09 Functions: 76 79 96.2 %
Branches: 1559 3140 49.6 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright 2006-2009 Savarese Software Research Corporation
       2                 :            :  *
       3                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       4                 :            :  * you may not use this file except in compliance with the License.
       5                 :            :  * You may obtain a copy of the License at
       6                 :            :  *
       7                 :            :  *     https://www.savarese.com/software/ApacheLicense-2.0
       8                 :            :  *
       9                 :            :  * Unless required by applicable law or agreed to in writing, software
      10                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      11                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12                 :            :  * See the License for the specific language governing permissions and
      13                 :            :  * limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include <ssrc/wispers/database/MultiRowOperations.h>
      17                 :            : #include <ssrc/wispers/database/InitializeLibrary.h>
      18                 :            : #include <ssrc/wispers/utility/AppendToContainer.h>
      19                 :            : #include <ssrc/wispers/types.h>
      20                 :            : 
      21                 :            : #include <boost/scoped_ptr.hpp>
      22                 :            : #include <boost/mpl/list.hpp>
      23                 :            : 
      24                 :            : #define BOOST_TEST_MODULE DatabaseTest
      25                 :            : #include <boost/test/unit_test.hpp>
      26                 :            : 
      27                 :            : using namespace NS_SSRC_WSPR_DATABASE;
      28                 :            : using NS_SSRC_WSPR_UTILITY::AppendToContainer;
      29                 :            : 
      30   [ +  -  +  -  :        194 : WSPR_DB_ROW_WITH_KEY(foo, ((string, bar))((int, baz)), (1))
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  -  +  -  
             +  -  +  - ]
      31   [ +  -  +  -  :         76 : WSPR_DB_ROW(two_key_type0, ((int, key0))((int, key1)))
          +  -  +  -  +  
          +  -  +  -  +  
                -  +  - ]
      32                 :          5 : WSPR_DB_ROW_WITH_KEY(two_key_type1, ((int, key0))((string, bar))((int, key1)), (0)(2))
      33                 :            : 
      34                 :            : WSPR_DB_ROW_WITH_KEY(uint_type,
      35   [ +  -  +  -  :        147 :                      ((unsigned int, num32))((std::uint64_t, num64))((std::uint16_t, num16)), (0)(1)(2))
          +  -  #  #  #  
          #  #  #  #  #  
             #  #  +  - ]
      36                 :            : 
      37                 :            : using std::get;
      38                 :            : 
      39         [ +  - ]:          6 : class DatabaseTestFixture {
      40                 :            : protected:
      41                 :            :   InitializeLibrary _init_lib;
      42                 :            :   boost::scoped_ptr<Database> db;
      43                 :            : 
      44                 :            : public:
      45                 :            :   typedef MultiRowOperations<foo> row_ops;
      46                 :            :   typedef MultiRowOperations<two_key_type0> two_ops;
      47                 :            : 
      48   [ +  -  +  -  :          6 :   DatabaseTestFixture() : _init_lib(), db(new Database()) { }
             +  -  +  - ]
      49                 :            : 
      50                 :          5 :   void init_data() {
      51                 :            :     prepared_statement_ptr statement =
      52   [ +  -  +  -  :         10 :       db->prepare("CREATE TABLE `foo` (`bar` CHAR(4), `baz` INTEGER PRIMARY KEY);");
                   +  - ]
      53                 :            : 
      54   [ +  -  +  -  :          5 :     BOOST_REQUIRE(!statement->expired());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
      55   [ +  -  +  -  :          5 :     BOOST_REQUIRE(0 == statement->count_parameters());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
      56   [ +  -  +  -  :          5 :     BOOST_REQUIRE(0 == statement->count_columns());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
      57                 :            : 
      58   [ +  -  +  -  :         10 :     QueryResult result = statement->execute();
                   +  - ]
      59                 :            : 
      60   [ +  -  +  -  :          5 :     BOOST_REQUIRE(!result.result_set);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      61   [ +  -  +  -  :          5 :     BOOST_REQUIRE(0 == result.changes);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      62                 :            : 
      63   [ +  -  +  -  :          5 :     statement = db->prepare("INSERT INTO `foo` VALUES('foo', 42);");
          +  -  +  -  +  
                      - ]
      64                 :            : 
      65   [ +  -  +  -  :          5 :     result = statement->execute();
             +  -  +  - ]
      66                 :            : 
      67   [ +  -  +  -  :          5 :     BOOST_REQUIRE(!result.result_set);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      68   [ +  -  +  -  :          5 :     BOOST_REQUIRE(1 == result.changes);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      69   [ +  -  +  -  :          5 :     BOOST_REQUIRE(0 == statement->count_columns());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
      70                 :            : 
      71   [ +  -  +  -  :          5 :     BOOST_REQUIRE(1 == std::tuple_size<foo::primary_key_columns_type>::value);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      72         [ +  - ]:          5 :     foo::primary_key_columns_type foocols = foo::primary_key_columns();
      73   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<0>(foocols) == 1);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      74   [ +  -  +  -  :          5 :     BOOST_REQUIRE(foo::Key<0>::column == 1);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      75                 :            : 
      76   [ +  -  +  -  :          5 :     BOOST_REQUIRE(2 == std::tuple_size<two_key_type0::primary_key_columns_type>::value);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      77                 :            :     two_key_type0::primary_key_columns_type tkt0cols =
      78         [ +  - ]:          5 :       two_key_type0::primary_key_columns();
      79   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<0>(tkt0cols) == 0);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      80   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<1>(tkt0cols) == 1);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      81   [ +  -  +  -  :          5 :     BOOST_REQUIRE(two_key_type0::Key<0>::column == 0);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      82   [ +  -  +  -  :          5 :     BOOST_REQUIRE(two_key_type0::Key<1>::column == 1);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      83                 :            : 
      84   [ +  -  +  -  :          5 :     BOOST_REQUIRE(2 == std::tuple_size<two_key_type1::primary_key_columns_type>::value);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      85                 :            :     two_key_type1::primary_key_columns_type tkt1cols =
      86         [ +  - ]:          5 :       two_key_type1::primary_key_columns();
      87   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<0>(tkt1cols) == 0);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      88   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<1>(tkt1cols) == 2);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      89   [ +  -  +  -  :          5 :     BOOST_REQUIRE(two_key_type1::Key<0>::column == 0);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      90   [ +  -  +  -  :          5 :     BOOST_REQUIRE(two_key_type1::Key<1>::column == 2);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      91                 :            : 
      92                 :            : 
      93   [ +  -  +  -  :          5 :     BOOST_REQUIRE(3 == std::tuple_size<uint_type::primary_key_columns_type>::value);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
      94                 :            :     uint_type::primary_key_columns_type uintcols =
      95         [ +  - ]:          5 :       uint_type::primary_key_columns();
      96   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<0>(uintcols) == 0);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      97   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<1>(uintcols) == 1);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      98   [ +  -  +  -  :          5 :     BOOST_REQUIRE(std::get<2>(uintcols) == 2);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
      99   [ +  -  +  -  :          5 :     BOOST_REQUIRE(uint_type::Key<0>::column == 0);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     100   [ +  -  +  -  :          5 :     BOOST_REQUIRE(uint_type::Key<1>::column == 1);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     101   [ +  -  +  -  :          5 :     BOOST_REQUIRE(uint_type::Key<2>::column == 2);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     102                 :          5 :   }
     103                 :            : };
     104                 :            : 
     105   [ +  -  +  - ]:          3 : BOOST_AUTO_TEST_CASE(test_null_min_max) {
     106                 :            :   using namespace NS_SSRC_WSPR;
     107   [ +  -  -  + ]:          1 :   BOOST_CHECK_EQUAL(null_row_id<row_id_type>(), NullRowId);
     108   [ +  -  -  + ]:          1 :   BOOST_CHECK_EQUAL(min_row_id<row_id_type>(), MinRowId);
     109                 :          1 : }
     110                 :            : 
     111                 :          1 : BOOST_FIXTURE_TEST_SUITE(all, DatabaseTestFixture)
     112                 :            : 
     113   [ +  -  +  -  :          5 : BOOST_AUTO_TEST_CASE(test_prepare_statement) {
                   +  - ]
     114                 :          1 :   init_data();
     115                 :            : 
     116                 :            :   prepared_statement_ptr statement =
     117   [ +  -  +  -  :          2 :     db->prepare("SELECT * FROM `foo` WHERE `bar` = 'foo';");
                   +  - ]
     118                 :            : 
     119   [ +  -  +  -  :          1 :   BOOST_CHECK(2 == statement->count_columns());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     120   [ +  -  +  -  :          1 :   BOOST_CHECK(statement->column_name(0) == "bar");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  -  
                      + ]
     121   [ +  -  +  -  :          1 :   BOOST_CHECK(statement->column_name(1) == "baz");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  -  
                      + ]
     122                 :            : 
     123   [ +  -  +  -  :          2 :   QueryResult result = statement->execute();
                   +  - ]
     124                 :            : 
     125   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     126   [ +  -  +  -  :          1 :   BOOST_CHECK(0 == result.changes);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     127   [ +  -  +  -  :          1 :   BOOST_CHECK(2 == result.result_set->count_values());
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     128   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set->value<string>(0) == "foo");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     129   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set->value<int>(1) == 42);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     130   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set->value<string>(1) == "42");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     131   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set->column_type(0) == ResultSet::Text);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     132   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set->column_type(1) == ResultSet::Integer);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     133   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set->value<blob_type>(0).second == 3);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     134                 :            : 
     135                 :            :   typedef std::tuple<string, int> row_type;
     136   [ +  -  +  - ]:          2 :   row_type row = result.result_set->values<row_type>();
     137                 :            : 
     138   [ +  -  +  -  :          1 :   BOOST_CHECK(get<0>(row) == "foo");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     139   [ +  -  +  -  :          1 :   BOOST_CHECK(get<1>(row) == 42);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     140                 :            : 
     141   [ +  -  +  -  :          1 :   row = *result.result_set;
                   +  - ]
     142                 :            : 
     143   [ +  -  +  -  :          1 :   BOOST_CHECK(get<0>(row) == "foo");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     144   [ +  -  +  -  :          1 :   BOOST_CHECK(get<1>(row) == 42);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     145                 :            : 
     146   [ +  -  +  -  :          1 :   BOOST_CHECK(!result.result_set->next());
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     147                 :            : 
     148   [ +  -  +  -  :          1 :   BOOST_CHECK_NO_THROW(statement->execute());
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     149                 :          1 : }
     150                 :            : 
     151   [ +  -  +  -  :          5 : BOOST_AUTO_TEST_CASE(test_bind) {
                   +  - ]
     152                 :          1 :   init_data();
     153                 :            : 
     154                 :            :   prepared_statement_ptr statement =
     155   [ +  -  +  -  :          2 :     db->prepare("SELECT * FROM `foo` WHERE `bar` = ? AND `baz` = ?;");
                   +  - ]
     156                 :            : 
     157   [ +  -  +  -  :          2 :   QueryResult result = statement->execute("foo", 42);
                   +  - ]
     158                 :            : 
     159   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     160   [ +  -  +  -  :          1 :   BOOST_CHECK(0 == result.changes);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     161   [ +  -  +  -  :          1 :   BOOST_CHECK(2 == result.result_set->count_values());
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     162                 :            : 
     163                 :            :   std::tuple<string, int> row =
     164   [ +  -  +  - ]:          2 :     result.result_set->values<string, int>();
     165                 :            : 
     166   [ +  -  +  -  :          1 :   BOOST_CHECK(get<0>(row) == "foo");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     167   [ +  -  +  -  :          1 :   BOOST_CHECK(get<1>(row) == 42);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     168                 :            : 
     169   [ +  -  +  -  :          1 :   BOOST_CHECK(!result.result_set->next());
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     170                 :            : 
     171                 :          1 :   const char *foo = "blah";
     172         [ +  - ]:          1 :   blob_type blob(foo, 5);
     173                 :            : 
     174   [ +  -  +  -  :          1 :   db->prepare("INSERT INTO `foo` VALUES(x'626C616800', 43);")->execute();
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     175                 :            : 
     176   [ +  -  +  -  :          1 :   result = statement->execute(blob, 43);
             +  -  +  - ]
     177                 :            : 
     178   [ +  -  +  -  :          1 :   BOOST_CHECK(result.result_set);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     179   [ +  -  +  -  :          1 :   BOOST_CHECK(0 == result.changes);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     180   [ +  -  +  -  :          1 :   BOOST_CHECK(2 == result.result_set->count_values());
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     181                 :            : 
     182                 :            :   std::tuple<blob_type, int> blob_row =
     183         [ +  - ]:          1 :     result.result_set->values<blob_type, int>();
     184   [ +  -  +  -  :          1 :   BOOST_CHECK(get<0>(blob_row).second == 5);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  + ]
     185   [ +  -  +  -  :          1 :   BOOST_CHECK(string("blah") ==
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  -  
                      + ]
     186                 :            :               static_cast<const char*>(get<0>(blob_row).first));
     187                 :          1 : }
     188                 :            : 
     189   [ +  -  +  -  :          5 : BOOST_AUTO_TEST_CASE(test_row_type) {
                   +  - ]
     190                 :          1 :   init_data();
     191                 :            : 
     192   [ +  -  +  -  :          1 :   BOOST_CHECK(!foo::is_primary_key(0));
             +  -  -  + ]
     193   [ +  -  +  -  :          1 :   BOOST_CHECK(foo::is_primary_key(1));
             +  -  -  + ]
     194   [ +  -  +  -  :          1 :   BOOST_CHECK(!foo::is_primary_key<0>());
             +  -  -  + ]
     195   [ +  -  +  -  :          1 :   BOOST_CHECK(foo::is_primary_key<1>());
             +  -  -  + ]
     196                 :            : 
     197   [ +  -  +  -  :          2 :   foo row("bar", 8);
                   +  - ]
     198   [ +  -  +  -  :          1 :   BOOST_CHECK(8 == row.primary_key_value());
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     199                 :            : 
     200                 :          1 :   two_key_type0 two_row(9, 8);
     201   [ +  -  +  -  :          1 :   BOOST_CHECK(get<0>(two_row.primary_key_value()) == 9);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     202   [ +  -  +  -  :          1 :   BOOST_CHECK(get<1>(two_row.primary_key_value()) == 8);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     203                 :          1 : }
     204                 :            : 
     205                 :            : // Even though we could use std::false_type and std::true_type, what's
     206                 :            : // being tested is made more clear by defining these classes.
     207                 :            : struct ImplicitColumns {
     208                 :            :   static const bool value = DatabaseTestFixture::row_ops::ImplicitColumns;
     209                 :            : };
     210                 :            : struct ExplicitColumns {
     211                 :            :   static const bool value = DatabaseTestFixture::row_ops::ExplicitColumns;
     212                 :            : };
     213                 :            : 
     214                 :            : typedef boost::mpl::list<ImplicitColumns, ExplicitColumns> test_row_ops_types;
     215                 :            : 
     216   [ +  -  +  - ]:         10 : BOOST_AUTO_TEST_CASE_TEMPLATE(test_row_operations, specify_columns,
     217         [ +  - ]:          1 :                               test_row_ops_types)
     218                 :            : {
     219                 :          2 :   init_data();
     220                 :            : 
     221                 :            :   row_ops crud(*db, DefaultValueBinder(), DefaultValueLoader(),
     222   [ +  -  +  -  :          4 :                specify_columns::value);
             +  -  +  - ]
     223   [ +  -  +  -  :          4 :   row_ops::find_result_type result = crud.find(42);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     224                 :            : 
     225   [ +  -  +  -  :          2 :   BOOST_CHECK(result.first);
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     226   [ +  -  +  -  :          2 :   BOOST_CHECK(result.second == foo("foo", 42));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     227                 :            : 
     228   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.exists(42));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     229   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.exists(result.second));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     230                 :            : 
     231   [ +  -  +  -  :          4 :   foo foo_row, foo_row2;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     232                 :            : 
     233   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.find(42, foo_row));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     234   [ +  -  +  -  :          2 :   BOOST_CHECK(foo_row == result.second);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     235                 :            : 
     236   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.find(foo_row, foo_row2));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     237   [ +  -  +  -  :          2 :   BOOST_CHECK(foo_row2 == foo_row);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     238                 :            : 
     239   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.save(foo("bar", 42)));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     240   [ +  -  +  -  :          2 :   BOOST_CHECK(!crud.insert(foo("bar", 42)));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     241   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.insert(foo("blah", 991)));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     242                 :            : 
     243   [ +  -  +  -  :          2 :   result = crud.find(42);
          +  -  +  -  +  
                -  +  - ]
     244   [ +  -  +  -  :          2 :   BOOST_CHECK(result.first);
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     245   [ +  -  +  -  :          2 :   BOOST_CHECK(result.second == foo("bar", 42));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     246                 :            : 
     247   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.save(foo("baz", 45)));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     248                 :            : 
     249   [ +  -  +  -  :          2 :   result = crud.find(45);
          +  -  +  -  +  
                -  +  - ]
     250   [ +  -  +  -  :          2 :   BOOST_CHECK(result.second == foo("baz", 45));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     251                 :            : 
     252                 :          2 :   int keys[3] = { 42, 45, 991 };
     253   [ +  -  +  -  :          4 :   std::vector<foo> values;
             +  -  +  - ]
     254                 :            : 
     255   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.for_each_row(&keys[0], &keys[3], 3, AppendToContainer<std::vector<foo> >(values)) == 3);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     256                 :            : 
     257   [ +  -  +  -  :          2 :   BOOST_CHECK(values[0].baz == 42);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     258   [ +  -  +  -  :          2 :   BOOST_CHECK(values[0].bar == "bar");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     259   [ +  -  +  -  :          2 :   BOOST_CHECK(values[1].baz == 45);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     260   [ +  -  +  -  :          2 :   BOOST_CHECK(values[1].bar == "baz");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     261   [ +  -  +  -  :          2 :   BOOST_CHECK(values[2].baz == 991);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     262   [ +  -  +  -  :          2 :   BOOST_CHECK(values[2].bar == "blah");
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     263                 :            : 
     264   [ +  -  +  -  :          2 :   BOOST_CHECK(crud.erase(result.second) == 1);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     265   [ +  -  +  -  :          2 :   BOOST_CHECK(!crud.find(45).first);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     266                 :            : 
     267   [ +  -  +  -  :          2 :   db->execute("CREATE TABLE `two_key_type0` (`key0` INTEGER, `key1` INTEGER,  PRIMARY KEY (`key0`, `key1`));");
          +  -  +  -  +  
                -  +  - ]
     268                 :            : 
     269                 :            :   two_ops crud2(*db, DefaultValueBinder(), DefaultValueLoader(),
     270   [ +  -  +  -  :          4 :                 specify_columns::value);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     271                 :            : 
     272   [ +  -  +  -  :          2 :   BOOST_CHECK(crud2.save(two_key_type0(19, 24)));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     273                 :            : 
     274                 :            :   two_ops::find_result_type result2 =
     275   [ +  -  +  -  :          2 :     crud2.find(two_key_type0::primary_key_type(19, 24));
          +  -  +  -  +  
                -  +  - ]
     276                 :            : 
     277   [ +  -  +  -  :          2 :   BOOST_CHECK(result2.first);
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     278   [ +  -  +  -  :          2 :   BOOST_CHECK(result2.second == two_key_type0(19, 24));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     279                 :            : 
     280   [ +  -  +  -  :          2 :   result2 = crud2.find(19, 24);
             +  -  +  - ]
     281                 :            : 
     282   [ +  -  +  -  :          2 :   BOOST_CHECK(result2.first);
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     283   [ +  -  +  -  :          2 :   BOOST_CHECK(result2.second == two_key_type0(19, 24));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     284                 :            : 
     285   [ +  -  +  -  :          2 :   BOOST_CHECK(crud2.exists(result2.second));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     286   [ +  -  +  -  :          2 :   BOOST_CHECK(crud2.exists(19, 24));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     287                 :            : 
     288   [ +  -  +  -  :          2 :   result2 = crud2.find(result2.second);
             +  -  +  - ]
     289                 :            : 
     290   [ +  -  +  -  :          2 :   BOOST_CHECK(result2.first);
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     291   [ +  -  +  -  :          2 :   BOOST_CHECK(result2.second == two_key_type0(19, 24));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     292                 :            : 
     293                 :            :   two_key_type0::primary_key_type keys2[1] = {
     294                 :            :     two_key_type0::primary_key_type(19, 24)
     295   [ +  -  +  - ]:          2 :   };
     296   [ +  -  +  -  :          4 :   std::vector<two_key_type0> values2;
             +  -  +  - ]
     297                 :            : 
     298   [ +  -  +  -  :          2 :   BOOST_CHECK(crud2.for_each_row(&keys2[0], &keys2[1], 1, AppendToContainer<std::vector<two_key_type0> >(values2)) == 1);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     299   [ +  -  +  -  :          2 :   BOOST_CHECK(values2[0] == two_key_type0(19, 24));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
                      + ]
     300                 :            : 
     301   [ +  -  +  -  :          2 :   BOOST_CHECK(crud2.erase(result2.second));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     302                 :            : 
     303   [ +  -  +  -  :          2 :   result2 = crud2.find(result2.second);
             +  -  +  - ]
     304                 :            : 
     305   [ +  -  +  -  :          2 :   BOOST_CHECK(!result2.first);
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  -  + ]
     306                 :            : 
     307   [ +  -  +  -  :          2 :   BOOST_CHECK(!crud2.erase(19, 24));
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     308                 :          2 : }
     309                 :            : 
     310                 :            : // This isn't a real unit test.  It is to determine whether or not
     311                 :            : // unsigned integers outside of the signed int range are preserved.
     312   [ +  -  +  -  :          5 : BOOST_AUTO_TEST_CASE(test_uint) {
                   +  - ]
     313   [ +  -  +  -  :          1 :   db->execute("CREATE TABLE `uint_type` (`num32` INTEGER, `num64` INTEGER, `num16` INTEGER,  PRIMARY KEY (`num32`, `num64`, `num16`));");
                   +  - ]
     314                 :            : 
     315                 :          1 :   const unsigned int max16 = boost::integer_traits<std::uint16_t>::const_max;
     316                 :          1 :   const unsigned int max32 = boost::integer_traits<unsigned int>::const_max;
     317                 :          1 :   const std::uint64_t max64 = boost::integer_traits<std::uint64_t>::const_max;
     318   [ +  -  +  - ]:          2 :   RowOperations<uint_type> crud(*db);
     319                 :            : 
     320   [ +  -  +  +  :         33 :   for(unsigned int i = 1, j =0; i < max32 && j < 32; i*=2, ++j) {
                   +  + ]
     321                 :         32 :     const std::uint16_t num16 = max16 - i + 1;
     322                 :         32 :     const unsigned int num32 = max32 - i + 1;
     323                 :         32 :     const std::uint64_t num64 = max64 - i + 1;
     324                 :            : 
     325         [ +  - ]:         32 :     crud.save(uint_type(num32, num64, num16));
     326                 :            : 
     327                 :            :     RowOperations<uint_type>::find_result_type result =
     328   [ +  -  +  -  :         32 :       crud.find(uint_type::primary_key_type(num32, num64, num16));
                   +  - ]
     329                 :            : 
     330   [ +  -  +  -  :         32 :     BOOST_CHECK(result.first);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     331   [ +  -  +  -  :         32 :     BOOST_CHECK(result.second.num32 == num32);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     332   [ +  -  +  -  :         32 :     BOOST_CHECK(result.second.num64 == num64);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     333   [ +  -  +  -  :         32 :     BOOST_CHECK(result.second.num16 == num16);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     334                 :            :   }
     335                 :            : 
     336                 :            : 
     337         [ +  - ]:          1 :   crud.save(uint_type(0, 0, 0));
     338                 :            : 
     339                 :            :   RowOperations<uint_type>::find_result_type result =
     340   [ +  -  +  -  :          1 :     crud.find(uint_type::primary_key_type(0, 0, 0));
                   +  - ]
     341                 :            : 
     342   [ +  -  +  -  :          1 :   BOOST_CHECK(result.first);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     343   [ +  -  +  -  :          1 :   BOOST_CHECK(result.second.num32 == 0);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     344   [ +  -  +  -  :          1 :   BOOST_CHECK(result.second.num64 == 0);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     345   [ +  -  +  -  :          1 :   BOOST_CHECK(result.second.num16 == 0);
          +  -  +  -  +  
          -  +  -  +  -  
                   -  + ]
     346                 :          1 : }
     347                 :            : 
     348   [ +  -  +  - ]:          3 : BOOST_AUTO_TEST_SUITE_END()