Belle II Software development
sqlite.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <framework/utilities/sqlite.h>
10#include <framework/geometry/B2Vector3.h>
11
12#include <gtest/gtest.h>
13#include <set>
14
15using namespace Belle2;
16
17namespace {
19 class SQLiteTest: public ::testing::Test {
20 protected:
22 sqlite3* m_connection{nullptr};
24 void SetUp() override
25 {
26 int result = sqlite3_open_v2(":memory:", &m_connection, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
27 ASSERT_EQ(result, SQLITE_OK);
28 std::string sql = R"DOC(
29 CREATE TABLE test(name TEXT, x FLOAT, y FLOAT, z FLOAT);
30 INSERT INTO test VALUES ('IP', 0, 0, 0);
31 INSERT INTO test VALUES ('X', 1, 0, 0);
32 INSERT INTO test VALUES ('Y', 0, 1, 0);
33 INSERT INTO test VALUES ('Z', 0, 0, 1);
34 )DOC";
35 result = sqlite3_exec(m_connection, sql.c_str(), nullptr, nullptr, nullptr);
36 ASSERT_EQ(result, SQLITE_OK);
37 }
38
40 void TearDown() override
41 {
42 int result = sqlite3_close_v2(m_connection);
43 ASSERT_EQ(result, SQLITE_OK);
44 }
45 };
46
48 TEST_F(SQLiteTest, Statement)
49 {
50 sqlite::Statement<std::string, double> stmt(m_connection, "SELECT name, x from test ORDER by name DESC", false);
51 std::vector<std::tuple<std::string, double>> expected{{"IP", 0.}, {"X", 1.}, {"Y", 0.}, {"Z", 0.}};
52 for (auto&& row : stmt) {
53 ASSERT_FALSE(expected.empty());
54 ASSERT_EQ(row, expected.back());
55 expected.pop_back();
56 }
57 ASSERT_TRUE(expected.empty());
58 }
59
61 TEST_F(SQLiteTest, StatementTypeConversion)
62 {
63 sqlite::Statement<std::string, std::string> stmt(m_connection, "SELECT name, x from test ORDER by name DESC", false);
64 std::vector<std::tuple<std::string, std::string>> expected{{"IP", "0.0"}, {"X", "1.0"}, {"Y", "0.0"}, {"Z", "0.0"}};
65 for (auto&& row : stmt) {
66 ASSERT_FALSE(expected.empty());
67 ASSERT_EQ(row, expected.back());
68 expected.pop_back();
69 }
70 ASSERT_TRUE(expected.empty());
71 }
72
74 TEST_F(SQLiteTest, StatementTypeConversion2)
75 {
76 sqlite::Statement<std::string, int> stmt(m_connection, "SELECT name, x from test ORDER by name DESC", false);
77 std::vector<std::tuple<std::string, int>> expected{{"IP", 0}, {"X", 1}, {"Y", 0}, {"Z", 0}};
78 for (auto&& row : stmt) {
79 ASSERT_FALSE(expected.empty());
80 ASSERT_EQ(row, expected.back());
81 expected.pop_back();
82 }
83 ASSERT_TRUE(expected.empty());
84 }
85
87 TEST_F(SQLiteTest, SimpleStatement)
88 {
89 sqlite::SimpleStatement<std::string> stmt(m_connection, "SELECT name from test WHERE Y=?", false);
90 std::set<std::string> expected{"IP", "X", "Z"};
91 stmt.execute(0.);
92 std::set<std::string> actual(stmt.begin(), stmt.end());
93 ASSERT_EQ(expected, actual);
94 expected = {"Y"};
95 stmt.execute(1.);
96 actual = std::set<std::string>(stmt.begin(), stmt.end());
97 ASSERT_EQ(expected, actual);
98 }
99
101 TEST_F(SQLiteTest, SimpleStatementParameterConversion)
102 {
103 sqlite::SimpleStatement<std::string> stmt(m_connection, "SELECT name from test WHERE Y=?", false);
104 std::set<std::string> expected{"IP", "X", "Z"};
105 stmt.execute("0");
106 std::set<std::string> actual(stmt.begin(), stmt.end());
107 ASSERT_EQ(expected, actual);
108 expected = {"Y"};
109 stmt.execute(1);
110 actual = std::set<std::string>(stmt.begin(), stmt.end());
111 ASSERT_EQ(expected, actual);
112 }
113
115 TEST_F(SQLiteTest, ObjectStatement)
116 {
117 sqlite::ObjectStatement<B2Vector3D, double, double, double> stmt(m_connection, "SELECT x,y,z from test ORDER by name", false);
118 auto it = stmt.begin();
119 ASSERT_NE(it, stmt.end());
120 ASSERT_EQ(*it, B2Vector3D(0, 0, 0));
121 ASSERT_NE(++it, stmt.end());
122 ASSERT_EQ(*it, B2Vector3D(1, 0, 0));
123 ASSERT_NE(++it, stmt.end());
124 ASSERT_EQ(*it, B2Vector3D(0, 1, 0));
125 ASSERT_NE(++it, stmt.end());
126 ASSERT_EQ(*it, B2Vector3D(0, 0, 1));
127 ASSERT_EQ(++it, stmt.end());
128 }
129
131 TEST_F(SQLiteTest, NotEnoughParams)
132 {
133 sqlite::SimpleStatement<std::string> stmt(m_connection, "SELECT name from test WHERE Y=?", false);
134 ASSERT_THROW(stmt.execute(), std::runtime_error);
135 }
136
138 TEST_F(SQLiteTest, TooManyParams)
139 {
140 sqlite::SimpleStatement<std::string> stmt(m_connection, "SELECT name from test WHERE Y=?", false);
141 ASSERT_THROW(stmt.execute(0, "foo"), std::runtime_error);
142 }
143
145 TEST_F(SQLiteTest, NotEnoughColumns)
146 {
147 auto construct = [this]() { return sqlite::Statement<std::string, int>(m_connection, "SELECT name from test ORDER by name DESC", false);};
148 ASSERT_THROW(construct(), std::runtime_error);
149 }
150
152 TEST_F(SQLiteTest, TooManyColumns)
153 {
154 auto construct = [this]() { return sqlite::Statement<std::string>(m_connection, "SELECT name, x from test ORDER by name DESC", false);};
155 ASSERT_THROW(construct(), std::runtime_error);
156 }
157}
SQLite prepared statement wrapper.
Definition: sqlite.h:194
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
Abstract base class for different kinds of events.