aboutsummaryrefslogtreecommitdiff
path: root/mod
diff options
context:
space:
mode:
Diffstat (limited to 'mod')
-rw-r--r--mod/mod-build-log.cxx7
-rw-r--r--mod/mod-builds.cxx68
-rw-r--r--mod/mod-packages.cxx35
-rw-r--r--mod/options.cli7
-rw-r--r--mod/page.cxx18
-rw-r--r--mod/page.hxx23
6 files changed, 124 insertions, 34 deletions
diff --git a/mod/mod-build-log.cxx b/mod/mod-build-log.cxx
index 70e2c7e..ee5d1b2 100644
--- a/mod/mod-build-log.cxx
+++ b/mod/mod-build-log.cxx
@@ -212,10 +212,13 @@ handle (request& rq, response& rs)
//
ostream& os (rs.content (200, "text/plain;charset=utf-8", false));
- auto print_header = [&os, &b] ()
+ auto print_header = [&os, &b, this] ()
{
- // @@ Should we print the tenant? How to call it if that's the case?
+ // Print the build tenant in the multi-tenant mode.
//
+ if (!b->tenant.empty ())
+ os << options_->tenant_name () << ": " << b->tenant << endl << endl;
+
os << "package: " << b->package_name << endl
<< "version: " << b->package_version << endl
<< "toolchain: " << b->toolchain_name << '-' << b->toolchain_version
diff --git a/mod/mod-builds.cxx b/mod/mod-builds.cxx
index d2e3a25..a55b6f9 100644
--- a/mod/mod-builds.cxx
+++ b/mod/mod-builds.cxx
@@ -94,7 +94,7 @@ template <typename T>
static inline query<T>
build_query (const brep::cstrings& configs,
const brep::params::builds& params,
- const brep::optional<string>& tenant)
+ const brep::optional<brep::string>& tenant)
{
using namespace brep;
using query = query<T>;
@@ -207,12 +207,16 @@ build_query (const brep::cstrings& configs,
template <typename T, typename P = typename query<T>::build_package>
static inline query<T>
-package_query (const brep::params::builds& params, const string& tenant)
+package_query (const brep::params::builds& params,
+ const brep::optional<brep::string>& tenant)
{
using namespace brep;
using query = query<T>;
- query q (P::id.tenant == tenant);
+ query q (true);
+
+ if (tenant)
+ q = q && P::id.tenant == *tenant;
// Note that there is no error reported if the filter parameters parsing
// fails. Instead, it is considered that no packages match such a query.
@@ -281,6 +285,7 @@ handle (request& rq, response& rs)
const size_t page_configs (options_->build_configurations ());
const string& host (options_->host ());
const dir_path& root (options_->root ());
+ const string& tenant_name (options_->tenant_name ());
params::builds params;
@@ -321,18 +326,25 @@ handle (request& rq, response& rs)
<< DIV_HEADER (options_->logo (), options_->menu (), root, tenant)
<< DIV(ID="content");
+ // If the tenant is empty then we are in the global view and will display
+ // builds from all the tenants.
+ //
+ optional<string> tn;
+ if (!tenant.empty ())
+ tn = tenant;
+
// Return the list of distinct toolchain name/version pairs. The build db
// transaction must be started.
//
using toolchains = vector<pair<string, version>>;
- auto query_toolchains = [this] () -> toolchains
+ auto query_toolchains = [this, &tn] () -> toolchains
{
using query = query<toolchain>;
toolchains r;
for (auto& t: build_db_->query<toolchain> (
- (query::id.package.tenant == tenant) +
+ (tn ? query::id.package.tenant == *tn : query (true)) +
"ORDER BY" + query::toolchain_name +
order_by_version_desc (query::id.toolchain_version, false)))
r.emplace_back (move (t.name), move (t.version));
@@ -428,7 +440,7 @@ handle (request& rq, response& rs)
transaction t (build_db_->begin ());
count = build_db_->query_value<package_build_count> (
- build_query<package_build_count> (*build_conf_names_, params, tenant));
+ build_query<package_build_count> (*build_conf_names_, params, tn));
// Print the filter form.
//
@@ -443,7 +455,7 @@ handle (request& rq, response& rs)
//
s << DIV;
for (auto& pb: build_db_->query<package_build> (
- build_query<package_build> (*build_conf_names_, params, tenant) +
+ build_query<package_build> (*build_conf_names_, params, tn) +
"ORDER BY" + query<package_build>::build::timestamp + "DESC" +
"OFFSET" + to_string (page * page_configs) +
"LIMIT" + to_string (page_configs)))
@@ -461,8 +473,8 @@ handle (request& rq, response& rs)
s << TABLE(CLASS="proplist build")
<< TBODY
- << TR_NAME (b.package_name, string (), root, tenant)
- << TR_VERSION (b.package_name, b.package_version, root, tenant)
+ << TR_NAME (b.package_name, string (), root, b.tenant)
+ << TR_VERSION (b.package_name, b.package_version, root, b.tenant)
<< TR_VALUE ("toolchain",
b.toolchain_name + '-' +
b.toolchain_version.string ())
@@ -470,8 +482,15 @@ handle (request& rq, response& rs)
<< TR_VALUE ("machine", b.machine)
<< TR_VALUE ("target", b.target.string ())
<< TR_VALUE ("timestamp", ts)
- << TR_BUILD_RESULT (b, host, root)
- << ~TBODY
+ << TR_BUILD_RESULT (b, host, root);
+
+ // In the global view mode add the tenant builds link. Note that the
+ // global view (and the link) makes sense only in the multi-tenant mode.
+ //
+ if (!tn && !b.tenant.empty ())
+ s << TR_TENANT (tenant_name, "builds", root, b.tenant);
+
+ s << ~TBODY
<< ~TABLE;
}
s << ~DIV;
@@ -589,12 +608,12 @@ handle (request& rq, response& rs)
size_t nmax (
config_toolchains.size () *
build_db_->query_value<buildable_package_count> (
- package_query<buildable_package_count> (params, tenant)));
+ package_query<buildable_package_count> (params, tn)));
size_t ncur = build_db_->query_value<package_build_count> (
build_query<package_build_count> (*build_conf_names_,
bld_params,
- tenant));
+ tn));
// From now we will be using specific package name and version for each
// build database query.
@@ -641,7 +660,7 @@ handle (request& rq, response& rs)
//
using query = query<build_constrained_package>;
query q (package_query<build_constrained_package, query> (params,
- tenant));
+ tn));
for (const auto& p: build_db_->query<build_constrained_package> (q))
{
@@ -696,18 +715,17 @@ handle (request& rq, response& rs)
using pkg_query = query<buildable_package>;
using prep_pkg_query = prepared_query<buildable_package>;
- pkg_query pq (package_query<buildable_package> (params, tenant));
+ pkg_query pq (package_query<buildable_package> (params, tn));
// Specify the portion. Note that we will still be querying packages in
// chunks, not to hold locks for too long.
//
size_t offset (0);
- // @@ TENANT: use tenant for sorting when add support for global view.
- //
pq += "ORDER BY" +
pkg_query::build_package::id.name +
order_by_version_desc (pkg_query::build_package::id.version, false) +
+ "," + pkg_query::build_package::id.tenant +
"OFFSET" + pkg_query::_ref (offset) + "LIMIT 50";
connection_ptr conn (build_db_->connection ());
@@ -834,14 +852,22 @@ handle (request& rq, response& rs)
s << TABLE(CLASS="proplist build")
<< TBODY
- << TR_NAME (id.name, string (), root, tenant)
- << TR_VERSION (id.name, p.version, root, tenant)
+ << TR_NAME (id.name, string (), root, id.tenant)
+ << TR_VERSION (id.name, p.version, root, id.tenant)
<< TR_VALUE ("toolchain",
string (ct.toolchain_name) + '-' +
ct.toolchain_version.string ())
<< TR_VALUE ("config", ct.configuration)
- << TR_VALUE ("target", i->second->target.string ())
- << ~TBODY
+ << TR_VALUE ("target", i->second->target.string ());
+
+ // In the global view mode add the tenant builds link. Note that
+ // the global view (and the link) makes sense only in the
+ // multi-tenant mode.
+ //
+ if (!tn && !id.tenant.empty ())
+ s << TR_TENANT (tenant_name, "builds", root, id.tenant);
+
+ s << ~TBODY
<< ~TABLE;
if (--print == 0) // Bail out the configuration loop.
diff --git a/mod/mod-packages.cxx b/mod/mod-packages.cxx
index 1515a53..27e1270 100644
--- a/mod/mod-packages.cxx
+++ b/mod/mod-packages.cxx
@@ -67,7 +67,7 @@ init (scanner& s)
template <typename T>
static inline query<T>
-search_param (const brep::string& q, const brep::string& t)
+search_param (const brep::string& q, const brep::optional<brep::string>& t)
{
using query = query<T>;
return "(" +
@@ -75,7 +75,7 @@ search_param (const brep::string& q, const brep::string& t)
? query ("NULL")
: "plainto_tsquery (" + query::_val (q) + ")") +
"," +
- query::_val (t) +
+ (!t ? query ("NULL") : query (query::_val (*t))) +
")";
}
@@ -89,6 +89,7 @@ handle (request& rq, response& rs)
const size_t res_page (options_->search_results ());
const dir_path& root (options_->root ());
const string& title (options_->search_title ());
+ const string& tenant_name (options_->tenant_name ());
params::packages params;
@@ -135,25 +136,30 @@ handle (request& rq, response& rs)
<< DIV_HEADER (options_->logo (), options_->menu (), root, tenant)
<< DIV(ID="content");
+ // If the tenant is empty then we are in the global view and will display
+ // packages from all the tenants.
+ //
+ optional<string> tn;
+ if (!tenant.empty ())
+ tn = tenant;
+
session sn;
transaction t (package_db_->begin ());
auto pkg_count (
package_db_->query_value<latest_package_count> (
- search_param<latest_package_count> (squery, tenant)));
+ search_param<latest_package_count> (squery, tn)));
s << FORM_SEARCH (squery, "packages")
<< DIV_COUNTER (pkg_count, "Package", "Packages");
// Enclose the subsequent tables to be able to use nth-child CSS selector.
//
- // @@ TENANT: use tenant for sorting when add support for global view.
- //
s << DIV;
for (const auto& pr:
package_db_->query<latest_package_search_rank> (
- search_param<latest_package_search_rank> (squery, tenant) +
- "ORDER BY rank DESC, name" +
+ search_param<latest_package_search_rank> (squery, tn) +
+ "ORDER BY rank DESC, name, tenant" +
"OFFSET" + to_string (page * res_page) +
"LIMIT" + to_string (res_page)))
{
@@ -161,13 +167,20 @@ handle (request& rq, response& rs)
s << TABLE(CLASS="proplist package")
<< TBODY
- << TR_NAME (p->name, equery, root, tenant)
+ << TR_NAME (p->name, equery, root, p->tenant)
<< TR_SUMMARY (p->summary)
<< TR_LICENSE (p->license_alternatives)
<< TR_TAGS (p->project, p->tags, root, tenant)
- << TR_DEPENDS (p->dependencies, root, tenant)
- << TR_REQUIRES (p->requirements)
- << ~TBODY
+ << TR_DEPENDS (p->dependencies, root, p->tenant)
+ << TR_REQUIRES (p->requirements);
+
+ // In the global view mode add the tenant packages link. Note that the
+ // global view (and the link) makes sense only in the multi-tenant mode.
+ //
+ if (!tn && !p->tenant.empty ())
+ s << TR_TENANT (tenant_name, "packages", root, p->tenant);
+
+ s << ~TBODY
<< ~TABLE;
}
s << ~DIV;
diff --git a/mod/options.cli b/mod/options.cli
index 5fbd117..c78af73 100644
--- a/mod/options.cli
+++ b/mod/options.cli
@@ -46,6 +46,13 @@ namespace brep
(\cb{http://example.org/})."
}
+ string tenant-name = "tenant"
+ {
+ "<name>",
+ "Name to call the tenant values on web pages. If not specified, then
+ \cb{tenant} is used."
+ }
+
uint16_t verbosity = 0
{
"<level>",
diff --git a/mod/page.cxx b/mod/page.cxx
index ce12da6..1b2faae 100644
--- a/mod/page.cxx
+++ b/mod/page.cxx
@@ -182,6 +182,24 @@ namespace brep
<< ~TR;
}
+ // TR_TENANT
+ //
+ void TR_TENANT::
+ operator() (serializer& s) const
+ {
+ s << TR(CLASS="tenant")
+ << TH << name_ << ~TH
+ << TD
+ << SPAN(CLASS="value")
+ << A
+ << HREF << tenant_dir (root_, tenant_) << '?' << service_ << ~HREF
+ << tenant_
+ << ~A
+ << ~SPAN
+ << ~TD
+ << ~TR;
+ }
+
// TR_NAME
//
void TR_NAME::
diff --git a/mod/page.hxx b/mod/page.hxx
index d9f4249..4b59e7d 100644
--- a/mod/page.hxx
+++ b/mod/page.hxx
@@ -162,6 +162,29 @@ namespace brep
const vector<pair<string, string>>& options_;
};
+ // Generates tenant id element.
+ //
+ // Displays a link to the service page for the specified tenant.
+ //
+ class TR_TENANT
+ {
+ public:
+ TR_TENANT (const string& n,
+ const string& s,
+ const dir_path& r,
+ const string& t)
+ : name_ (n), service_ (s), root_ (r), tenant_ (t) {}
+
+ void
+ operator() (xml::serializer&) const;
+
+ private:
+ const string& name_;
+ const string& service_;
+ const dir_path& root_;
+ const string& tenant_;
+ };
+
// Generates package name element with an optional search criteria. The
// search string should be url-encoded, if specified.
//