Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
pkg: add the ability to query by flavors
Baptiste Daroussin committed 3 years ago
commit 0b15679acbc1410de0c2bf28ffe1d6a3d723227b
parent ade813b
5 files changed +70 -22
modified libpkg/pkg.h.in
@@ -199,7 +199,8 @@ typedef enum {
	FIELD_NAME,
	FIELD_NAMEVER,
	FIELD_COMMENT,
-
	FIELD_DESC
+
	FIELD_DESC,
+
	FIELD_FLAVOR,
} pkgdb_field;

/**
modified libpkg/pkgdb.c
@@ -128,6 +128,7 @@ pkgdb_regex(sqlite3_context *ctx, int argc, sqlite3_value **argv)

	if (argc != 2 || (regex = sqlite3_value_text(argv[0])) == NULL ||
		(str = sqlite3_value_text(argv[1])) == NULL) {
+
		pkg_debug(4, "meh, %s", str);
		sqlite3_result_error(ctx, "SQL function regex() called "
		    "with invalid arguments.\n", -1);
		return;
modified libpkg/pkgdb_query.c
@@ -63,12 +63,15 @@ pkgdb_get_pattern_query(const char *pattern, match_t match)
{
	char		*checkorigin = NULL;
	char		*checkuid = NULL;
+
	char		*checkflavor = NULL;
	const char	*comp = NULL;

	if (pattern != NULL) {
		checkuid = strchr(pattern, '~');
		if (checkuid == NULL)
			checkorigin = strchr(pattern, '/');
+
		if (checkorigin != NULL)
+
			checkflavor = strchr(checkorigin, '@');
	}

	switch (match) {
@@ -80,8 +83,10 @@ pkgdb_get_pattern_query(const char *pattern, match_t match)
			if (checkuid == NULL) {
				if (checkorigin == NULL)
					comp = " WHERE (p.name = ?1 OR p.name || '-' || version = ?1)";
-
				else
+
				else if (checkflavor == NULL)
					comp = " WHERE (origin = ?1 OR categories.name || substr(origin, instr(origin, '/')) = ?1)";
+
				else
+
					comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor = ?1)";
			} else {
				comp = " WHERE p.name = ?1";
			}
@@ -90,8 +95,10 @@ pkgdb_get_pattern_query(const char *pattern, match_t match)
				if (checkorigin == NULL)
					comp = " WHERE (p.name = ?1 COLLATE NOCASE OR "
					"p.name || '-' || version = ?1 COLLATE NOCASE)";
-
				else
+
				else if (checkflavor == NULL)
					comp = " WHERE (origin = ?1 COLLATE NOCASE OR categories.name || substr(origin, instr(origin, '/'))  = ?1 COLLATE NOCASE)";
+
				else
+
					comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor = ?1 COLLATE NOCASE)";
			} else {
				comp = " WHERE p.name = ?1 COLLATE NOCASE";
			}
@@ -102,10 +109,12 @@ pkgdb_get_pattern_query(const char *pattern, match_t match)
			if (checkorigin == NULL)
				comp = " WHERE (p.name GLOB ?1 "
					"OR p.name || '-' || version GLOB ?1)";
-
			else
+
			else if (checkflavor == NULL)
				comp = " WHERE (origin GLOB ?1 OR categories.name || substr(origin, instr(origin, '/')) GLOB ?1)";
+
			else
+
				comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor GLOB ?1)";
		} else {
-
			comp = " WHERE p.name = ?1";
+
			comp = " WHERE p.name GLOB ?1";
		}
		break;
	case MATCH_REGEX:
@@ -113,10 +122,12 @@ pkgdb_get_pattern_query(const char *pattern, match_t match)
			if (checkorigin == NULL)
				comp = " WHERE (p.name REGEXP ?1 "
				    "OR p.name || '-' || version REGEXP ?1)";
+
			else if (checkflavor == NULL)
+
				comp = " WHERE (origin REGEXP ?1 OR categories.name || substr(origin, instr(origin, '/')) REGEXP ?1)";
			else
-
				comp = " WHERE (origin REGEXP ?1 OR categories.name || substr(origin, instr(origin, '/'))e  REGEXP ?1)";
+
				comp = "WHERE (categories.name || substr(origin, instr(origin, '/')) || '@' || flavor REGEXP ?1)";
		} else {
-
			comp = " WHERE p.name = ?1";
+
			comp = " WHERE p.name REGEXP ?1";
		}
		break;
	}
@@ -140,18 +151,29 @@ pkgdb_query_cond(struct pkgdb *db, const char *cond, const char *pattern, match_

	if (cond)
		sqlite3_snprintf(sizeof(sql), sql,
+
				"WITH flavors AS "
+
				"  (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
+
				"   LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
+
				"   LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
+
				"   WHERE tag.annotation = 'flavor') "
				"SELECT DISTINCT p.id, origin, p.name, p.name as uniqueid, "
-
					"version, comment, desc, "
-
					"message, arch, maintainer, www, "
-
					"prefix, flatsize, licenselogic, automatic, "
-
					"locked, time, manifestdigest, vital "
-
					"FROM packages AS p "
-
					"LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
-
					"LEFT JOIN categories ON categories.id = pkg_categories.category_id "
-
					" %s %s (%s) ORDER BY p.name;",
+
				"   version, comment, desc, "
+
				"   message, arch, maintainer, www, "
+
				"   prefix, flatsize, licenselogic, automatic, "
+
				"   locked, time, manifestdigest, vital "
+
				"   FROM packages AS p "
+
				"   LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
+
				"   LEFT JOIN categories ON categories.id = pkg_categories.category_id "
+
				"   LEFT JOIN flavors ON flavors.package_id = p.id "
+
				"    %s %s (%s) ORDER BY p.name;",
					comp, pattern == NULL ? "WHERE" : "AND", cond + 7);
	else
		sqlite3_snprintf(sizeof(sql), sql,
+
				"WITH flavors AS "
+
				"  (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
+
				"   LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
+
				"   LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
+
				"   WHERE tag.annotation = 'flavor') "
				"SELECT DISTINCT p.id, origin, p.name, p.name as uniqueid, "
					"version, comment, desc, "
					"message, arch, maintainer, www, "
@@ -160,6 +182,7 @@ pkgdb_query_cond(struct pkgdb *db, const char *cond, const char *pattern, match_
				"FROM packages AS p "
				"LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
				"LEFT JOIN categories ON categories.id = pkg_categories.category_id "
+
				"LEFT JOIN flavors ON flavors.package_id = p.id "
				"%s"
				" ORDER BY p.name", comp);

modified libpkg/repo/binary/query.c
@@ -103,13 +103,21 @@ pkg_repo_binary_query(struct pkg_repo *repo, const char *cond, const char *patte
	char *sql = NULL;
	const char	*comp = NULL;
	char basesql[] = ""
+
		"WITH flavors AS "
+
		"  (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
+
		"   LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
+
		"   LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
+
		"   WHERE tag.annotation = 'flavor') "
+

		"SELECT DISTINCT p.id, origin, p.name, p.name as uniqueid, version, comment, "
		"prefix, desc, arch, maintainer, www, "
		"licenselogic, flatsize, pkgsize, "
		"cksum, manifestdigest, path AS repopath, '%s' AS dbname "
		"FROM packages  as p "
		"LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
-
		"LEFT JOIN categories ON categories.id = pkg_categories.category_id %s"
+
		"LEFT JOIN categories ON categories.id = pkg_categories.category_id "
+
		"LEFT JOIN flavors ON flavors.package_id = p.id "
+
		" %s "
		"%s%s%s "
		"ORDER BY p.name;";

@@ -296,7 +304,10 @@ pkg_repo_binary_build_search_query(xstring *sql, match_t match,
		what = NULL;
		break;
	case FIELD_ORIGIN:
-
		what = "categories.name || substr(origin, instr(origin, '/')) as mycat";
+
		what = "categories.name || substr(origin, instr(origin, '/'))";
+
		break;
+
	case FIELD_FLAVOR:
+
		what = "categories.name || substr(origin, instr(origin, '/')) || '@' || flavor";
		break;
	case FIELD_NAME:
		what = "p.name";
@@ -320,8 +331,10 @@ pkg_repo_binary_build_search_query(xstring *sql, match_t match,
		orderby = NULL;
		break;
	case FIELD_ORIGIN:
-
		orderby = " ORDER BY mycat";
+
		orderby = " ORDER BY origin";
		break;
+
	case FIELD_FLAVOR:
+
		orderby = " ORDER BY p.name";
	case FIELD_NAME:
		orderby = " ORDER BY p.name";
		break;
@@ -351,13 +364,19 @@ pkg_repo_binary_search(struct pkg_repo *repo, const char *pattern, match_t match
	xstring	*sql = NULL;
	char *sqlcmd = NULL;
	const char	*multireposql = ""
+
		"WITH flavors AS "
+
		"  (SELECT package_id, value.annotation AS flavor FROM pkg_annotation "
+
		"   LEFT JOIN annotation tag ON pkg_annotation.tag_id = tag.annotation_id "
+
		"   LEFT JOIN annotation value ON pkg_annotation.value_id = value.annotation_id "
+
		"   WHERE tag.annotation = 'flavor') "
		"SELECT DISTINCT p.id, origin, p.name, version, comment, "
		"prefix, desc, arch, maintainer, www, "
		"licenselogic, flatsize, pkgsize, "
		"cksum, path AS repopath, '%1$s' AS dbname, '%2$s' AS repourl "
		"FROM packages  as p "
		"LEFT JOIN pkg_categories ON p.id = pkg_categories.package_id "
-
		"LEFT JOIN categories ON categories.id = pkg_categories.category_id ";
+
		"LEFT JOIN categories ON categories.id = pkg_categories.category_id "
+
		"LEFT JOIN flavors ON flavors.package_id = p.id ";

	if (pattern == NULL || pattern[0] == '\0')
		return (NULL);
modified src/search.c
@@ -373,9 +373,12 @@ exec_search(int argc, char **argv)
		return (EXIT_FAILURE);
	}
	if (search == FIELD_NONE) {
-
		if (strchr(pattern, '/') != NULL)
-
			search = FIELD_ORIGIN;
-
		else
+
		if (strchr(pattern, '/') != NULL) {
+
			if (strchr(pattern, '@') != NULL)
+
				search = FIELD_FLAVOR;
+
			else
+
				search = FIELD_ORIGIN;
+
		} else
			search = FIELD_NAMEVER; /* Default search */
	}
	if (label == FIELD_NONE)
@@ -392,6 +395,7 @@ exec_search(int argc, char **argv)
			opt |= INFO_TAG_ORIGIN|INFO_COMMENT;
		}
		break;
+
	case FIELD_FLAVOR:
	case FIELD_NAME:
		opt |= INFO_TAG_NAME|INFO_COMMENT;
		break;