socsvn commit: r256499 - in soc2013/mattbw/backend: . actions query

mattbw at FreeBSD.org mattbw at FreeBSD.org
Sun Aug 25 11:30:49 UTC 2013


Author: mattbw
Date: Sun Aug 25 11:30:48 2013
New Revision: 256499
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=256499

Log:
  (*STILL* broken) Dump of work to query code.
  
  This is not a very well-structured commit as it contains lots of broken
  changes to lots of things, but I thought that it'd be better to have at
  least some record of the story so far in the version control.
  
  Currently working on the long overdue query overhaul with an eye to
  implementing GetDepends and GetRequires later today.
  

Added:
  soc2013/mattbw/backend/query/find.c
  soc2013/mattbw/backend/query/packages.c
  soc2013/mattbw/backend/query/packages.h
  soc2013/mattbw/backend/query/split_id.c
  soc2013/mattbw/backend/query/traverse.c
Modified:
  soc2013/mattbw/backend/Makefile
  soc2013/mattbw/backend/actions/resolve.c
  soc2013/mattbw/backend/query.h
  soc2013/mattbw/backend/query/core.c
  soc2013/mattbw/backend/query/do.c
  soc2013/mattbw/backend/query/match.c

Modified: soc2013/mattbw/backend/Makefile
==============================================================================
--- soc2013/mattbw/backend/Makefile	Sun Aug 25 10:57:48 2013	(r256498)
+++ soc2013/mattbw/backend/Makefile	Sun Aug 25 11:30:48 2013	(r256499)
@@ -64,6 +64,14 @@
 
 PKGS= 		pkg gio-2.0 gio-unix-2.0
 
+# ATF test flags
+TESTSRCS=					\
+		query/id_test.c
+
+TESTCFLAGS=	`pkgconf --cflags atf-c`
+TESTLDFLAGS=	`pkgconf --libs-only-L --libs-only-other atf-c`
+TESTLIBS=	`pkgconf --libs-only-l atf-c`
+
 # 0.6.* versions of PackageKit do not export pkgconf information, so here's a
 # bodge.
 USE_PK_PKGCONF=	0	# Set to 1 if using recent PackageKit
@@ -82,4 +90,11 @@
 group_map.c: groups group_map.awk
 	sort groups | awk -f group_map.awk > group_map.c
 
+# TODO: Find a more BSD way of doing this
+query/id_test: query/id_test.o query/id.o
+	${CC} ${LDFLAGS} ${TESTLDFLAGS} -o ${.TARGET} ${.ALLSRC} ${LIBS} ${TESTLIBS}
+
+query/id_test.o: query/id_test.c
+	${CC} ${CFLAGS} ${TESTCFLAGS} -o query/id_test.o -c query/id_test.c
+
 .include <bsd.lib.mk>

Modified: soc2013/mattbw/backend/actions/resolve.c
==============================================================================
--- soc2013/mattbw/backend/actions/resolve.c	Sun Aug 25 10:57:48 2013	(r256498)
+++ soc2013/mattbw/backend/actions/resolve.c	Sun Aug 25 11:30:48 2013	(r256499)
@@ -28,6 +28,7 @@
 #include "../actions.h"		/* resolve_thread prototype */
 
 static bool	emit(struct pkg *pkg, const gchar *id, struct query *q);
+static bool	query_with_db(struct pkgdb *db, PkBackend *backend);
 
 /*
  * Resolves a package identifier, which may be a full PackageID or a package
@@ -36,22 +37,63 @@
 gboolean
 resolve_thread(PkBackend *backend)
 {
-	gboolean success;
-	struct query_source s;
-	struct query_target t;
+	bool		success;
+	struct pkgdb   *db;
 
+	assert(backend != NULL);
+
+	db = db_open_remote(backend);
+	if (db != NULL) {
+		success = query_with_db(db, backend);
+
+		db_close(&db);
+	}
+/*
 	s.type = QUERY_BACKEND_MIXED;
 	t.load_flags = PKG_LOAD_BASIC;
 	t.f = emit;
 	t.error_if_not_found = true;
 
 	success = query_do(backend, &s, &t);
+*/
 
 	(void)pk_backend_finished(backend);
 	return success ? TRUE : FALSE;
 }
 
 static bool
