aboutsummaryrefslogtreecommitdiff
path: root/brep/package
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-06-30 19:20:16 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-08-06 20:34:25 +0200
commit8e866579cb459c5104c532d5e41d562d45236ea5 (patch)
treef72548e3499bfdc50bc1183ec014d14e6b53918c /brep/package
parentc188831c50456754de79aadc26df74149cb00422 (diff)
Implement loader
Diffstat (limited to 'brep/package')
-rw-r--r--brep/package302
1 files changed, 240 insertions, 62 deletions
diff --git a/brep/package b/brep/package
index 62ad8d6..c0c9fc9 100644
--- a/brep/package
+++ b/brep/package
@@ -2,30 +2,60 @@
// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef BPKG_PACKAGE
-#define BPKG_PACKAGE
+#ifndef BREP_PACKAGE
+#define BREP_PACKAGE
#include <map>
#include <string>
#include <vector>
+#include <chrono>
#include <memory> // shared_ptr
-#include <utility> // pair
+#include <cstddef> // size_t
+#include <utility> // move()
#include <cstdint> // uint16
#include <odb/core.hxx>
#include <odb/forward.hxx> // database
#include <odb/lazy-ptr.hxx>
-#include <odb/nullable.hxx>
+
+#include <butl/path>
+#include <butl/path-io>
+#include <butl/optional>
+#include <butl/timestamp>
+
+namespace brep
+{
+ // Use an image type to map bpkg::version to the database since there
+ // is no way to modify individual components directly.
+ //
+ #pragma db value
+ struct _version
+ {
+ std::uint16_t epoch;
+ std::string upstream;
+ std::uint16_t revision;
+ std::string canonical_upstream;
+ };
+}
#include <bpkg/manifest>
+// We have to keep this mapping at the global scope instead of inside
+// the brep namespace because it needs to be also effective in the
+// bpkg namespace from which we "borrow" types (and some of them use
+// version).
+//
+#pragma db map type(bpkg::version) as(brep::_version) \
+ to(brep::_version{(?).epoch (), \
+ (?).upstream (), \
+ (?).revision (), \
+ (?).canonical_upstream ()}) \
+ from(bpkg::version ((?).epoch, std::move ((?).upstream), (?).revision))
+
namespace brep
{
// @@ If namespace, then should probably call it 'repo'.
//
- // @@ Should probably use optional from libbutl instead of odb::nullable
- // for consistency. Create butl profile?
- //
// @@ Might make sense to put some heavy members (e.g., description,
// containers) into a separate section.
//
@@ -36,38 +66,63 @@ namespace brep
// Forward declarations.
//
- struct package;
- struct package_version;
+ class repository;
+ class package;
+ class package_version;
using strings = std::vector<std::string>;
- using version = bpkg::version;
- #pragma db value(version) definition
+ template <typename T>
+ using optional = butl::optional<T>;
+
+ using path = butl::path;
+
+ #pragma db map type(path) as(std::string) \
+ to((?).string ()) from(brep::path (?))
+
+ using dir_path = butl::dir_path;
+
+ #pragma db map type(dir_path) as(std::string) \
+ to((?).string ()) from(brep::dir_path (?))
+
+ using timestamp = butl::timestamp;
- using version_type = brep::version;
+ #pragma db map type(timestamp) as(std::uint64_t) \
+ to(std::chrono::system_clock::to_time_t (?)) \
+ from(std::chrono::system_clock::from_time_t (?))
+
+ using version = bpkg::version;
+ using repository_location = bpkg::repository_location;
#pragma db value
struct package_version_id
{
+ std::string repository;
std::string package;
std::uint16_t epoch;
- std::string canonical;
+ std::string canonical_upstream;
// Database mapping.
//
- #pragma db member(package) points_to(package)
+ #pragma db member(repository) points_to(repository) //on_delete(cascade)
+ #pragma db member(package) points_to(package) //on_delete(cascade)
};
inline bool
operator< (const package_version_id& x, const package_version_id& y)
{
- int r (x.package.compare (y.package));
+ int r (x.repository.compare (y.repository));
+
+ if (r != 0)
+ return r < 0;
+
+ r = x.package.compare (y.package);
if (r != 0)
return r < 0;
return x.epoch < y.epoch ||
- x.epoch == y.epoch && x.canonical < y.canonical;
+ (x.epoch == y.epoch && x.canonical_upstream < y.canonical_upstream);
}
using priority = bpkg::priority;
@@ -76,7 +131,7 @@ namespace brep
using url = bpkg::url;
#pragma db value(url) definition
- #pragma db member(url::value) virtual(std::string) before access(this) \
+ #pragma db member(url::value) virtual(std::string) before access(this) \
column("")
using email = bpkg::email;
@@ -153,31 +208,110 @@ namespace brep
std::size_t first;
std::size_t second;
- index_pair (std::size_t f = 0, std::size_t s = 0): first (f), second (s) {}
+ index_pair () = default;
+ index_pair (std::size_t f, std::size_t s): first (f), second (s) {}
bool
operator< (const index_pair& v) const
{
- return first < v.first || first == v.first && second < v.second;
+ return first < v.first || (first == v.first && second < v.second);
}
};
#pragma db object pointer(std::shared_ptr) session
- struct package
+ class repository
{
- // Manifest data.
+ public:
+ using path_type = brep::path;
+ using timestamp_type = brep::timestamp;
+ using package_versions_type =
+ std::vector<odb::lazy_weak_ptr<package_version>>;
+ using prerequisite_repositories_type =
+ std::vector<odb::lazy_weak_ptr<repository>>;
+
+ // Create internal repository.
+ //
+ repository (repository_location,
+ std::string display_name,
+ dir_path local_path);
+
+ // Create external repository.
+ //
+ explicit
+ repository (repository_location l)
+ : location (std::move (l)), internal (false) {}
+
+ repository_location location;
+ std::string display_name;
+
+ // Non empty for internal repositories and external ones with a filesystem
+ // path location.
+ //
+ dir_path local_path;
+
+ // Initialized with timestamp_nonexistent by default.
+ //
+ timestamp_type timestamp;
+
+ bool internal;
+ package_versions_type package_versions;
+ prerequisite_repositories_type prerequisite_repositories;
+
+ // Database mapping.
//
+ #pragma db value
+ struct _id_type
+ {
+ std::string canonical_name;
+ std::string location;
+ };
+
+ _id_type
+ _id () const;
+
+ void
+ _id (_id_type&&);
+
+ #pragma db member(location) transient
+
+ #pragma db member(id) virtual(_id_type) before id(canonical_name) \
+ get(_id) set(_id (std::move (?))) column("")
+
+ #pragma db member(package_versions) inverse(id.data.repository)
+ #pragma db member(prerequisite_repositories) id_column("repository") \
+ value_column("prerequisite_repository") value_not_null
+
+ private:
+ friend class odb::access;
+ repository () = default;
+ };
+
+ #pragma db object pointer(std::shared_ptr) session
+ class package
+ {
+ public:
using url_type = brep::url;
using email_type = brep::email;
+ package (std::string name,
+ std::string summary,
+ strings tags,
+ optional<std::string> description,
+ url_type,
+ optional<url_type> package_url,
+ email_type,
+ optional<email_type> package_email);
+
+ // Manifest data.
+ //
std::string name;
std::string summary;
strings tags;
- std::string description;
+ optional<std::string> description;
url_type url;
- odb::nullable<url_type> package_url;
+ optional<url_type> package_url;
email_type email;
- odb::nullable<email_type> package_email;
+ optional<email_type> package_email;
std::vector<odb::lazy_weak_ptr<package_version>> versions;
// Additional data.
@@ -187,55 +321,71 @@ namespace brep
//
#pragma db member(name) id
#pragma db member(tags) id_column("package") value_column("tag")
- #pragma db member(versions) inverse(id.package)
+ #pragma db member(versions) inverse(id.data.package)
+
+ private:
+ friend class odb::access;
+ package () = default;
};
#pragma db object pointer(std::shared_ptr) session
- struct package_version
+ class package_version
{
- // Manifest data.
- //
+ public:
+ using repository_type = brep::repository;
using package_type = brep::package;
+ using version_type = brep::version;
using priority_type = brep::priority;
using license_alternatives_type = brep::license_alternatives;
using dependencies_type = brep::dependencies;
using requirements_type = brep::requirements;
+ package_version (odb::lazy_shared_ptr<repository_type>,
+ odb::lazy_shared_ptr<package_type>,
+ version_type,
+ priority_type,
+ license_alternatives_type,
+ std::string changes,
+ dependencies_type,
+ requirements_type);
+
+ // Manifest data.
+ //
+ odb::lazy_shared_ptr<repository_type> repository;
+ odb::lazy_shared_ptr<package_type> package;
version_type version;
- std::shared_ptr<package_type> package;
priority_type priority;
license_alternatives_type license_alternatives;
std::string changes;
dependencies_type dependencies;
requirements_type requirements;
- // Additional data.
- //
- std::string repository; // E.g., "stable", "testing".
-
// Database mapping.
//
// id
//
- package_version_id
- id () const
+ #pragma db value
+ struct _id_type
{
- return package_version_id
- {package->name, version.epoch, version.canonical};
- }
+ #pragma db column("")
+ package_version_id data;
+ std::string upstream;
+ std::uint16_t revision;
+ };
+
+ _id_type
+ _id () const;
void
- id (const package_version_id&, odb::database&);
+ _id (_id_type&&, odb::database&);
#pragma db member(version) transient
#pragma db member(package) transient
- #pragma db member(id) virtual(package_version_id) before id \
- get(id) set(id ((?), (!))) column("")
- #pragma db member(upstream) virtual(std::string) after(id) \
- get(version.upstream) set(version.upstream=(?))
- #pragma db member(revision) virtual(std::uint16_t) after(upstream) \
- get(version.revision) set(version.revision = (?))
+ #pragma db member(repository) transient
+
+ #pragma db member(id) virtual(_id_type) before id(data) \
+ get(_id) set(_id (std::move (?), (!))) column("")
// license
//
@@ -247,11 +397,11 @@ namespace brep
#pragma db member(_license_key::second) column("index")
#pragma db member(license_alternatives) id_column("") value_column("")
- #pragma db member(licenses) \
- virtual(_licenses_type) \
- after(license_alternatives) \
- get(_get (this.license_alternatives)) \
- set(_set (this.license_alternatives, (?))) \
+ #pragma db member(licenses) \
+ virtual(_licenses_type) \
+ after(license_alternatives) \
+ get(_get (this.license_alternatives)) \
+ set(_set (this.license_alternatives, (?))) \
id_column("") key_column("") value_column("license")
// dependencies
@@ -265,11 +415,11 @@ namespace brep
#pragma db member(_dependency_key::second) column("index")
#pragma db member(dependencies) id_column("") value_column("")
- #pragma db member(dependency_alternatives) \
- virtual(_dependency_alternatives_type) \
- after(dependencies) \
- get(_get (this.dependencies)) \
- set(_set (this.dependencies, (?))) \
+ #pragma db member(dependency_alternatives) \
+ virtual(_dependency_alternatives_type) \
+ after(dependencies) \
+ get(_get (this.dependencies)) \
+ set(_set (this.dependencies, (?))) \
id_column("") key_column("") value_column("dep_")
// requirements
@@ -283,12 +433,40 @@ namespace brep
#pragma db member(_requirement_key::second) column("index")
#pragma db member(requirements) id_column("") value_column("")
- #pragma db member(requirement_alternatives) \
- virtual(_requirement_alternatives_type) \
- after(requirements) \
- get(_get (this.requirements)) \
- set(_set (this.requirements, (?))) \
+ #pragma db member(requirement_alternatives) \
+ virtual(_requirement_alternatives_type) \
+ after(requirements) \
+ get(_get (this.requirements)) \
+ set(_set (this.requirements, (?))) \
id_column("") key_column("") value_column("id")
+
+ private:
+ friend class odb::access;
+ package_version () = default;
+ };
+
+ #pragma db view object(package_version) \
+ query((?) + "ORDER BY" + package_version::id.data.epoch + "DESC," + \
+ package_version::id.data.canonical_upstream + "DESC," + \
+ package_version::id.revision + "DESC LIMIT 1")
+ struct max_package_version
+ {
+ using version_type = brep::version;
+
+ version_type version;
+
+ void
+ _id (package_version::_id_type&&);
+
+ // Database mapping.
+ //
+ #pragma db member(version) transient
+
+ // Can't specify column expression using aggregate max function for a
+ // data member of a composite value type.
+ //
+ #pragma db member(id) virtual(package_version::_id_type) \
+ get() set(_id (std::move (?)))
};
}
@@ -306,7 +484,7 @@ namespace brep
#include <map>
#include <vector>
#include <cstddef> // size_t
-#include <utility> // pair, declval()
+#include <utility> // declval()
#include <cassert>
#include <type_traits> // remove_reference
@@ -355,4 +533,4 @@ namespace odb
}
}
-#endif // BPKG_PACKAGE
+#endif // BREP_PACKAGE