1*b0d29bc4SBrooks Davis // Copyright 2011 The Kyua Authors.
2*b0d29bc4SBrooks Davis // All rights reserved.
3*b0d29bc4SBrooks Davis //
4*b0d29bc4SBrooks Davis // Redistribution and use in source and binary forms, with or without
5*b0d29bc4SBrooks Davis // modification, are permitted provided that the following conditions are
6*b0d29bc4SBrooks Davis // met:
7*b0d29bc4SBrooks Davis //
8*b0d29bc4SBrooks Davis // * Redistributions of source code must retain the above copyright
9*b0d29bc4SBrooks Davis // notice, this list of conditions and the following disclaimer.
10*b0d29bc4SBrooks Davis // * Redistributions in binary form must reproduce the above copyright
11*b0d29bc4SBrooks Davis // notice, this list of conditions and the following disclaimer in the
12*b0d29bc4SBrooks Davis // documentation and/or other materials provided with the distribution.
13*b0d29bc4SBrooks Davis // * Neither the name of Google Inc. nor the names of its contributors
14*b0d29bc4SBrooks Davis // may be used to endorse or promote products derived from this software
15*b0d29bc4SBrooks Davis // without specific prior written permission.
16*b0d29bc4SBrooks Davis //
17*b0d29bc4SBrooks Davis // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*b0d29bc4SBrooks Davis // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*b0d29bc4SBrooks Davis // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*b0d29bc4SBrooks Davis // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*b0d29bc4SBrooks Davis // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*b0d29bc4SBrooks Davis // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*b0d29bc4SBrooks Davis // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*b0d29bc4SBrooks Davis // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*b0d29bc4SBrooks Davis // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*b0d29bc4SBrooks Davis // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*b0d29bc4SBrooks Davis // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*b0d29bc4SBrooks Davis
29*b0d29bc4SBrooks Davis #include "cli/cmd_db_exec.hpp"
30*b0d29bc4SBrooks Davis
31*b0d29bc4SBrooks Davis #include <cstring>
32*b0d29bc4SBrooks Davis
33*b0d29bc4SBrooks Davis #include <atf-c++.hpp>
34*b0d29bc4SBrooks Davis
35*b0d29bc4SBrooks Davis #include "utils/format/macros.hpp"
36*b0d29bc4SBrooks Davis #include "utils/sqlite/database.hpp"
37*b0d29bc4SBrooks Davis #include "utils/sqlite/statement.ipp"
38*b0d29bc4SBrooks Davis
39*b0d29bc4SBrooks Davis namespace sqlite = utils::sqlite;
40*b0d29bc4SBrooks Davis
41*b0d29bc4SBrooks Davis
42*b0d29bc4SBrooks Davis namespace {
43*b0d29bc4SBrooks Davis
44*b0d29bc4SBrooks Davis
45*b0d29bc4SBrooks Davis /// Performs a test for the cli::format_cell() function.
46*b0d29bc4SBrooks Davis ///
47*b0d29bc4SBrooks Davis /// \tparam Cell The type of the value to insert into the test column.
48*b0d29bc4SBrooks Davis /// \param column_type The SQL type of the test column.
49*b0d29bc4SBrooks Davis /// \param value The value to insert into the test column.
50*b0d29bc4SBrooks Davis /// \param exp_value The expected return value of cli::format_cell().
51*b0d29bc4SBrooks Davis template< class Cell >
52*b0d29bc4SBrooks Davis static void
do_format_cell_test(const std::string column_type,const Cell & value,const std::string & exp_value)53*b0d29bc4SBrooks Davis do_format_cell_test(const std::string column_type,
54*b0d29bc4SBrooks Davis const Cell& value, const std::string& exp_value)
55*b0d29bc4SBrooks Davis {
56*b0d29bc4SBrooks Davis sqlite::database db = sqlite::database::in_memory();
57*b0d29bc4SBrooks Davis
58*b0d29bc4SBrooks Davis sqlite::statement create = db.create_statement(
59*b0d29bc4SBrooks Davis F("CREATE TABLE test (column %s)") % column_type);
60*b0d29bc4SBrooks Davis create.step_without_results();
61*b0d29bc4SBrooks Davis
62*b0d29bc4SBrooks Davis sqlite::statement insert = db.create_statement(
63*b0d29bc4SBrooks Davis "INSERT INTO test (column) VALUES (:column)");
64*b0d29bc4SBrooks Davis insert.bind(":column", value);
65*b0d29bc4SBrooks Davis insert.step_without_results();
66*b0d29bc4SBrooks Davis
67*b0d29bc4SBrooks Davis sqlite::statement query = db.create_statement("SELECT * FROM test");
68*b0d29bc4SBrooks Davis ATF_REQUIRE(query.step());
69*b0d29bc4SBrooks Davis ATF_REQUIRE_EQ(exp_value, cli::format_cell(query, 0));
70*b0d29bc4SBrooks Davis ATF_REQUIRE(!query.step());
71*b0d29bc4SBrooks Davis }
72*b0d29bc4SBrooks Davis
73*b0d29bc4SBrooks Davis
74*b0d29bc4SBrooks Davis } // anonymous namespace
75*b0d29bc4SBrooks Davis
76*b0d29bc4SBrooks Davis
77*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(format_cell__blob);
ATF_TEST_CASE_BODY(format_cell__blob)78*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(format_cell__blob)
79*b0d29bc4SBrooks Davis {
80*b0d29bc4SBrooks Davis const char* contents = "Some random contents";
81*b0d29bc4SBrooks Davis do_format_cell_test(
82*b0d29bc4SBrooks Davis "BLOB", sqlite::blob(contents, std::strlen(contents)),
83*b0d29bc4SBrooks Davis F("BLOB of %s bytes") % strlen(contents));
84*b0d29bc4SBrooks Davis }
85*b0d29bc4SBrooks Davis
86*b0d29bc4SBrooks Davis
87*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(format_cell__float);
ATF_TEST_CASE_BODY(format_cell__float)88*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(format_cell__float)
89*b0d29bc4SBrooks Davis {
90*b0d29bc4SBrooks Davis do_format_cell_test("FLOAT", 3.5, "3.5");
91*b0d29bc4SBrooks Davis }
92*b0d29bc4SBrooks Davis
93*b0d29bc4SBrooks Davis
94*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(format_cell__integer);
ATF_TEST_CASE_BODY(format_cell__integer)95*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(format_cell__integer)
96*b0d29bc4SBrooks Davis {
97*b0d29bc4SBrooks Davis do_format_cell_test("INTEGER", 123456, "123456");
98*b0d29bc4SBrooks Davis }
99*b0d29bc4SBrooks Davis
100*b0d29bc4SBrooks Davis
101*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(format_cell__null);
ATF_TEST_CASE_BODY(format_cell__null)102*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(format_cell__null)
103*b0d29bc4SBrooks Davis {
104*b0d29bc4SBrooks Davis do_format_cell_test("TEXT", sqlite::null(), "NULL");
105*b0d29bc4SBrooks Davis }
106*b0d29bc4SBrooks Davis
107*b0d29bc4SBrooks Davis
108*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(format_cell__text);
ATF_TEST_CASE_BODY(format_cell__text)109*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(format_cell__text)
110*b0d29bc4SBrooks Davis {
111*b0d29bc4SBrooks Davis do_format_cell_test("TEXT", "Hello, world", "Hello, world");
112*b0d29bc4SBrooks Davis }
113*b0d29bc4SBrooks Davis
114*b0d29bc4SBrooks Davis
115*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(format_headers);
ATF_TEST_CASE_BODY(format_headers)116*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(format_headers)
117*b0d29bc4SBrooks Davis {
118*b0d29bc4SBrooks Davis sqlite::database db = sqlite::database::in_memory();
119*b0d29bc4SBrooks Davis
120*b0d29bc4SBrooks Davis sqlite::statement create = db.create_statement(
121*b0d29bc4SBrooks Davis "CREATE TABLE test (c1 TEXT, c2 TEXT, c3 TEXT)");
122*b0d29bc4SBrooks Davis create.step_without_results();
123*b0d29bc4SBrooks Davis
124*b0d29bc4SBrooks Davis sqlite::statement query = db.create_statement(
125*b0d29bc4SBrooks Davis "SELECT c1, c2, c3 AS c3bis FROM test");
126*b0d29bc4SBrooks Davis ATF_REQUIRE_EQ("c1,c2,c3bis", cli::format_headers(query));
127*b0d29bc4SBrooks Davis }
128*b0d29bc4SBrooks Davis
129*b0d29bc4SBrooks Davis
130*b0d29bc4SBrooks Davis ATF_TEST_CASE_WITHOUT_HEAD(format_row);
ATF_TEST_CASE_BODY(format_row)131*b0d29bc4SBrooks Davis ATF_TEST_CASE_BODY(format_row)
132*b0d29bc4SBrooks Davis {
133*b0d29bc4SBrooks Davis sqlite::database db = sqlite::database::in_memory();
134*b0d29bc4SBrooks Davis
135*b0d29bc4SBrooks Davis sqlite::statement create = db.create_statement(
136*b0d29bc4SBrooks Davis "CREATE TABLE test (c1 TEXT, c2 BLOB)");
137*b0d29bc4SBrooks Davis create.step_without_results();
138*b0d29bc4SBrooks Davis
139*b0d29bc4SBrooks Davis const char* memory = "BLOB contents";
140*b0d29bc4SBrooks Davis sqlite::statement insert = db.create_statement(
141*b0d29bc4SBrooks Davis "INSERT INTO test VALUES (:v1, :v2)");
142*b0d29bc4SBrooks Davis insert.bind(":v1", "A string");
143*b0d29bc4SBrooks Davis insert.bind(":v2", sqlite::blob(memory, std::strlen(memory)));
144*b0d29bc4SBrooks Davis insert.step_without_results();
145*b0d29bc4SBrooks Davis
146*b0d29bc4SBrooks Davis sqlite::statement query = db.create_statement("SELECT * FROM test");
147*b0d29bc4SBrooks Davis query.step();
148*b0d29bc4SBrooks Davis ATF_REQUIRE_EQ(
149*b0d29bc4SBrooks Davis (F("A string,BLOB of %s bytes") % std::strlen(memory)).str(),
150*b0d29bc4SBrooks Davis cli::format_row(query));
151*b0d29bc4SBrooks Davis }
152*b0d29bc4SBrooks Davis
153*b0d29bc4SBrooks Davis
ATF_INIT_TEST_CASES(tcs)154*b0d29bc4SBrooks Davis ATF_INIT_TEST_CASES(tcs)
155*b0d29bc4SBrooks Davis {
156*b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, format_cell__blob);
157*b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, format_cell__float);
158*b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, format_cell__integer);
159*b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, format_cell__null);
160*b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, format_cell__text);
161*b0d29bc4SBrooks Davis
162*b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, format_headers);
163*b0d29bc4SBrooks Davis
164*b0d29bc4SBrooks Davis ATF_ADD_TEST_CASE(tcs, format_row);
165*b0d29bc4SBrooks Davis }
166