+query_with_db(struct pkgdb *db, PkBackend *backend)
+{
+	bool		success;
+	guint		count;
+	struct query_id *query_ids;
+	gchar	      **names;
+	struct pkg    **packages;
+
+	assert(db != NULL);
+	assert(backend != NULL);
+
+	success = false;
+
+	names = pk_backend_get_strv("package_ids");
+	assert(names != NULL);
+	count = g_strv_length(names);
+
+	query_ids = query_id_array_from_names(names, count);
+	if (query_ids != NULL) {
+		packages = query_match_ids(query_ids, count, db,
+		    PKG_LOAD_BASIC);
+	}
+
+	if (packages != NULL) {
+		success = emit_packages(backend, db, emit, packages, count);
+		query_free_packages(packages, count);
+	}
+
+	return success;
+}
+
+static bool
 emit(struct pkg *pkg, const gchar *id, struct query *q)
 {
 	PkBackend	*backend;

Modified: soc2013/mattbw/backend/query.h
==============================================================================
--- soc2013/mattbw/backend/query.h	Sun Aug 25 10:57:48 2013	(r256498)
+++ soc2013/mattbw/backend/query.h	Sun Aug 25 11:30:48 2013	(r256499)
@@ -25,6 +25,6 @@
 
 #include "query/do.h"		/* query_do_... */
 #include "query/match.h"	/* query_match_... */
-#include "query/depends.h"	/* query_depends_... */
+#include "query/id.h"		/* query_id_... */
 
 #endif				/* !_PKGNG_BACKEND_QUERY_H_ */

Modified: soc2013/mattbw/backend/query/core.c
==============================================================================
--- soc2013/mattbw/backend/query/core.c	Sun Aug 25 10:57:48 2013	(r256498)
+++ soc2013/mattbw/backend/query/core.c	Sun Aug 25 11:30:48 2013	(r256499)
@@ -17,7 +17,6 @@
  * 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>		/* assert */
 #include <stdbool.h>
 #include <string.h>
@@ -30,19 +29,6 @@
 #include "../pkgutils.h"	/* pkgutils_... */
 #include "core.h"		/* Prototypes */
 
-
-struct query {
-	PkBackend      *backend;
-	struct pkgdb   *db;
-
-	gchar         **id_strv;
-
-	enum repo_type	rtype;
-
-	struct query_source *s;
-	struct query_target *t;
-};
-
 typedef		struct pkgdb_it * (*query_func_ptr) (struct query *q);
 
 static bool	can_remote_iterate(struct query *q);
@@ -56,153 +42,6 @@
 static struct pkgdb_it *remote_query(struct query *q);
 
 
-struct query_split_id {
-	gchar	       *namever;
-	gchar	       *arch;
-	gchar	       *repo;
-}
-
-/* Given an array of PackageIDs, returns an array of matching packages.
- *
- * Returns NULL if any of the packages did not match.
- */
-struct pkg **
-query_by_ids(PkBackend *backend, unsigned int load_flags,
-    gchar **package_ids, unsigned int package_count)
-{
-	struct pkg    **packages;
-	struct query_split_id **package_split_ids;
-
-	assert(backend != NULL);
-	assert(package_ids != NULL);
-
-	packages = NULL;
-
-	package_split_ids = split_package_ids(package_ids, count);
-	if (package_split_ids != NULL) {
-		packages = query_by_split_ids(backend, load_flags,
-		    package_split_ids, package_count);
-		free_split_package_ids(&package_split_ids);
-	}
-
-	return packages;
-}
-
-
-struct pkg **
-query_by_names(PkBackend *backend, unsigned int load_flags,
-    const char **package_names, unsigned int package_count)
-{
-	struct pkg    **packages;
-	struct query_split_id **package_split_ids;
-
-	assert(backend != NULL);
-	assert(package_names != NULL);
-
-	packages = NULL;
-
-	package_split_ids = names_to_split_ids(package_names, count);
-	if (package_split_ids != NULL) {
-		packages = query_by_split_ids(backend, load_flags,
-		    package_split_ids, package_count);
-		free_split_package_ids(&package_split_ids);
-	}
-
-	return packages;
-}
-
-struct pkg **
-query_by_split_ids(PkBackend *backend, unsigned int load_flags,
-    struct query_split_id *package_split_ids, unsigned int package_count)
-{
-	struct pkg    **packages;
-
-	packages =
-}
-
-/* Converts an array of PackageIDs to split IDs. */
-static struct query_split_id *
-split_package_ids(gchar **package_ids, unsigned int package_count)
-{
-	unsigned int		i;
-	struct query_split_id *split_ids;
-
-	split_ids = alloc_split_ids(package_count);
-	for ()
-
-	return split_ids;
-}
-
-/* Converts an array of names (or name-version strings) to split IDs. */
-static struct query_split_id *
-names_to_split(gchar **package_names, unsigned int package_count)
-{
-	unsigned int	i;
-	gchar	       *split_package_id;
-	struct query_split_id *split_ids;
-
-	split_ids = alloc_split_ids(package_count);
-	if (split_ids != NULL) {
-		bool		error;
-		unsigned int	i;
-
-		error = false;
-		for (i = 0; i < package_count; i++) {
-			error = name_to_split(package_names[i], split_ids + i);
-			if (error) {
-				free_split_ids(&split_ids, package_count);
-				break;
-			}
-		}
-	}
-
-	return split_ids;
-}
-
-bool
-name_to_split(const char *name, struct query_split_id *split_id)
-{
-	bool		success;
-
-	assert(name != NULL);
-	assert(split_id != NULL);
-
-	split_ids->namever = strdup(name);
-	split_ids->arch = NULL;
-	split_ids->repo = NULL;
-
-	return (split_ids->namever == NULL);
-}
-
-bool
-package_id_to_split(gchar *package_id, struct query_split_id *split_id)
-{
-	bool		success;
-	gchar	      **split_package_id;
-
-	assert(name != NULL);
-	assert(split_id != NULL);
-
-	split_package_id = pk_package_id_split(package_id);
-	if (split_package_id == NULL) {
-		error = true;
-	} else if () {
-
-				split_ids[i].namever = join_namever(name, version);
-				g_strfreev(split_package_id);
-			}
-		}
-	}
-
-	return split_ids;
-}
-
-static struct query_split_id *
-alloc_split_ids(unsigned int count)
-{
-	return calloc(package_count, sizeof(struct query_split_id));
-}
-
 /*
  * Returns the backend stored inside the given query.
  */
