From 1963538d18459e1e9f09808912cb0aae9ace1f3c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 27 Jun 2015 23:57:16 +0200 Subject: Use bpkg structs in package --- brep/package | 182 ++++++++++++++++++++++------------------------------ brep/package.cxx | 3 +- brep/search.cxx | 9 ++- brep/view.cxx | 7 +- brep/wrapper-traits | 63 ++++++++++++++++++ build.sh | 8 ++- buildfile | 4 +- etc/apachectl | 4 ++ etc/config | 1 + 9 files changed, 166 insertions(+), 115 deletions(-) create mode 100644 brep/wrapper-traits diff --git a/brep/package b/brep/package index 1ad11b2..6b43d30 100644 --- a/brep/package +++ b/brep/package @@ -10,12 +10,15 @@ #include #include // shared_ptr #include // pair +#include // uint16 #include #include // database #include #include +#include + namespace brep { // @@ If namespace, then should probably call it 'repo'. @@ -38,11 +41,17 @@ namespace brep using strings = std::vector; + using version = bpkg::version; + #pragma db value(version) definition + + using version_type = brep::version; + #pragma db value struct package_version_id { std::string package; - std::string version; + std::uint16_t epoch; + std::string canonical; // Database mapping. // @@ -53,128 +62,83 @@ namespace brep operator< (const package_version_id& x, const package_version_id& y) { int r (x.package.compare (y.package)); - return r < 0 || r == 0 && x.version < y.version; - } - - #pragma db value - class priority - { - public: - enum value_type {low, medium, high, security}; - value_type value; // Shouldn't be necessary to access directly. - std::string comment; + if (r != 0) + return r < 0; - priority (value_type v = low): value (v) {} - operator value_type () const {return value;} - - // Database mapping. - // - #pragma db member(value) column("") - }; - - #pragma db value - struct url: std::string - { - std::string comment; + return x.epoch < y.epoch || + x.epoch == y.epoch && x.canonical < y.canonical; + } - // Database mapping. - // - #pragma db member(value) virtual(std::string) before \ - access(this) column("") - }; + using priority = bpkg::priority; + #pragma db value(priority) definition + #pragma db member(priority::value) column("") - #pragma db value - struct email: std::string - { - std::string comment; + using url = bpkg::url; + #pragma db value(url) definition + #pragma db member(url::value) virtual(std::string) before access(this) \ + column("") - // Database mapping. - // - #pragma db member(value) virtual(std::string) before \ - access(this) column("") - }; + using email = bpkg::email; + #pragma db value(email) definition + #pragma db member(email::value) virtual(std::string) before access(this) \ + column("") // licenses // - #pragma db value - struct licenses: strings - { - std::string comment; - }; + using licenses = bpkg::licenses; + #pragma db value(licenses) definition using license_alternatives = std::vector; // dependencies // - enum class comparison {eq, lt, gt, le, ge}; + using comparison = bpkg::comparison; + using version_comparison = bpkg::version_comparison; + #pragma db value(version_comparison) definition + #pragma db member(version_comparison::value) column("") - #pragma db value - struct version_comparison - { - std::string value; - comparison operation; - }; - - #pragma db value - struct dependency - { - using package_type = brep::package; - - // Notes: - // - // 1. Will the package be always resolvable? What if it is in - // another repository (i.e., a "chained" third-party repo). - // The question is then whether we will load such "third- - // party packages" (i.e., packages that are not in our - // repository). If the answer is yes, then we can have - // a pointer here. If the answer is no, then we can't. - // Also, if the answer is yes, we probably don't need to - // load as much information as for "our own" packages. We - // also shouldn't be showing them in search results, etc. - // I think all we need is to know which repository this - // package comes from so that we can tell the user. How are - // we going to capture this? Poly hierarchy of packages? - // - // 2. I believe we don't need to use a weak pointer here since - // there should be no package dependency cycles (and therefore - // ownership cycles). - // - // 3. Actually there can be dependency cycle as dependency referes not to - // just a package but a specific version, so for the same pair of - // packages dependency for different versions can have an opposite - // directions. The possible solution is instead of a package we point - // to the earliest version that satisfies the condition. But this - // approach requires to ensure no cycles exist before instantiating - // package objects which in presense of "foreign" packages can be - // tricky. Can stick to just a package name until get some clarity on - // "foreign" package resolution. - // - std::string package; - odb::nullable version; - - // Database mapping. - // - #pragma db member(package) not_null - }; + // Notes: + // + // 1. Will the package be always resolvable? What if it is in + // another repository (i.e., a "chained" third-party repo). + // The question is then whether we will load such "third- + // party packages" (i.e., packages that are not in our + // repository). If the answer is yes, then we can have + // a pointer here. If the answer is no, then we can't. + // Also, if the answer is yes, we probably don't need to + // load as much information as for "our own" packages. We + // also shouldn't be showing them in search results, etc. + // I think all we need is to know which repository this + // package comes from so that we can tell the user. How are + // we going to capture this? Poly hierarchy of packages? + // + // 2. I believe we don't need to use a weak pointer here since + // there should be no package dependency cycles (and therefore + // ownership cycles). + // + // 3. Actually there can be dependency cycle as dependency referes not to + // just a package but a specific version, so for the same pair of + // packages dependency for different versions can have an opposite + // directions. The possible solution is instead of a package we point + // to the earliest version that satisfies the condition. But this + // approach requires to ensure no cycles exist before instantiating + // package objects which in presense of "foreign" packages can be + // tricky. Can stick to just a package name until get some clarity on + // "foreign" package resolution. + // + using dependency = bpkg::dependency; + #pragma db value(dependency) definition - #pragma db value - struct dependency_alternatives: std::vector - { - bool conditional; - std::string comment; - }; + using dependency_alternatives = bpkg::dependency_alternatives; + #pragma db value(dependency_alternatives) definition using dependencies = std::vector; // requirements // - #pragma db value - struct requirement_alternatives: strings - { - bool conditional; - std::string comment; - }; + using requirement_alternatives = bpkg::requirement_alternatives; + #pragma db value(requirement_alternatives) definition using requirements = std::vector; @@ -216,7 +180,7 @@ namespace brep using dependencies_type = brep::dependencies; using requirements_type = brep::requirements; - std::string version; + version_type version; std::shared_ptr package; priority_type priority; license_alternatives_type license_alternatives; @@ -234,7 +198,11 @@ namespace brep // id // package_version_id - id () const {return package_version_id {package->name, version};} + id () const + { + return package_version_id + {package->name, version.epoch, version.canonical}; + } void id (const package_version_id&, odb::database&); @@ -243,6 +211,10 @@ namespace brep #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 = (?)) // license // diff --git a/brep/package.cxx b/brep/package.cxx index 9331f55..11cd974 100644 --- a/brep/package.cxx +++ b/brep/package.cxx @@ -15,7 +15,8 @@ namespace brep void package_version:: id (const package_version_id& v, odb::database& db) { - version = v.version; + version.epoch = v.epoch; + version.canonical = v.canonical; package = db.load (v.package); } } diff --git a/brep/search.cxx b/brep/search.cxx index 9fc37e2..c4ed4b9 100644 --- a/brep/search.cxx +++ b/brep/search.cxx @@ -68,14 +68,17 @@ namespace brep std::shared_ptr v (make_shared ()); - v->version = "1.1"; + v->version = version ("1.1"); v->package = cli; v->license_alternatives.push_back (l); dependency_alternatives da; - da.push_back ({"icl", version_comparison{"1.3.3", comparison::gt}}); - da.push_back ({"ocl", version_comparison{"1.5.5", comparison::lt}}); + da.push_back ( + {"icl", version_comparison{version ("1.3.3"), comparison::gt}}); + + da.push_back ( + {"ocl", version_comparison{version ("1.5.5"), comparison::lt}}); v->dependencies.push_back (da); diff --git a/brep/view.cxx b/brep/view.cxx index 48c8188..222558a 100644 --- a/brep/view.cxx +++ b/brep/view.cxx @@ -82,7 +82,8 @@ namespace brep } else { - o << "
licenses:" << v->license_alternatives.size (); + o << "
version:" << v->version.string() + << "
licenses:" << v->license_alternatives.size (); for (const auto& la : v->license_alternatives) { @@ -104,9 +105,9 @@ namespace brep { o << " |" << d.package; - if (!d.version.null ()) + if (d.version) { - o << "," << d.version->value << "," + o << "," << d.version->value.string () << "," << static_cast (d.version->operation) << "|"; } } diff --git a/brep/wrapper-traits b/brep/wrapper-traits new file mode 100644 index 0000000..24bab18 --- /dev/null +++ b/brep/wrapper-traits @@ -0,0 +1,63 @@ +// file : bpkg/wrapper-traits -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BREP_WRAPPER_TRAITS +#define BREP_WRAPPER_TRAITS + +#include + +#include + +#include + +namespace odb +{ + template + class wrapper_traits> + { + public: + typedef T wrapped_type; + typedef butl::optional wrapper_type; + + // T can be const. + // + typedef + typename odb::details::meta::remove_const::result + unrestricted_wrapped_type; + + static const bool null_handler = true; + static const bool null_default = true; + + static bool + get_null (const wrapper_type& o) + { + return !o; + } + + static void + set_null (wrapper_type& o) + { + o = wrapper_type (); + } + + static const wrapped_type& + get_ref (const wrapper_type& o) + { + return *o; + } + + static unrestricted_wrapped_type& + set_ref (wrapper_type& o) + { + if (!o) + o = unrestricted_wrapped_type (); + + return const_cast (*o); + } + }; +} + +#include + +#endif // BREP_WRAPPER_TRAITS diff --git a/build.sh b/build.sh index ef4e11a..8ff422e 100755 --- a/build.sh +++ b/build.sh @@ -4,7 +4,11 @@ cd ./brep; cli --generate-file-scanner --suppress-usage --hxx-suffix "" \ --option-prefix "" ./options.cli; cd .. cd ./brep; odb -d pgsql --std c++11 --generate-query --generate-schema \ + --odb-epilogue '#include ' \ + --hxx-prologue '#include ' \ + -I .. -I ../../libbpkg -I ../../libbutl \ package; cd .. -g++ -shared $DEBUG -std=c++11 -I. -I/usr/include/apr-1 \ - -fPIC -o libbrep.so `find . -name '*.cxx'` -lodb-pgsql -lodb +g++ -shared $DEBUG -std=c++11 -I. -I/usr/include/apr-1 -I ../libbpkg \ + -I ../libbutl -L ../libbpkg/bpkg \ + -fPIC -o libbrep.so `find . -name '*.cxx'` -lbpkg -lodb-pgsql -lodb diff --git a/buildfile b/buildfile index 6104ee0..dede941 100644 --- a/buildfile +++ b/buildfile @@ -1,6 +1,8 @@ brep=brep/{diagnostics module options package package-odb search view} web=web/apache/{request service} -libso{brep}: cxx{$brep $web services} +import libs += libbpkg + +libso{brep}: cxx{$brep $web services} $libs cxx.poptions += -I$src_root cxx.libs += -lodb-pgsql -lodb diff --git a/etc/apachectl b/etc/apachectl index 8f58896..43e39ee 100755 --- a/etc/apachectl +++ b/etc/apachectl @@ -37,6 +37,10 @@ export AP_WWW_DIR export AP_CONFIG_DIR export AP_WORKSPACE_DIR +if test -n "$AP_LIB_DIRS"; then + export LD_LIBRARY_PATH=$AP_LIB_DIRS:$LD_LIBRARY_PATH +fi + mkdir -p "$AP_WORKSPACE_DIR" mkdir -p "$AP_LOG_DIR" diff --git a/etc/config b/etc/config index 31a03a2..ba428c5 100644 --- a/etc/config +++ b/etc/config @@ -18,6 +18,7 @@ AP_ADMIN_EMAIL=admin@cppget.org AP_LOG_LEVEL=trace1 AP_DB_HOST="$PG_WORKSPACE_DIR" AP_DB_PORT=$PG_PORT +AP_LIB_DIRS="$PROJECT_DIR/../libbutl/butl:$PROJECT_DIR/../libbpkg/bpkg" AP_MODULE_DIR="$PROJECT_DIR" AP_WWW_DIR="$PROJECT_DIR/www" AP_CONFIG_DIR="$CONFIG_DIR" -- cgit v1.1