GCC Code Coverage Report


Directory: libimgdoc2/
File: libimgdoc2/src/db/utilities.cpp
Date: 2025-02-03 12:41:04
Exec Total Coverage
Lines: 153 174 87.9%
Functions: 14 14 100.0%
Branches: 178 354 50.3%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH
2 //
3 // SPDX-License-Identifier: MIT
4
5 #include <sstream>
6 #include <limits>
7 #include <utility>
8 #include <vector>
9 #include <tuple>
10 #include "utilities.h"
11
12 using namespace std;
13 using namespace imgdoc2;
14
15 44 /*static*/std::tuple<std::string, std::vector<Utilities::DataBindInfo>> Utilities::CreateWhereConditionForDimQueryClause(
16 const imgdoc2::IDimCoordinateQueryClause* clause,
17 const std::function<void(imgdoc2::Dimension, std::string&)>& funcGetColumnNameForDimension)
18 {
19 44 vector<Utilities::DataBindInfo> databind_info;
20
1/2
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
44 ostringstream string_stream;
21 44 string column_name_for_dimension;
22 44 bool first_dimension_iteration = true;
23
24
3/4
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 38 times.
✓ Branch 9 taken 44 times.
82 for (const auto dimension : clause->GetTileDimsForClause())
25 {
26
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 const std::vector<IDimCoordinateQueryClause::RangeClause>* rangeClauses = clause->GetRangeClause(dimension);
27
28
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 if (rangeClauses != nullptr)
29 {
30
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36 times.
38 if (!first_dimension_iteration)
31 {
32
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 string_stream << " AND ";
33 }
34
35
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 string_stream << "(";
36 38 bool first_iteration = true;
37
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 funcGetColumnNameForDimension(dimension, column_name_for_dimension);
38
2/2
✓ Branch 5 taken 44 times.
✓ Branch 6 taken 38 times.
82 for (const auto rangeClause : *rangeClauses)
39 {
40
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if (!first_iteration)
41 {
42
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 string_stream << " OR ";
43 }
44
45
2/4
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44 times.
✗ Branch 4 not taken.
44 if (ProcessRangeClause(column_name_for_dimension, rangeClause, databind_info, string_stream))
46 {
47 44 first_iteration = false;
48 }
49 }
50
51
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 string_stream << ")";
52
53 38 first_dimension_iteration = false;
54 }
55 }
56
57
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 36 times.
44 if (first_dimension_iteration)
58 {
59 // This means that the dimension-query-clause was empty, i.e. did not contain a condition.
60 // In this case, we create a SQL-fragment "(TRUE)"
61
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 string_stream << "(TRUE)";
62 }
63
64
2/4
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
88 return make_tuple(string_stream.str(), databind_info);
65 44 }
66
67 16 /*static*/std::tuple<std::string, std::vector<Utilities::DataBindInfo>> Utilities::CreateWhereConditionForTileInfoQueryClause(const imgdoc2::ITileInfoQueryClause* clause, const std::string& column_name_pyramidlevel)
68 {
69
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 ostringstream string_stream;
70
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 string_stream << "(";
71 16 vector<Utilities::DataBindInfo> data_bind_infos;
72 16 for (int no = 0;; ++no)
73 {
74 32 int value = -1;
75 32 ComparisonOperation comparison_operator{ ComparisonOperation::Invalid };
76 32 LogicalOperator logical_operator{ LogicalOperator::Invalid };
77
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 const bool b = clause->GetPyramidLevelCondition(no, &logical_operator, &comparison_operator, &value);
78
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (!b)
79 {
80
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 if (no == 0)
81 {
82 // this means we have an empty tile-info-query-clause
83
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
6 return make_tuple("(TRUE)", vector<Utilities::DataBindInfo>());
84 }
85
86
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 string_stream << ")";
87
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 return make_tuple(string_stream.str(), data_bind_infos);
88 }
89
90
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 if (no > 0)
91 {
92
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
6 string_stream << " " << Utilities::LogicalOperatorToString(logical_operator) << " ";
93 }
94
95
6/12
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 16 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 16 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 16 times.
✗ Branch 17 not taken.
16 string_stream << "( [" << column_name_pyramidlevel << "] " << Utilities::ComparisonOperatorToString(comparison_operator) << " ?)";
96
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 data_bind_infos.push_back({ DataBindInfo(value) });
97 16 }
98 16 }
99
100 16 /*static*/const char* Utilities::ComparisonOperatorToString(ComparisonOperation comparison_operator)
101 {
102
3/7
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
16 switch (comparison_operator)
103 {
104 12 case ComparisonOperation::Equal:
105 12 return "=";
106 case ComparisonOperation::NotEqual:
107 return "<>";
108 case ComparisonOperation::LessThan:
109 return "<";
110 2 case ComparisonOperation::LessThanOrEqual:
111 2 return "<=";
112 2 case ComparisonOperation::GreaterThan:
113 2 return ">";
114 case ComparisonOperation::GreaterThanOrEqual:
115 return ">=";
116 case ComparisonOperation::Invalid:
117 default:
118 throw invalid_argument("invalid operator encountered");
119 }
120 }
121
122 6 /*static*/const char* Utilities::LogicalOperatorToString(imgdoc2::LogicalOperator logical_operator)
123 {
124
2/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
6 switch (logical_operator)
125 {
126 2 case LogicalOperator::And:
127 2 return "AND";
128 4 case LogicalOperator::Or:
129 4 return "OR";
130 case LogicalOperator::Invalid:
131 default:
132 throw invalid_argument("invalid operator encountered");
133 }
134 }
135
136 26 /*static*/std::tuple<std::string, std::vector<Utilities::DataBindInfo>> Utilities::CreateWhereStatement(const imgdoc2::IDimCoordinateQueryClause* dim_coordinate_query_clause, const imgdoc2::ITileInfoQueryClause* tileInfo_query_clause, const DatabaseConfiguration2D& database_configuration)
137 {
138 return CreateWhereStatement(
139 dim_coordinate_query_clause,
140 tileInfo_query_clause,
141 52 { database_configuration.GetDimensionsColumnPrefix() , database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_PyramidLevel) });
142
3/8
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 26 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
26 }
143
144 40 /*static*/std::tuple<std::string, std::vector<Utilities::DataBindInfo>> Utilities::CreateWhereStatement(const imgdoc2::IDimCoordinateQueryClause* dim_coordinate_query_clause, const imgdoc2::ITileInfoQueryClause* tileInfo_query_clause, const DatabaseConfiguration3D& database_configuration)
145 {
146 return CreateWhereStatement(
147 dim_coordinate_query_clause,
148 tileInfo_query_clause,
149 80 { database_configuration.GetDimensionsColumnPrefix() , database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration3D::kTilesInfoTable_Column_PyramidLevel) });
150
3/8
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
40 }
151
152 96 /*static*/bool Utilities::TryReadStringFromPropertyBag(IDbConnection* db_connection, const std::string& table_name, const std::string& key_column_name, const std::string& value_column_name, const std::string& key, std::string* output)
153 {
154
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 ostringstream string_stream;
155
9/18
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 96 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 96 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 96 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 96 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 96 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 96 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 96 times.
✗ Branch 26 not taken.
96 string_stream << "SELECT [" << value_column_name << "] FROM [" << table_name << "] WHERE [" << key_column_name << "]='" << key << "';";
156
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
96 const auto statement = db_connection->PrepareStatement(string_stream.str());
157
3/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 70 times.
✓ Branch 5 taken 26 times.
96 if (db_connection->StepStatement(statement.get()))
158 {
159
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
70 if (output != nullptr)
160 {
161
1/2
✓ Branch 2 taken 70 times.
✗ Branch 3 not taken.
70 *output = statement->GetResultString(0);
162 }
163
164 70 return true;
165 }
166
167 26 return false;
168 96 }
169
170 38 /*static*/void Utilities::WriteStringIntoPropertyBag(IDbConnection* db_connection, const std::string& table_name, const std::string& key_column_name, const std::string& value_column_name, const std::string& key, const std::string& value)
171 {
172
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
38 ostringstream string_stream;
173
7/14
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 38 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 38 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 38 times.
✗ Branch 20 not taken.
38 string_stream << "INSERT OR REPLACE INTO [" << table_name << "] (" << key_column_name << "," << value_column_name << ") VALUES(? , ?);";
174
2/4
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38 times.
✗ Branch 5 not taken.
38 const auto statement = db_connection->PrepareStatement(string_stream.str());
175 38 int binding_index = 1;
176
1/2
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
38 statement->BindString(binding_index++, key);
177
1/2
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
38 statement->BindString(binding_index++, value);
178
1/2
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
38 db_connection->Execute(statement.get());
179 38 }
180
181 2 /*static*/void Utilities::DeleteItemFromPropertyBag(IDbConnection* db_connection, const std::string& table_name, const std::string& key_column_name, const std::string& value_column_name, const std::string& key)
182 {
183
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 ostringstream string_stream;
184
7/14
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
2 string_stream << "DELETE FROM [" << table_name << "] WHERE [" << table_name << "].[" << key_column_name << "] = ?;";
185
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 const auto statement = db_connection->PrepareStatement(string_stream.str());
186
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 statement->BindString(1, key);
187
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 db_connection->Execute(statement.get());
188 2 }
189
190 44 /*static*/bool Utilities::ProcessRangeClause(const string& column_name_for_dimension, const IDimCoordinateQueryClause::RangeClause& rangeClause, vector<Utilities::DataBindInfo>& databind_info, ostringstream& string_stream)
191 {
192 44 bool range_clause_processed = false;
193
3/6
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 44 times.
✗ Branch 7 not taken.
44 if (rangeClause.start != numeric_limits<int>::min() && rangeClause.end != numeric_limits<int>::max())
194 {
195
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 10 times.
44 if (rangeClause.start < rangeClause.end)
196 {
197 34 string_stream << "([" << column_name_for_dimension << "] > ? AND [" << column_name_for_dimension << "] < ?)";
198
1/2
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
34 databind_info.emplace_back(DataBindInfo(rangeClause.start));
199
1/2
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
34 databind_info.emplace_back(DataBindInfo(rangeClause.end));
200 34 range_clause_processed = true;
201 }
202
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 else if (rangeClause.start == rangeClause.end)
203 {
204 10 string_stream << "([" << column_name_for_dimension << "] = ?)";
205
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 databind_info.emplace_back(DataBindInfo(rangeClause.start));
206 10 range_clause_processed = true;
207 }
208 }
209 else if (rangeClause.start == numeric_limits<int>::min() && rangeClause.end != numeric_limits<int>::max())
210 {
211 string_stream << "([" << column_name_for_dimension << "] < ?)";
212 databind_info.emplace_back(DataBindInfo(rangeClause.end));
213 range_clause_processed = true;
214 }
215 else if (rangeClause.start != numeric_limits<int>::min() && rangeClause.end == numeric_limits<int>::max())
216 {
217 string_stream << "([" << column_name_for_dimension << "] > ?)";
218 databind_info.emplace_back(DataBindInfo(rangeClause.start));
219 range_clause_processed = true;
220 }
221
222 44 return range_clause_processed;
223 }
224
225 66 /*static*/std::tuple<std::string, std::vector<Utilities::DataBindInfo>> Utilities::CreateWhereStatement(const imgdoc2::IDimCoordinateQueryClause* dim_coordinate_query_clause, const imgdoc2::ITileInfoQueryClause* tileInfo_query_clause, const CreateWhereInfo& create_where_info)
226 {
227 auto get_column_name_func =
228 28 [&](imgdoc2::Dimension dimension, std::string& column_name)->void
229 {
230 28 column_name = create_where_info.dimension_column_prefix;
231 28 column_name += dimension;
232 94 };
233
234 66 std::tuple<std::string, std::vector<Utilities::DataBindInfo>> return_value;
235
236
4/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 32 times.
66 if (dim_coordinate_query_clause != nullptr && tileInfo_query_clause != nullptr)
237 {
238
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 auto dimension_query = CreateWhereConditionForDimQueryClause(dim_coordinate_query_clause, get_column_name_func);
239
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 auto tileinfo_query = CreateWhereConditionForTileInfoQueryClause(tileInfo_query_clause, create_where_info.column_name_pyramid_level/*database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_PyramidLevel)*/);
240
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 ostringstream string_stream;
241
3/6
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
4 string_stream << get<0>(dimension_query) << " AND " << get<0>(tileinfo_query);
242 4 auto& databind_info = get<1>(dimension_query);
243
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
4 std::move(get<1>(tileinfo_query).begin(), get<1>(tileinfo_query).end(), std::back_inserter(databind_info));
244
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 return_value = make_tuple(string_stream.str(), databind_info);
245 4 }
246
3/4
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
62 else if (dim_coordinate_query_clause != nullptr && tileInfo_query_clause == nullptr)
247 {
248
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 return_value = CreateWhereConditionForDimQueryClause(dim_coordinate_query_clause, get_column_name_func);
249 }
250
3/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 24 times.
30 else if (dim_coordinate_query_clause == nullptr && tileInfo_query_clause != nullptr)
251 {
252
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 return_value = CreateWhereConditionForTileInfoQueryClause(tileInfo_query_clause, create_where_info.column_name_pyramid_level/*database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_PyramidLevel)*/);
253 }
254 else
255 {
256
2/4
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 24 times.
✗ Branch 6 not taken.
24 return_value = make_tuple(" (TRUE) ", std::vector<Utilities::DataBindInfo>{});
257 }
258
259 132 return return_value;
260 }
261
262 14 /*static*/std::tuple<std::string, std::vector<Utilities::DataBindInfo>> Utilities::CreateWhereConditionForIntersectingWithPlaneClause(const imgdoc2::Plane_NormalAndDistD& plane, const DatabaseConfiguration3D& database_configuration)
263 {
264
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 const auto column_name_tile_x = database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration3D::kTilesInfoTable_Column_TileX);
265
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 const auto column_name_tile_y = database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration3D::kTilesInfoTable_Column_TileY);
266
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 const auto column_name_tile_z = database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration3D::kTilesInfoTable_Column_TileZ);
267
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 const auto column_name_tile_w = database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration3D::kTilesInfoTable_Column_TileW);
268
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 const auto column_name_tile_h = database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration3D::kTilesInfoTable_Column_TileH);
269
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 const auto column_name_tile_d = database_configuration.GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration3D::kTilesInfoTable_Column_TileD);
270
271
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 ostringstream string_stream;
272
273 // The following SQL-statement is doing an intersection test between a plane and an axis-aligned-cuboid. The cuboid's coordinates
274 // are read from the DB-table, and the plane's normal-representation are passed as parameters ?1-?4.
275 // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/
276 //
277 // What comes out is something like this:
278 // SELECT [Pk] FROM [TILESINFO] WHERE 2*abs(-?4+([TileW]/2+[TileX])*?1+([TileH]/2+[TileY])*?2+([TileD]/2+[TileZ])*?3)<=abs(?3)*[TileD]+abs(?2)*[TileH]+abs(?1)*[TileW];
279 //
280 // where ?1=plane_normal.x, ?2=plane_normal.y, ?3=plane_normal.z and ?4=plane_normal.distance
281 // (in the code below, we use '?' instead of '?1..' and add the parameters multiple times).
282 string_stream <<
283 "(2*abs(-?+([" << column_name_tile_w << "]/2+[" << column_name_tile_x << "])*?+" <<
284 "([" << column_name_tile_h << "]/2+[" << column_name_tile_y << "])*?+" <<
285 "([" << column_name_tile_d << "]/2+[" << column_name_tile_z << "])*?)" <<
286 "<=" <<
287
23/46
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 14 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 14 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 14 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 14 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 14 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 14 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 14 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 14 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 14 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 14 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 14 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 14 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 14 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 14 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 14 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 14 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 14 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 14 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 14 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 14 times.
✗ Branch 68 not taken.
14 "abs(?)*[" << column_name_tile_d << "]+abs(?)*[" << column_name_tile_h << "]+abs(?)*[" << column_name_tile_w << "])";
288
289 return make_tuple(
290
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 string_stream.str(),
291
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
42 std::vector<Utilities::DataBindInfo>
292 {
293 14 DataBindInfo(plane.distance),
294 14 DataBindInfo(plane.normal.x),
295 14 DataBindInfo(plane.normal.y),
296 14 DataBindInfo(plane.normal.z),
297 14 DataBindInfo(plane.normal.z),
298 14 DataBindInfo(plane.normal.y),
299 14 DataBindInfo(plane.normal.x)
300
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 });
301 14 }
302
303 68 /*static*/int Utilities::AddDataBindInfoListToDbStatement(const std::vector<Utilities::DataBindInfo>& data_bind_info, IDbStatement* db_statement, int binding_index)
304 {
305
2/2
✓ Branch 4 taken 142 times.
✓ Branch 5 taken 68 times.
210 for (const auto& binding_info : data_bind_info)
306 {
307
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 98 times.
142 if (holds_alternative<int>(binding_info.value))
308 {
309
2/4
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
44 db_statement->BindInt32(binding_index, get<int>(binding_info.value));
310 }
311
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 98 times.
98 else if (holds_alternative<int64_t>(binding_info.value))
312 {
313 db_statement->BindInt64(binding_index, get<int64_t>(binding_info.value));
314 }
315
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 else if (holds_alternative<double>(binding_info.value))
316 {
317
2/4
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 98 times.
✗ Branch 5 not taken.
98 db_statement->BindDouble(binding_index, get<double>(binding_info.value));
318 }
319 else
320 {
321 throw logic_error("invalid variant");
322 }
323
324 142 ++binding_index;
325 }
326
327 68 return binding_index;
328 }
329