socsvn commit: r257380 - in soc2013/mattbw/backend: . query

mattbw at FreeBSD.org mattbw at FreeBSD.org
Sun Sep 15 15:28:49 UTC 2013


Author: mattbw
Date: Sun Sep 15 15:28:49 2013
New Revision: 257380
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257380

Log:
  Add basic error handling back into the query code.
  
  This should make the cases of `repo-list`ing non-installed packages and
  passing incorrect package IDs work properly.
  

Added:
  soc2013/mattbw/backend/query/error.c
  soc2013/mattbw/backend/query/error.h
Modified:
  soc2013/mattbw/backend/Makefile
  soc2013/mattbw/backend/query/depends.c
  soc2013/mattbw/backend/query/do.c
  soc2013/mattbw/backend/query/find.c
  soc2013/mattbw/backend/query/find.h
  soc2013/mattbw/backend/query/match.c
  soc2013/mattbw/backend/query/match.h

Modified: soc2013/mattbw/backend/Makefile
==============================================================================
--- soc2013/mattbw/backend/Makefile	Sun Sep 15 14:51:23 2013	(r257379)
+++ soc2013/mattbw/backend/Makefile	Sun Sep 15 15:28:49 2013	(r257380)
@@ -56,6 +56,7 @@
 		query/check.c			\
 		query/depends.c			\
 		query/do.c			\
+		query/error.c			\
 		query/find.c			\
 		query/id.c			\
 		query/match.c			\

Modified: soc2013/mattbw/backend/query/depends.c
==============================================================================
--- soc2013/mattbw/backend/query/depends.c	Sun Sep 15 14:51:23 2013	(r257379)
+++ soc2013/mattbw/backend/query/depends.c	Sun Sep 15 15:28:49 2013	(r257380)
@@ -27,6 +27,7 @@
 #include "../pkgutils.h"	/* pkgutils_... */
 #include "../utils.h"		/* ERR */
 #include "depends.h"		/* query_depends_... */
+#include "error.h"		/* query_error_... */
 #include "id.h"			/* query_id, query_id_... */
 #include "match.h"		/* query_match_... */
 
