socsvn commit: r253509 - in soc2013/mattbw/backend: . actions

mattbw at FreeBSD.org mattbw at FreeBSD.org
Tue Jun 25 23:37:18 UTC 2013


Author: mattbw
Date: Tue Jun 25 23:37:18 2013
New Revision: 253509
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=253509

Log:
  implemented GetFiles; may not throw the correct error message at the moment for non-installed files.

Added:
  soc2013/mattbw/backend/actions/get-files.c
  soc2013/mattbw/backend/actions/get-files.h
Modified:
  soc2013/mattbw/backend/Makefile
  soc2013/mattbw/backend/actions/get-details.c
  soc2013/mattbw/backend/db.c
  soc2013/mattbw/backend/db.h
  soc2013/mattbw/backend/iterate.c
  soc2013/mattbw/backend/pk-backend-pkgng.c

Modified: soc2013/mattbw/backend/Makefile
==============================================================================
--- soc2013/mattbw/backend/Makefile	Tue Jun 25 22:46:52 2013	(r253508)
+++ soc2013/mattbw/backend/Makefile	Tue Jun 25 23:37:18 2013	(r253509)
@@ -3,7 +3,7 @@
 LIB=		pk_backend_pkgng
 SHLIB_MAJOR=	1
 SRCS=		pk-backend-pkgng.c groups.c db.c licenses.c iterate.c
-SRCS+=		actions/get-details.c
+SRCS+=		actions/get-details.c actions/get-files.c
 
 LIBDIR=		/usr/local/lib/packagekit-backend
 

Modified: soc2013/mattbw/backend/actions/get-details.c
==============================================================================
--- soc2013/mattbw/backend/actions/get-details.c	Tue Jun 25 22:46:52 2013	(r253508)
+++ soc2013/mattbw/backend/actions/get-details.c	Tue Jun 25 23:37:18 2013	(r253509)
@@ -18,11 +18,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <string.h>
 #include <glib.h>
 #include "../pk-backend.h"
 #include "pkg.h"
 
+#include "../db.h"		/* db_query_from_id */
 #include "../groups.h"		/* group_from_origin */
 #include "../iterate.h"		/* Package iteration */
 #include "../licenses.h"	/* license_from_pkg */
@@ -30,17 +30,7 @@
 #include "get-details.h"	/* get_details_thread prototype */
 
 static const int LOAD_FLAGS = PKG_LOAD_BASIC | PKG_LOAD_LICENSES;