@@ -470,111 +309,3 @@
 
 	return match_id;
 }
-
-/*
- * Tries to find a query-matching package in a database iterator. Returns the
- * package if one matches, or NULL; if match_id_p is non-null, its full
- * PackageID will be emitted there.
- */
-static struct pkg *
-match_iterator(struct pkgdb_it *it, struct query *q, gchar **match_id_p)
-{
-	gchar          *match_id;
-	struct pkg     *pkg;
-
-	assert(it != NULL);
-	assert(q != NULL);
-
-	match_id = NULL;
-	pkg = NULL;
-	while (pkgdb_it_next(it, &pkg, q->t->load_flags) == EPKG_OK) {
-		match_id = match_pkg(pkg, q);
-		/* Did it match? */
-		if (match_id != NULL)
-			break;
-	}
-
-	if (match_id_p != NULL) {
-		g_free(*match_id_p);
-		*match_id_p = match_id;
-	} else
-		g_free(match_id);
-
-	return pkg;
-}
-
-static struct pkgdb_it *
-local_query(struct query *q)
-{
-
-	return pkgdb_query(q->db, q->id_strv[PK_PACKAGE_ID_NAME], MATCH_EXACT);
-}
-
-static struct pkgdb_it *
-remote_query(struct query *q)
-{
-	struct pkgdb_it *iterator;
-
-	iterator = pkgdb_rquery(q->db, q->id_strv[PK_PACKAGE_ID_NAME],
-	    MATCH_EXACT, query_repo(q));
-
-	/*
-	 * 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(q)) {
-		pkgdb_it_free(iterator);
-		iterator = NULL;
-	}
-
-	return iterator;
-}
-
-/* Unpacks a query source into name/version/arch/data pointers. */
-static gchar  **
-init_unpack_source(PkBackend *backend, struct query_source *s)
-{
-	gchar	      **id_strv;
-
-	assert(backend != NULL);
-	assert(s != NULL);
-
-	id_strv = NULL;
-	if (s->type == QUERY_SINGLE_NAME) {
-		id_strv = make_fake_id_split(s->single);
-	} else if (s->type == QUERY_SINGLE_ID) {
-		id_strv = pk_package_id_split(s->single);
-		if (id_strv == NULL)
-			ERR(backend,
-			    PK_ERROR_ENUM_PACKAGE_ID_INVALID,
-			    "invalid package id");
-	} else {
-		ERR(backend,
-		    PK_ERROR_ENUM_INTERNAL_ERROR,
-		    "init_unpack_source given silly source type");
-	}
-
-	return id_strv;
-}
-
-static gchar  **
-make_fake_id_split(const char *name)
-{
-	gchar	      **id_strv;
-
-	assert(name != NULL);
-
-	/*
-	 * Make a snake-oil ID vector; we won't be doing rigid
-	 * checking against it so it doesn't matter that the version
-	 * might be in the name column etc.
-	 */
-	id_strv = g_malloc0_n(5, (gsize) sizeof(gchar *));
-
-	id_strv[PK_PACKAGE_ID_NAME] = g_strdup(name);
-	id_strv[PK_PACKAGE_ID_VERSION] = g_strdup("");
-	id_strv[PK_PACKAGE_ID_ARCH] = g_strdup("");
-	id_strv[PK_PACKAGE_ID_DATA] = g_strdup("");
-
-	return id_strv;
-}

Modified: soc2013/mattbw/backend/query/do.c
==============================================================================
--- soc2013/mattbw/backend/query/do.c	Sun Aug 25 10:57:48 2013	(r256498)
+++ soc2013/mattbw/backend/query/do.c	Sun Aug 25 11:30:48 2013	(r256499)
@@ -31,93 +31,88 @@
 #include "do.h"			/* query_do_... */
 #include "core.h"		/* query_... */
 
-static bool	do_single(PkBackend *backend, struct pkgdb *db, struct query_source *s, struct query_target *t);
-static bool	do_backend_ids(PkBackend *backend, struct pkgdb *db, struct query_source *s, struct query_target *t);
-
+static bool emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter, struct pkg *packages, unsigned int count);
+static bool query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags, emit_ptr emitter);
 /*
- * Given information about a query's source and target, creates and runs it.
+ * Runs a query over the PackageIDs selected in the backend that sends the
+ * first match to an emitting function.
+ *
+ * This is a wrapper over several lower level query functions.
  */
 bool