@@ -110,12 +111,14 @@
 static struct pkg *
 id_to_package(gchar *package_id, struct pkgdb *db, unsigned int load_flags)
 {
+	enum query_error error;
 	struct pkg     *package;
 	struct query_id	query_id;
 
 	assert(package_id != NULL);
 	assert(db != NULL);
 
+	error = QUERY_ERROR_OK;
 	package = NULL;
 
 	if (package_id != NULL) {
@@ -123,7 +126,10 @@
 
 		success = query_id_from_package_id(package_id, &query_id);
 		if (success) {
-			package = query_match_id(&query_id, db, load_flags);
+			package = query_match_id(&query_id, db, load_flags,
+			    &error);
+			assert(error == QUERY_ERROR_OK || package != NULL);
+			assert(error != QUERY_ERROR_OK || package == NULL);
 		}
 	}
 	return package;

Modified: soc2013/mattbw/backend/query/do.c
==============================================================================
--- soc2013/mattbw/backend/query/do.c	Sun Sep 15 14:51:23 2013	(r257379)
+++ soc2013/mattbw/backend/query/do.c	Sun Sep 15 15:28:49 2013	(r257380)
@@ -110,7 +110,6 @@
 	assert(db != NULL);
 	assert(emitter != NULL);
 
-	success = false;
 	packages = NULL;
 
 	package_ids = get_strv_and_length(backend, "package_ids", &count);
@@ -118,7 +117,14 @@
 
 	query_ids = to_query_ids(package_ids, count);
 	if (query_ids != NULL) {
-		packages = query_match_ids(query_ids, count, db, load_flags);
+		enum query_error error;
+
+		error = QUERY_ERROR_OK;
+		packages = query_match_ids(query_ids, count, db, load_flags,
+		    &error);
+		success = query_error_handle(backend, error);
+	} else {
+		success = query_error_handle(backend, QUERY_ERROR_INVALID_IDS);
 	}
 	if (packages != NULL) {
 		success = emit_packages(backend, db, emitter, packages, count);

Added: soc2013/mattbw/backend/query/error.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/mattbw/backend/query/error.c	Sun Sep 15 15:28:49 2013	(r257380)
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (C) 2013 Matt Windsor <mattbw at FreeBSD.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include "../pk-backend.h"
+
+#include "../utils.h"		/* ERR */
+#include "error.h"		/* query_error */
+
+/* Reports query errors on the backend. */
+
+static const char *ERROR_STRINGS[QUERY_ERROR_COUNT] = {
+	"QUERY_ERROR_OK reported as error, this is an internal bug.",
+	"Cannot perform this action on a package from a remote repository.",
+	"No results were found.",
+	"The given PackageID(s) could not be interpreted."
+};
+
+static PkErrorEnum ERROR_ENUMS[QUERY_ERROR_COUNT] = {
+	PK_ERROR_ENUM_INTERNAL_ERROR,
+	PK_ERROR_ENUM_CANNOT_GET_FILELIST,
+	PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
+	PK_ERROR_ENUM_PACKAGE_ID_INVALID
+};
+
+bool
+query_error_handle(PkBackend *backend, enum query_error error)
+{
+
+	assert(backend != NULL);
+	assert(error < QUERY_ERROR_COUNT);
+
+	if (error != QUERY_ERROR_OK) {
+		ERR(backend, ERROR_ENUMS[error], ERROR_STRINGS[error]);
+	}
+	return (error == QUERY_ERROR_OK);
+}

Added: soc2013/mattbw/backend/query/error.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/mattbw/backend/query/error.h	Sun Sep 15 15:28:49 2013	(r257380)
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (C) 2013 Matt Windsor <mattbw at FreeBSD.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _PKGNG_BACKEND_QUERY_ERROR_H_
+#define _PKGNG_BACKEND_QUERY_ERROR_H_
+
+#include <stdbool.h>
+#include "../pk-backend.h"
+
+enum query_error {
+	QUERY_ERROR_OK,
+	QUERY_ERROR_REMOTE_NOT_ALLOWED,
+	QUERY_ERROR_NO_RESULTS,
+	QUERY_ERROR_INVALID_IDS,
+	QUERY_ERROR_COUNT
+};
+
+bool		query_error_handle(PkBackend *backend, enum query_error error);
+
+#endif				/* !_PKGNG_BACKEND_QUERY_ERROR_H_ */

Modified: soc2013/mattbw/backend/query/find.c
==============================================================================
--- soc2013/mattbw/backend/query/find.c	Sun Sep 15 14:51:23 2013	(r257379)
+++ soc2013/mattbw/backend/query/find.c	Sun Sep 15 15:28:49 2013	(r257380)
@@ -26,39 +26,45 @@
 
 #include "../utils.h"		/* INTENTIONALLY_IGNORE */
 #include "find.h"		/* query_find_... */
-#include "id.h"			/* struct query_id */
+#include "id.h"			/* struct spec->query_id */
 
 static bool	can_remote_iterate(struct query_id *query_id, unsigned int load_flags);
 
 struct pkgdb_it *
-query_find_local(struct query_id *query_id, struct pkgdb *db,
-    unsigned int load_flags)
+query_find_local(struct query_find_spec *spec)
 {
 
-	assert(query_id != NULL);
-	assert(db != NULL);
-	INTENTIONALLY_IGNORE(load_flags);
-	return pkgdb_query(db, query_id->namever, MATCH_EXACT);
+	assert(spec != NULL);
+	assert(spec->query_id != NULL);
+	assert(spec->db != NULL);
+	return pkgdb_query(spec->db, spec->query_id->namever, MATCH_EXACT);
 }
 
 struct pkgdb_it *
-query_find_remote(struct query_id *query_id, struct pkgdb *db,
-    unsigned int load_flags)
+query_find_remote(struct query_find_spec *spec)
 {
 	struct pkgdb_it *iterator;
 
-	assert(query_id != NULL);
-	assert(db != NULL);
-	iterator = pkgdb_rquery(db, query_id->namever, MATCH_EXACT,
-	    query_id->repo);
+	assert(spec != NULL);
+	assert(spec->query_id != NULL);
+	assert(spec->db != NULL);
+	assert(spec->error_p != NULL);
+	iterator = pkgdb_rquery(spec->db, spec->query_id->namever, MATCH_EXACT,
+	    spec->query_id->repo);
 
 	/*
 	 * Make sure we can use this iterator.  (We only check now so that
 	 * the case of there being no remote matches is properly handled.)
 	 */
-	if (!(iterator == NULL || can_remote_iterate(query_id, load_flags))) {
-		pkgdb_it_free(iterator);
-		iterator = NULL;
+	if (iterator != NULL) {
+		if (!can_remote_iterate(spec->query_id, spec->load_flags)) {
+			pkgdb_it_free(iterator);
+			iterator = NULL;
+
+			*(spec->error_p) = QUERY_ERROR_REMOTE_NOT_ALLOWED;
+		}
+	} else {
+		*(spec->error_p) = QUERY_ERROR_NO_RESULTS;
 	}
 	return iterator;
 }

Modified: soc2013/mattbw/backend/query/find.h
==============================================================================
--- soc2013/mattbw/backend/query/find.h	Sun Sep 15 14:51:23 2013	(r257379)
+++ soc2013/mattbw/backend/query/find.h	Sun Sep 15 15:28:49 2013	(r257380)
@@ -23,8 +23,19 @@
 
 #include "pkg.h"		/* struct pkgdb */
 #include "id.h"			/* struct query_id */
+#include "error.h"		/* enum query_error */
 
-struct pkgdb_it *query_find_local(struct query_id *query_id, struct pkgdb *db, unsigned int load_flags);
-struct pkgdb_it *query_find_remote(struct query_id *query_id, struct pkgdb *db, unsigned int load_flags);
+struct query_find_spec {
+	unsigned int load_flags;
+
+	enum query_error *error_p;
+	struct pkgdb *db;
+	struct query_id *query_id;
+};
+
+typedef struct pkgdb_it *(*query_find_function) (struct query_find_spec *spec);
+
+struct pkgdb_it *query_find_local(struct query_find_spec *spec);
+struct pkgdb_it *query_find_remote(struct query_find_spec *spec);
 
 #endif				/* !_PKGNG_BACKEND_QUERY_FIND_H_ */

Modified: soc2013/mattbw/backend/query/match.c
==============================================================================
--- soc2013/mattbw/backend/query/match.c	Sun Sep 15 14:51:23 2013	(r257379)
+++ soc2013/mattbw/backend/query/match.c	Sun Sep 15 15:28:49 2013	(r257380)
@@ -33,14 +33,12 @@
 
 /* Attempts to match a set of QueryIDs into packages. */
 
-typedef struct pkgdb_it *(*query_func_ptr) (struct query_id *id, struct pkgdb *db, unsigned int load_flags);
-
-static struct pkg *query_match_from(query_func_ptr function, struct pkgdb *db, struct query_id *query_id, unsigned int load_flags);
-static struct pkg *match_iterator(struct pkgdb_it *it, struct query_id *query_id, unsigned int load_flags);
+static struct pkg *query_match_from(query_find_function function, struct query_find_spec *spec);
+static struct pkg *match_iterator(struct pkgdb_it *it, struct query_find_spec *spec);
 
 struct pkg    **
 query_match_ids(struct query_id *query_ids, unsigned int count,
-    struct pkgdb *db, unsigned int load_flags)
+    struct pkgdb *db, unsigned int load_flags, enum query_error *error_p)
 {
 	bool		success;
 	unsigned int	i;
@@ -48,6 +46,7 @@
 
 	assert(query_ids != NULL);
 	assert(db != NULL);
+	assert(error_p != NULL);
 
 	packages = query_packages_array_alloc(count);
 	success = (packages != NULL);
@@ -60,7 +59,8 @@
 			 */
 			break;
 		}
-		packages[i] = query_match_id(query_ids + i, db, load_flags);
+		packages[i] = query_match_id(query_ids + i, db, load_flags,
+		    error_p);
 		success = (packages[i] != NULL);
 	}
 
@@ -74,52 +74,58 @@
  * Takes a QueryID and attempts to retrieve its corresponding package.
  */
 struct pkg     *
-query_match_id(struct query_id *query_id, struct pkgdb *db, unsigned int load_flags)
+query_match_id(struct query_id *query_id, struct pkgdb *db,
+    unsigned int load_flags, enum query_error *error_p)
 {
 	bool		try_local;
 	bool		try_remote;
 	enum repo_type	type;
 	struct pkg     *package;
+	struct query_find_spec spec;
 
 	assert(query_id != NULL);
 	assert(db != NULL);
+	assert(error_p != NULL);
+
+	spec.query_id = query_id;
+	spec.db = db;
+	spec.error_p = error_p;
+	spec.load_flags = load_flags;
 
 	/*
 	 * If we're not given a specific repository in the PackageID, we want
 	 * to try searching locally first and then remotely; otherwise which
 	 * database we query depends on the repository we have been given.
 	 */
-	type = repo_type(query_id->repo);
+	type = repo_type(spec.query_id->repo);
 	try_local = (type != REPO_REMOTE);
 	try_remote = (type != REPO_LOCAL);
 
 	package = NULL;
 	if (try_local) {
-		package = query_match_from(query_find_local, db, query_id, load_flags);
+		package = query_match_from(query_find_local, &spec);
 	}
 	if (package == NULL && try_remote) {
-		package = query_match_from(query_find_remote, db, query_id, load_flags);
+		package = query_match_from(query_find_remote, &spec);
 	}
 	return package;
 }
 
 /* Takes a querying function and attempts to find a QueryID using it. */
 static struct pkg *
-query_match_from(query_func_ptr function, struct pkgdb *db,
-    struct query_id *query_id, unsigned int load_flags)
+query_match_from(query_find_function function, struct query_find_spec *spec)
 {
 	struct pkg     *result;
 	struct pkgdb_it *iterator;
 
 	assert(function != NULL);
-	assert(db != NULL);
-	assert(query_id != NULL);
+	assert(spec != NULL);
 
 	result = NULL;
 
-	iterator = function(query_id, db, load_flags);
+	iterator = function(spec);
 	if (iterator != NULL) {
-		result = match_iterator(iterator, query_id, load_flags);
+		result = match_iterator(iterator, spec);
 		pkgdb_it_free(iterator);
 	}
 	return result;
@@ -130,19 +136,20 @@
  * package if one matches, or NULL if none do.
  */
 static struct pkg *
-match_iterator(struct pkgdb_it *it, struct query_id *query_id,
-    unsigned int load_flags)
+match_iterator(struct pkgdb_it *it, struct query_find_spec *spec)
 {
 	bool		success;
 	struct pkg     *pkg;
 
 	assert(it != NULL);
+	assert(spec != NULL);
+	assert(spec->query_id != NULL);
 
 	success = false;
 
 	pkg = NULL;
-	while (pkgdb_it_next(it, &pkg, load_flags) == EPKG_OK) {
-		success = query_check_package(pkg, query_id);
+	while (pkgdb_it_next(it, &pkg, spec->load_flags) == EPKG_OK) {
+		success = query_check_package(pkg, spec->query_id);
 		/* Did it match? */
 		if (success) {
 			break;

Modified: soc2013/mattbw/backend/query/match.h
==============================================================================
--- soc2013/mattbw/backend/query/match.h	Sun Sep 15 14:51:23 2013	(r257379)
+++ soc2013/mattbw/backend/query/match.h	Sun Sep 15 15:28:49 2013	(r257380)
@@ -24,9 +24,10 @@
 #include <stdbool.h>
 #include "pkg.h"
 
+#include "error.h"		/* enum query_error */
 #include "id.h"			/* struct query_id */
 
-struct pkg     *query_match_id(struct query_id *query_id, struct pkgdb *db, unsigned int load_flags);
-struct pkg    **query_match_ids(struct query_id *query_ids, unsigned int count, struct pkgdb *db, unsigned int load_flags);
+struct pkg     *query_match_id(struct query_id *query_id, struct pkgdb *db, unsigned int load_flags, enum query_error *error_p);
+struct pkg    **query_match_ids(struct query_id *query_ids, unsigned int count, struct pkgdb *db, unsigned int load_flags, enum query_error *error_p);
 
 #endif				/* !_PKGNG_BACKEND_QUERY_MATCH_H_ */


More information about the svn-soc-all mailing list