| 534 | // --------------------------------------------------------------------------- |
| 535 | |
| 536 | void SQLiteHandle::checkDatabaseLayout(const std::string &mainDbPath, |
| 537 | const std::string &path, |
| 538 | const std::string &dbNamePrefix) { |
| 539 | if (!dbNamePrefix.empty() && run("SELECT 1 FROM " + dbNamePrefix + |
| 540 | "sqlite_master WHERE name = 'metadata'") |
| 541 | .empty()) { |
| 542 | // Accept auxiliary databases without metadata table (sparse DBs) |
| 543 | return; |
| 544 | } |
| 545 | auto res = run("SELECT key, value FROM " + dbNamePrefix + |
| 546 | "metadata WHERE key IN " |
| 547 | "('DATABASE.LAYOUT.VERSION.MAJOR', " |
| 548 | "'DATABASE.LAYOUT.VERSION.MINOR')"); |
| 549 | if (res.empty() && !dbNamePrefix.empty()) { |
| 550 | // Accept auxiliary databases without layout metadata. |
| 551 | return; |
| 552 | } |
| 553 | if (res.size() != 2) { |
| 554 | throw FactoryException( |
| 555 | path + " lacks DATABASE.LAYOUT.VERSION.MAJOR / " |
| 556 | "DATABASE.LAYOUT.VERSION.MINOR " |
| 557 | "metadata. It comes from another PROJ installation."); |
| 558 | } |
| 559 | int major = 0; |
| 560 | int minor = 0; |
| 561 | for (const auto &row : res) { |
| 562 | if (row[0] == "DATABASE.LAYOUT.VERSION.MAJOR") { |
| 563 | major = atoi(row[1].c_str()); |
| 564 | } else if (row[0] == "DATABASE.LAYOUT.VERSION.MINOR") { |
| 565 | minor = atoi(row[1].c_str()); |
| 566 | } |
| 567 | } |
| 568 | if (major != DATABASE_LAYOUT_VERSION_MAJOR) { |
| 569 | throw FactoryException( |
| 570 | path + |
| 571 | " contains DATABASE.LAYOUT.VERSION.MAJOR = " + toString(major) + |
| 572 | " whereas " + toString(DATABASE_LAYOUT_VERSION_MAJOR) + |
| 573 | " is expected. " |
| 574 | "It comes from another PROJ installation."); |
| 575 | } |
| 576 | |
| 577 | if (minor < DATABASE_LAYOUT_VERSION_MINOR) { |
| 578 | throw FactoryException( |
| 579 | path + |
| 580 | " contains DATABASE.LAYOUT.VERSION.MINOR = " + toString(minor) + |
| 581 | " whereas a number >= " + toString(DATABASE_LAYOUT_VERSION_MINOR) + |
| 582 | " is expected. " |
| 583 | "It comes from another PROJ installation."); |
| 584 | } |
| 585 | |
| 586 | if (dbNamePrefix.empty()) { |
| 587 | nLayoutVersionMajor_ = major; |
| 588 | nLayoutVersionMinor_ = minor; |
| 589 | } else if (nLayoutVersionMajor_ != major || nLayoutVersionMinor_ != minor) { |
| 590 | throw FactoryException( |
| 591 | "Auxiliary database " + path + |
| 592 | " contains a DATABASE.LAYOUT.VERSION = " + toString(major) + '.' + |
| 593 | toString(minor) + |
no test coverage detected