// file : bpkg/package -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef BPKG_PACKAGE #define BPKG_PACKAGE #include #include #include // uint16 #include #include #include #include #pragma db model version(1, 1, open) namespace bpkg { // Use an image type to map version to the database since there // is no way to modify individual components directly. // #pragma db value struct _version { std::uint16_t epoch; string upstream; std::uint16_t revision; string canonical_upstream; }; } #include namespace bpkg { // compare_lazy_ptr // // Compare two lazy pointers via the pointed-to object ids. // struct compare_lazy_ptr { template bool operator() (const P& x, const P& y) const { return x.object_id () < y.object_id (); } }; // path // using optional_string = optional; using optional_path = optional; using optional_dir_path = optional; #pragma db map type(path) as(string) \ to((?).string ()) from(bpkg::path (?)) #pragma db map type(optional_path) as(bpkg::optional_string) \ to((?) ? (?)->string () : bpkg::optional_string ()) \ from((?) ? bpkg::path (*(?)) : bpkg::optional_path ()) #pragma db map type(dir_path) as(string) \ to((?).string ()) from(bpkg::dir_path (?)) #pragma db map type(optional_dir_path) as(bpkg::optional_string) \ to((?) ? (?)->string () : bpkg::optional_string ()) \ from((?) ? bpkg::dir_path (*(?)) : bpkg::optional_dir_path ()) // version // #pragma db map type(version) as(_version) \ to(bpkg::_version{(?).epoch (), \ (?).upstream (), \ (?).revision (), \ (?).canonical_upstream ()}) \ from(bpkg::version ((?).epoch, std::move ((?).upstream), (?).revision)) // repository // #pragma db object pointer(std::shared_ptr) session class repository { public: // We use a weak pointer for prerequisite repositories because we // might have cycles. // using complements_type = std::set, compare_lazy_ptr>; using prerequisites_type = std::set, compare_lazy_ptr>; repository_location location; complements_type complements; prerequisites_type prerequisites; const string& name () const {return location.canonical_name ();} // Used to detect recursive fecthing. Will probably be replaced // by the 'repositories' file timestamp or hashsum later. // #pragma db transient bool fetched = false; public: explicit repository (repository_location l): location (move (l)) {} // Database mapping. // #pragma db value struct _id_type { string name; // Canonical name. string location; }; _id_type _id () const; void _id (_id_type&&); #pragma db member(location) transient #pragma db member(id) virtual(_id_type) before id(name) \ get(_id) set(_id (std::move (?))) column("") #pragma db member(complements) id_column("repository") \ value_column("complement") value_not_null #pragma db member(prerequisites) id_column("repository") \ value_column("prerequisite") value_not_null private: friend class odb::access; repository () = default; }; #pragma db view object(repository) query(repository::id.name != "" && (?)) struct repository_count { #pragma db column("count(" + repository::id.name + ")") size_t result; }; // package_version_id // #pragma db value struct package_version_id { string name; std::uint16_t epoch; string upstream; // Canonical upstream. std::uint16_t revision; package_version_id () = default; package_version_id (string, const version&); #pragma db member(epoch) column("version_epoch") #pragma db member(upstream) column("version_upstream") #pragma db member(revision) column("version_revision") }; bool operator< (const package_version_id&, const package_version_id&); // package_location // #pragma db value struct package_location { using repository_type = bpkg::repository; lazy_shared_ptr repository; path location; // Relative to the repository. }; // available_package // #pragma db object pointer(shared_ptr) session class available_package { public: using version_type = bpkg::version; string name; version_type version; // List of repositories to which this package version belongs (yes, // in our world, it can be in multiple, unrelated repositories). // std::vector locations; // Database mapping. // // id // #pragma db value struct _id_type { package_version_id data; string version_original_upstream; #pragma db member(data) column("") }; _id_type _id () const; void _id (_id_type&&); #pragma db member(name) transient #pragma db member(version) transient #pragma db member(id) virtual(_id_type) before id(data) \ get(_id) set(_id (std::move (?))) column("") // repositories // #pragma db member(locations) id_column("") value_column("") \ unordered value_not_null private: friend class odb::access; available_package () = default; }; #pragma db view object(available_package) struct available_package_count { #pragma db column("count(" + available_package::id.data.name + ")") size_t result; }; // state // enum class state { broken, fetched, unpacked, configured }; string to_string (state); state from_string (const string&); // May throw invalid_argument. inline std::ostream& operator<< (std::ostream& os, state s) {return os << to_string (s);} #pragma db map type(state) as(string) \ to(to_string (?)) \ from(bpkg::from_string (?)) // package // #pragma db object pointer(shared_ptr) session class package { public: using version_type = bpkg::version; using state_type = bpkg::state; string name; version_type version; state_type state; // Path to the archive of this package, if any. If not absolute, // then it is relative to the configuration directory. The purge // flag indicates whether the archive should be removed when the // packaged is purged. If the archive is not present, it should // be false. // optional archive; bool purge_archive; // Path to the source directory of this package, if any. If not // absolute, then it is relative to the configuration directory. // The purge flag indicates whether the directory should be // removed when the packaged is purged. If the source directory // is not present, it should be false. // optional src_root; bool purge_src; // Path to the output directory of this package, if any. It is // always relative to the configuration directory and currently // is always -. It is only set once the package // is configured and its main purse is to keep track of what // needs to be cleaned by the user before a broken package can // be purged. Note that it could be the same as out_root. // optional out_root; // Database mapping. // #pragma db member(name) id private: friend class odb::access; package () = default; }; } #include #endif // BPKG_PACKAGE