| 1320 | // --------------------------------------------------------------------------- |
| 1321 | |
| 1322 | void DatabaseContext::Private::attachExtraDatabases( |
| 1323 | const std::vector<std::string> &auxiliaryDatabasePaths) { |
| 1324 | |
| 1325 | auto l_handle = handle(); |
| 1326 | assert(l_handle); |
| 1327 | |
| 1328 | auto tables = run("SELECT name, type, sql FROM sqlite_master WHERE type IN " |
| 1329 | "('table', 'view') " |
| 1330 | "AND name NOT LIKE 'sqlite_stat%'"); |
| 1331 | |
| 1332 | struct TableStructure { |
| 1333 | std::string name{}; |
| 1334 | bool isTable = false; |
| 1335 | std::string sql{}; |
| 1336 | std::vector<std::string> columns{}; |
| 1337 | }; |
| 1338 | std::vector<TableStructure> tablesStructure; |
| 1339 | for (const auto &rowTable : tables) { |
| 1340 | TableStructure tableStructure; |
| 1341 | tableStructure.name = rowTable[0]; |
| 1342 | tableStructure.isTable = rowTable[1] == "table"; |
| 1343 | tableStructure.sql = rowTable[2]; |
| 1344 | auto tableInfo = |
| 1345 | run("PRAGMA table_info(\"" + |
| 1346 | replaceAll(tableStructure.name, "\"", "\"\"") + "\")"); |
| 1347 | for (const auto &rowCol : tableInfo) { |
| 1348 | const auto &colName = rowCol[1]; |
| 1349 | tableStructure.columns.push_back(colName); |
| 1350 | } |
| 1351 | tablesStructure.push_back(std::move(tableStructure)); |
| 1352 | } |
| 1353 | |
| 1354 | const int nLayoutVersionMajor = l_handle->getLayoutVersionMajor(); |
| 1355 | const int nLayoutVersionMinor = l_handle->getLayoutVersionMinor(); |
| 1356 | |
| 1357 | closeDB(); |
| 1358 | if (auxiliaryDatabasePaths.empty()) { |
| 1359 | open(databasePath_, pjCtxt()); |
| 1360 | return; |
| 1361 | } |
| 1362 | |
| 1363 | sqlite3 *sqlite_handle = nullptr; |
| 1364 | sqlite3_open_v2( |
| 1365 | ":memory:", &sqlite_handle, |
| 1366 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_URI, nullptr); |
| 1367 | if (!sqlite_handle) { |
| 1368 | throw FactoryException("cannot create in memory database"); |
| 1369 | } |
| 1370 | sqlite_handle_ = SQLiteHandle::initFromExisting( |
| 1371 | sqlite_handle, true, nLayoutVersionMajor, nLayoutVersionMinor); |
| 1372 | l_handle = sqlite_handle_; |
| 1373 | |
| 1374 | run("ATTACH DATABASE ? AS db_0", {databasePath_}); |
| 1375 | detach_ = true; |
| 1376 | int count = 1; |
| 1377 | for (const auto &otherDbPath : auxiliaryDatabasePaths) { |
| 1378 | const auto attachedDbName("db_" + toString(static_cast<int>(count))); |
| 1379 | std::string sql = "ATTACH DATABASE ? AS "; |
no test coverage detected