Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Add pkgdb_{add,modify,delete}_annotation()
Matthew Seaman committed 13 years ago
commit 4d4dc4d69af687519c364ff9034d408973ca46be
parent 93b70c7
3 files changed +145 -9
modified libpkg/pkg.c
@@ -908,7 +908,7 @@ pkg_addannotation(struct pkg *pkg, const char *key, const char *value)
	struct pkg_note *an = NULL;

	assert(pkg != NULL);
-
	assert(key != NULL && key[0] != '\0');
+
	assert(key != NULL);
	assert(value != NULL);

	/* Keys are unique per-package */
@@ -938,17 +938,16 @@ pkg_delannotation(struct pkg *pkg, const char *key)
	struct pkg_note *an = NULL;

	assert(pkg != NULL);
-
	assert(key != NULL && key[0] != '\0');
+
	assert(key != NULL);

	HASH_FIND_STR(pkg->annotations, __DECONST(char *, key), an);
	if (an != NULL) {
-
		HASH_DEL(pkg->annotations,
-
		    __DECONST(char *, pkg_annotation_key(an)));
+
		HASH_DEL(pkg->annotations, an);
		pkg_annotation_free(an);
		return (EPKG_OK);
	} else {
-
		pkg_emit_error("deleting key %s -- no annotation found"
-
			       " with matching key", key);
+
		pkg_emit_error("deleting key \'%s\' -- no matching annotation "
+
			       "found", key);
		return (EPKG_WARN);
	}
}
modified libpkg/pkg.h.in
@@ -963,6 +963,19 @@ struct pkgdb_it * pkgdb_query_which(struct pkgdb *db, const char *path, bool glo
struct pkgdb_it * pkgdb_query_shlib_required(struct pkgdb *db, const char *shlib);
struct pkgdb_it * pkgdb_query_shlib_provided(struct pkgdb *db, const char *shlib);

+
/**
+
 * Add/Modify/Delete an annotation for a package
+
 * @param key -- tag for the annotation
+
 * @param value -- text of the annotation
+
 * @return An error code
+
 */
+
int pkgdb_add_annotation(struct pkgdb *db, const char *pkgname,
+
	const char *pkgversion, const char *key, const char *value);
+
int pkgdb_modify_annotation(struct pkgdb *db, const char *pkgname,
+
	const char *pkgversion, const char *key, const char *value);
+
int pkgdb_delete_annotation(struct pkgdb *db, const char *pkgname,
+
        const char *pkgversion, const char *key);
+

#define PKG_LOAD_BASIC			0
#define PKG_LOAD_DEPS			(1U << 0)
#define PKG_LOAD_RDEPS			(1U << 1)
modified libpkg/pkgdb.c
@@ -2093,6 +2093,9 @@ typedef enum _sql_prstmt_index {
	SHLIBS_PROV,
	ANNOTATE1,
	ANNOTATE2,
+
	ANNOTATE_ADD1,
+
	ANNOTATE_DEL1,
+
	ANNOTATE_DEL2,
	PRSTMT_LAST,
} sql_prstmt_index;

@@ -2230,10 +2233,35 @@ static sql_prstmt sql_prepared_statements[PRSTMT_LAST] = {
		NULL,
		"INSERT OR ROLLBACK INTO pkg_annotation(package_id, key_id, value_id) "
		"VALUES (?1,"
-
		" (SELECT annotation_id FROM annotation WHERE annotation=?2),"
-
		" (SELECT annotation_id FROM annotation WHERE annotation=?3))",
+
		" (SELECT annotation_id FROM annotation WHERE annotation = ?2),"
+
		" (SELECT annotation_id FROM annotation WHERE annotation = ?3))",
		"ITT",
	},
+
	[ANNOTATE_ADD1] = {
+
		NULL,
+
		"INSERT OR ROLLBACK INTO pkg_annotation(package_id, key_id, value_id) "
+
		"VALUES ("
+
		" (SELECT id FROM packages WHERE name = ?1 AND version = ?2),"
+
		" (SELECT annotation_id FROM annotation WHERE annotation = ?3),"
+
		" (SELECT annotation_id FROM annotation WHERE annotation = ?4))",
+
		"TTTT",
+
	},
+
	[ANNOTATE_DEL1] = {
+
		NULL,
+
		"DELETE FROM pkg_annotation WHERE "
+
		"package_id IN"
+
                " (SELECT id FROM packages WHERE name = ?1 AND version = ?2) "
+
		"AND key_id IN"
+
		" (SELECT key_id FROM annotation WHERE annotation = ?3)",
+
		"TTT",
+
	},
+
	[ANNOTATE_DEL2] = {
+
		NULL,
+
		"DELETE FROM annotation WHERE"
+
		" annotation_id NOT IN (SELECT key_id FROM pkg_annotation) AND"
+
		" annotation_id NOT IN (SELECT value_id FROM pkg_annotation)",
+
		"",
+
	},
	/* PRSTMT_LAST */
};

