diff options
-rw-r--r-- | mod/build-config-module.cxx | 3 | ||||
-rw-r--r-- | mod/mod-builds.cxx | 78 |
2 files changed, 58 insertions, 23 deletions
diff --git a/mod/build-config-module.cxx b/mod/build-config-module.cxx index d21849e..35d9c0e 100644 --- a/mod/build-config-module.cxx +++ b/mod/build-config-module.cxx @@ -361,6 +361,9 @@ namespace brep return false; } + // @@ Here we don't suppose the wildcard pattern to contain the bracket + // expressions, while we probably should. + // path build_config_module:: dash_components_to_path (const string& s) { diff --git a/mod/mod-builds.cxx b/mod/mod-builds.cxx index 71e7f7b..d446133 100644 --- a/mod/mod-builds.cxx +++ b/mod/mod-builds.cxx @@ -13,7 +13,8 @@ #include <odb/transaction.hxx> #include <libbutl/timestamp.mxx> // to_string() -#include <libbutl/filesystem.mxx> // path_match() +#include <libbutl/filesystem.mxx> // path_match(), path_pattern(), literal(), + // path_pattern_iterator #include <libbbot/manifest.hxx> // to_result_status(), to_string(result_status) @@ -66,32 +67,66 @@ init (scanner& s) options_->root (dir_path ("/")); } -// Transform the wildcard to the LIKE-pattern. +// Transform the wildcard to the SIMILAR TO-pattern. // static string -transform (const string& s) +transform (const string& pattern) { - if (s.empty ()) + if (pattern.empty ()) return "%"; string r; - for (char c: s) + for (const path_pattern_char& pc: path_pattern_iterator (pattern)) { - switch (c) + switch (pc.type) { - case '*': c = '%'; break; - case '?': c = '_'; break; - case '\\': - case '%': - case '_': r += '\\'; break; - } + case path_pattern_char_type::question_mark: r += '_'; break; + case path_pattern_char_type::star: r += '%'; break; + case path_pattern_char_type::bracket_expr: + { + size_t n (r.size ()); + r.append (pc.begin, pc.end); - r += c; + // Translate the inverse character, if present. + // + if (r[n + 1] == '!') + r[n + 1] = '^'; + + break; + } + case path_pattern_char_type::literal: + { + char c (literal (pc)); + + // Note that '.' is not a special character for SIMILAR TO. + // + switch (c) + { + case '\\': + case '%': + case '_': + case '|': + case '+': + case '{': + case '(': r += '\\'; break; + } + + r += c; + break; + } + } } return r; } +template <typename T, typename C> +static inline query<T> +match (const C qc, const string& pattern) +{ + return qc + "SIMILAR TO" + query<T>::_val (transform (pattern)); +} + template <typename T> static inline query<T> build_query (const brep::cstrings* configs, @@ -124,8 +159,7 @@ build_query (const brep::cstrings* configs, // Package name. // if (!params.name ().empty ()) - q = q && pid.name.like (package_name (transform (params.name ()), - package_name::raw_string)); + q = q && match<T> (pid.name, params.name ()); // Package version. // @@ -167,17 +201,17 @@ build_query (const brep::cstrings* configs, // Build configuration name. // if (!params.configuration ().empty ()) - q = q && qb::id.configuration.like (transform (params.configuration ())); + q = q && match<T> (qb::id.configuration, params.configuration ()); // Build machine name. // if (!params.machine ().empty ()) - q = q && qb::machine.like (transform (params.machine ())); + q = q && match<T> (qb::machine, params.machine ()); // Build target. // if (!params.target ().empty ()) - q = q && qb::target.like (transform (params.target ())); + q = q && match<T> (qb::target, params.target ()); // Build result. // @@ -250,8 +284,7 @@ package_query (const brep::params::builds& params, // Package name. // if (!params.name ().empty ()) - q = q && qp::id.name.like ( - package_name (transform (params.name ()), package_name::raw_string)); + q = q && match<T> (qp::id.name, params.name ()); // Package version. // @@ -466,9 +499,8 @@ handle (request& rq, response& rs) // We will not display hidden configurations, unless the configuration is // specified explicitly. // - bool exclude_hidden ( - params.configuration ().empty () || - params.configuration ().find_first_of ("*?") != string::npos); + bool exclude_hidden (params.configuration ().empty () || + path_pattern (params.configuration ())); cstrings conf_names; |