-query_do(PkBackend *backend, struct query_source *s, struct query_target *t)
+query_do_from_backend(PkBackend *backend, unsigned int load_flags,
+    emit_ptr emitter)
 {
 	bool		success;
 	struct pkgdb   *db;
 
+	assert(backend != NULL);
+	assert(emitter != NULL);
+
 	success = false;
 
 	db = db_open_remote(backend);
 	if (db != NULL) {
-		switch (s->type) {
-		case QUERY_BACKEND_IDS:
-		case QUERY_BACKEND_MIXED:
-			success = do_backend_ids(backend, db, s, t);
-			break;
-		case QUERY_SINGLE_NAME:
-		case QUERY_SINGLE_ID:
-			success = do_single(backend, db, s, t);
-			break;
-		}
+		success = query_with_db(db, backend, load_flags, emitter);
 
-		pkgdb_close(db);
+		db_close(&db);
 	}
-
 	return success;
 }
 
-/*
- * Performs a query whose source is the set of PackageIDs stored in the
- * backend.
- */
 static bool
-do_backend_ids(PkBackend *backend, struct pkgdb *db, struct query_source *s,
-    struct query_target *t)
+query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags,
+    emit_ptr emitter)
 {
 	bool		success;
-	gchar         **package_ids;
-	struct query_source new_s;
-
-	/* Cheat by running a separate single-ID query for each ID. */
-
-	success = true;
-	package_ids = pk_backend_get_strv(backend, "package_ids");
-
-	new_s.total = g_strv_length(package_ids);
+	guint		count;
+	struct pkg    **packages;
+	struct query_id *query_ids;
+	gchar	      **package_ids;
+
+	assert(backend != NULL);
+	assert(db != NULL);
+	assert(emitter != NULL);
 
-	for (new_s.position = 0;
-	    new_s.position < new_s.total && success;
-	    (new_s.position)++) {
-		if (!success) {
-			break;
-		}
-
-		new_s.single = package_ids[new_s.position];
+	success = false;
+	packages = NULL;
 
-		/* Treat non-PackageIDs as pkgng package names, if allowed */
-		if (s->type == QUERY_BACKEND_IDS ||
-		    pk_package_id_check(new_s.single) == TRUE)
-			new_s.type = QUERY_SINGLE_ID;
-		else
-			new_s.type = QUERY_SINGLE_NAME;
+	package_ids = pk_backend_get_strv("package_ids");
+	assert(package_ids != NULL);
+	count = g_strv_length(package_ids);
+
+	query_ids = query_id_array_from_package_ids(package_ids, count);
+	if (query_ids != NULL) {
+		packages = query_match_ids(query_ids, count, db, load_flags);
+	}
 
-		success = do_single(backend, db, &new_s, t);
+	if (packages != NULL) {
+		success = emit_packages(backend, db, emitter, packages, count);
+		query_free_packages(packages, count);
 	}
 
 	return success;
 }
 
-/*
- * Performs a query whose source is a single PackageID or name.
- */
 static bool
-do_single(PkBackend *backend, struct pkgdb *db, struct query_source *s,
-    struct query_target *t)
+emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter,
+    struct pkg *packages, unsigned int count)
 {
 	bool		success;
-	struct query   *q;
+	unsigned int	i;
+
+	assert(backend != NULL);
+	assert(db != NULL);
+	assert(emitter != NULL);
+	assert(packages != NULL);
 
-	q = query_init(backend, db, s, t);
-	success = q == NULL ? false : query_run(q);
-	query_free(&q);
+	success = true;
+	for (i = 0; i < count; i++) {
+		success = emitter(backend, db, packages + i);
+		if (success = false) {
+			break;
+		}
+	}
 
 	return success;
 }

