From 675e973bf8e0e24593552f596eb3d81e57e19c94 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 19 Sep 2015 15:12:48 +0200 Subject: Elaborate package search and package version search pages --- brep/package | 30 +++++++++++++-- brep/package-search.cxx | 41 ++++++++++----------- brep/package-version-search.cxx | 77 +++++++++++++------------------------- brep/page | 63 ++++++++++++++++++++++++++++--- brep/page.cxx | 82 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 205 insertions(+), 88 deletions(-) (limited to 'brep') diff --git a/brep/package b/brep/package index c383b82..75920c4 100644 --- a/brep/package +++ b/brep/package @@ -463,7 +463,6 @@ namespace brep struct max_package_version { using version_type = brep::version; - version_type version; void @@ -480,10 +479,33 @@ namespace brep get() set(_id (std::move (?))) }; - #pragma db view object(package) - struct package_count + #pragma db view object(package_version = version) \ + object(package_version = v: \ + version::id.data.package == v::id.data.package && \ + (version::id.data.epoch < v::id.data.epoch || \ + (version::id.data.epoch == v::id.data.epoch && \ + (version::id.data.canonical_upstream < \ + v::id.data.canonical_upstream || \ + (version::id.data.canonical_upstream == \ + v::id.data.canonical_upstream && \ + version::id.data.revision < v::id.data.revision))))) \ + object(package inner: version::id.data.package == package::name && \ + version::internal_repository.is_not_null () && \ + v::id.data.package.is_null ()) + struct internal_package { - #pragma db column("count(*)") + using package_type = brep::package; + std::shared_ptr package; + std::shared_ptr version; + }; + + #pragma db view object(package) \ + object(package_version: package_version::id.data.package == \ + package::name) \ + query(package_version::internal_repository.is_not_null () && (?)) + struct internal_package_count + { + #pragma db column("count(DISTINCT" + package::name + ")") std::size_t count; }; diff --git a/brep/package-search.cxx b/brep/package-search.cxx index 02a8547..a840687 100644 --- a/brep/package-search.cxx +++ b/brep/package-search.cxx @@ -71,14 +71,12 @@ namespace brep << HEAD << TITLE << title << ~TITLE << CSS_STYLE << ident - << pager_style () << ident - << "a {text-decoration: none;}" << ident - << "a:hover {text-decoration: underline;}" << ident + << A_STYLE () << ident + << PAGER_STYLE () << ident << ".packages {font-size: x-large;}" << ident << ".package {margin: 0.5em 0 0;}" << ident << ".name {font-size: x-large;}" << ident - << ".tags {margin: 0.1em 0 0;}" << ident - << ".tag {padding: 0 0.3em 0 0;}" + << ".dependencies {margin: 0.3em 0 0;}" << ident << ~CSS_STYLE << ~HEAD << BODY; @@ -92,7 +90,7 @@ namespace brep // @@ Query will include search criteria if specified. // - size_t pc (db_->query_value ().count); + size_t pc (db_->query_value ().count); s << DIV(CLASS="packages") << "Packages (" << pc << ")" @@ -102,15 +100,19 @@ namespace brep // and search index structure get implemented. Query will also // include search criteria if specified. // - using query = query; + using query = query; + auto r ( - db_->query ( - "ORDER BY" + query::name + + db_->query ( + "ORDER BY" + query::package::name + "OFFSET" + to_string (pr.page () * rop) + "LIMIT" + to_string (rop))); - for (const auto& p: r) + for (const auto& ip: r) { + const package& p = *ip.package; + const package_version& v = *ip.version; + s << DIV(CLASS="package") << DIV(CLASS="name") << A @@ -127,17 +129,12 @@ namespace brep << ~DIV << DIV(CLASS="summary") << p.summary - << ~DIV; - - if (!p.tags.empty ()) - { - s << DIV(CLASS="tags"); - - for (const auto& t: p.tags) - s << SPAN(CLASS="tag") << t << ~SPAN << " "; - - s << ~DIV; - } + << ~DIV + << DIV(CLASS="dependencies") + << "Dependencies: " << v.dependencies.size () + << ~DIV + << LICENSES (v.license_alternatives) + << TAGS (p.tags); s << ~DIV; } @@ -157,7 +154,7 @@ namespace brep return url; }); - s << pager (pr.page (), pc, rop, options_->pages_in_pager (), u) + s << PAGER (pr.page (), pc, rop, options_->pages_in_pager (), u) << ~BODY << ~HTML; } diff --git a/brep/package-version-search.cxx b/brep/package-version-search.cxx index bd01a46..336650e 100644 --- a/brep/package-version-search.cxx +++ b/brep/package-version-search.cxx @@ -7,7 +7,6 @@ #include #include // make_shared(), shared_ptr #include // size_t -#include #include @@ -71,19 +70,18 @@ namespace brep << HEAD << TITLE << title << ~TITLE << CSS_STYLE << ident - << pager_style () << ident - << "a {text-decoration: none;}" << ident - << "a:hover {text-decoration: underline;}" << ident + << A_STYLE () << ident + << PAGER_STYLE () << ident << ".name {font-size: xx-large; font-weight: bold;}" << ident << ".summary {font-size: x-large; margin: 0.2em 0 0;}" << ident - << ".url {font-size: small;}" << ident - << ".email {font-size: small;}" << ident + << ".url {font-size: 90%;}" << ident + << ".email {font-size: 90%;}" << ident << ".description {margin: 0.5em 0 0;}" << ident - << ".tags {margin: 0.5em 0 0;}" << ident - << ".tag {padding: 0 0.3em 0 0;}" << ident + << ".tags {margin: 0.3em 0 0;}" << ident << ".versions {font-size: x-large; margin: 0.5em 0 0;}" << ident << ".package_version {margin: 0.5em 0 0;}" << ident - << ".version {font-size: x-large;}" + << ".version {font-size: x-large;}" << ident + << ".priority {margin: 0.3em 0 0;}" << ~CSS_STYLE << ~HEAD << BODY; @@ -106,9 +104,8 @@ namespace brep << ~DIV << DIV(CLASS="summary") << p->summary - << ~DIV; - - s << DIV(CLASS="url") + << ~DIV + << DIV(CLASS="url") << A << HREF << p->url << ~HREF << p->url << ~A << ~DIV << DIV(CLASS="email") @@ -120,22 +117,19 @@ namespace brep << *p->description << ~DIV; - if (!p->tags.empty ()) - { - s << DIV(CLASS="tags"); + s << TAGS (p->tags); - for (const auto& t: p->tags) - s << SPAN(CLASS="tag") << t << ~SPAN << " "; + size_t pvc; + { + using query = query; - s << ~DIV; + // @@ Query will also include search criteria if specified. + // + pvc = db_->query_value ( + query::id.data.package == name && + query::internal_repository.is_not_null ()).count; } - // @@ Query will also include search criteria if specified. - // - size_t pvc ( - db_->query_value ( - query::id.data.package == name).count); - s << DIV(CLASS="versions") << "Versions (" << pvc << ")" << ~DIV; @@ -161,7 +155,9 @@ namespace brep // using query = query; auto r ( - db_->query ((query::id.data.package == name) + + db_->query ( + (query::id.data.package == name && + query::internal_repository.is_not_null ()) + "ORDER BY" + query::id.data.epoch + "DESC," + query::id.data.canonical_upstream + "DESC," + query::id.data.revision + "DESC " + @@ -170,11 +166,6 @@ namespace brep for (const auto& v: r) { - static const strings priority_names ( - {"low", "medium", "high", "security"}); - - assert (v.priority < priority_names.size ()); - const string& vs (v.version.string ()); s << DIV(CLASS="package_version") @@ -186,27 +177,11 @@ namespace brep << vs << ~A << ~DIV - << DIV(CLASS="priority") - << "Priority: " << priority_names[v.priority] + << PRIORITY (v.priority) + << DIV(CLASS="dependencies") + << "Dependencies: " << v.dependencies.size () << ~DIV - << DIV(CLASS="licenses") - << "Licenses: "; - - for (const auto& la: v.license_alternatives) - { - if (&la != &v.license_alternatives[0]) - s << " or "; - - for (const auto& l: la) - { - if (&l != &la[0]) - s << ", "; - - s << l; - } - } - - s << ~DIV + << LICENSES (v.license_alternatives) << ~DIV; } @@ -226,7 +201,7 @@ namespace brep return url; }); - s << pager (pr.page (), pvc, rop, options_->pages_in_pager (), u) + s << PAGER (pr.page (), pvc, rop, options_->pages_in_pager (), u) << ~BODY << ~HTML; } diff --git a/brep/page b/brep/page index 81b6da8..06f3350 100644 --- a/brep/page +++ b/brep/page @@ -11,19 +11,29 @@ #include +#include + namespace brep { // Page common building blocks. // - // Generates paging element block. + // A element default style. + // + struct A_STYLE + { + void + operator() (xml::serializer& s) const; + }; + + // Generates paging element. // - class pager + class PAGER { public: using get_url_type = std::function; - pager (std::size_t current_page, + PAGER (std::size_t current_page, std::size_t item_count, std::size_t item_per_page, std::size_t page_number_count, @@ -40,13 +50,56 @@ namespace brep get_url_type get_url_; }; - // Default pager element block style. + // PAGER element default style. // - struct pager_style + struct PAGER_STYLE { void operator() (xml::serializer& s) const; }; + + // Generates package tags element. + // + class TAGS + { + public: + TAGS (const strings& ts): tags_ (ts) {} + + void + operator() (xml::serializer& s) const; + + private: + const strings& tags_; + }; + + // Generates package version license alternatives element. + // + class LICENSES + { + public: + LICENSES (const license_alternatives& la) + : license_alternatives_ (la) {} + + void + operator() (xml::serializer& s) const; + + private: + const license_alternatives& license_alternatives_; + }; + + // Generates package version priority element. + // + class PRIORITY + { + public: + PRIORITY (const priority& pr): priority_ (pr) {} + + void + operator() (xml::serializer& s) const; + + private: + const priority& priority_; + }; } #endif // BREP_PAGE diff --git a/brep/page.cxx b/brep/page.cxx index 70c6d8c..ad93e7c 100644 --- a/brep/page.cxx +++ b/brep/page.cxx @@ -4,6 +4,7 @@ #include +#include #include // move() #include // min() @@ -11,16 +12,28 @@ #include +#include + using namespace std; using namespace xml; using namespace web::xhtml; namespace brep { - // pager + // A_STYLE + // + void A_STYLE:: + operator() (xml::serializer& s) const + { + const char* ident ("\n "); + s << "a {text-decoration: none;}" << ident + << "a:hover {text-decoration: underline;}"; + } + + // PAGER // - pager:: - pager (size_t current_page, + PAGER:: + PAGER (size_t current_page, size_t item_count, size_t item_per_page, size_t page_number_count, @@ -33,7 +46,7 @@ namespace brep { } - void pager:: + void PAGER:: operator() (serializer& s) const { if (item_count_ == 0 || item_per_page_ == 0) @@ -89,9 +102,9 @@ namespace brep } } - // pager_style + // PAGER_STYLE // - void pager_style:: + void PAGER_STYLE:: operator() (xml::serializer& s) const { const char* ident ("\n "); @@ -100,4 +113,61 @@ namespace brep << ".pg-page {padding: 0 0.3em 0 0;}" << ident << ".pg-cpage {padding: 0 0.3em 0 0; font-weight: bold;}"; } + + // LICENSES + // + void LICENSES:: + operator() (serializer& s) const + { + s << DIV(CLASS="licenses") + << "Licenses: "; + + for (const auto& la: license_alternatives_) + { + if (&la != &license_alternatives_[0]) + s << " | "; + + for (const auto& l: la) + { + if (&l != &la[0]) + s << " & "; + + s << l; + } + } + + s << ~DIV; + } + + // TAGS + // + void TAGS:: + operator() (serializer& s) const + { + if (!tags_.empty ()) + { + s << DIV(CLASS="tags") + << "Tags: "; + + for (const auto& t: tags_) + s << t << " "; + + s << ~DIV; + } + } + + // PRIORITY + // + void PRIORITY:: + operator() (serializer& s) const + { + static const strings priority_names ( + {"low", "medium", "high", "security"}); + + assert (priority_ < priority_names.size ()); + + s << DIV(CLASS="priority") + << "Priority: " << priority_names[priority_] + << ~DIV; + } } -- cgit v1.1