-
-/* TODO: move out of get-details? */
-const char     *null_if_empty(const char *in);
-
-static gboolean
-get_details_query(const gchar *name,
-		  const gchar *version,
-		  const gchar *arch,
-		  const gchar *reponame,
-		  PkBackend *backend,
-		  struct pkgdb *db);
+static void get_details_emit(struct pkg *pkg, const gchar *id, PkBackend *backend);
 static gboolean
 get_details_for(gchar *package_id,
 		PkBackend *backend,
@@ -60,9 +50,7 @@
  * Emits the given package's details. To be used as an iterating function.
  */
 static void
-emit_get_details(struct pkg *pkg,
-		 const gchar *id,
-		 PkBackend *backend)
+get_details_emit(struct pkg *pkg, const gchar *id, PkBackend *backend)
 {
 	const char     *description;
 	const char     *origin;
@@ -86,118 +74,11 @@
 }
 
 /*
- * Looks the split PackageID up in the package databases.
- * 
- * Usually, a remote query will be done on the repository named by "reponame".
- * If reponame is NULL, a remote check will be done against all repostories.
- * If it is "installed", a local check will be done.  (This is in keeping
- * with the special meaning of the "installed" repository in PackageIDs).
+ * Look up and emit package details for the given PackageID, if it can be
+ * found.
  */
-static gboolean
-get_details_query(const gchar *name,
-		  const gchar *version,
-		  const gchar *arch,
-		  const gchar *reponame,
-		  PkBackend *backend,
-		  struct pkgdb *db)
-{
-	struct pkgdb_it *it;
-	gboolean	success;
-
-	success = FALSE;
-
-	/* Are we doing a local query? */
-	if (g_strcmp0(reponame, "installed") == 0)
-		it = pkgdb_query(db, name, MATCH_EXACT);
-	else
-		it = pkgdb_rquery(db, name, MATCH_EXACT, reponame);
-	if (it)
-		success = iterate_id_matches(it,
-					     backend,
-					     name,
-					     version,
-					     arch,
-					     reponame,
-					     LOAD_FLAGS,
-					     emit_get_details);
-	return success;
-}
-
-/*
- * If the input pointer points to a string that is empty, return the null
- * pointer; else pass through the pointer unmolested.
- * 
- * This does NOT free anything!
- */
-const char     *
-null_if_empty(const char *in)
-{
-	return (in != NULL && strlen(in) == 0) ? NULL : in;
-}
-
 gboolean
 get_details_for(gchar *package_id, PkBackend *backend, struct pkgdb *db)
 {
-	gchar         **parts;
-	gboolean	success;
-
-	success = FALSE;
-
-	parts = pk_package_id_split(package_id);
-	if (parts == NULL)
-		pk_backend_error_code(backend,
-				      PK_ERROR_ENUM_PACKAGE_ID_INVALID,
-				      "invalid package id");
-	else {
-		/* Parts of the package ID */
-		const gchar    *name;
-		const gchar    *version;
-		const gchar    *arch;
-		const gchar    *data;
-
-		/*
-		 * Make really really REALLY sure that the PackageID fields
-		 * either have sensible data in them, or are NULL.
-		 */
-		name = null_if_empty(parts[PK_PACKAGE_ID_NAME]);
-		version = null_if_empty(parts[PK_PACKAGE_ID_VERSION]);
-		arch = null_if_empty(parts[PK_PACKAGE_ID_ARCH]);
-		data = null_if_empty(parts[PK_PACKAGE_ID_DATA]);
-
-		/*
-		 * If the PackageID has a repository specified (even if it's
-		 * "installed" i.e. currently installed package), running
-		 * "get_details_query" directly should handle remote/local
-		 * queries properly.
-		 * 
-		 * If there is no repository specified, however (data is NULL),
-		 * we may need to check both the local and (all) remote
-		 * repositories, in that order. (TODO: local packages?)
-		 */
-		if (data == NULL) {
-			/* Try local database first. */
-			success = get_details_query(name,
-						    version,
-						    arch,
-						    "installed",
-						    backend,
-						    db);
-			if (success == FALSE)
-				success = get_details_query(name, version, NULL, data, backend, db);
-		} else
-			success = get_details_query(name, version, arch, data, backend, db);
-		/*
-		 * Assume any error is due to not finding packages. At time
-		 * of writing this is true, but may change.
-		 */
-		if (success == FALSE)
-			pk_backend_error_code(backend,
-					    PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
-					      "package not found");
-		g_strfreev(parts);
-	}
-
-	return success;
+	return db_query_with_id(package_id, backend, db, LOAD_FLAGS, get_details_emit);
 }
-
-

Added: soc2013/mattbw/backend/actions/get-files.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/mattbw/backend/actions/get-files.c	Tue Jun 25 23:37:18 2013	(r253509)
@@ -0,0 +1,102 @@
+/*-
+ * 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 files.
+ *
+ * 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 <glib.h>
+#include "../pk-backend.h"
+#include "pkg.h"
+
+#include "../db.h"		/* db_query_from_id */
+#include "../groups.h"		/* group_from_origin */
+#include "../iterate.h"		/* Package iteration */
+#include "../licenses.h"	/* license_from_pkg */
+
+#include "get-files.h"	/* get_files_thread prototype */
+
+static const int FILE_NAME_STEP = 10;
+static const int LOAD_FLAGS = PKG_LOAD_BASIC | PKG_LOAD_FILES;
+
+static void get_files_emit(struct pkg *pkg, const gchar *id, PkBackend *backend);
+static gboolean
+get_files_for(gchar *package_id,
+		PkBackend *backend,
+		struct pkgdb *db);
+
+/*
+ * The thread that performs a GetDetails operation. Should be invoked by the
+ * pk_backend_get_files hook.
+ */
+gboolean
+get_files_thread(PkBackend *backend)
+{
+	return iterate_ids(backend, get_files_for);
+}
+
+/*
+ * Emits the given package's files. To be used as an iterating function.
+ */
+static void
+get_files_emit(struct pkg *pkg, const gchar *id, PkBackend *backend)
+{
+	struct pkg_file *file;
+	int err;
+
+	gchar **filenames;
+	gchar *joined_filenames;
+	gint capacity;
+	gint i;
+
+	i = 0;
+	file = NULL;
+	/* Start off with a small array to hold the file names,
+	 * and expand it if needs be.
+	 */
+	capacity = FILE_NAME_STEP;
+	filenames = g_new(gchar *, capacity);	
+	do {
+		err = pkg_files(pkg, &file);
+		if (err == EPKG_OK) {
+			/* Out of capacity (leaving a NULL)?  Expand the array. */
+			if (i >= (capacity - 1)) {
+				capacity += FILE_NAME_STEP;
+				filenames = g_renew(gchar *, filenames, capacity);
+			}
+
+			filenames[i] = g_strdup(pkg_file_path(file));
+			i++;
+		}
+	} while (err == EPKG_OK);
+	filenames[i] = NULL;
+
+	joined_filenames = g_strjoinv(";", filenames);
+	g_strfreev(filenames);
+
+	pk_backend_files(backend, id, joined_filenames);
+	g_free(joined_filenames);
+}
+
+/*
+ * Look up and emit package files for the given PackageID, if it can be
+ * found.
+ */
+gboolean
+get_files_for(gchar *package_id, PkBackend *backend, struct pkgdb *db)
+{
+	return db_query_with_id(package_id, backend, db, LOAD_FLAGS, get_files_emit);
+}

Added: soc2013/mattbw/backend/actions/get-files.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ soc2013/mattbw/backend/actions/get-files.h	Tue Jun 25 23:37:18 2013	(r253509)
@@ -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 files.
+ *
+ * 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_GET_FILES_H_
+#define _PKGNG_BACKEND_GET_FILES_H_
+
+#include <glib.h>		/* gboolean */
+#include "../pk-backend.h"	/* PkBackend */
+
+gboolean	get_files_thread(PkBackend *backend);
+
+#endif				/* !_PKGNG_BACKEND_GET_FILES_H_ */

Modified: soc2013/mattbw/backend/db.c
==============================================================================
--- soc2013/mattbw/backend/db.c	Tue Jun 25 22:46:52 2013	(r253508)
+++ soc2013/mattbw/backend/db.c	Tue Jun 25 23:37:18 2013	(r253509)
@@ -19,11 +19,25 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <string.h>
 #include <glib.h>
 #include "pk-backend.h"
 #include "pkg.h"
 
 #include "db.h"			/* prototypes */
+#include "iterate.h"		/* pkg_func_ptr */
+
+static const char *null_if_empty(const char *in);
+
+static gboolean
+db_query_split(const gchar *name,
+	       const gchar *version,
+	       const gchar *arch,
+	       const gchar *reponame,
+	       PkBackend *backend,
+	       struct pkgdb *db,
+	       int load_flags,
+	       pkg_func_ptr emitter);
 
 /*
  * Opens a pkgdb ready for remote operations. This will always return TRUE if
@@ -57,3 +71,131 @@
 
 	return success;
 }
+
+/*
+ * Performs a package database query against a PackageID, and then hands the
+ * matching results to an emitter function.
+ * 
+ * The exact type of query depends on the repository given.
+ */
+gboolean
+db_query_with_id(const gchar *package_id,
+		 PkBackend *backend,
+		 struct pkgdb *db,
+		 int load_flags,
+		 pkg_func_ptr emitter)
+{
+	gchar         **parts;
+	gboolean	success;
+
+	success = FALSE;
+
+	parts = pk_package_id_split(package_id);
+	if (parts == NULL)
+		pk_backend_error_code(backend,
+				      PK_ERROR_ENUM_PACKAGE_ID_INVALID,
+				      "invalid package id");
+	else {
+		/* Parts of the package ID */
+		const gchar    *name;
+		const gchar    *version;
+		const gchar    *arch;
+		const gchar    *data;
+
+		/*
+		 * Make really really REALLY sure that the PackageID fields
+		 * either have sensible data in them, or are NULL.
+		 */
+		name = null_if_empty(parts[PK_PACKAGE_ID_NAME]);
+		version = null_if_empty(parts[PK_PACKAGE_ID_VERSION]);
+		arch = null_if_empty(parts[PK_PACKAGE_ID_ARCH]);
+		data = null_if_empty(parts[PK_PACKAGE_ID_DATA]);
+
+		/*
+		 * If the PackageID has a repository specified (even if it's
+		 * "installed" i.e. currently installed package), running
+		 * "get_details_query" directly should handle remote/local
+		 * queries properly.
+		 * 
+		 * If there is no repository specified, however (data is NULL),
+		 * we may need to check both the local and (all) remote
+		 * repositories, in that order. (TODO: local packages?)
+		 */
+		if (data == NULL)
+			/* Try local database first. */
+			success = db_query_split(name,
+						 version,
+						 arch,
+						 "installed",
+						 backend,
+						 db,
+						 load_flags,
+						 emitter);
+		if (success == FALSE)
+			success = db_query_split(name, version, arch, data,
+					  backend, db, load_flags, emitter);
+		/*
+		 * Assume any error is due to not finding packages. At time
+		 * of writing this is true, but may change.
+		 */
+		if (success == FALSE)
+			pk_backend_error_code(backend,
+					    PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
+					      "package not found");
+		g_strfreev(parts);
+	}
+
+	return success;
+}
+
+/*
+ * Looks the split PackageID up in the package databases.
+ * 
+ * Usually, a remote query will be done on the repository named by "reponame".
+ * If reponame is NULL, a remote check will be done against all repostories.
+ * If it is "installed", a local check will be done.  (This is in keeping
+ * with the special meaning of the "installed" repository in PackageIDs).
+ */
+static gboolean
+db_query_split(const gchar *name,
+	       const gchar *version,
+	       const gchar *arch,
+	       const gchar *reponame,
+	       PkBackend *backend,
+	       struct pkgdb *db,
+	       int load_flags,
+	       pkg_func_ptr emitter)
+{
+	struct pkgdb_it *it;
+	gboolean	success;
+
+	success = FALSE;
+
+	/* Are we doing a local query? */
+	if (g_strcmp0(reponame, "installed") == 0)
+		it = pkgdb_query(db, name, MATCH_EXACT);
+	else
+		it = pkgdb_rquery(db, name, MATCH_EXACT, reponame);
+	if (it)
+		success = iterate_id_matches(it,
+					     backend,
+					     name,
+					     version,
+					     arch,
+					     reponame,
+					     load_flags,
+					     emitter);
+	return success;
+}
+
+/*
+ * If the input pointer points to a string that is empty, return the null
+ * pointer; else pass through the pointer unmolested.
+ * 
+ * This does NOT free anything!
+ */
+static const char *
+null_if_empty(const char *in)
+{
+	return (in != NULL && strlen(in) == 0) ? NULL : in;
+}

Modified: soc2013/mattbw/backend/db.h
==============================================================================
--- soc2013/mattbw/backend/db.h	Tue Jun 25 22:46:52 2013	(r253508)
+++ soc2013/mattbw/backend/db.h	Tue Jun 25 23:37:18 2013	(r253509)
@@ -26,6 +26,14 @@
 #include "pk-backend.h"		/* PkBackend */
 #include "pkg.h"		/* struct pkgdb */
 
+#include "iterate.h"		/* pk_func_ptr */
+
 gboolean	open_remote_db(struct pkgdb **db, PkBackend *backend);
+gboolean
+db_query_with_id(const gchar *package_id,
+		 PkBackend *backend,
+		 struct pkgdb *db,
+		 int load_flags,
+		 pkg_func_ptr emitter);
 
 #endif				/* !_PKGNG_BACKEND_DETAILS_H_ */

Modified: soc2013/mattbw/backend/iterate.c
==============================================================================
--- soc2013/mattbw/backend/iterate.c	Tue Jun 25 22:46:52 2013	(r253508)
+++ soc2013/mattbw/backend/iterate.c	Tue Jun 25 23:37:18 2013	(r253509)
@@ -25,7 +25,7 @@
 
 #include "iterate.h"		/* Prototypes */
 
-#include "db.h"		/* open_remote_db */
+#include "db.h"			/* open_remote_db */
 
 static gboolean
 try_id_match(struct pkg *pkg, const gchar *name, const gchar *version, const
@@ -53,7 +53,19 @@
 	pkg = NULL;
 	match_id = NULL;
 	do {
-		err = pkgdb_it_next(iterator, &pkg, fetch_flags);
+		/*
+		 * Stop pkg from catching fire if we try to load files from
+		 * non-installed packages.
+		 */
+		if ((fetch_flags & PKG_LOAD_FILES) && g_strcmp0(data,
+							"installed") != 0) {
+			pk_backend_error_code(backend,
+					  PK_ERROR_ENUM_CANNOT_GET_FILELIST,
+			       "Cannot get files for non-installed package."
+				);
+			err = EPKG_FATAL;
+		} else
+			err = pkgdb_it_next(iterator, &pkg, fetch_flags);
 
 		if (err == EPKG_OK && try_id_match(pkg,
 						   name,
@@ -133,11 +145,12 @@
 	return result;
 }
 
-/* Iterates over a set of PackageIDs provided for this job with a function.
- *
+/*
+ * Iterates over a set of PackageIDs provided for this job with a function.
+ * 
  * This provides each iterating function call with an open database connection
  * and updates the percentage after each iteration.
- *
+ * 
  * It also *finishes* the backend job.
  */
 gboolean

Modified: soc2013/mattbw/backend/pk-backend-pkgng.c
==============================================================================
--- soc2013/mattbw/backend/pk-backend-pkgng.c	Tue Jun 25 22:46:52 2013	(r253508)
+++ soc2013/mattbw/backend/pk-backend-pkgng.c	Tue Jun 25 23:37:18 2013	(r253509)
@@ -31,6 +31,7 @@
 #include "pkg.h"
 
 #include "groups.h"		/* available_groups */
+#include "actions/get-files.h"	/* get_files_thread */
 #include "actions/get-details.h"/* get_details_thread */
 
 #define INTENTIONALLY_IGNORE(x)	(void)(x)
@@ -218,25 +219,13 @@
 void
 pk_backend_get_files(PkBackend *backend, gchar **package_ids)
 {
-	guint		i;
-	guint		len;
-	const gchar    *package_id;
+	INTENTIONALLY_IGNORE(package_ids);	/* can be retrieved from
+						 * backend */
 
 	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
+	pk_backend_set_percentage(backend, PK_BACKEND_PERCENTAGE_INVALID);
 
-	len = g_strv_length(package_ids);
-	for (i = 0; i < len; i++) {
-		package_id = package_ids[i];
-		if (g_strcmp0(package_id, "powertop;1.8-1.fc8;i386;fedora") == 0)
-			pk_backend_files(backend, package_id, "/usr/share/man/man1/boo;/usr/bin/xchat-gnome");
-		else if (g_strcmp0(package_id, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed") == 0)
-			pk_backend_files(backend, package_id, "/usr/share/man/man1;/usr/share/man/man1/gnome-power-manager.1.gz;/usr/lib/firefox-3.5.7/firefox");
-		else if (g_strcmp0(package_id, "gtkhtml2;2.19.1-4.fc8;i386;fedora") == 0)
-			pk_backend_files(backend, package_id, "/usr/share/man/man1;/usr/bin/ck-xinit-session;/lib/libselinux.so.1");
-		else
-			pk_backend_files(backend, package_id, "/usr/share/gnome-power-manager;/usr/bin/ck-xinit-session");
-	}
-	pk_backend_finished(backend);
+	pk_backend_thread_create(backend, get_files_thread);
 }
 
 /**


More information about the svn-soc-all mailing list