@@ -2604,7 +2632,7 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int complete, int forced)
		goto cleanup;

	/*
-
	 * Insert annotations
+
	 * Insert annotation
	 */
	if (pkgdb_insert_annotations(pkg, package_id, s) != EPKG_OK)
		goto cleanup;
@@ -2745,6 +2773,102 @@ pkgdb_reanalyse_shlibs(struct pkgdb *db, struct pkg *pkg)
	return (ret);
}

+
int
+
pkgdb_add_annotation(struct pkgdb *db, const char *pkgname,
+
    const char *pkgversion, const char *key, const char *value)
+
{
+
	assert(pkgname != NULL && pkgname[0] != '\0');
+
	assert(pkgversion != NULL && pkgversion[0] != '\0');
+
	assert(key != NULL);
+
	assert(value != NULL);
+

+
	if (!db->prstmt_initialized && prstmt_initialize(db) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	if (pkgdb_transaction_begin(db->sqlite, NULL) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	if (run_prstmt(ANNOTATE1, key) != SQLITE_DONE
+
	    ||
+
	    run_prstmt(ANNOTATE1, value) != SQLITE_DONE
+
	    ||
+
	    run_prstmt(ANNOTATE_ADD1, pkgname, pkgversion, key, value)
+
	    != SQLITE_DONE) {
+
		ERROR_SQLITE(db->sqlite);
+
		pkgdb_transaction_rollback(db->sqlite, NULL);
+
		return (EPKG_FATAL);
+
	}
+

+
	if (pkgdb_transaction_commit(db->sqlite, NULL) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	return (EPKG_OK);
+
}
+

+
int
+
pkgdb_modify_annotation(struct pkgdb *db, const char *pkgname,
+
    const char *pkgversion, const char *key, const char *value)
+
{
+
	assert(pkgname != NULL && pkgname[0] != '\0');
+
	assert(pkgversion != NULL && pkgversion[0] != '\0');
+
	assert(key != NULL);
+
	assert(value != NULL);
+

+
	if (!db->prstmt_initialized && prstmt_initialize(db) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	if (pkgdb_transaction_begin(db->sqlite, NULL) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	if (run_prstmt(ANNOTATE_DEL1, pkgname, pkgversion, key) != SQLITE_DONE
+
	    ||
+
	    run_prstmt(ANNOTATE1, key) != SQLITE_DONE /* is this necessary? */
+
	    ||
+
	    run_prstmt(ANNOTATE1, value) != SQLITE_DONE
+
	    ||
+
	    run_prstmt(ANNOTATE_ADD1, pkgname, pkgversion, key, value) !=
+
	        SQLITE_DONE
+
	    ||
+
	    run_prstmt(ANNOTATE_DEL2) != SQLITE_DONE) {
+
		ERROR_SQLITE(db->sqlite);
+
		pkgdb_transaction_rollback(db->sqlite, NULL);
+
		return (EPKG_FATAL);
+
	}
+

+
	if (pkgdb_transaction_commit(db->sqlite, NULL) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	return (EPKG_OK);
+
}
+

+
int
+
pkgdb_delete_annotation(struct pkgdb *db, const char *pkgname,
+
    const char *pkgversion, const char *key)
+
{
+
	assert(pkgname != NULL && pkgname[0] != '\0');
+
	assert(pkgversion != NULL && pkgversion[0] != '\0');
+
	assert(key != NULL);
+

+
	if (!db->prstmt_initialized && prstmt_initialize(db) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	if (pkgdb_transaction_begin(db->sqlite, NULL) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	if (run_prstmt(ANNOTATE_DEL1, pkgname, pkgversion, key) != SQLITE_DONE
+
	    ||
+
	    run_prstmt(ANNOTATE_DEL2) != SQLITE_DONE) {
+
		ERROR_SQLITE(db->sqlite);
+
		pkgdb_transaction_rollback(db->sqlite, NULL);
+
		return (EPKG_FATAL);
+
	}
+

+
	if (pkgdb_transaction_commit(db->sqlite, NULL) != EPKG_OK)
+
		return (EPKG_FATAL);
+

+
	return (EPKG_OK);
+
}
+


int
pkgdb_register_finale(struct pkgdb *db, int retcode)