include/simdb/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
99 / 118
83.9%
Branches:
90 / 116
77.6%
Functions:
11 / 11
100.0%

sqlite/Dump.hpp
Line Branch Exec Source
1 // <Dump.hpp> -*- C++ -*-
2
3 #pragma once
4
5 #include "simdb/sqlite/DatabaseManager.hpp"
6
7 #include <algorithm>
8 #include <deque>
9 #include <iomanip>
10 #include <iostream>
11 #include <numeric>
12 #include <optional>
13 #include <string>
14 #include <type_traits>
15 #include <vector>
16
17 namespace simdb {
18
19 namespace detail {
20 57 template <typename T> inline bool to_string(const std::optional<T>& opt, std::string& out)
21 {
22
7/12
bool simdb::detail::to_string<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::optional<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 8 times.
bool simdb::detail::to_string<double>(std::optional<double> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 5 not taken.
bool simdb::detail::to_string<int>(std::optional<int> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 3 → 4 taken 8 times.
✓ Branch 3 → 5 taken 9 times.
bool simdb::detail::to_string<unsigned int>(std::optional<unsigned int> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 5 not taken.
bool simdb::detail::to_string<long>(std::optional<long> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 5 not taken.
bool simdb::detail::to_string<unsigned long>(std::optional<unsigned long> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 5 not taken.
57 if (!opt.has_value())
23 {
24 40 return false;
25 }
26
27 if constexpr (std::is_same_v<T, std::string>)
28 {
29 8 out = opt.value();
30 } else
31 {
32
1/8
bool simdb::detail::to_string<double>(std::optional<double> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✗ Branch 5 → 6 not taken.
✗ Branch 6 → 7 not taken.
bool simdb::detail::to_string<int>(std::optional<int> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✓ Branch 5 → 6 taken 9 times.
bool simdb::detail::to_string<unsigned int>(std::optional<unsigned int> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✗ Branch 5 → 6 not taken.
bool simdb::detail::to_string<long>(std::optional<long> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✗ Branch 5 → 6 not taken.
✗ Branch 6 → 7 not taken.
bool simdb::detail::to_string<unsigned long>(std::optional<unsigned long> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&):
✗ Branch 5 → 6 not taken.
✗ Branch 6 → 7 not taken.
9 out = std::to_string(opt.value());
33 }
34 17 return true;
35 }
36
37 9 inline void dumpTable(const std::string& table_name, const std::vector<std::string>& headers,
38 const std::vector<std::vector<std::string>>& row_strings)
39 {
40 9 std::vector<size_t> col_sizes;
41
2/2
✓ Branch 10 → 5 taken 32 times.
✓ Branch 10 → 11 taken 9 times.
41 for (const auto& h : headers)
42 {
43
1/1
✓ Branch 7 → 8 taken 32 times.
32 col_sizes.push_back(h.size());
44 }
45
46 9 auto num_dashes = std::accumulate(col_sizes.begin(), col_sizes.end(), 0) + (col_sizes.size() * 4) + 10;
47
48
2/2
✓ Branch 28 → 16 taken 5 times.
✓ Branch 28 → 29 taken 9 times.
14 for (size_t i = 0; i < row_strings.size(); ++i)
49 {
50
2/2
✓ Branch 25 → 17 taken 17 times.
✓ Branch 25 → 26 taken 5 times.
22 for (size_t j = 0; j < row_strings[i].size(); ++j)
51 {
52 17 const auto& s = row_strings[i][j];
53
1/1
✓ Branch 19 → 20 taken 17 times.
17 auto& size = col_sizes.at(j);
54 17 size = std::max(size, s.size());
55 }
56 }
57
58 // Give some extra space
59
2/2
✓ Branch 34 → 31 taken 32 times.
✓ Branch 34 → 35 taken 9 times.
41 for (auto& size : col_sizes)
60 {
61 32 size += 4;
62 }
63
64 // Begin printing
65
3/3
✓ Branch 37 → 38 taken 9 times.
✓ Branch 38 → 39 taken 9 times.
✓ Branch 39 → 40 taken 9 times.
9 std::cout << std::string(num_dashes, '=') << "\n";
66
3/3
✓ Branch 42 → 43 taken 9 times.
✓ Branch 43 → 44 taken 9 times.
✓ Branch 44 → 45 taken 9 times.
9 std::cout << "Table: " << table_name << "\n";
67
68 // Print headers
69
2/2
✓ Branch 54 → 46 taken 32 times.
✓ Branch 54 → 55 taken 9 times.
41 for (size_t i = 0; i < headers.size(); ++i)
70 {
71
2/2
✓ Branch 49 → 50 taken 32 times.
✓ Branch 51 → 52 taken 32 times.
32 std::cout << std::setw(col_sizes[i]) << std::left << headers[i];
72 }
73
1/1
✓ Branch 55 → 56 taken 9 times.
9 std::cout << "\n";
74
75 // Print dashes
76
3/3
✓ Branch 58 → 59 taken 9 times.
✓ Branch 59 → 60 taken 9 times.
✓ Branch 60 → 61 taken 9 times.
9 std::cout << std::string(num_dashes, '-') << "\n";
77
78 // Print rows
79
2/2
✓ Branch 64 → 65 taken 6 times.
✓ Branch 64 → 66 taken 3 times.
9 if (row_strings.empty())
80 {
81
1/1
✓ Branch 65 → 83 taken 6 times.
6 std::cout << "(table has no records)\n";
82 } else
83 {
84
2/2
✓ Branch 82 → 67 taken 5 times.
✓ Branch 82 → 83 taken 3 times.
8 for (size_t i = 0; i < row_strings.size(); ++i)
85 {
86
2/2
✓ Branch 78 → 68 taken 17 times.
✓ Branch 78 → 79 taken 5 times.
22 for (size_t j = 0; j < row_strings[i].size(); ++j)
87 {
88 17 const auto& s = row_strings[i][j];
89
2/2
✓ Branch 73 → 74 taken 17 times.
✓ Branch 74 → 75 taken 17 times.
17 std::cout << std::setw(col_sizes[j]) << std::left << s;
90 }
91
1/1
✓ Branch 79 → 80 taken 5 times.
5 std::cout << "\n";
92 }
93 }
94
95
1/1
✓ Branch 83 → 84 taken 9 times.
9 std::cout << std::endl;
96 9 }
97 } // namespace detail
98
99 9 inline void dumpTable(DatabaseManager* db_mgr, const std::string& table_name)
100 {
101 // TODO cnyce: Can we call sqlite3 directly and simply parse the dumped output on stdout?
102 struct SelectedValueUnion
103 {
104 std::optional<int32_t> i;
105 std::optional<uint32_t> I;
106 std::optional<int64_t> q;
107 std::optional<uint64_t> Q;
108 std::optional<double> d;
109 std::optional<std::string> s;
110
111 25 SelectedValueUnion(SqlQuery* query, const Column* col) :
112 25 SelectedValueUnion(query, col->getName(), col->getDataType())
113 {
114 25 }
115
116 32 SelectedValueUnion(SqlQuery* query, const std::string& col_name, const SqlDataType dtype)
117 32 {
118 using dt = SqlDataType;
119
4/7
✓ Branch 8 → 9 taken 16 times.
✓ Branch 8 → 12 taken 3 times.
✗ Branch 8 → 15 not taken.
✓ Branch 8 → 18 taken 1 time.
✗ Branch 8 → 21 not taken.
✓ Branch 8 → 24 taken 12 times.
✗ Branch 8 → 27 not taken.
32 switch (dtype)
120 {
121 16 case dt::int32_t:
122
1/1
✓ Branch 10 → 11 taken 16 times.
16 query->select(col_name.c_str(), i);
123 16 break;
124 3 case dt::uint32_t:
125
1/1
✓ Branch 13 → 14 taken 3 times.
3 query->select(col_name.c_str(), I);
126 3 break;
127 ✗ case dt::int64_t:
128
0/1
✗ Branch 16 → 17 not taken.
✗ query->select(col_name.c_str(), q);
129 ✗ break;
130 1 case dt::uint64_t:
131
1/1
✓ Branch 19 → 20 taken 1 time.
1 query->select(col_name.c_str(), Q);
132 1 break;
133 ✗ case dt::double_t:
134
0/1
✗ Branch 22 → 23 not taken.
✗ query->select(col_name.c_str(), d);
135 ✗ break;
136 12 case dt::string_t:
137
1/1
✓ Branch 25 → 26 taken 12 times.
12 query->select(col_name.c_str(), s);
138 12 break;
139 ✗ default:
140 ✗ break;
141 }
142 32 }
143
144 17 std::optional<std::string> stringify() const
145 {
146 17 std::string out;
147
5/7
✓ Branch 3 → 4 taken 17 times.
✓ Branch 5 → 6 taken 8 times.
✓ Branch 6 → 7 taken 8 times.
✗ Branch 6 → 16 not taken.
✓ Branch 7 → 8 taken 8 times.
✓ Branch 8 → 9 taken 8 times.
✗ Branch 8 → 16 not taken.
25 if (!detail::to_string(i, out) && !detail::to_string(I, out) && !detail::to_string(q, out) &&
148
9/13
✓ Branch 4 → 5 taken 8 times.
✓ Branch 4 → 16 taken 9 times.
✓ Branch 9 → 10 taken 8 times.
✓ Branch 10 → 11 taken 8 times.
✗ Branch 10 → 16 not taken.
✓ Branch 11 → 12 taken 8 times.
✓ Branch 12 → 13 taken 8 times.
✗ Branch 12 → 16 not taken.
✓ Branch 13 → 14 taken 8 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 8 times.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 17 times.
25 !detail::to_string(Q, out) && !detail::to_string(d, out) && !detail::to_string(s, out))
149 {
150 ✗ return std::nullopt;
151 }
152 17 return out;
153 17 }
154 };
155
156 9 const auto& schema = db_mgr->getSchema();
157
1/1
✓ Branch 3 → 4 taken 9 times.
9 const auto& table = schema.getTable(table_name);
158 9 const auto& columns = table.getColumns();
159
160 9 std::vector<std::string> headers;
161
1/1
✓ Branch 6 → 7 taken 9 times.
9 std::deque<SelectedValueUnion> selects;
162
163
1/1
✓ Branch 8 → 9 taken 9 times.
9 auto query = db_mgr->createQuery(table_name.c_str());
164
3/3
✓ Branch 10 → 11 taken 9 times.
✓ Branch 11 → 12 taken 7 times.
✓ Branch 11 → 21 taken 2 times.
9 if (table.getPrimaryKey() == "Id")
165 {
166
2/2
✓ Branch 14 → 15 taken 7 times.
✓ Branch 15 → 16 taken 7 times.
7 headers.push_back("Id");
167
1/1
✓ Branch 19 → 20 taken 7 times.
7 selects.emplace_back(query.get(), "Id", SqlDataType::int32_t);
168 }
169
170
2/2
✓ Branch 32 → 23 taken 25 times.
✓ Branch 32 → 33 taken 9 times.
34 for (const auto& col : columns)
171 {
172
1/1
✓ Branch 26 → 27 taken 25 times.
25 headers.push_back(col->getName());
173
1/1
✓ Branch 29 → 30 taken 25 times.
25 selects.emplace_back(query.get(), col.get());
174 }
175
176 9 std::vector<std::vector<std::string>> row_strings;
177
178
1/1
✓ Branch 35 → 36 taken 9 times.
9 auto results = query->getResultSet();
179
3/3
✓ Branch 61 → 62 taken 14 times.
✓ Branch 62 → 37 taken 5 times.
✓ Branch 62 → 63 taken 9 times.
14 while (results.getNextRecord())
180 {
181 5 std::vector<std::string> col_strings;
182
2/2
✓ Branch 56 → 40 taken 17 times.
✓ Branch 56 → 57 taken 5 times.
22 for (const auto& col_result : selects)
183 {
184
1/1
✓ Branch 41 → 42 taken 17 times.
17 auto s = col_result.stringify();
185
1/2
✓ Branch 43 → 44 taken 17 times.
✗ Branch 43 → 46 not taken.
17 if (s.has_value())
186 {
187
2/2
✓ Branch 44 → 45 taken 17 times.
✓ Branch 45 → 53 taken 17 times.
17 col_strings.push_back(s.value());
188 } else
189 {
190
0/2
✗ Branch 48 → 49 not taken.
✗ Branch 49 → 50 not taken.
✗ col_strings.push_back("<NULL>");
191 }
192 17 }
193
1/1
✓ Branch 58 → 59 taken 5 times.
5 row_strings.emplace_back(std::move(col_strings));
194 5 }
195
196
1/1
✓ Branch 63 → 64 taken 9 times.
9 detail::dumpTable(table_name, headers, row_strings);
197 9 }
198
199 } // namespace simdb
200