GCC Code Coverage Report


Directory: libimgdoc2/
File: libimgdoc2/src/db/database_discovery.cpp
Date: 2025-02-03 12:41:04
Exec Total Coverage
Lines: 124 154 80.5%
Functions: 16 18 88.9%
Branches: 158 338 46.7%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH
2 //
3 // SPDX-License-Identifier: MIT
4
5 #include <algorithm>
6 #include <vector>
7 #include <sstream>
8 #include <cstring>
9 #include "database_discovery.h"
10 #include "database_constants.h"
11 #include "IDbConnection.h"
12 #include <exceptions.h>
13
14 #include "database_utilities.h"
15 #include "utilities.h"
16
17 using namespace std;
18 using namespace imgdoc2;
19
20 16 void DbDiscovery::DoDiscovery()
21 {
22 // first step - find the "GENERAL" table and see if we can make sense of it
23
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
16 GeneralDataDiscoveryResult general_table_discovery_result = this->DiscoverGeneralTable();
24
25 // now, check whether those tables exist and are usable
26
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 this->Check_Tables_And_Determine_Dimensions(general_table_discovery_result);
27
28 // if we get here, then we determined the database to be 'usable' for us, so we construct a corresponding
29 // "database-configuration"-object here from the data we gathered.
30
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 if (general_table_discovery_result.document_type == DocumentType::kImage2d)
31 {
32
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 const auto configuration2d = make_shared<DatabaseConfiguration2D>();
33
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 this->FillInformationForConfiguration2D(general_table_discovery_result, *configuration2d);
34 8 this->configuration_ = configuration2d;
35 8 }
36
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 else if (general_table_discovery_result.document_type == DocumentType::kImage3d)
37 {
38
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 const auto configuration3d = make_shared<DatabaseConfiguration3D>();
39
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 this->FillInformationForConfiguration3D(general_table_discovery_result, *configuration3d);
40 6 this->configuration_ = configuration3d;
41 6 }
42 else
43 {
44 throw runtime_error("only document_type='Image2d' or document_type='Image3d' supported currently");
45 }
46 14 }
47
48 imgdoc2::DocumentType DbDiscovery::GetDocumentType() const
49 {
50 return this->GetDatabaseConfigurationCommon()->GetDocumentType();
51 }
52
53 std::shared_ptr<DatabaseConfigurationCommon> DbDiscovery::GetDatabaseConfigurationCommon() const
54 {
55 auto configuration = this->configuration_;
56 if (!configuration)
57 {
58 throw logic_error("No valid database-configuration.");
59 }
60
61 return configuration;
62 }
63
64 6 std::shared_ptr<DatabaseConfiguration2D> DbDiscovery::GetDatabaseConfiguration2DOrThrow() const
65 {
66 6 auto configuration2d = this->GetDatabaseConfiguration2DOrNull();
67
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!configuration2d)
68 {
69 throw internal_error_exception("No valid database-configuration for 2D.");
70 }
71
72 6 return configuration2d;
73 }
74
75 4 std::shared_ptr<DatabaseConfiguration3D> DbDiscovery::GetDatabaseConfiguration3DOrThrow() const
76 {
77 4 auto configuration3d = this->GetDatabaseConfiguration3DOrNull();
78
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (!configuration3d)
79 {
80 throw internal_error_exception("No valid database-configuration for 3D.");
81 }
82
83 4 return configuration3d;
84 }
85
86 10 std::shared_ptr<DatabaseConfiguration2D> DbDiscovery::GetDatabaseConfiguration2DOrNull() const
87 {
88 10 return dynamic_pointer_cast<DatabaseConfiguration2D>(this->configuration_);
89 }
90
91 6 std::shared_ptr<DatabaseConfiguration3D> DbDiscovery::GetDatabaseConfiguration3DOrNull() const
92 {
93 6 return dynamic_pointer_cast<DatabaseConfiguration3D>(this->configuration_);
94 }
95
96 8 void DbDiscovery::FillInformationForConfiguration2D(const GeneralDataDiscoveryResult& general_data_discovery_result, DatabaseConfiguration2D& database_configuration_2d)
97 {
98 8 database_configuration_2d.SetDimensionColumnPrefix(DbConstants::kDimensionColumnPrefix_Default/*"Dim_"*/);
99 8 database_configuration_2d.SetIndexForDimensionColumnPrefix(DbConstants::kIndexForDimensionColumnPrefix_Default/*"IndexForDim_"*/);
100 8 database_configuration_2d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::GeneralInfo, DbConstants::kGeneralTable_Name/*"GENERAL"*/);
101 8 database_configuration_2d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::TilesData, general_data_discovery_result.tilesdatatable_name.c_str());
102 8 database_configuration_2d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::TilesInfo, general_data_discovery_result.tileinfotable_name.c_str());
103
104 8 database_configuration_2d.SetDefaultColumnNamesForTilesInfoTable();
105 8 database_configuration_2d.SetTileDimensions(general_data_discovery_result.dimensions.cbegin(), general_data_discovery_result.dimensions.cend());
106 8 database_configuration_2d.SetIndexedTileDimensions(general_data_discovery_result.indexed_dimensions.cbegin(), general_data_discovery_result.indexed_dimensions.cend());
107 8 database_configuration_2d.SetDefaultColumnNamesForTilesDataTable();
108
109
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
8 if (!general_data_discovery_result.spatial_index_table_name.empty())
110 {
111 2 database_configuration_2d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::TilesSpatialIndex, general_data_discovery_result.spatial_index_table_name.c_str());
112 }
113
114
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (!general_data_discovery_result.blobtable_name.empty())
115 {
116 database_configuration_2d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::Blobs, general_data_discovery_result.blobtable_name.c_str());
117 database_configuration_2d.SetColumnNameForBlobTable(DatabaseConfiguration2D::kBlobTable_Column_Pk, DbConstants::kBlobTable_Column_Pk_DefaultName); // TODO(JBL): I guess the presence of those columns should be tested for
118 database_configuration_2d.SetColumnNameForBlobTable(DatabaseConfiguration2D::kBlobTable_Column_Data, DbConstants::kBlobTable_Column_Data_DefaultName);
119 }
120 8 }
121
122 6 void DbDiscovery::FillInformationForConfiguration3D(const GeneralDataDiscoveryResult& general_data_discovery_result, DatabaseConfiguration3D& configuration_3d)
123 {
124 6 configuration_3d.SetDimensionColumnPrefix(DbConstants::kDimensionColumnPrefix_Default/*"Dim_"*/);
125 6 configuration_3d.SetIndexForDimensionColumnPrefix(DbConstants::kIndexForDimensionColumnPrefix_Default/*"IndexForDim_"*/);
126 6 configuration_3d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::GeneralInfo, DbConstants::kGeneralTable_Name/*"GENERAL"*/);
127 6 configuration_3d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::TilesData, general_data_discovery_result.tilesdatatable_name.c_str());
128 6 configuration_3d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::TilesInfo, general_data_discovery_result.tileinfotable_name.c_str());
129 6 configuration_3d.SetDefaultColumnNamesForTilesInfoTable();
130 6 configuration_3d.SetTileDimensions(general_data_discovery_result.dimensions.cbegin(), general_data_discovery_result.dimensions.cend());
131 6 configuration_3d.SetIndexedTileDimensions(general_data_discovery_result.indexed_dimensions.cbegin(), general_data_discovery_result.indexed_dimensions.cend());
132 6 configuration_3d.SetDefaultColumnNamesForTilesDataTable();
133
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
6 if (!general_data_discovery_result.spatial_index_table_name.empty())
134 {
135 2 configuration_3d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::TilesSpatialIndex, general_data_discovery_result.spatial_index_table_name.c_str());
136 }
137
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!general_data_discovery_result.blobtable_name.empty())
138 {
139 configuration_3d.SetTableName(DatabaseConfigurationCommon::TableTypeCommon::Blobs, general_data_discovery_result.blobtable_name.c_str());
140 configuration_3d.SetColumnNameForBlobTable(DatabaseConfiguration3D::kBlobTable_Column_Pk, DbConstants::kBlobTable_Column_Pk_DefaultName); // TODO(JBL): I guess the presence of those columns should be tested for
141 configuration_3d.SetColumnNameForBlobTable(DatabaseConfiguration3D::kBlobTable_Column_Data, DbConstants::kBlobTable_Column_Data_DefaultName);
142 }
143 6 }
144
145 16 DbDiscovery::GeneralDataDiscoveryResult DbDiscovery::DiscoverGeneralTable()
146 {
147
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 const auto columns_of_general_table = this->db_connection_->GetTableInfo(DbConstants::kGeneralTable_Name);
148
149 // ok, if that worked, then we need to have two columns named "Key" and "ValueString"
150
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
16 if (!
151
3/4
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 2 times.
30 (any_of(columns_of_general_table.cbegin(), columns_of_general_table.cend(), [](const IDbConnection::ColumnInfo& column_info)->bool {return column_info.column_name == DbConstants::kGeneralTable_KeyColumnName; }) &&
152
2/4
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
42 any_of(columns_of_general_table.cbegin(), columns_of_general_table.cend(), [](const IDbConnection::ColumnInfo& column_info)->bool {return column_info.column_name == DbConstants::kGeneralTable_ValueStringColumnName; }))
153 )
154 {
155
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 throw discovery_exception("Unexpected content in the 'GENERAL'-table");
156 }
157
158 14 GeneralDataDiscoveryResult general_discovery_result;
159
160 // first of all, read the key=DocType
161 14 string str;
162
7/14
✓ 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 17 taken 14 times.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 14 times.
112 if (!Utilities::TryReadStringFromPropertyBag(
163 this->db_connection_.get(),
164 DbConstants::kGeneralTable_Name,
165 DbConstants::kGeneralTable_KeyColumnName,
166 DbConstants::kGeneralTable_ValueStringColumnName,
167 DbConstants::GetGeneralTable_ItemKey(GeneralTableItems::kDocType), // "DocType",
168 &str))
169 {
170 throw discovery_exception("Property 'DocType' not present, refusing to open this database.");
171 }
172
173
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 const DocumentType document_type = DbUtilities::GetDocumentTypeFromDocTypeField(str);
174
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
14 if (document_type != DocumentType::kImage2d && document_type != DocumentType::kImage3d)
175 {
176 ostringstream string_stream;
177 string_stream << "'DocType'=" << str << " is not supported at this time.";
178 throw discovery_exception(string_stream.str());
179 }
180
181 14 general_discovery_result.document_type = document_type;
182
183 // ok, so now get the content for key=TilesInfoTable and key=TilesDataTable. Those will give us the name of the tables we are
184 // to use. If the values are not present, we go with default-values.
185
7/14
✓ 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 17 taken 14 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 14 times.
✗ Branch 24 not taken.
112 if (Utilities::TryReadStringFromPropertyBag(
186 this->db_connection_.get(),
187 DbConstants::kGeneralTable_Name,
188 DbConstants::kGeneralTable_KeyColumnName,
189 DbConstants::kGeneralTable_ValueStringColumnName,
190 DbConstants::GetGeneralTable_ItemKey(GeneralTableItems::kTilesInfoTable), // "TilesInfoTable",
191 &str))
192 {
193
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 general_discovery_result.tileinfotable_name = str;
194 }
195 else
196 {
197 general_discovery_result.tileinfotable_name = DbConstants::kTilesInfoTable_DefaultName;
198 }
199
200
7/14
✓ 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 17 taken 14 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 14 times.
✗ Branch 24 not taken.
112 if (Utilities::TryReadStringFromPropertyBag(
201 this->db_connection_.get(),
202 DbConstants::kGeneralTable_Name,
203 DbConstants::kGeneralTable_KeyColumnName,
204 DbConstants::kGeneralTable_ValueStringColumnName,
205 DbConstants::GetGeneralTable_ItemKey(GeneralTableItems::kTilesDataTable), // "TilesDataTable",
206 &str))
207 {
208
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 general_discovery_result.tilesdatatable_name = str;
209 }
210 else
211 {
212 general_discovery_result.tilesdatatable_name = DbConstants::kTilesDataTable_DefaultName;
213 }
214
215
7/14
✓ 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 17 taken 14 times.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 14 times.
112 if (Utilities::TryReadStringFromPropertyBag(
216 this->db_connection_.get(),
217 DbConstants::kGeneralTable_Name,
218 DbConstants::kGeneralTable_KeyColumnName,
219 DbConstants::kGeneralTable_ValueStringColumnName,
220 DbConstants::GetGeneralTable_ItemKey(GeneralTableItems::kBlobTable), //"BlobTable",
221 &str))
222 {
223 general_discovery_result.blobtable_name = str;
224 // TODO(JBL): may check the table-structure here?
225 }
226
227
8/14
✓ 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 17 taken 14 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 6 times.
✓ Branch 24 taken 8 times.
112 if (Utilities::TryReadStringFromPropertyBag(
228 this->db_connection_.get(),
229 DbConstants::kGeneralTable_Name,
230 DbConstants::kGeneralTable_KeyColumnName,
231 DbConstants::kGeneralTable_ValueStringColumnName,
232 DbConstants::GetGeneralTable_ItemKey(GeneralTableItems::kSpatialIndexTable), //"SpatialIndexTable",
233 &str))
234 {
235
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 general_discovery_result.spatial_index_table_name = str;
236 }
237
238
7/14
✓ 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 17 taken 14 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 14 times.
✗ Branch 24 not taken.
112 if (Utilities::TryReadStringFromPropertyBag(
239 this->db_connection_.get(),
240 DbConstants::kGeneralTable_Name,
241 DbConstants::kGeneralTable_KeyColumnName,
242 DbConstants::kGeneralTable_ValueStringColumnName,
243 DbConstants::GetGeneralTable_ItemKey(GeneralTableItems::kMetadataTable), //"MetadataTable",
244 &str))
245 {
246
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 general_discovery_result.metadatatable_name = str;
247 }
248
249 28 return general_discovery_result;
250 16 }
251
252 14 void DbDiscovery::Check_Tables_And_Determine_Dimensions(GeneralDataDiscoveryResult& general_table_discovery_result)
253 {
254 // check the tiles-data table for the expected columns
255 vector<ExpectedColumnsInfo> expected_columns_for_table
256 {
257 ExpectedColumnsInfo(DbConstants::kTilesDataTable_Column_Pk_DefaultName),
258 ExpectedColumnsInfo(DbConstants::kTilesDataTable_Column_PixelWidth_DefaultName),
259 ExpectedColumnsInfo(DbConstants::kTilesDataTable_Column_PixelHeight_DefaultName),
260 ExpectedColumnsInfo(DbConstants::kTilesDataTable_Column_PixelType_DefaultName),
261 ExpectedColumnsInfo(DbConstants::kTilesDataTable_Column_TileDataType_DefaultName),
262 ExpectedColumnsInfo(DbConstants::kTilesDataTable_Column_BinDataStorageType_DefaultName),
263 ExpectedColumnsInfo(DbConstants::kTilesDataTable_Column_BinDataId_DefaultName),
264
3/6
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 14 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
126 };
265
266
1/2
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
14 auto columns_of_table = this->db_connection_->GetTableInfo(general_table_discovery_result.tilesdatatable_name.c_str());
267
268
2/2
✓ Branch 5 taken 98 times.
✓ Branch 6 taken 14 times.
112 for (const auto& expected_column_info : expected_columns_for_table)
269 {
270
2/4
✓ Branch 3 taken 98 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 98 times.
98 if (!any_of(
271 columns_of_table.cbegin(),
272 columns_of_table.cend(),
273 416 [&](const IDbConnection::ColumnInfo& column_info)->bool
274 {
275 416 return column_info.column_name == expected_column_info.column_name;
276 }))
277 {
278 throw discovery_exception("Column not found or column is inappropriate.");
279 }
280 }
281
282 // check the metadata table for the expected columns
283
3/6
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 98 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
140 expected_columns_for_table = vector<ExpectedColumnsInfo>
284 {
285 ExpectedColumnsInfo(DbConstants::kMetadataTable_Column_Pk_DefaultName),
286 ExpectedColumnsInfo(DbConstants::kMetadataTable_Column_Name_DefaultName),
287 ExpectedColumnsInfo(DbConstants::kMetadataTable_Column_AncestorId_DefaultName),
288 ExpectedColumnsInfo(DbConstants::kMetadataTable_Column_TypeDiscriminator_DefaultName),
289 ExpectedColumnsInfo(DbConstants::kMetadataTable_Column_ValueDouble_DefaultName),
290 ExpectedColumnsInfo(DbConstants::kMetadataTable_Column_ValueInteger_DefaultName),
291 ExpectedColumnsInfo(DbConstants::kMetadataTable_Column_ValueString_DefaultName),
292 126 };
293
294
1/2
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
14 columns_of_table = this->db_connection_->GetTableInfo(general_table_discovery_result.metadatatable_name.c_str());
295
296
2/2
✓ Branch 5 taken 98 times.
✓ Branch 6 taken 14 times.
112 for (const auto& expected_column_info : expected_columns_for_table)
297 {
298
2/4
✓ Branch 3 taken 98 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 98 times.
98 if (!any_of(
299 columns_of_table.cbegin(),
300 columns_of_table.cend(),
301 392 [&](const IDbConnection::ColumnInfo& column_info)->bool
302 {
303 392 return column_info.column_name == expected_column_info.column_name;
304 }))
305 {
306 throw discovery_exception("Column not found or column is inappropriate.");
307 }
308 }
309
310 // check the tiles-info table for the expected columns, and determine the dimensions
311
3/6
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 98 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
140 expected_columns_for_table = vector<ExpectedColumnsInfo>
312 {
313 ExpectedColumnsInfo(DbConstants::kTilesInfoTable_Column_Pk_DefaultName),
314 ExpectedColumnsInfo(DbConstants::kTilesInfoTable_Column_TileX_DefaultName),
315 ExpectedColumnsInfo(DbConstants::kTilesInfoTable_Column_TileY_DefaultName),
316 ExpectedColumnsInfo(DbConstants::kTilesInfoTable_Column_TileW_DefaultName),
317 ExpectedColumnsInfo(DbConstants::kTilesInfoTable_Column_TileH_DefaultName),
318 ExpectedColumnsInfo(DbConstants::kTilesInfoTable_Column_PyramidLevel_DefaultName),
319 ExpectedColumnsInfo(DbConstants::kTilesInfoTable_Column_TileDataId_DefaultName),
320 126 };
321
322
1/2
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
14 columns_of_table = this->db_connection_->GetTableInfo(general_table_discovery_result.tileinfotable_name.c_str());
323
324
2/2
✓ Branch 5 taken 98 times.
✓ Branch 6 taken 14 times.
112 for (const auto& expected_column_info : expected_columns_for_table)
325 {
326
2/4
✓ Branch 3 taken 98 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 98 times.
98 if (!any_of(
327 columns_of_table.cbegin(),
328 columns_of_table.cend(),
329 428 [&](const IDbConnection::ColumnInfo& column_info)->bool
330 {
331 428 return column_info.column_name == expected_column_info.column_name;
332 }))
333 {
334 throw discovery_exception("Column not found or column is inappropriate.");
335 }
336 }
337
338 // now we look for columns where the name is starting with "Dim_" - this gives us the list of dimensions
339 14 const size_t length_of_column_prefix_string = strlen(DbConstants::kDimensionColumnPrefix_Default);
340
2/2
✓ Branch 5 taken 144 times.
✓ Branch 6 taken 14 times.
158 for (const auto& column : columns_of_table)
341 {
342
5/6
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 110 times.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 34 times.
✓ Branch 7 taken 110 times.
144 if (column.column_name.find(DbConstants::kDimensionColumnPrefix_Default) == 0 && column.column_name.length() == length_of_column_prefix_string + 1)
343 {
344
1/2
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
34 general_table_discovery_result.dimensions.push_back(column.column_name[length_of_column_prefix_string]);
345 }
346 }
347
348 // Ok, and now we find out which of the dimensions are indexed.
349
1/2
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
14 const auto list_of_indices = this->db_connection_->GetIndicesOfTable(general_table_discovery_result.tileinfotable_name.c_str());
350 14 const size_t length_of_dimension_index = strlen(DbConstants::kIndexForDimensionColumnPrefix_Default);
351
2/2
✓ Branch 5 taken 20 times.
✓ Branch 6 taken 14 times.
34 for (const auto& index_column : list_of_indices)
352 {
353
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
20 if (index_column.index_name.find(DbConstants::kIndexForDimensionColumnPrefix_Default) == 0 && index_column.index_name.length() == length_of_dimension_index + 1)
354 {
355 // we better make sure that the indices we get here are actually listed as 'dimensions'
356 // TODO(JBL): maybe we should report some warning (if this is not the case)
357 20 Dimension dimension_of_index = index_column.index_name[length_of_dimension_index];
358
2/4
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
60 if (any_of(general_table_discovery_result.dimensions.cbegin(), general_table_discovery_result.dimensions.cend(), [dimension_of_index](Dimension dimension)->bool {return dimension == dimension_of_index; }))
359 {
360
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 general_table_discovery_result.indexed_dimensions.push_back(index_column.index_name[length_of_dimension_index]);
361 }
362 }
363 }
364
365 // now, find out whether we have a spatial index
366
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 8 times.
14 if (!general_table_discovery_result.spatial_index_table_name.empty())
367 {
368
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
6 const auto columns_of_spatial_index = this->db_connection_->GetTableInfo(general_table_discovery_result.spatial_index_table_name.c_str());
369
370 // We check if we find all the expected columns here, and then declare "spatial index operational".
371 // Otherwise, we clear the "spatial-index-table-field", notifying that there is no spatial index available.
372
3/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
48 expected_columns_for_table = vector<ExpectedColumnsInfo>
373 {
374 ExpectedColumnsInfo(DbConstants::kSqliteSpatialIndexTable_Column_Pk_DefaultName),
375 ExpectedColumnsInfo(DbConstants::kSqliteSpatialIndexTable_Column_minX_DefaultName),
376 ExpectedColumnsInfo(DbConstants::kSqliteSpatialIndexTable_Column_maxX_DefaultName),
377 ExpectedColumnsInfo(DbConstants::kSqliteSpatialIndexTable_Column_minY_DefaultName),
378 ExpectedColumnsInfo(DbConstants::kSqliteSpatialIndexTable_Column_maxY_DefaultName)
379 42 };
380
381 6 bool spatial_index_ok = true;
382
2/2
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 4 times.
26 for (const auto& expected_column_info : expected_columns_for_table)
383 {
384
3/4
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 20 times.
22 if (!any_of(
385 columns_of_spatial_index.cbegin(),
386 columns_of_spatial_index.cend(),
387 60 [&](const IDbConnection::ColumnInfo& column_info)->bool
388 {
389 60 return column_info.column_name == expected_column_info.column_name;
390 }))
391 {
392 2 spatial_index_ok = false;
393 2 break;
394 }
395 }
396
397
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (!spatial_index_ok)
398 {
399 2 general_table_discovery_result.spatial_index_table_name.clear();
400 }
401 6 }
402
26/68
✓ 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 6 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 6 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 6 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 6 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 6 times.
✗ Branch 77 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
62 }
403