From 6ce19c537bd9de8d3c9821841bc5ed680b762742 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 24 May 2018 00:25:45 +0300 Subject: Adapt to inventing package_name type --- INSTALL | 15 ++++++++ INSTALL-DEV | 15 ++++++++ clean/clean.cxx | 8 ++--- libbrep/build-extra.sql | 4 +-- libbrep/build.cxx | 2 +- libbrep/build.hxx | 11 +++--- libbrep/build.xml | 6 ++-- libbrep/common-traits.hxx | 65 ++++++++++++++++++++++++++++++++++ libbrep/common.hxx | 16 +++++++-- libbrep/odb.sh | 1 + libbrep/package-extra.sql | 10 +++--- libbrep/package-traits.hxx | 8 ++--- libbrep/package.cxx | 9 ++--- libbrep/package.hxx | 12 +++---- libbrep/package.xml | 24 ++++++------- load/load.cxx | 2 +- mod/build-config.cxx | 4 +-- mod/mod-build-force.cxx | 12 +++++-- mod/mod-build-log.cxx | 12 +++++-- mod/mod-build-result.cxx | 12 ++++--- mod/mod-build-task.cxx | 3 +- mod/mod-builds.cxx | 6 ++-- mod/mod-package-details.cxx | 64 +++++++++++++++++++--------------- mod/mod-package-version-details.cxx | 69 ++++++++++++++++++++++--------------- mod/mod-repository-root.cxx | 5 --- mod/page.cxx | 14 ++++---- mod/page.hxx | 8 ++--- tests/load/driver.cxx | 58 ++++++++++++++++++++----------- 28 files changed, 320 insertions(+), 155 deletions(-) create mode 100644 libbrep/common-traits.hxx diff --git a/INSTALL b/INSTALL index 7588197..4904dc7 100644 --- a/INSTALL +++ b/INSTALL @@ -179,6 +179,21 @@ Restart PostgreSQL: $ sudo systemctl restart postgresql +Enable creating database tables with columns of the case-insensitive character +string type: + +$ sudo sudo -u postgres psql -d brep_package + +CREATE EXTENSION citext; + +Exit psql (^D) + +$ sudo sudo -u postgres psql -d brep_build + +CREATE EXTENSION citext; + +Exit psql (^D) + 5. Create Database Schemes and Load Repositories diff --git a/INSTALL-DEV b/INSTALL-DEV index ed7cb13..b051cb2 100644 --- a/INSTALL-DEV +++ b/INSTALL-DEV @@ -97,6 +97,21 @@ To troubleshoot, see PostgreSQL logs, for example: $ sudo tail -f /var/log/postgresql/*.log +Enable creating database tables with columns of the case-insensitive character +string type: + +$ sudo sudo -u postgres psql -d brep_package + +CREATE EXTENSION citext; + +Exit psql (^D) + +$ sudo sudo -u postgres psql -d brep_build + +CREATE EXTENSION citext; + +Exit psql (^D) + 2. Create Database Schemes and Load the Repository diff --git a/clean/clean.cxx b/clean/clean.cxx index 00da55c..1071123 100644 --- a/clean/clean.cxx +++ b/clean/clean.cxx @@ -152,11 +152,11 @@ try using pkg_query = query; using prep_pkg_query = prepared_query; - string package_name; + package_name pkg_name; set package_versions; pkg_query pq ( - pkg_query::build_package::id.name == pkg_query::_ref (package_name)); + pkg_query::build_package::id.name == pkg_query::_ref (pkg_name)); prep_pkg_query pkg_prep_query ( conn->prepare_query ("package-query", pq)); @@ -195,9 +195,9 @@ try // if (!cleanup) { - if (package_name != b.package_name) + if (pkg_name != b.package_name) { - package_name = b.package_name; + pkg_name = b.package_name; package_versions.clear (); for (auto& p: pkg_prep_query.execute ()) diff --git a/libbrep/build-extra.sql b/libbrep/build-extra.sql index 4da75e5..96e355c 100644 --- a/libbrep/build-extra.sql +++ b/libbrep/build-extra.sql @@ -22,7 +22,7 @@ SERVER package_server OPTIONS (table_name 'repository'); -- -- CREATE FOREIGN TABLE build_package ( - name TEXT NOT NULL, + name CITEXT NOT NULL, version_epoch INTEGER NOT NULL, version_canonical_upstream TEXT NOT NULL, version_canonical_release TEXT NOT NULL COLLATE "C", @@ -37,7 +37,7 @@ SERVER package_server OPTIONS (table_name 'package'); -- -- CREATE FOREIGN TABLE build_package_constraints ( - name TEXT NOT NULL, + name CITEXT NOT NULL, version_epoch INTEGER NOT NULL, version_canonical_upstream TEXT NOT NULL, version_canonical_release TEXT NOT NULL COLLATE "C", diff --git a/libbrep/build.cxx b/libbrep/build.cxx index 9b379b7..6ed711c 100644 --- a/libbrep/build.cxx +++ b/libbrep/build.cxx @@ -55,7 +55,7 @@ namespace brep // build // build:: - build (string pnm, version pvr, + build (package_name_type pnm, version pvr, string cfg, string tnm, version tvr, optional afp, optional ach, diff --git a/libbrep/build.hxx b/libbrep/build.hxx index 81c3749..64eb10a 100644 --- a/libbrep/build.hxx +++ b/libbrep/build.hxx @@ -24,9 +24,9 @@ // Used by the data migration entries. // -#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 2 +#define LIBBREP_BUILD_SCHEMA_VERSION_BASE 3 -#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 2, closed) +#pragma db model version(LIBBREP_BUILD_SCHEMA_VERSION_BASE, 3, open) // We have to keep these mappings at the global scope instead of inside // the brep namespace because they need to be also effective in the @@ -161,12 +161,13 @@ namespace brep class build { public: - using timestamp_type = brep::timestamp; + using timestamp_type = brep::timestamp; + using package_name_type = brep::package_name; // Create the build object with the building state, non-existent status, // the timestamp set to now and the force state set to unforced. // - build (string package_name, version package_version, + build (package_name_type, version, string configuration, string toolchain_name, version toolchain_version, optional agent_fingerprint, @@ -176,7 +177,7 @@ namespace brep build_id id; - string& package_name; // Tracks id.package.name. + package_name_type& package_name; // Tracks id.package.name. upstream_version package_version; // Original of id.package.version. string& configuration; // Tracks id.configuration. string toolchain_name; diff --git a/libbrep/build.xml b/libbrep/build.xml index e765c00..04ffd78 100644 --- a/libbrep/build.xml +++ b/libbrep/build.xml @@ -1,7 +1,7 @@ - + - + @@ -39,7 +39,7 @@
- + diff --git a/libbrep/common-traits.hxx b/libbrep/common-traits.hxx new file mode 100644 index 0000000..b3c562e --- /dev/null +++ b/libbrep/common-traits.hxx @@ -0,0 +1,65 @@ +// file : libbrep/common-traits.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef LIBBREP_COMMON_TRAITS_HXX +#define LIBBREP_COMMON_TRAITS_HXX + +#include +#include // size_t +#include // move() + +#include + +#include + +namespace odb +{ + namespace pgsql + { + template <> + class value_traits: + value_traits + { + public: + using value_type = bpkg::package_name; + using query_type = bpkg::package_name; + using image_type = details::buffer; + + using base_type = value_traits; + + static void + set_value (value_type& v, + const details::buffer& b, + std::size_t n, + bool is_null) + { + std::string s; + base_type::set_value (s, b, n, is_null); + v = !s.empty () ? value_type (std::move (s)) : value_type (); + } + + static void + set_image (details::buffer& b, + std::size_t& n, + bool& is_null, + const value_type& v) + { + base_type::set_image (b, n, is_null, v.string ()); + } + }; + + template <> + struct type_traits + { + static const database_type_id db_type_id = id_string; + + struct conversion + { + static const char* to () {return "(?)::CITEXT";} + }; + }; + } +} + +#endif // LIBBREP_COMMON_TRAITS_HXX diff --git a/libbrep/common.hxx b/libbrep/common.hxx index 0950e7f..7860876 100644 --- a/libbrep/common.hxx +++ b/libbrep/common.hxx @@ -9,6 +9,8 @@ #include #include // static_assert +#include + #include #include @@ -188,14 +190,24 @@ namespace brep // extern const version wildcard_version; + // package_name + // + using bpkg::package_name; + + #pragma db value(package_name) type("CITEXT") + + #pragma db map type("CITEXT") as("TEXT") to("(?)::CITEXT") from("(?)::TEXT") + + // package_id + // #pragma db value struct package_id { - string name; + package_name name; canonical_version version; package_id () = default; - package_id (string n, const brep::version& v) + package_id (package_name n, const brep::version& v) : name (move (n)), version { v.epoch, v.canonical_upstream, v.canonical_release, v.revision} diff --git a/libbrep/odb.sh b/libbrep/odb.sh index 17a6ac4..3234899 100755 --- a/libbrep/odb.sh +++ b/libbrep/odb.sh @@ -12,6 +12,7 @@ lib="\ $odb $lib -d pgsql --std c++14 --generate-query \ --odb-epilogue '#include ' \ --hxx-prologue '#include ' \ + --hxx-prologue '#include ' \ -DLIBODB_BUILD2 -DLIBODB_PGSQL_BUILD2 \ -I .. -I ../../libbbot -I ../../libbpkg -I ../../libbutl \ --include-with-brackets --include-prefix libbrep \ diff --git a/libbrep/package-extra.sql b/libbrep/package-extra.sql index 5c18da2..bd5a27b 100644 --- a/libbrep/package-extra.sql +++ b/libbrep/package-extra.sql @@ -17,9 +17,9 @@ -- -- DROP FUNCTION IF EXISTS to_tsvector(IN document weighted_text); -- -DROP FUNCTION IF EXISTS search_packages(IN query tsquery, INOUT name TEXT); +DROP FUNCTION IF EXISTS search_packages(IN query tsquery, INOUT name CITEXT); DROP FUNCTION IF EXISTS search_latest_packages(IN query tsquery); -DROP FUNCTION IF EXISTS latest_package(INOUT name TEXT); +DROP FUNCTION IF EXISTS latest_package(INOUT name CITEXT); DROP FUNCTION IF EXISTS latest_packages(); DROP TYPE IF EXISTS weighted_text CASCADE; @@ -50,7 +50,7 @@ $$ LANGUAGE SQL STABLE; -- not found. -- CREATE FUNCTION -latest_package(INOUT name TEXT, +latest_package(INOUT name CITEXT, OUT version_epoch INTEGER, OUT version_canonical_upstream TEXT, OUT version_canonical_release TEXT, @@ -69,7 +69,7 @@ $$ LANGUAGE SQL STABLE; -- CREATE FUNCTION search_latest_packages(IN query tsquery, - OUT name TEXT, + OUT name CITEXT, OUT version_epoch INTEGER, OUT version_canonical_upstream TEXT, OUT version_canonical_release TEXT, @@ -93,7 +93,7 @@ $$ LANGUAGE SQL STABLE; -- CREATE FUNCTION search_packages(IN query tsquery, - INOUT name TEXT, + INOUT name CITEXT, OUT version_epoch INTEGER, OUT version_canonical_upstream TEXT, OUT version_canonical_release TEXT, diff --git a/libbrep/package-traits.hxx b/libbrep/package-traits.hxx index 56c8cec..6045633 100644 --- a/libbrep/package-traits.hxx +++ b/libbrep/package-traits.hxx @@ -1,9 +1,9 @@ -// file : brep/package-traits -*- C++ -*- +// file : libbrep/package-traits.hxx -*- C++ -*- // copyright : Copyright (c) 2014-2018 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -#ifndef BREP_PACKAGE_TRAITS -#define BREP_PACKAGE_TRAITS +#ifndef LIBBREP_PACKAGE_TRAITS +#define LIBBREP_PACKAGE_TRAITS #include // size_t @@ -35,4 +35,4 @@ namespace odb } } -#endif // BREP_PACKAGE_TRAITS +#endif // LIBBREP_PACKAGE_TRAITS diff --git a/libbrep/package.cxx b/libbrep/package.cxx index 984f36b..7d94422 100644 --- a/libbrep/package.cxx +++ b/libbrep/package.cxx @@ -15,7 +15,7 @@ namespace brep { // dependency // - string dependency:: + package_name dependency:: name () const { return package.object_id ().name; @@ -47,7 +47,7 @@ namespace brep // package // package:: - package (string nm, + package (package_name nm, version_type vr, priority_type pr, string sm, @@ -97,7 +97,7 @@ namespace brep } package:: - package (string nm, + package (package_name nm, version_type vr, shared_ptr rp) : id (move (nm), vr), @@ -123,7 +123,8 @@ namespace brep // Probably drop-box would be better as also tells what are // the available internal repositories. // - string k (id.name + " " + version.string () + " " + version.string (true)); + string k (id.name.string () + " " + version.string () + " " + + version.string (true)); // Add tags to keywords. // diff --git a/libbrep/package.hxx b/libbrep/package.hxx index 98e8178..c6e1162 100644 --- a/libbrep/package.hxx +++ b/libbrep/package.hxx @@ -19,9 +19,9 @@ // Used by the data migration entries. // -#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 5 +#define LIBBREP_PACKAGE_SCHEMA_VERSION_BASE 6 -#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 5, closed) +#pragma db model version(LIBBREP_PACKAGE_SCHEMA_VERSION_BASE, 6, open) namespace brep { @@ -125,7 +125,7 @@ namespace brep // Prerequisite package name. // - string + package_name name () const; // Database mapping. @@ -298,7 +298,7 @@ namespace brep // Create internal package object. Note that for stubs the build // constraints are meaningless, and so not saved. // - package (string name, + package (package_name name, version_type, priority_type, string summary, @@ -327,7 +327,7 @@ namespace brep // The only package information required to compose such a link is the // package name, version, and repository location. // - package (string name, version_type, shared_ptr); + package (package_name name, version_type, shared_ptr); bool internal () const noexcept {return internal_repository != nullptr;} @@ -492,7 +492,7 @@ namespace brep double rank; }; - #pragma db view query("/*CALL*/ SELECT count(*) FROM search_packages(?)") + #pragma db view query("/*CALL*/ SELECT count(*) FROM search_packages(?)") struct package_count { size_t result; diff --git a/libbrep/package.xml b/libbrep/package.xml index 1c85e49..9b83bb2 100644 --- a/libbrep/package.xml +++ b/libbrep/package.xml @@ -1,5 +1,5 @@ - +
@@ -70,7 +70,7 @@
- + @@ -118,7 +118,7 @@
- + @@ -151,7 +151,7 @@
- + @@ -182,7 +182,7 @@
- + @@ -215,7 +215,7 @@
- + @@ -250,14 +250,14 @@
- + - + @@ -313,7 +313,7 @@
- + @@ -348,7 +348,7 @@
- + @@ -379,7 +379,7 @@
- + @@ -415,7 +415,7 @@
- + diff --git a/load/load.cxx b/load/load.cxx index 6318d97..e63f1f5 100644 --- a/load/load.cxx +++ b/load/load.cxx @@ -384,7 +384,7 @@ load_packages (const shared_ptr& rp, database& db) // if (pda.buildtime && !pda.empty ()) { - const string& n (pda.front ().name); + const package_name& n (pda.front ().name); if (n == "build2" || n == "bpkg") continue; } diff --git a/mod/build-config.cxx b/mod/build-config.cxx index c460b2f..84562e7 100644 --- a/mod/build-config.cxx +++ b/mod/build-config.cxx @@ -118,7 +118,7 @@ namespace brep // the package version into the URL path part and so don't encode it. // string url (host + root.representation () + - mime_url_encode (b.package_name, false) + '/' + + mime_url_encode (b.package_name.string (), false) + '/' + b.package_version.string () + "/log/" + mime_url_encode (b.configuration, false) + '/' + b.toolchain_version.string ()); @@ -141,7 +141,7 @@ namespace brep // encoded by design. // return host + root.string () + - "?build-force&pn=" + mime_url_encode (b.package_name) + + "?build-force&pn=" + mime_url_encode (b.package_name.string ()) + "&pv=" + b.package_version.string () + "&cf=" + mime_url_encode (b.configuration) + "&tc=" + b.toolchain_version.string () + "&reason="; diff --git a/mod/mod-build-force.cxx b/mod/mod-build-force.cxx index da063ea..af47b4c 100644 --- a/mod/mod-build-force.cxx +++ b/mod/mod-build-force.cxx @@ -77,10 +77,16 @@ handle (request& rq, response& rs) try { - string& p (params.package ()); + package_name p; - if (p.empty ()) - throw invalid_argument ("empty package name"); + try + { + p = package_name (move (params.package ())); + } + catch (const invalid_argument& e) + { + throw invalid_argument (string ("invalid package name: ") + e.what ()); + } // We accept the non-url-encoded version representation. Note that the // parameter is already url-decoded by the web server, so we just restore diff --git a/mod/mod-build-log.cxx b/mod/mod-build-log.cxx index 3fc24cc..c1eec4c 100644 --- a/mod/mod-build-log.cxx +++ b/mod/mod-build-log.cxx @@ -83,10 +83,16 @@ handle (request& rq, response& rs) auto i (lpath.begin ()); assert (i != lpath.end ()); - string name (*i++); + package_name name; - if (name.empty ()) - throw invalid_argument ("empty package name"); + try + { + name = package_name (*i++); + } + catch (const invalid_argument& e) + { + throw invalid_argument (string ("invalid package name: ") + e.what ()); + } assert (i != lpath.end ()); diff --git a/mod/mod-build-result.cxx b/mod/mod-build-result.cxx index 024502a..1253d14 100644 --- a/mod/mod-build-result.cxx +++ b/mod/mod-build-result.cxx @@ -117,9 +117,12 @@ handle (request& rq, response&) if (p == string::npos) throw invalid_argument ("no package version"); - string& name (rqm.result.name); - if (name.compare (0, name.size (), s, 0, p) != 0) - throw invalid_argument ("package name mismatch"); + package_name& name (rqm.result.name); + { + const string& n (name.string ()); + if (n.compare (0, n.size (), s, 0, p) != 0) + throw invalid_argument ("package name mismatch"); + } size_t b (p + 1); // Start of version. p = s.find ('/', b); // End of version. @@ -383,7 +386,8 @@ handle (request& rq, response&) try { string subj ((unforced ? "build " : "rebuild ") + - to_string (*b->status) + ": " + b->package_name + '/' + + to_string (*b->status) + ": " + + b->package_name.string () + '/' + b->package_version.string () + '/' + b->configuration + '/' + b->toolchain_name + '-' + b->toolchain_version.string ()); diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx index 8287865..f1e4cdb 100644 --- a/mod/mod-build-task.cxx +++ b/mod/mod-build-task.cxx @@ -181,7 +181,8 @@ handle (request& rq, response& rs) chrono::duration_cast ( b->timestamp.time_since_epoch ()).count ()); - string session (b->package_name + '/' + b->package_version.string () + + string session (b->package_name.string () + '/' + + b->package_version.string () + '/' + b->configuration + '/' + b->toolchain_version.string () + '/' + to_string (ts)); diff --git a/mod/mod-builds.cxx b/mod/mod-builds.cxx index 135aceb..e43739f 100644 --- a/mod/mod-builds.cxx +++ b/mod/mod-builds.cxx @@ -111,7 +111,8 @@ build_query (const brep::cstrings& configs, const brep::params::builds& params) // Package name. // if (!params.name ().empty ()) - q = q && qb::id.package.name.like (transform (params.name ())); + q = q && qb::id.package.name.like ( + package_name (transform (params.name ()), package_name::raw_string)); // Package version. // @@ -214,7 +215,8 @@ package_query (const brep::params::builds& params) // Package name. // if (!params.name ().empty ()) - q = q && P::id.name.like (transform (params.name ())); + q = q && P::id.name.like ( + package_name (transform (params.name ()), package_name::raw_string)); // Package version. // diff --git a/mod/mod-package-details.cxx b/mod/mod-package-details.cxx index 7c825d1..c56d91a 100644 --- a/mod/mod-package-details.cxx +++ b/mod/mod-package-details.cxx @@ -50,7 +50,7 @@ init (scanner& s) template static inline query -search_params (const brep::string& n, const brep::string& q) +search_params (const brep::package_name& n, const brep::string& q) { using query = query; @@ -74,9 +74,6 @@ handle (request& rq, response& rs) const size_t res_page (options_->search_results ()); const dir_path& root (options_->root ()); - const string& name (*rq.path ().rbegin ()); - const string ename (mime_url_encode (name, false)); - params::package_details params; bool full; @@ -96,6 +93,31 @@ handle (request& rq, response& rs) size_t page (params.page ()); const string& squery (params.query ()); + session sn; + transaction t (package_db_->begin ()); + + shared_ptr pkg; + + try + { + package_name n (*rq.path ().rbegin ()); + + latest_package lp; + if (!package_db_->query_one ( + query ("(" + query::_val (n) + ")"), + lp)) + throw invalid_request (404, "Package '" + n.string () + "' not found"); + + pkg = package_db_->load (lp.id); + } + catch (const invalid_argument& ) + { + throw invalid_request (400, "invalid package name format"); + } + + const package_name& name (pkg->id.name); + const string ename (mime_url_encode (name.string (), false)); + auto url = [&ename] (bool f = false, const string& q = "", size_t p = 0, @@ -111,7 +133,7 @@ handle (request& rq, response& rs) return u; }; - xml::serializer s (rs.content (), name); + xml::serializer s (rs.content (), name.string ()); s << HTML << HEAD @@ -140,26 +162,12 @@ handle (request& rq, response& rs) if (full) s << CLASS("full"); - s << DIV(ID="heading") - << H1 << A(HREF=url ()) << name << ~A << ~H1 - << A(HREF=url (!full, squery, page)) - << (full ? "[brief]" : "[full]") - << ~A - << ~DIV; - - session sn; - transaction t (package_db_->begin ()); - - shared_ptr pkg; - { - latest_package lp; - if (!package_db_->query_one ( - query( - "(" + query::_val (name) + ")"), lp)) - throw invalid_request (404, "Package '" + name + "' not found"); - - pkg = package_db_->load (lp.id); - } + s << DIV(ID="heading") + << H1 << A(HREF=url ()) << name << ~A << ~H1 + << A(HREF=url (!full, squery, page)) + << (full ? "[brief]" : "[full]") + << ~A + << ~DIV; const auto& licenses (pkg->license_alternatives); @@ -182,10 +190,10 @@ handle (request& rq, response& rs) << TR_URL (pkg->url); if (pkg->doc_url) - s << TR_URL (*pkg->doc_url, "doc-url"); + s << TR_URL (*pkg->doc_url, "doc-url"); if (pkg->src_url) - s << TR_URL (*pkg->src_url, "src-url"); + s << TR_URL (*pkg->src_url, "src-url"); s << TR_EMAIL (pkg->email) << TR_TAGS (pkg->tags, root) @@ -226,7 +234,7 @@ handle (request& rq, response& rs) // vector> class, so comments are not considered. // if (p->license_alternatives != licenses) - s << TR_LICENSE (p->license_alternatives); + s << TR_LICENSE (p->license_alternatives); assert (p->internal ()); diff --git a/mod/mod-package-version-details.cxx b/mod/mod-package-version-details.cxx index 2683388..2134cc6 100644 --- a/mod/mod-package-version-details.cxx +++ b/mod/mod-package-version-details.cxx @@ -83,10 +83,18 @@ handle (request& rq, response& rs) throw invalid_request (400, "invalid package version format"); } - const string& sver (ver.string ()); - assert (i != rq.path ().rend ()); - const string& name (*i); + + package_name pn; + + try + { + pn = package_name (*i); + } + catch (const invalid_argument& ) + { + throw invalid_request (400, "invalid package name format"); + } params::package_version_details params; bool full; @@ -104,6 +112,8 @@ handle (request& rq, response& rs) throw invalid_request (400, e.what ()); } + const string& sver (ver.string ()); + auto url = [&sver] (bool f = false, const string& a = "") -> string { string u (sver); @@ -113,6 +123,32 @@ handle (request& rq, response& rs) return u; }; + bool not_found (false); + shared_ptr pkg; + + session sn; + transaction t (package_db_->begin ()); + + try + { + pkg = package_db_->load (package_id (pn, ver)); + + // If the requested package turned up to be an "external" one just + // respond that no "internal" package is present. + // + not_found = !pkg->internal (); + } + catch (const object_not_persistent& ) + { + not_found = true; + } + + if (not_found) + throw invalid_request ( + 404, "Package '" + pn.string () + ' ' + sver + "' not found"); + + const string& name (pkg->id.name.string ()); + const string title (name + " " + sver); xml::serializer s (rs.content (), title); @@ -139,29 +175,6 @@ handle (request& rq, response& rs) << A(HREF=url (!full)) << (full ? "[brief]" : "[full]") << ~A << ~DIV; - bool not_found (false); - shared_ptr pkg; - - session sn; - transaction t (package_db_->begin ()); - - try - { - pkg = package_db_->load (package_id (name, ver)); - - // If the requested package turned up to be an "external" one just - // respond that no "internal" package is present. - // - not_found = !pkg->internal (); - } - catch (const object_not_persistent& ) - { - not_found = true; - } - - if (not_found) - throw invalid_request (404, "Package '" + title + "' not found"); - s << H2 << pkg->summary << ~H2; static const string id ("description"); @@ -256,8 +269,8 @@ handle (request& rq, response& rs) : p->other_repositories[0].load ()); const auto& dcon (d.constraint); - const string& dname (p->id.name); - string ename (mime_url_encode (dname, false)); + const package_name& dname (p->id.name); + string ename (mime_url_encode (dname.string (), false)); if (r->url) { diff --git a/mod/mod-repository-root.cxx b/mod/mod-repository-root.cxx index e9c491a..aaf6988 100644 --- a/mod/mod-repository-root.cxx +++ b/mod/mod-repository-root.cxx @@ -343,11 +343,6 @@ namespace brep // // If any of the checks fails, then the handling is declined. // - // @@ Shouldn't we validate that the package name is not "@", is not - // digit-only, does not start with '.' while parsing and serializing - // the package manifest ? Probably also need to mention these - // constraints in the manifest.txt file. - // if (n != "@" && n.find_first_not_of ("0123456789") != string::npos && n[0] != '.') { diff --git a/mod/page.cxx b/mod/page.cxx index 706b42f..94e4f4f 100644 --- a/mod/page.cxx +++ b/mod/page.cxx @@ -188,7 +188,8 @@ namespace brep // Propagate search criteria to the package details page. // - << root_ / path (mime_url_encode (name_, false)) << query_param_ + << root_ / path (mime_url_encode (name_.string (), false)) + << query_param_ << ~HREF << name_ @@ -218,8 +219,9 @@ namespace brep else { assert (root_ != nullptr); - s << A(HREF=*root_ / dir_path (mime_url_encode (*package_, false)) / - path (version_)) + s << A(HREF=*root_ / + dir_path (mime_url_encode (package_->string (), false)) / + path (version_)) << version_; if (stub_) @@ -363,7 +365,7 @@ namespace brep // Suppress package name duplicates. // - set names; + set names; for (const auto& da: d) names.emplace (da.name ()); @@ -375,7 +377,7 @@ namespace brep bool first (true); for (const auto& da: d) { - string n (da.name ()); + package_name n (da.name ()); if (names.find (n) != names.end ()) { names.erase (n); @@ -393,7 +395,7 @@ namespace brep ? p->internal_repository.load () : p->other_repositories[0].load ()); - auto en (mime_url_encode (n, false)); + auto en (mime_url_encode (n.string (), false)); if (r->url) s << A(HREF=*r->url + en) << n << ~A; diff --git a/mod/page.hxx b/mod/page.hxx index 51b4b92..2b8c31f 100644 --- a/mod/page.hxx +++ b/mod/page.hxx @@ -163,14 +163,14 @@ namespace brep class TR_NAME { public: - TR_NAME (const string& n, const string& q, const dir_path& r) + TR_NAME (const package_name& n, const string& q, const dir_path& r) : name_ (n), query_param_ (q), root_ (r) {} void operator() (xml::serializer&) const; private: - const string& name_; + const package_name& name_; const string& query_param_; const dir_path& root_; }; @@ -182,7 +182,7 @@ namespace brep public: // Display the version as a link to the package version details page. // - TR_VERSION (const string& p, const version& v, const dir_path& r) + TR_VERSION (const package_name& p, const version& v, const dir_path& r) : package_ (&p), version_ (v.string ()), stub_ (v.compare (wildcard_version, true) == 0), @@ -204,7 +204,7 @@ namespace brep operator() (xml::serializer&) const; private: - const string* package_; + const package_name* package_; string version_; bool stub_; const dir_path* root_; diff --git a/tests/load/driver.cxx b/tests/load/driver.cxx index b5f831c..3538863 100644 --- a/tests/load/driver.cxx +++ b/tests/load/driver.cxx @@ -35,7 +35,7 @@ check_location (shared_ptr& p) { if (p->internal ()) return p->location && *p->location == - path (p->id.name + "-" + p->version.string () + ".tar.gz"); + path (p->id.name.string () + "-" + p->version.string () + ".tar.gz"); else return !p->location; } @@ -194,7 +194,8 @@ main (int argc, char* argv[]) // libfoo-1.0 // shared_ptr fpv1 ( - db.load (package_id ("libfoo", version ("1.0")))); + db.load ( + package_id (package_name ("libfoo"), version ("1.0")))); assert (fpv1->summary == "The Foo Library"); assert (fpv1->tags.empty ()); @@ -227,7 +228,8 @@ main (int argc, char* argv[]) // libfoo-1.2.2 // shared_ptr fpv2 ( - db.load (package_id ("libfoo", version ("1.2.2")))); + db.load ( + package_id (package_name ("libfoo"), version ("1.2.2")))); assert (fpv2->summary == "The Foo library"); assert (fpv2->tags == strings ({"c++", "foo"})); @@ -253,7 +255,8 @@ main (int argc, char* argv[]) auto dep = [&db] ( const char* n, const optional& c) -> dependency { - return {lazy_shared_ptr (db, package_id (n, version ())), c}; + return {lazy_shared_ptr ( + db, package_id (package_name (n), version ())), c}; }; assert (fpv2->dependencies[0][0] == @@ -278,7 +281,8 @@ main (int argc, char* argv[]) // libfoo-1.2.2-alpha.1 // shared_ptr fpv2a ( - db.load (package_id ("libfoo", version ("1.2.2-alpha.1")))); + db.load ( + package_id (package_name ("libfoo"), version ("1.2.2-alpha.1")))); assert (fpv2a->summary == "The Foo library"); assert (fpv2a->tags == strings ({"c++", "foo"})); @@ -347,7 +351,8 @@ main (int argc, char* argv[]) // libfoo-1.2.3-4 // shared_ptr fpv3 ( - db.load (package_id ("libfoo", version ("1.2.3+4")))); + db.load ( + package_id (package_name ("libfoo"), version ("1.2.3+4")))); assert (fpv3->summary == "The Foo library"); assert (fpv3->tags == strings ({"c++", "foo"})); @@ -384,7 +389,8 @@ main (int argc, char* argv[]) // libfoo-1.2.4 // shared_ptr fpv4 ( - db.load (package_id ("libfoo", version ("1.2.4")))); + db.load ( + package_id (package_name ("libfoo"), version ("1.2.4")))); assert (fpv4->summary == "The Foo Library"); assert (fpv4->tags == strings ({"c++", "foo"})); @@ -451,7 +457,8 @@ main (int argc, char* argv[]) // Verify libstudxml package version. // shared_ptr xpv ( - db.load (package_id ("libstudxml", version ("1.0.0+1")))); + db.load ( + package_id (package_name ("libstudxml"), version ("1.0.0+1")))); assert (xpv->summary == "Modern C++ XML API"); assert (xpv->tags == strings ({"c++", "xml", "parser", "serializer", @@ -500,7 +507,8 @@ main (int argc, char* argv[]) // libfoo-1.2.4-1 // shared_ptr fpv5 ( - db.load (package_id ("libfoo", version ("1.2.4+1")))); + db.load ( + package_id (package_name ("libfoo"), version ("1.2.4+1")))); assert (fpv5->summary == "The Foo Math Library"); assert (fpv5->tags == strings ({"c++", "foo", "math"})); @@ -619,7 +627,8 @@ main (int argc, char* argv[]) // libexp-1+1.2 // shared_ptr epv ( - db.load (package_id ("libexp", version ("+1-1.2+1")))); + db.load ( + package_id (package_name ("libexp"), version ("+1-1.2+1")))); assert (epv->summary == "The exponent"); assert (epv->tags == strings ({"c++", "exponent"})); @@ -670,7 +679,7 @@ main (int argc, char* argv[]) // libpq-0 // shared_ptr qpv ( - db.load (package_id ("libpq", version ("0")))); + db.load (package_id (package_name ("libpq"), version ("0")))); assert (qpv->summary == "PostgreSQL C API client library"); @@ -705,7 +714,8 @@ main (int argc, char* argv[]) // libbar-2.4.0+3 // shared_ptr bpv ( - db.load (package_id ("libbar", version ("2.4.0+3")))); + db.load ( + package_id (package_name ("libbar"), version ("2.4.0+3")))); assert (check_external (*bpv)); assert (bpv->other_repositories.size () == 1); @@ -717,7 +727,8 @@ main (int argc, char* argv[]) // libfoo-0.1 // shared_ptr fpv0 ( - db.load (package_id ("libfoo", version ("0.1")))); + db.load ( + package_id (package_name ("libfoo"), version ("0.1")))); assert (check_external (*fpv0)); assert (fpv0->other_repositories.size () == 1); @@ -727,7 +738,8 @@ main (int argc, char* argv[]) // libfoo-1.2.4-2 // shared_ptr fpv6 ( - db.load (package_id ("libfoo", version ("1.2.4+2")))); + db.load ( + package_id (package_name ("libfoo"), version ("1.2.4+2")))); assert (check_external (*fpv6)); assert (fpv6->other_repositories.size () == 1); @@ -765,7 +777,8 @@ main (int argc, char* argv[]) // libmisc-2.4.0 // shared_ptr mpv0 ( - db.load (package_id ("libmisc", version ("2.4.0")))); + db.load ( + package_id (package_name ("libmisc"), version ("2.4.0")))); assert (check_external (*mpv0)); assert (mpv0->other_repositories.size () == 1); @@ -775,7 +788,8 @@ main (int argc, char* argv[]) // libmisc-2.3.0+1 // shared_ptr mpv1 ( - db.load (package_id ("libmisc", version ("2.3.0+1")))); + db.load ( + package_id (package_name ("libmisc"), version ("2.3.0+1")))); assert (check_external (*mpv1)); assert (mpv1->other_repositories.size () == 1); @@ -812,7 +826,8 @@ main (int argc, char* argv[]) // libexpat-5.1 // shared_ptr tpv ( - db.load (package_id ("libexpat", version ("5.1")))); + db.load ( + package_id (package_name ("libexpat"), version ("5.1")))); assert (check_external (*tpv)); assert (tpv->other_repositories.size () == 1); @@ -824,7 +839,8 @@ main (int argc, char* argv[]) // libgenx-1.0 // shared_ptr gpv ( - db.load (package_id ("libgenx", version ("1.0")))); + db.load ( + package_id (package_name ("libgenx"), version ("1.0")))); assert (check_external (*gpv)); assert (gpv->other_repositories.size () == 1); @@ -836,7 +852,8 @@ main (int argc, char* argv[]) // libmisc-1.0 // shared_ptr mpv2 ( - db.load (package_id ("libmisc", version ("1.0")))); + db.load ( + package_id (package_name ("libmisc"), version ("1.0")))); assert (check_external (*mpv2)); assert (mpv2->other_repositories.size () == 1); @@ -856,7 +873,8 @@ main (int argc, char* argv[]) transaction t (db.begin ()); shared_ptr bpv ( - db.load (package_id ("libbar", version ("2.4.0+3")))); + db.load ( + package_id (package_name ("libbar"), version ("2.4.0+3")))); assert (bpv->summary == "test"); -- cgit v1.1