From c470e488b76818c8908d2e195f1b2a408c1b8b0d Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 17 Jan 2022 18:28:41 +0300 Subject: Fix database migration to version 13 --- bpkg/buildfile | 4 ++++ bpkg/database.cxx | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/bpkg/buildfile b/bpkg/buildfile index 6ef5ef4..dbd16ab 100644 --- a/bpkg/buildfile +++ b/bpkg/buildfile @@ -13,6 +13,10 @@ import libs += libbutl%lib{butl} import libs += libodb%lib{odb} import libs += libodb-sqlite%lib{odb-sqlite} +# @@ TMP Only required for the database migration to schema version 13. +# +import libs += libsqlite3%lib{sqlite3} + options_topics = \ bpkg-options \ cfg-create-options \ diff --git a/bpkg/database.cxx b/bpkg/database.cxx index 39013e8..08f8122 100644 --- a/bpkg/database.cxx +++ b/bpkg/database.cxx @@ -3,6 +3,8 @@ #include +#include // @@ TMP sqlite3_libversion_number() + #include #include @@ -187,6 +189,16 @@ namespace bpkg "ON selected_package_prerequisites (configuration, prerequisite)"); }); + // @@ Since there is no proper support for dropping table columns not in + // SQLite prior to 3.35.5 nor in ODB, we will drop the + // available_package_dependency_alternatives.dep_* columns manually. We, + // however, cannot do it here since ODB will try to set the dropped + // column values to NULL at the end of migration. Thus, we will do it + // ad hoc after the below schema_catalog::migrate() call. + // + // NOTE: remove the mentioned ad hoc migration when removing this + // function. + // static const migration_entry<13> migrate_v13 ([] (odb::database& db) { @@ -556,6 +568,49 @@ namespace bpkg // schema_catalog::migrate (*this); + // Note that the potential data corruption with `DROP COLUMN` is fixed + // in 3.35.5. + // + // @@ TMP Get rid of manual column dropping when ODB starts supporting + // that properly. Not doing so will result in failure of the below + // queries. + // + if (sqlite3_libversion_number () >= 3035005) + { + auto drop = [this] (const char* table, const char* column) + { + execute (std::string ("ALTER TABLE \"main\".") + table + + " DROP COLUMN \"" + column + "\""); + }; + + // @@ TMP See migrate_v13() for details. + // + if (sv < 13) + { + const char* cs[] = {"dep_name", + "dep_min_version_epoch", + "dep_min_version_canonical_upstream", + "dep_min_version_canonical_release", + "dep_min_version_revision", + "dep_min_version_iteration", + "dep_min_version_upstream", + "dep_min_version_release", + "dep_max_version_epoch", + "dep_max_version_canonical_upstream", + "dep_max_version_canonical_release", + "dep_max_version_revision", + "dep_max_version_iteration", + "dep_max_version_upstream", + "dep_max_version_release", + "dep_min_open", + "dep_max_open", + nullptr}; + + for (const char** c (cs); *c != nullptr; ++c) + drop ("available_package_dependency_alternatives", *c); + } + } + for (auto& c: query (odb::query::id != 0)) { dir_path d (c.effective_path (config)); -- cgit v1.1