From owner-svn-soc-all@FreeBSD.ORG Sun Aug 18 14:44:56 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 31741F25 for ; Sun, 18 Aug 2013 14:44:56 +0000 (UTC) (envelope-from mattbw@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 0FBAD2A7E for ; Sun, 18 Aug 2013 14:44:56 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7IEitOq027095 for ; Sun, 18 Aug 2013 14:44:55 GMT (envelope-from mattbw@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r7IEittJ027088 for svn-soc-all@FreeBSD.org; Sun, 18 Aug 2013 14:44:55 GMT (envelope-from mattbw@FreeBSD.org) Date: Sun, 18 Aug 2013 14:44:55 GMT Message-Id: <201308181444.r7IEittJ027088@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to mattbw@FreeBSD.org using -f From: mattbw@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r256110 - in soc2013/mattbw/backend: actions query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Aug 2013 14:44:56 -0000 Author: mattbw Date: Sun Aug 18 14:44:55 2013 New Revision: 256110 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=256110 Log: (BROKEN) Dump of initial query refactoring. The query code is being rewritten in places to be more modular and allow easier usage outside of actions. The main body of work at the moment is writing code to massage the various different query inputs (PackageIDs, package names, name-versions, bundles of name, version, arch and repo) into one single format that can be used to check matches. I've decided to go with a combination of namever (as in "package-1.2.34", arch and repo, which is referred to internally as a 'query ID'. Currently I'm midway through writing the converters from other formats to this one. This code will NOT compile; please use a previous revision. It's intended as a quick dump of the state of my working copy. Added: soc2013/mattbw/backend/query/id.c Modified: soc2013/mattbw/backend/actions/resolve.c soc2013/mattbw/backend/query/core.c soc2013/mattbw/backend/query/core.h soc2013/mattbw/backend/query/depends.c soc2013/mattbw/backend/query/match.c Modified: soc2013/mattbw/backend/actions/resolve.c ============================================================================== --- soc2013/mattbw/backend/actions/resolve.c Sun Aug 18 13:38:39 2013 (r256109) +++ soc2013/mattbw/backend/actions/resolve.c Sun Aug 18 14:44:55 2013 (r256110) @@ -43,6 +43,7 @@ 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); Modified: soc2013/mattbw/backend/query/core.c ============================================================================== --- soc2013/mattbw/backend/query/core.c Sun Aug 18 13:38:39 2013 (r256109) +++ soc2013/mattbw/backend/query/core.c Sun Aug 18 14:44:55 2013 (r256110) @@ -55,6 +55,154 @@ static struct pkgdb_it *local_query(struct query *q); 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. */ Modified: soc2013/mattbw/backend/query/core.h ============================================================================== --- soc2013/mattbw/backend/query/core.h Sun Aug 18 13:38:39 2013 (r256109) +++ soc2013/mattbw/backend/query/core.h Sun Aug 18 14:44:55 2013 (r256110) @@ -57,6 +57,7 @@ struct query_target { unsigned int load_flags; emit_ptr f; + bool error_if_not_found; }; PkBackend *query_backend(struct query *q); Modified: soc2013/mattbw/backend/query/depends.c ============================================================================== --- soc2013/mattbw/backend/query/depends.c Sun Aug 18 13:38:39 2013 (r256109) +++ soc2013/mattbw/backend/query/depends.c Sun Aug 18 14:44:55 2013 (r256110) @@ -30,6 +30,7 @@ query_depends_emit(PkBackend *backend, struct pkg *pkg, depends_get_ptr get) { bool success; + gchar *package_id; struct pkg_dep *dep; assert(backend != NULL); @@ -40,7 +41,10 @@ dep = NULL; while (get(pkg, &dep) == EPKG_OK) { - ; /* Do something here */ + package_id = dep_to_package_id(dep); + assert(package_id != NULL); + + g_free(package_id); } ERR(backend, PK_ERROR_ENUM_NOT_SUPPORTED, "soon"); Added: soc2013/mattbw/backend/query/id.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/mattbw/backend/query/id.c Sun Aug 18 14:44:55 2013 (r256110) @@ -0,0 +1,147 @@ +typedef bool (*id_from_string_ptr) (const char *, struct query_id *); + +/* Converts an array of PackageIDs to query IDs. */ +static struct query_id * +query_id_array_from_package_ids(gchar **package_ids, + unsigned int package_count) +{ + + return query_id_array_from_strings(package_names, package_count, + query_id_from_package_id); +} + +/* Converts an array of names (or name-version strings) to query IDs. */ +static struct query_id * +query_id_array_from_names(gchar **package_names, unsigned int package_count) +{ + + return query_id_array_from_strings(package_names, package_count, + query_id_from_name); +} + +/* + * Converts an array of strings to query IDs using the given transforming + * function. + */ +static struct query_id * +query_id_array_from_strings(char **strings, unsigned int package_count, + id_from_string_ptr id_from_string) +{ + unsigned int i; + gchar *split_package_id; + struct query_id *query_ids; + + assert(strings != NULL); + assert(id_from_string != NULL); + + query_ids = query_id_alloc_array(package_count); + if (query_ids != NULL) { + bool error; + unsigned int i; + + error = false; + for (i = 0; i < package_count; i++) { + error = id_from_string(strings[i], query_ids + i); + if (error) { + free_split_ids(&query_ids, package_count); + break; + } + } + } + + return split_ids; +} + +/* + * Converts a package name or name-version string to a query ID. + * Overwrites the contents of *query_id with said ID. + */ +static bool +query_id_from_name(const char *name, struct query_id *query_id) +{ + + assert(name != NULL); + assert(query_id != NULL); + + query_id->namever = strdup(name); + query_id->arch = NULL; + query_id->repo = NULL; + + return (query_id->namever == NULL); +} + +/* + * Converts a PackageKit package ID to a query ID. + * Overwrites the contents of *query_id with said ID. + */ +bool +query_id_from_package_id(const gchar *package_id, struct query_id *split_id) +{ + bool success; + gchar **split_package_id; + + assert(name != NULL); + assert(split_id != NULL); + + success = false; + + split_package_id = pk_package_id_split(package_id); + if (split_package_id == NULL) { + error = true; + } else { + bool have_name; + bool have_version; + gchar *name; + gchar *version; + + /* We're not allowed to have an empty name or version. */ + + name = split_package_id[PK_PACKAGE_ID_NAME]; + have_name = !(name != NULL && name[0] != '\0'); + + version = split_package_id[PK_PACKAGE_ID_VERSION]; + have_version = (version != NULL && version[0] != '\0'); + + if (have_name && have_version) { + split_ids[1].namever = join_namever(name, version); + } + + if (*split_package_id[PK_PACKAGE_ID_VERSION] == '\0') { + + + g_strfreev(split_package_id); + } + i + o + } + } + + return split_ids; +} + +/* + * Joins a name and version together to create a 'namever'. + * The returned string is newly allocated and must be freed using free(3). + */ +static char * +join_namever(const char *name, const char *version) { + char *namever; + + /* + * The calling code should have checked to make sure the name and + * version are present. + */ + assert(name != NULL); + assert(version != NULL); + + namever = NULL; + asprintf(&namever, "%s-%s", name, version); + +} + +/* Allocates an array of query IDs. */ +static struct query_id * +query_id_alloc_array(unsigned int count) +{ + return calloc(count, sizeof(struct query_id)); +} Modified: soc2013/mattbw/backend/query/match.c ============================================================================== --- soc2013/mattbw/backend/query/match.c Sun Aug 18 13:38:39 2013 (r256109) +++ soc2013/mattbw/backend/query/match.c Sun Aug 18 14:44:55 2013 (r256110) @@ -26,6 +26,8 @@ #include "match.h" /* query_match_... */ + + /* * Runs a query over the PackageIDs selected in the backend that sends the * first match to an emitting function. @@ -44,6 +46,7 @@ t.f = emitter; t.load_flags = load_flags; + t.error_if_not_found = true; return query_do(backend, &s, &t); }