Added: soc2013/mattbw/backend/query/find.c
==============================================================================

Modified: soc2013/mattbw/backend/query/match.c
==============================================================================
--- soc2013/mattbw/backend/query/match.c	Sun Aug 25 10:57:48 2013	(r256498)
+++ soc2013/mattbw/backend/query/match.c	Sun Aug 25 11:30:48 2013	(r256499)
@@ -17,7 +17,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-
 #include <stdbool.h>
 #include "../pk-backend.h"
 
@@ -25,89 +24,186 @@
 #include "do.h"			/* query_do... */
 #include "match.h"		/* query_match_... */
 
+typedef		struct pkgdb_it * (*query_func_ptr) (struct query_id *id, struct pkgdb *db);
+
+static struct pkg *match_iterator(struct pkgdb_it *it, struct query *q, gchar **match_id_p);
+static struct pkg *query_match_from(query_func_ptr function, struct pkgdb *db, struct query_id *query_id);
+static struct pkgdb_it *local_query(struct query_id *id, struct pkgdb *db);
+static struct pkgdb_it *remote_query(struct query_id *id, struct pkgdb *db);
+
+/* Attempts to match a set of QueryIDs into packages. */
+struct pkg **
+query_match_ids(struct query_id *query_ids, unsigned int count,
+    struct pkgdb *db, int load_flags)
+{
+	bool		success;
+	unsigned int	i;
+	struct pkg     *packages;
+
+	assert(query_ids != NULL);
+	assert(db != NULL);
+
+	packages = query_packages_array_alloc(count);
+	success = (packages != NULL);
+
+	for (i = 0; i < count; i++) {
+		if (!success) {
+			/*
+			 * Catch both the packages being NULL and any failures
+			 * below.
+			 */
+			break;
+		}
+
+		success = query_match_id(packages + i, query_ids + i,
+		    db, load_flags);
+	}
 
-static bool emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter, struct pkg *packages, unsigned int count);
-static bool query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags, emit_ptr emitter);
+	if (!success) {
+		package_array_free(&packages, count);
+	}
 
