aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/database.cxx46
-rw-r--r--bpkg/package.hxx6
-rw-r--r--bpkg/package.xml2
-rw-r--r--doc/manual.cli33
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 <odb::schema_version v>
+ using migration_entry = odb::data_migration_entry<v, DB_SCHEMA_VERSION_BASE>;
+
+ // 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 <bpkg/diagnostics.hxx>
-#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 @@
<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="sqlite" version="1">
+ <changeset version="5"/>
+
<model version="4">
<table name="repository_fragment" kind="object">
<column name="name" type="TEXT" null="true"/>
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