From: Baptiste Jonglez <[email protected]>

It is now possible to search for packages that depend on a given package,
for instance:

    /rpc/?v=5&type=search&by=depends&arg=ocaml

It is similarly possible to match on "makedepends", "checkdepends" and
"optdepends".

Signed-off-by: Baptiste Jonglez <[email protected]>
---
 doc/rpc.txt               |  8 +++++++-
 web/lib/aurjson.class.php | 33 +++++++++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/doc/rpc.txt b/doc/rpc.txt
index f353ff0..3148ebe 100644
--- a/doc/rpc.txt
+++ b/doc/rpc.txt
@@ -11,6 +11,10 @@ search argument and _field_ is one of the following values:
 * `name` (search by package name only)
 * `name-desc` (search by package name and description)
 * `maintainer` (search by package maintainer)
+* `depends` (search for packages that depend on _keywords_)
+* `makedepends` (search for packages that makedepend on _keywords_)
+* `optdepends` (search for packages that optdepend on _keywords_)
+* `checkdepends` (search for packages that checkdepend on _keywords_)
 
 The _by_ parameter can be skipped and defaults to `name-desc`.
 
@@ -30,7 +34,9 @@ Examples
 `search`::
   `/rpc/?v=5&type=search&arg=foobar`
 `search` by maintainer::
-  `/rpc/?v=5&type=search&search_by=maintainer&arg=john`
+  `/rpc/?v=5&type=search&by=maintainer&arg=john`
+`search` packages that have _boost_ as `makedepends`::
+  `/rpc/?v=5&type=search&by=makedepends&arg=boost`
 `search` with callback::
   `/rpc/?v=5&type=search&arg=foobar&callback=jsonp1192244621103`
 `info`::
diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php
index 9eeaafd..30bdc89 100644
--- a/web/lib/aurjson.class.php
+++ b/web/lib/aurjson.class.php
@@ -17,7 +17,8 @@ class AurJSON {
                'suggest-pkgbase', 'get-comment-form'
        );
        private static $exposed_fields = array(
-               'name', 'name-desc', 'maintainer'
+               'name', 'name-desc', 'maintainer',
+               'depends', 'makedepends', 'checkdepends', 'optdepends'
        );
        private static $fields_v1 = array(
                'Packages.ID', 'Packages.Name',
@@ -243,16 +244,27 @@ class AurJSON {
 
        /*
         * Retrieve package information (used in info, multiinfo, search and
-        * msearch requests).
+        * depends requests).
         *
         * @param $type The request type.
         * @param $where_condition An SQL WHERE-condition to filter packages.
+        * @param $join_depends Whether to add a SQL JOIN on the PackageDepends 
table.
+        *        It will produce duplicate packages unless $where_condition 
filters
+        *        the result appropriately.
         *
         * @return mixed Returns an array of package matches.
         */
-       private function process_query($type, $where_condition) {
+       private function process_query($type, $where_condition, 
$join_depends=false) {
                $max_results = config_get_int('options', 'max_rpc_results');
 
+               $additional_joins = "";
+               if ($join_depends) {
+                       $additional_joins .= "LEFT JOIN PackageDepends " .
+                                       "ON Packages.ID = 
PackageDepends.PackageID " .
+                                       "LEFT JOIN DependencyTypes " .
+                                       "ON PackageDepends.DepTypeID = 
DependencyTypes.ID";
+               }
+
                if ($this->version == 1) {
                        $fields = implode(',', self::$fields_v1);
                        $query = "SELECT {$fields} " .
@@ -264,6 +276,7 @@ class AurJSON {
                                "ON PackageLicenses.PackageID = Packages.ID " .
                                "LEFT JOIN Licenses " .
                                "ON Licenses.ID = PackageLicenses.LicenseID " .
+                               "${additional_joins} " .
                                "WHERE ${where_condition} " .
                                "AND PackageBases.PackagerUID IS NOT NULL " .
                                "LIMIT $max_results";
@@ -278,6 +291,7 @@ class AurJSON {
                                "ON PackageBases.ID = Packages.PackageBaseID " .
                                "LEFT JOIN Users " .
                                "ON PackageBases.MaintainerUID = Users.ID " .
+                               "${additional_joins} " .
                                "WHERE ${where_condition} " .
                                "AND PackageBases.PackagerUID IS NOT NULL " .
                                "LIMIT $max_results";
@@ -380,6 +394,7 @@ class AurJSON {
         * @return mixed Returns an array of package matches.
         */
        private function search($http_data) {
+               $join_depends = false;
                $keyword_string = $http_data['arg'];
 
                if (isset($http_data['by'])) {
@@ -407,9 +422,19 @@ class AurJSON {
                                $keyword_string = 
$this->dbh->quote($keyword_string);
                                $where_condition = "Users.Username = 
$keyword_string ";
                        }
+               } else if (in_array($search_by, ['depends', 'makedepends', 
'checkdepends', 'optdepends'])) {
+                       if (empty($keyword_string)) {
+                               return $this->json_error('Query arg is empty.');
+                       } else {
+                               $keyword_string = 
$this->dbh->quote($keyword_string);
+                               $search_string = $this->dbh->quote($search_by);
+                               $where_condition = "PackageDepends.DepName = 
$keyword_string AND ";
+                               $where_condition .= "DependencyTypes.Name = 
$search_string";
+                               $join_depends = true;
+                       }
                }
 
-               return $this->process_query('search', $where_condition);
+               return $this->process_query('search', $where_condition, 
$join_depends);
        }
 
        /*
-- 
2.16.1

Reply via email to