+	return packages;
+}
 
 /*
- * Runs a query over the PackageIDs selected in the backend that sends the
- * first match to an emitting function.
+ * Takes a QueryID and attempts to retrieve its corresponding package.
  */
 bool
-query_match_id_to_emitter(PkBackend *backend, unsigned int load_flags,
-    emit_ptr emitter)
+query_match_id(struct pkg **package_p, struct query_id *query_id,
+    struct pkgdb *db, int load_flags)
 {
 	bool		success;
+	bool		try_local;
+	bool		try_remote;
 
-	assert(backend != NULL);
-	assert(emitter != NULL);
+	assert(package_p != NULL);
+	assert(*package_p == NULL);
+	assert(db != NULL);
 
 	success = false;
 
-	db = db_open_remote(backend);
-	if (db != NULL) {
-		success = query_with_db(db, backend, load_flags, emitter);
+	/*
+	 * 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.
+	 */
+	repo_type = type_of_repo_name(query_id->repo);
+	try_local = (repo_type != REPO_REMOTE);
+	try_remote = (repo_type != REPO_LOCAL);
 
-		db_close(&db);
+	if (try_local) {
+		*package_p = query_match_from(query_find_local, db, query_id);
+	}
+	if (*package_p == NULL && try_remote) {
+		*package_p = query_match_from(query_find_remote, db, query_id);
 	}
-	return success;
+
+	return (package_p != NULL);
 }
 
-static bool
-query_with_db(struct pkgdb *db, PkBackend *backend, unsigned int load_flags,
-    emit_ptr emitter)
+/* 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)
 {
-	bool		success;
-	guint		count;
-	struct pkg     *packages;
-	struct pkgdb   *db;
-	struct query_id *query_ids;
-	gchar	      **package_ids;
+	struct pkg     *result;
+	struct pkgdb_it *iterator;
 
-	assert(backend != NULL);
+	assert(function != NULL);
 	assert(db != NULL);
-	assert(emitter != NULL);
+	assert(query_id != NULL);
 
-	success = false;
-	packages = NULL;
+	result = NULL;
+
+	iterator = function(db, query_id);
+	if (iterator != NULL) {
+		result = match_iterator(iterator, q, match_id_p);
+		pkgdb_it_free(iterator);
+	}
+
+	return result;
+}
 
-	package_ids = pk_backend_get_strv("package_ids");
-	assert(package_ids != NULL);
-	count = g_strv_length(package_ids);
+/*
+ * Tries to find a query-matching package in a database iterator. Returns the
+ * package if one matches, or NULL; if match_id_p is non-null, its full
+ * PackageID will be emitted there.
+ */
+static struct pkg *
+match_iterator(struct pkgdb_it *it, struct query *q, gchar **match_id_p)
+{
+	gchar          *match_id;
+	struct pkg     *pkg;
 
-	query_ids = query_id_array_from_package_ids(package_ids, count);
-	if (query_ids != NULL) {
-		packages = query_match_ids(query_ids, count, load_flags);
+	assert(it != NULL);
+	assert(q != NULL);
+
+	match_id = NULL;
+	pkg = NULL;
+	while (pkgdb_it_next(it, &pkg, q->t->load_flags) == EPKG_OK) {
+		match_id = match_pkg(pkg, q);
+		/* Did it match? */
+		if (match_id != NULL)
+			break;
 	}
 
-	if (packages != NULL) {
-		success = emit_packages(backend, db, emitter, packages, count);
-		query_free_packages(packages, count);
+	if (match_id_p != NULL) {
+		g_free(*match_id_p);
+		*match_id_p = match_id;
+	} else
+		g_free(match_id);
+
+	return pkg;
+}
+
+static struct pkgdb_it *
+local_query(struct query_id *id, struct pkgdb *db)
+{
+
+	return pkgdb_query(db, q->id_strv[PK_PACKAGE_ID_NAME], MATCH_EXACT);
+}
+
+static struct pkgdb_it *
+remote_query(struct query_id *id, struct pkgdb *db)
+{
+	struct pkgdb_it *iterator;
+
+	iterator = pkgdb_rquery(db, q->id_strv[PK_PACKAGE_ID_NAME],
+	    MATCH_EXACT, query_repo(q));
+
+	/*
+	 * 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)) {
+		pkgdb_it_free(iterator);
+		iterator = NULL;
 	}
 
-	return success;
+	return iterator;
 }
 
-static bool
-emit_packages(PkBackend *backend, struct pkgdb *db, emit_ptr emitter,
-    struct pkg *packages, unsigned int count)
+static struct pkg **
+query_packages_array_alloc(unsigned int package_count)
+{
+
+	return calloc(package_count, sizeof(struct pkg *))
+}
+
+static void
+query_packages_array_free(struct pkg **packages_p, unsigned int package_count)
 {
-	bool		success;
 	unsigned int	i;
 
-	assert(backend != NULL);
-	assert(db != NULL);
-	assert(emitter != NULL);
-	assert(packages != NULL);
+	assert(packages_p != NULL);
 
-	success = true;
-	for (i = 0; i < count; i++) {
-		success = emitter(backend, packages + i);
-		if (success = false) {
-			break;
+	if (*packages_p != NULL) {
+		for (i = 0; i < package_count; i++) {
+			pkg_free((*packages_p)[i]);
 		}
-	}
 
-	return success;
+		free(*packages_p);
+		*packages_p = NULL;
+	}
 }

Added: soc2013/mattbw/backend/query/packages.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/mattbw/backend/query/packages.c	Sun Aug 25 11:30:48 2013	(r256499)
@@ -0,0 +1,50 @@
+/*-
+ * 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.
+ */
+
+/* Functions for dealing with arrays of package pointers. */
+#include "pkg.h"		/* struct pkg, pkg_free */
+
+#include "packages.h"		/* query_packages_... */
+
+/* Allocates an array of size 'package_count' of null pointers to packages. */
+struct pkg **
+query_packages_array_alloc(unsigned int package_count)
+{
+
+	return calloc(package_count, sizeof(struct pkg *))
+}
+
+/* Frees an array of size 'package_count' of pointers to packages. */
+void
+query_packages_array_free(struct pkg **packages_p, unsigned int package_count)
+{
+	unsigned int	i;
+
+	assert(packages_p != NULL);
+
+	if (*packages_p != NULL) {
+		for (i = 0; i < package_count; i++) {
+			pkg_free((*packages_p)[i]);
+		}
+
+		free(*packages_p);
+		*packages_p = NULL;
+	}
+}

Added: soc2013/mattbw/backend/query/packages.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/mattbw/backend/query/packages.h	Sun Aug 25 11:30:48 2013	(r256499)
@@ -0,0 +1,29 @@
+/*-
+ * 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_PACKAGES_H_
+#define _PKGNG_BACKEND_QUERY_PACKAGES_H_
+
+#include "pkg.h"
+
+struct pkg    **query_packages_array_alloc(unsigned int package_count);
+void		query_packages_array_free(struct pkg **packages_p, unsigned int package_count);
+
+#endif				/* !_PKGNG_BACKEND_QUERY_PACKAGES_H_ */

Added: soc2013/mattbw/backend/query/split_id.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/mattbw/backend/query/split_id.c	Sun Aug 25 11:30:48 2013	(r256499)
@@ -0,0 +1,38 @@
+/* Converts an array of PackageIDs to split IDs. */
+static struct query_split_id *
+split_package_ids(gchar **package_ids, unsigned int package_count)
+{
+	unsigned int	i;
+	struct query_split_id *split_ids;
+
+	split_ids = alloc_split_ids(package_count);
+	for ()
+
+	return split_ids;
+}
+
+/* Converts an array of names (or name-version strings) to split IDs. */
+static struct query_split_id *
+names_to_split(gchar **package_names, unsigned int package_count)
+{
+	unsigned int	i;
+	gchar	       *split_package_id;
+	struct query_split_id *split_ids;
+
+	split_ids = alloc_split_ids(package_count);
+	if (split_ids != NULL) {
+		bool		error;
+		unsigned int	i;
+
+		error = false;
+		for (i = 0; i < package_count; i++) {
+			error = name_to_split(package_names[i], split_ids + i);
+			if (error) {
+				free_split_ids(&split_ids, package_count);
+				break;
+			}
+		}
+	}
+
+	return split_ids;
+}

Added: soc2013/mattbw/backend/query/traverse.c
==============================================================================


More information about the svn-soc-all mailing list