From 299f9682a4a2df434d0e61e73780fd2555afa1b8 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 12 Jun 2018 22:02:08 +0300 Subject: Default version epoch to one --- bpkg/database.cxx | 46 ++++++++++++++++++++++++++++++++++++++++++++++ bpkg/package.hxx | 6 +++++- bpkg/package.xml | 2 ++ doc/manual.cli | 33 ++++++++++++++++++++------------- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/bpkg/database.cxx b/bpkg/database.cxx index 3c55237..7d0e2ac 100644 --- a/bpkg/database.cxx +++ b/bpkg/database.cxx @@ -44,6 +44,52 @@ namespace bpkg } }; + // Register the data migration functions. + // + template + using migration_entry = odb::data_migration_entry; + + // Migrate tables that contain package version columns converting the + // default zero version epoch to one, unless the version is a stub. + // + // Note that we can't really distinguish the default zero epoch from an + // explicitly specified one, so will just update all of them, assuming that + // it is currently unlikely that the epoch was specified explicitly for any + // package version. + // + static const migration_entry<5> + migrate_epoch_entry ([] (odb::database& db) + { + // Delay the foreign key constraint checks until we are done with all the + // tables. + // + assert (transaction::has_current ()); + db.execute ("PRAGMA defer_foreign_keys = ON"); + + auto update = [&db] (const string& table, + const string& version_prefix = "version") + { + string ec (version_prefix + "_epoch"); + + db.execute ("UPDATE " + table + " SET " + ec + " = 1 " + + "WHERE " + ec + " = 0 AND NOT (" + + version_prefix + "_canonical_upstream = '' AND " + + version_prefix + "_canonical_release = '~')"); + }; + + update ("available_package"); + update ("available_package_locations"); + update ("available_package_dependencies"); + update ("available_package_dependency_alternatives"); + update ("available_package_dependency_alternatives", "dep_min_version"); + update ("available_package_dependency_alternatives", "dep_max_version"); + update ("selected_package"); + update ("selected_package_prerequisites", "min_version"); + update ("selected_package_prerequisites", "max_version"); + + db.execute ("PRAGMA defer_foreign_keys = OFF"); + }); + database open (const dir_path& d, tracer& tr, bool create) { diff --git a/bpkg/package.hxx b/bpkg/package.hxx index 185059f..ab0d144 100644 --- a/bpkg/package.hxx +++ b/bpkg/package.hxx @@ -24,7 +24,11 @@ #include -#pragma db model version(4, 4, closed) +// Used by the data migration entries. +// +#define DB_SCHEMA_VERSION_BASE 4 + +#pragma db model version(DB_SCHEMA_VERSION_BASE, 5, open) namespace bpkg { diff --git a/bpkg/package.xml b/bpkg/package.xml index 2b7ac59..0cb00c1 100644 --- a/bpkg/package.xml +++ b/bpkg/package.xml @@ -1,4 +1,6 @@ + + diff --git a/doc/manual.cli b/doc/manual.cli index 8f0fec1..16485df 100644 --- a/doc/manual.cli +++ b/doc/manual.cli @@ -82,7 +82,10 @@ The \c{bpkg} package version has the following form: The \i{epoch} part should be an integer. It can be used to change to a new versioning scheme that would be incompatible with the old one. If not -specified, then \i{epoch} defaults to \c{0}. +specified, then \i{epoch} defaults to \c{1} except for a stub version (see +below) in which case it defaults to \c{0}. The explicit zero \i{epoch} can be +used if the current versioning scheme (for example, date-based) is known to be +temporary. The \i{upstream} part is the upstream software version that this package is based on. It can only contain alpha-numeric characters and \c{'.'}. The @@ -118,10 +121,11 @@ each modification would be impractical. This mechanism is similar to the automatic commit versioning provided by the \i{standard version} except that it is limited to the packaging information but works for uncommitted changes.| -Version \c{0-} (least possible version) is reserved and specifying it +Version \c{+0-0-} (least possible version) is reserved and specifying it explicitly is illegal. \N{Explicitly specifying this version does not make -much sense since \c{libfoo < 0-} is always false and \c{libfoo > 0-} is always -true. In the implementation this value is used as a special empty version.} +much sense since \c{libfoo < +0-0-} is always false and \c{libfoo > +0-0-} is +always true. In the implementation this value is used as a special empty +version.} Version \c{0} (with a potential revision, for example, \c{0+1}, \c{0+2}) is used to signify a \i{stub package}. A stub is a package that does not contain @@ -131,9 +135,10 @@ full-fledged package at which point it will be assigned a \"real\" version. It is assumed that this version will always be greater than the stub version. When displaying the package version or when using the version to derive the -file name, zero \i{epoch}, \i{revision}, and \i{iteration} are omitted (even -if they were explicitly specified, for instance, in the package manifest). For -example, \c{+0-1.2.3+0} will be used as \c{libfoo-1.2.3}. +file name, the default \i{epoch} value as well as zero \i{revision} and +\i{iteration} values are omitted (even if they were explicitly specified, for +instance, in the package manifest). For example, \c{+1-1.2.3+0} will be used +as \c{libfoo-1.2.3}. \N|This versioning scheme and the choice of delimiter characters (\c{.-+}) is meant to align with semantic versioning.| @@ -141,6 +146,8 @@ is meant to align with semantic versioning.| Some examples of versions: \ +0+1 ++0-20180112 1.2.3 1.2.3-a1 1.2.3-b2 @@ -149,11 +156,11 @@ Some examples of versions: 1.2.3-alpha.1 1.2.3-beta.1 1.2.3+1 -+1-1.2.3 -+1-1.2.3-alpha.1+3 -+1.2.3#1 ++2-1.2.3 ++2-1.2.3-alpha.1+3 ++2.2.3#1 1.2.3+1#1 -+1-1.2.3+1#2 ++2-1.2.3+1#2 \ The version sorting order is \i{epoch}, \i{upstream}, \i{prerel}, @@ -164,8 +171,8 @@ next. To compare two components, first the component types are determined. A component that only consists of digits is an integer. Otherwise, it is a string. If both components are integers, then they are compared as -integers. Otherwise, they are compared lexicographically and case- -insensitively. \N{The reason for case-insensitive comparison is Windows +integers. Otherwise, they are compared lexicographically and +case-insensitively. \N{The reason for case-insensitive comparison is Windows file names.} A non-existent component is considered 0 if the other component is an integer -- cgit