[aur-dev] [PATCH 0/3] Several additions to the RPC interface
This adds a lot of information (dependencies etc.) to RPC replies. Note that there will probably be a follow-up series that adds backwards compatibility, making it possible to request the old format via http://aur.archlinux.org/rpc.php?v=1&type=info&arg=yaourt Lukas Fleischer (3): Fix the RPC interface Add more fields to RPC info replies Add a version tag to RPC replies web/lib/aurjson.class.php | 82 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 11 deletions(-) -- 1.9.2
* Fix the SQL query to conform to the new database layout. * Remove the license field from replies. The license field is now stored in a separate table and no longer returned on search queries. * Add a "PackageBase" field that contains the name of the package base of every package in the result. * Fix the source tarball URL. The URL is now built based on the package base name instead of the package name. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/lib/aurjson.class.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php index 4364e5d..38cdd65 100644 --- a/web/lib/aurjson.class.php +++ b/web/lib/aurjson.class.php @@ -18,8 +18,9 @@ class AurJSON { 'search', 'info', 'multiinfo', 'msearch', 'suggest' ); private static $fields = array( - 'Packages.ID', 'Name', 'Version', 'CategoryID', 'Description', 'URL', - 'License', 'NumVotes', 'OutOfDateTS AS OutOfDate', + 'Packages.ID', 'Packages.Name', 'PackageBases.Name AS PackageBase', + 'Version', 'CategoryID', 'Description', 'URL', 'NumVotes', + 'OutOfDateTS AS OutOfDate', 'Users.UserName AS Maintainer', 'SubmittedTS AS FirstSubmitted', 'ModifiedTS AS LastModified' ); private static $numeric_fields = array( @@ -120,9 +121,10 @@ class AurJSON { private function process_query($type, $where_condition) { global $MAX_RPC_RESULTS; $fields = implode(',', self::$fields); - $query = "SELECT Users.Username as Maintainer, {$fields} " . - "FROM Packages LEFT JOIN Users " . - "ON Packages.MaintainerUID = Users.ID " . + $query = "SELECT {$fields} " . + "FROM Packages LEFT JOIN PackageBases " . + "ON PackageBases.ID = Packages.PackageBaseID " . + "LEFT JOIN Users ON PackageBases.MaintainerUID = Users.ID " . "WHERE ${where_condition}"; $result = $this->dbh->query($query); @@ -131,8 +133,8 @@ class AurJSON { $search_data = array(); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $resultcount++; - $name = $row['Name']; - $row['URLPath'] = URL_DIR . substr($name, 0, 2) . "/" . $name . "/" . $name . ".tar.gz"; + $pkgbase_name = $row['PackageBase']; + $row['URLPath'] = URL_DIR . substr($pkgbase_name, 0, 2) . "/" . $pkgbase_name . "/" . $pkgbase_name . ".tar.gz"; /* Unfortunately, mysql_fetch_assoc() returns all fields as * strings. We need to coerce numeric values into integers to @@ -204,7 +206,7 @@ class AurJSON { $keyword_string = $this->dbh->quote("%" . addcslashes($keyword_string, '%_') . "%"); - $where_condition = "(Name LIKE {$keyword_string} OR "; + $where_condition = "(Packages.Name LIKE {$keyword_string} OR "; $where_condition.= "Description LIKE {$keyword_string}) "; $where_condition.= "LIMIT {$MAX_RPC_RESULTS}"; @@ -224,7 +226,7 @@ class AurJSON { $where_condition = "Packages.ID={$pqdata}"; } else { - $where_condition = sprintf("Name=%s", $this->dbh->quote($pqdata)); + $where_condition = sprintf("Packages.Name=%s", $this->dbh->quote($pqdata)); } return $this->process_query('info', $where_condition); } @@ -255,7 +257,7 @@ class AurJSON { if ($names) { // individual names were quoted in parse_multiinfo_args() $names_value = implode(',', $args['names']); - $where_condition .= "Name IN ({$names_value}) "; + $where_condition .= "Packages.Name IN ({$names_value}) "; } $where_condition .= "LIMIT {$MAX_RPC_RESULTS}"; -- 1.9.2
This patch adds the following fields to info and multiinfo replies: * Depends * MakeDepends * CheckDepends * OptDepends * Conflicts * Provides * Replaces * Groups * License Each of these fields is an array. Note that since collecting all these fields is CPU-intensive, they are not included in replies to search queries. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/lib/aurjson.class.php | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php index 38cdd65..ab8ebbc 100644 --- a/web/lib/aurjson.class.php +++ b/web/lib/aurjson.class.php @@ -118,6 +118,55 @@ class AurJSON { return json_encode( array('type' => $type, 'resultcount' => $count, 'results' => $data) ); } + private function get_extended_fields($pkgid) { + $query = "SELECT DependencyTypes.Name AS Type, " . + "PackageDepends.DepName AS Name, " . + "PackageDepends.DepCondition AS Cond " . + "FROM PackageDepends " . + "LEFT JOIN DependencyTypes " . + "ON DependencyTypes.ID = PackageDepends.DepTypeID " . + "WHERE PackageDepends.PackageID = " . $pkgid . " " . + "UNION SELECT RelationTypes.Name AS Type, " . + "PackageRelations.RelName AS Name, " . + "PackageRelations.RelCondition AS Cond " . + "FROM PackageRelations " . + "LEFT JOIN RelationTypes " . + "ON RelationTypes.ID = PackageRelations.RelTypeID " . + "WHERE PackageRelations.PackageID = " . $pkgid . " " . + "UNION SELECT 'groups' AS Type, Groups.Name, '' AS Cond " . + "FROM Groups INNER JOIN PackageGroups " . + "ON PackageGroups.PackageID = " . $pkgid . " " . + "AND PackageGroups.GroupID = Groups.ID " . + "UNION SELECT 'license' AS Type, Licenses.Name, '' AS Cond " . + "FROM Licenses INNER JOIN PackageLicenses " . + "ON PackageLicenses.PackageID = " . $pkgid . " " . + "AND PackageLicenses.LicenseID = Licenses.ID"; + $result = $this->dbh->query($query); + + if (!$result) { + return null; + } + + $type_map = array( + 'depends' => 'Depends', + 'makedepends' => 'MakeDepends', + 'checkdepends' => 'CheckDepends', + 'optdepends' => 'OptDepends', + 'conflicts' => 'Conflicts', + 'provides' => 'Provides', + 'replaces' => 'Replaces', + 'groups' => 'Groups', + 'license' => 'License', + ); + $data = array(); + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + $type = $type_map[$row['Type']]; + $data[$type][] = $row['Name'] . $row['Cond']; + } + + return $data; + } + private function process_query($type, $where_condition) { global $MAX_RPC_RESULTS; $fields = implode(',', self::$fields); @@ -144,6 +193,10 @@ class AurJSON { $row[$field] = intval($row[$field]); } + if ($type == 'info' || $type == 'multiinfo') { + $row = array_merge($row, $this->get_extended_fields($row['ID'])); + } + if ($type == 'info') { $search_data = $row; break; -- 1.9.2
This is needed for clients to quickly differentiate between different versions of the RPC API. The version number should be bumped whenever there is a change that breaks backwards compatibility. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/lib/aurjson.class.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php index ab8ebbc..2e5e06d 100644 --- a/web/lib/aurjson.class.php +++ b/web/lib/aurjson.class.php @@ -115,7 +115,12 @@ class AurJSON { * @return mixed A json formatted result response. **/ private function json_results($type, $count, $data) { - return json_encode( array('type' => $type, 'resultcount' => $count, 'results' => $data) ); + return json_encode(array( + 'version' => 2, + 'type' => $type, + 'resultcount' => $count, + 'results' => $data + )); } private function get_extended_fields($pkgid) { -- 1.9.2
participants (1)
-
Lukas Fleischer