aboutsummaryrefslogtreecommitdiff
path: root/brep/mod-package-search.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-12-22 19:29:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-08 18:26:00 +0200
commitc715379c625935bd4b28bebb35f34721342cc7f3 (patch)
tree97e55364e786ab794514450e879006ee61ac8643 /brep/mod-package-search.cxx
parenteb16296f88ce0fdb4a98a08950b58a346a6e2bd9 (diff)
Source file names fixup
Diffstat (limited to 'brep/mod-package-search.cxx')
-rw-r--r--brep/mod-package-search.cxx148
1 files changed, 148 insertions, 0 deletions
diff --git a/brep/mod-package-search.cxx b/brep/mod-package-search.cxx
new file mode 100644
index 0000000..6d7bdd6
--- /dev/null
+++ b/brep/mod-package-search.cxx
@@ -0,0 +1,148 @@
+// file : brep/mod-package-search.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <brep/mod-package-search>
+
+#include <xml/serializer>
+
+#include <odb/session.hxx>
+#include <odb/database.hxx>
+#include <odb/transaction.hxx>
+
+#include <web/xhtml>
+#include <web/module>
+#include <web/mime-url-encoding>
+
+#include <brep/types>
+#include <brep/utility>
+
+#include <brep/page>
+#include <brep/options>
+#include <brep/package>
+#include <brep/database>
+#include <brep/package-odb>
+
+using namespace odb::core;
+using namespace brep::cli;
+
+void brep::package_search::
+init (scanner& s)
+{
+ MODULE_DIAG;
+
+ options_ = make_shared<options::package_search> (
+ s, unknown_mode::fail, unknown_mode::fail);
+
+ if (options_->root ().empty ())
+ options_->root (dir_path ("/"));
+
+ db_ = shared_database (*options_);
+}
+
+template <typename T>
+static inline query<T>
+search_param (const brep::string& q)
+{
+ using query = query<T>;
+ return "(" +
+ (q.empty ()
+ ? query ("NULL")
+ : "plainto_tsquery (" + query::_val (q) + ")") +
+ ")";
+}
+
+bool brep::package_search::
+handle (request& rq, response& rs)
+{
+ using namespace web::xhtml;
+
+ MODULE_DIAG;
+
+ // The module options object is not changed after being created once per
+ // server process.
+ //
+ static const size_t res_page (options_->search_results ());
+ static const dir_path& root (options_->root ());
+
+ params::package_search params;
+
+ try
+ {
+ name_value_scanner s (rq.parameters ());
+ params = params::package_search (s, unknown_mode::fail, unknown_mode::fail);
+ }
+ catch (const unknown_argument& e)
+ {
+ throw invalid_request (400, e.what ());
+ }
+
+ size_t page (params.page ());
+ const string& squery (params.query ());
+ string squery_param (squery.empty ()
+ ? ""
+ : "?q=" + web::mime_url_encode (squery));
+
+ static const string title ("Packages");
+ xml::serializer s (rs.content (), title);
+
+ s << HTML
+ << HEAD
+ << TITLE
+ << title;
+
+ if (!squery.empty ())
+ s << " " << squery;
+
+ s << ~TITLE
+ << CSS_LINKS (path ("package-search.css"), root)
+ << ~HEAD
+ << BODY
+ << DIV_HEADER (root)
+ << DIV(ID="content");
+
+ session sn;
+ transaction t (db_->begin ());
+
+ auto pkg_count (
+ db_->query_value<latest_package_count> (
+ search_param<latest_package_count> (squery)));
+
+ s << FORM_SEARCH (squery)
+ << DIV_COUNTER (pkg_count, "Package", "Packages");
+
+ // Enclose the subsequent tables to be able to use nth-child CSS selector.
+ //
+ s << DIV;
+ for (const auto& pr:
+ db_->query<latest_package_search_rank> (
+ search_param<latest_package_search_rank> (squery) +
+ "ORDER BY rank DESC, name" +
+ "OFFSET" + to_string (page * res_page) +
+ "LIMIT" + to_string (res_page)))
+ {
+ shared_ptr<package> p (db_->load<package> (pr.id));
+
+ s << TABLE(CLASS="proplist package")
+ << TBODY
+ << TR_NAME (p->id.name, squery_param, root)
+ << TR_SUMMARY (p->summary)
+ << TR_LICENSE (p->license_alternatives)
+ << TR_TAGS (p->tags, root)
+ << TR_DEPENDS (p->dependencies, root)
+ << TR_REQUIRES (p->requirements)
+ << ~TBODY
+ << ~TABLE;
+ }
+ s << ~DIV;
+
+ t.commit ();
+
+ s << DIV_PAGER (page, pkg_count, res_page, options_->search_pages (),
+ root.string () + squery_param)
+ << ~DIV
+ << ~BODY
+ << ~HTML;
+
+ return true;
+}