[PATCH] add rpc v6: support multiple _by_ fields
Li-Yu Yu
afg984 at gmail.com
Fri Jun 1 02:50:55 UTC 2018
---
web/lib/aurjson.class.php | 125 ++++++++++++++++++++++++++++++++++++--
1 file changed, 120 insertions(+), 5 deletions(-)
diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php
index c51e9c2..db11117 100644
--- a/web/lib/aurjson.class.php
+++ b/web/lib/aurjson.class.php
@@ -20,6 +20,14 @@ class AurJSON {
'name', 'name-desc', 'maintainer',
'depends', 'makedepends', 'checkdepends', 'optdepends'
);
+ private static $exposed_fields_v6 = array(
+ 'name', 'description', 'maintainer', 'provides',
+ );
+ private static $exposed_fields_map_v6 = array(
+ 'name' => 'Packages.Name',
+ 'description' => 'Packages.Description',
+ 'maintainer' => 'Packages.Maintainer',
+ );
private static $exposed_depfields = array(
'depends', 'makedepends', 'checkdepends', 'optdepends'
);
@@ -80,7 +88,7 @@ class AurJSON {
if (isset($http_data['v'])) {
$this->version = intval($http_data['v']);
}
- if ($this->version < 1 || $this->version > 5) {
+ if ($this->version < 1 || $this->version > 6) {
return $this->json_error('Invalid version specified.');
}
@@ -94,8 +102,21 @@ class AurJSON {
if (isset($http_data['search_by']) && !isset($http_data['by'])) {
$http_data['by'] = $http_data['search_by'];
}
- if (isset($http_data['by']) && !in_array($http_data['by'], self::$exposed_fields)) {
- return $this->json_error('Incorrect by field specified.');
+ if (isset($http_data['by'])) {
+ if ($this->version < 6) {
+ if (!in_array($http_data['by'], self::$exposed_fields)) {
+ return $this->json_error('Incorrect by field specified.');
+ }
+ } else {
+ if (!is_array($http_data['by'])) {
+ $http_data['by'] = array($http_data['by']);
+ }
+ foreach ($http_data['by'] as $by) {
+ if (!in_array($by, self::$exposed_fields_v6)) {
+ return $this->json_error("Incorrect by field '$by' specified.");
+ }
+ }
+ }
}
$this->dbh = DB::connect();
@@ -109,7 +130,11 @@ class AurJSON {
if ($type == 'info' && $this->version >= 5) {
$type = 'multiinfo';
}
- $json = call_user_func(array(&$this, $type), $http_data);
+ if ($this->version < 6) {
+ $json = call_user_func(array(&$this, $type), $http_data);
+ } else {
+ $json = $this->info_search_v6($type, $http_data);
+ }
$etag = md5($json);
header("Etag: \"$etag\"");
@@ -374,6 +399,21 @@ class AurJSON {
}
$result = $this->dbh->query($query);
+ return $this->process_result($type, $result);
+ }
+
+
+ /*
+ * Retrieve package information from a dbh->query result
+ *
+ * @param $type The request type.
+ * @param $result A dbh->query result.
+ *
+ * @return mixed Returns an array of package matches.
+ */
+ private function process_result($type, $result) {
+ $max_results = config_get_int('options', 'max_rpc_results');
+
if ($result) {
$resultcount = 0;
$search_data = array();
@@ -515,6 +555,82 @@ class AurJSON {
return $this->process_query('search', $where_condition);
}
+ /*
+ * Performs a info or search query to the package database.
+ *
+ * @param $type The request type.
+ * @param array $http_data Query parameters.
+ *
+ * @return mixed Returns an array of package matches.
+ */
+ private function info_search_v6($type, $http_data) {
+ if (isset($http_data['by'])) {
+ $query_by = $http_data['by'];
+ if (!is_array($query_by)) {
+ $query_by = array($query_by);
+ }
+ } else {
+ if ($type == "multiinfo") {
+ $query_by = array('name');
+ } else { // search
+ $query_by = array('name', 'description');
+ }
+ }
+
+ if ($type == "multiinfo") {
+ $args = $http_data['arg'];
+ if (!is_array($args)) {
+ $args = array($args);
+ }
+ foreach ($args as $i => $arg) {
+ $args[$i] = $this->dbh->quote($arg);
+ }
+ $op_rhs = " IN (" . implode(",", $args) . ")";
+ } else {
+ $keyword_string = $http_data['arg'];
+ $keyword_string = $this->dbh->quote("%" . addcslashes($keyword_string, '%_') . "%");
+ $op_rhs = " LIKE " . $keyword_string;
+ }
+
+ $has_provides_query = false;
+ $where_condition = "";
+ foreach ($query_by as $index => $by) {
+ if ($index != 0) {
+ $where_condition .= " OR ";
+ }
+ if ($by == "provides") {
+ $has_provides_query = true;
+ $where_condition .= "(RelationTypes.Name = 'provides' AND ";
+ $where_condition .= "PackageRelations.RelName $op_rhs)";
+ } else {
+ $where_condition .= self::$exposed_fields_map_v6[$by];
+ $where_condition .= $op_rhs;
+ }
+ }
+
+ $max_results = config_get_int('options', 'max_rpc_results');
+ $fields = implode(',', self::$fields_v4);
+ $q = "SELECT {$fields} " .
+ "FROM Packages LEFT JOIN PackageBases " .
+ "ON PackageBases.ID = Packages.PackageBaseID " .
+ "LEFT JOIN Users " .
+ "ON PackageBases.MaintainerUID = Users.ID ";
+ if ($has_provides_query) {
+ $q .= "LEFT JOIN PackageRelations ON PackageRelations.PackageID = Packages.ID ";
+ $q .= "LEFT JOIN RelationTypes ON RelationTypes.ID = PackageRelations.RelTypeID ";
+ }
+ $q .= "WHERE ${where_condition} ";
+ $q .= "AND PackageBases.PackagerUID IS NOT NULL ";
+ if ($has_provides_query) {
+ $q .= "GROUP BY Packages.ID ";
+ }
+ $q .= "LIMIT $max_results";
+
+ $result = $this->dbh->query($q);
+
+ return $this->process_result($type, $result);
+ }
+
/*
* Returns the info on a specific package.
*
@@ -680,4 +796,3 @@ class AurJSON {
return json_encode($output);
}
}
-
--
2.17.1
More information about the aur-dev
mailing list