aboutsummaryrefslogtreecommitdiff
path: root/bpkg/database.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/database.cxx')
-rw-r--r--bpkg/database.cxx297
1 files changed, 175 insertions, 122 deletions
diff --git a/bpkg/database.cxx b/bpkg/database.cxx
index 451ade3..65e3af8 100644
--- a/bpkg/database.cxx
+++ b/bpkg/database.cxx
@@ -3,13 +3,13 @@
#include <bpkg/database.hxx>
+#include <sqlite3.h> // @@ TMP sqlite3_libversion_number()
+
#include <map>
#include <odb/schema-catalog.hxx>
#include <odb/sqlite/exceptions.hxx>
-#include <libbutl/sha256.mxx>
-
#include <bpkg/package.hxx>
#include <bpkg/package-odb.hxx>
#include <bpkg/diagnostics.hxx>
@@ -61,130 +61,95 @@ namespace bpkg
template <odb::schema_version v>
using migration_entry = odb::data_migration_entry<v, DB_SCHEMA_VERSION_BASE>;
- static const migration_entry<8>
- migrate_v8 ([] (odb::database& db)
- {
- for (shared_ptr<repository> r: pointer_result (db.query<repository> ()))
- {
- if (!r->name.empty ()) // Non-root repository?
- {
- r->local = r->location.local ();
- db.update (r);
- }
- }
- });
-
- static const migration_entry<9>
- migrate_v9 ([] (odb::database& db)
- {
- // Add the unnamed self-link of the target type.
- //
- shared_ptr<configuration> sl (
- make_shared<configuration> (optional<string> (), "target"));
-
- db.persist (sl);
- db.execute (string ("UPDATE \"main\".selected_package_prerequisites ") +
- "SET configuration = '" + sl->uuid.string () + "'");
- });
-
- static const migration_entry<10>
- migrate_v10 ([] (odb::database& db)
+ // @@ 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)
{
- // Create the multi-column index for the configuration and prerequisite
- // columns of the selected_package_prerequisites table.
+ // Note that
+ // available_package_dependency_alternative_dependencies.alternative_index
+ // is copied from available_package_dependency_alternatives.index and
+ // available_package_dependency_alternative_dependencies.index is set to 0.
//
db.execute (
- "CREATE INDEX "
- "\"main\".selected_package_prerequisites_configuration_prerequisite_i "
- "ON selected_package_prerequisites (configuration, prerequisite)");
+ "INSERT INTO \"main\".\"available_package_dependency_alternative_dependencies\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"dependency_index\", "
+ "\"alternative_index\", "
+ "\"index\", "
+ "\"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\") "
+ "SELECT "
+ "\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"dependency_index\", "
+ "\"index\", "
+ "0, "
+ "\"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\" "
+ "FROM \"main\".\"available_package_dependency_alternatives\"");
});
- static const migration_entry<12>
- migrate_v12 ([] (odb::database& d)
+ // @@ 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_dependencies.conditional column 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<14>
+ migrate_v14 ([] (odb::database&)
{
- // Drop foreign key constraint for the prerequisite column of the
- // selected_package_prerequisites table.
- //
- // Note that since SQLite provides no API to drop constraints we will
- // rename the selected_package_prerequisites table, create the new table
- // without the constraint, and copy the data into the new table.
- //
- // Also note that we can only perform migration of the main database,
- // since dropping index and table in an attached database fails by some
- // reason with the SQLITE_LOCKED error. This, however, is probably ok
- // since the host and build system module configurations are already
- // created without this constraint and its highly unlikely to encounter an
- // already migrated (up to version 11) a linked target configuration.
- //
- database& db (static_cast<database&> (d));
-
- if (!db.main ())
- return;
-
- db.execute ("ALTER TABLE \"main\".\"selected_package_prerequisites\" "
- "RENAME TO \"selected_package_prerequisites_old\"");
-
- db.execute ("CREATE TABLE \"main\".\"selected_package_prerequisites\" (\n"
- " \"package\" TEXT NULL COLLATE NOCASE,\n"
- " \"configuration\" TEXT NULL,\n"
- " \"prerequisite\" TEXT NULL COLLATE NOCASE,\n"
- " \"min_version_epoch\" INTEGER NULL,\n"
- " \"min_version_canonical_upstream\" TEXT NULL,\n"
- " \"min_version_canonical_release\" TEXT NULL,\n"
- " \"min_version_revision\" INTEGER NULL,\n"
- " \"min_version_iteration\" INTEGER NULL,\n"
- " \"min_version_upstream\" TEXT NULL,\n"
- " \"min_version_release\" TEXT NULL,\n"
- " \"max_version_epoch\" INTEGER NULL,\n"
- " \"max_version_canonical_upstream\" TEXT NULL,\n"
- " \"max_version_canonical_release\" TEXT NULL,\n"
- " \"max_version_revision\" INTEGER NULL,\n"
- " \"max_version_iteration\" INTEGER NULL,\n"
- " \"max_version_upstream\" TEXT NULL,\n"
- " \"max_version_release\" TEXT NULL,\n"
- " \"min_open\" INTEGER NULL,\n"
- " \"max_open\" INTEGER NULL,\n"
- " CONSTRAINT \"package_fk\"\n"
- " FOREIGN KEY (\"package\")\n"
- " REFERENCES \"selected_package\" (\"name\")\n"
- " ON DELETE CASCADE)");
-
- db.execute ("INSERT INTO \"main\".\"selected_package_prerequisites\" "
- "SELECT "
- "\"package\", "
- "\"configuration\", "
- "\"prerequisite\", "
- "\"min_version_epoch\", "
- "\"min_version_canonical_upstream\", "
- "\"min_version_canonical_release\", "
- "\"min_version_revision\", "
- "\"min_version_iteration\", "
- "\"min_version_upstream\", "
- "\"min_version_release\", "
- "\"max_version_epoch\", "
- "\"max_version_canonical_upstream\", "
- "\"max_version_canonical_release\", "
- "\"max_version_revision\", "
- "\"max_version_iteration\", "
- "\"max_version_upstream\", "
- "\"max_version_release\", "
- "\"min_open\", "
- "\"max_open\" "
- "FROM \"main\".\"selected_package_prerequisites_old\"");
-
- db.execute ("DROP TABLE \"main\".\"selected_package_prerequisites_old\"");
-
- // Create the indexes after dropping the old table to make sure the old
- // indexes are also dropped to date.
- //
- db.execute ("CREATE INDEX "
- "\"main\".\"selected_package_prerequisites_package_i\"\n"
- " ON \"selected_package_prerequisites\" (\"package\")");
-
- db.execute (
- "CREATE INDEX "
- "\"main\".selected_package_prerequisites_configuration_prerequisite_i "
- "ON selected_package_prerequisites (configuration, prerequisite)");
});
static inline path
@@ -384,7 +349,6 @@ namespace bpkg
else
config_orig = config;
-
string = '[' + config_orig.representation () + ']';
try
@@ -490,6 +454,54 @@ 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);
+ }
+
+ // @@ TMP See migrate_v14() for details.
+ //
+ if (sv < 14)
+ drop ("available_package_dependencies", "conditional");
+ }
+
for (auto& c: query<configuration> (odb::query<configuration>::id != 0))
{
dir_path d (c.effective_path (config));
@@ -565,7 +577,7 @@ namespace bpkg
//
std::string schema;
{
- butl::sha256 h (d.string ());
+ sha256 h (d.string ());
for (size_t n (4);; ++n)
{
@@ -936,6 +948,39 @@ namespace bpkg
empty_string /* type */);
}
+ linked_databases database::
+ cluster_configs (bool sys_rep)
+ {
+ linked_databases r;
+
+ // If the database is not in the resulting list, then add it and its
+ // dependent and dependency configurations, recursively.
+ //
+ auto add = [&r, sys_rep] (database& db, const auto& add)
+ {
+ if (std::find (r.begin (), r.end (), db) != r.end ())
+ return;
+
+ r.push_back (db);
+
+ {
+ linked_databases cs (db.dependency_configs ());
+ for (auto i (cs.begin_linked ()); i != cs.end (); ++i)
+ add (*i, add);
+ }
+
+ {
+ linked_databases cs (db.dependent_configs (sys_rep));
+ for (auto i (cs.begin_linked ()); i != cs.end (); ++i)
+ add (*i, add);
+ }
+ };
+
+ add (*this, add);
+
+ return r;
+ }
+
database& database::
find_attached (uint64_t id, bool s)
{
@@ -1074,4 +1119,12 @@ namespace bpkg
{
return *this == main_database ();
}
+
+ // compare_lazy_ptr
+ //
+ bool compare_lazy_ptr::
+ less (const odb::database& x, const odb::database& y) const
+ {
+ return static_cast<const database&> (x) < static_cast<const database&> (y);
+ }
}