[Midnightbsd-cvs] src [12200] trunk/lib/libmport: rework install logic to try to use a recursive query in sqlite instead
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat May 25 13:42:07 EDT 2019
Revision: 12200
http://svnweb.midnightbsd.org/src/?rev=12200
Author: laffer1
Date: 2019-05-25 13:42:06 -0400 (Sat, 25 May 2019)
Log Message:
-----------
rework install logic to try to use a recursive query in sqlite instead
Modified Paths:
--------------
trunk/lib/libmport/index_depends.c
trunk/lib/libmport/install.c
Modified: trunk/lib/libmport/index_depends.c
===================================================================
--- trunk/lib/libmport/index_depends.c 2019-05-25 17:41:03 UTC (rev 12199)
+++ trunk/lib/libmport/index_depends.c 2019-05-25 17:42:06 UTC (rev 12200)
@@ -56,25 +56,25 @@
MPORT_CHECK_FOR_INDEX(mport, "mport_index_depends_list()")
if (mport_db_prepare(mport->db, &stmt,
- "SELECT COUNT(*) FROM idx.depends WHERE pkg = %Q and version = %Q",
+ "with RECURSIVE under_dep (parent, parent_ver, pkg, version, level) as ( values('?', '?', %Q, %Q, 0) union all select depends.pkg as parent, depends.version as parent_ver, depends.d_pkg as pkg, depends.d_version as version, under_dep.level + 1 from depends JOIN under_dep on depends.pkg = under_dep.pkg) select count(*) FROM under_dep where level > 0;",
pkgname, version) != MPORT_OK) {
sqlite3_finalize(stmt);
RETURN_CURRENT_ERROR;
}
-
+
switch (sqlite3_step(stmt)) {
- case SQLITE_ROW:
- count = sqlite3_column_int(stmt, 0);
- break;
- case SQLITE_DONE:
- ret = SET_ERROR(MPORT_ERR_FATAL,
- "No rows returned from a 'SELECT COUNT(*)' query.");
- goto DONE;
- break;
- default:
- ret = SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db));
- goto DONE;
- break;
+ case SQLITE_ROW:
+ count = sqlite3_column_int(stmt, 0);
+ break;
+ case SQLITE_DONE:
+ ret = SET_ERROR(MPORT_ERR_FATAL,
+ "No rows returned from a 'SELECT COUNT(*)' query.");
+ goto DONE;
+ break;
+ default:
+ ret = SET_ERROR(MPORT_ERR_FATAL, sqlite3_errmsg(mport->db));
+ goto DONE;
+ break;
}
sqlite3_finalize(stmt);
@@ -86,7 +86,8 @@
return MPORT_OK;
if (mport_db_prepare(mport->db, &stmt,
- "SELECT pkg, version, d_pkg, d_version FROM idx.depends WHERE pkg= %Q and version=%Q", pkgname, version) != MPORT_OK) {
+ "with RECURSIVE under_dep (parent, parent_ver, pkg, version, level) as ( values('?', '?', %Q, %Q, 0) union all select depends.pkg as parent, depends.version as parent_ver, depends.d_pkg as pkg, depends.d_version as version, under_dep.level + 1 from depends JOIN under_dep on depends.pkg = under_dep.pkg) select parent, parent_ver, pkg, version, level FROM under_dep where level > 0;"
+ , pkgname, version) != MPORT_OK) {
ret = mport_err_code();
goto DONE;
}
@@ -99,11 +100,16 @@
ret = MPORT_ERR_FATAL;
goto DONE;
}
-
+
+ /* parent, parent_ver, pkg, version, level */
e[i]->pkgname = strdup(sqlite3_column_text(stmt, 0));
e[i]->version = strdup(sqlite3_column_text(stmt, 1));
e[i]->d_pkgname = strdup(sqlite3_column_text(stmt, 2));
e[i]->d_version = strdup(sqlite3_column_text(stmt, 3));
+ e[i]->level = sqlite3_column_int(stmt, 4);
+ /* default these to false */
+ e[i]->already_installed = false;
+ e[i]->needs_upgrade = false;
if (e[i]->pkgname == NULL ||
e[i]->version == NULL ||
Modified: trunk/lib/libmport/install.c
===================================================================
--- trunk/lib/libmport/install.c 2019-05-25 17:41:03 UTC (rev 12199)
+++ trunk/lib/libmport/install.c 2019-05-25 17:42:06 UTC (rev 12200)
@@ -36,82 +36,82 @@
MPORT_PUBLIC_API int
mport_install(mportInstance *mport, const char *pkgname, const char *version, const char *prefix)
{
- mportIndexEntry **e;
- char *filename;
- int ret = MPORT_OK;
- int e_loc = 0;
+ mportIndexEntry **e;
+ char *filename;
+ int ret = MPORT_OK;
+ int e_loc = 0;
- MPORT_CHECK_FOR_INDEX(mport, "mport_install()");
-
- if (mport_index_lookup_pkgname(mport, pkgname, &e) != MPORT_OK)
- RETURN_CURRENT_ERROR;
+ MPORT_CHECK_FOR_INDEX(mport, "mport_install()");
- /* we don't support installing more than one top-level package at a time.
- * Consider a situation like this:
- *
- * mport_install(mport, "p5-Class-DBI*");
- *
- * Say this matches p5-Class-DBI and p5-Class-DBI-AbstractSearch
- * and say the order from the index puts p5-Class-DBI-AbstractSearch
- * first.
- *
- * p5-Class-DBI-AbstractSearch is installed, and its depends installed.
- * However, p5-Class-DBI is a depend of p5-Class-DBI-AbstractSearch, so
- * when it comes time to install p5-Class-DBI, we can't - because it is
- * already installed.
- *
- * If a user facing application wants this functionality, it would be
- * easy to piece together with mport_index_lookup_pkgname(), a
- * check for already installed packages, and mport_install().
- */
+ if (mport_index_lookup_pkgname(mport, pkgname, &e) != MPORT_OK)
+ RETURN_CURRENT_ERROR;
- if (e[1] != NULL) {
- if (version != NULL) {
- while (e[e_loc] != NULL) {
- if (strcmp(e[e_loc]->version, version) == 0) {
- break;
- }
- e_loc++;
- }
- if (e[e_loc] == NULL) {
- mport_index_entry_free_vec(e);
- RETURN_ERRORX(MPORT_ERR_FATAL, "Cound not resolve '%s-%s'.",
- pkgname, version);
- }
- } else {
- mport_index_entry_free_vec(e);
- RETURN_ERRORX(MPORT_ERR_FATAL, "Could not resolve '%s' to a single package.", pkgname);
- }
- }
-
- asprintf(&filename, "%s/%s", MPORT_FETCH_STAGING_DIR, e[e_loc]->bundlefile);
- if (filename == NULL) {
- mport_index_entry_free_vec(e);
- RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory.");
- }
+ /* we don't support installing more than one top-level package at a time.
+ * Consider a situation like this:
+ *
+ * mport_install(mport, "p5-Class-DBI*");
+ *
+ * Say this matches p5-Class-DBI and p5-Class-DBI-AbstractSearch
+ * and say the order from the index puts p5-Class-DBI-AbstractSearch
+ * first.
+ *
+ * p5-Class-DBI-AbstractSearch is installed, and its depends installed.
+ * However, p5-Class-DBI is a depend of p5-Class-DBI-AbstractSearch, so
+ * when it comes time to install p5-Class-DBI, we can't - because it is
+ * already installed.
+ *
+ * If a user facing application wants this functionality, it would be
+ * easy to piece together with mport_index_lookup_pkgname(), a
+ * check for already installed packages, and mport_install().
+ */
- if (!mport_file_exists(filename)) {
- if (mport_fetch_bundle(mport, e[e_loc]->bundlefile) != MPORT_OK) {
- free(filename);
- mport_index_entry_free_vec(e);
- RETURN_CURRENT_ERROR;
- }
- }
+ if (e[1] != NULL) {
+ if (version != NULL) {
+ while (e[e_loc] != NULL) {
+ if (strcmp(e[e_loc]->version, version) == 0) {
+ break;
+ }
+ e_loc++;
+ }
+ if (e[e_loc] == NULL) {
+ mport_index_entry_free_vec(e);
+ RETURN_ERRORX(MPORT_ERR_FATAL, "Could not resolve '%s-%s'.",
+ pkgname, version);
+ }
+ } else {
+ mport_index_entry_free_vec(e);
+ RETURN_ERRORX(MPORT_ERR_FATAL, "Could not resolve '%s' to a single package.", pkgname);
+ }
+ }
- if (mport_verify_hash(filename, e[e_loc]->hash) == 0) {
- free(filename);
- mport_index_entry_free_vec(e);
+ asprintf(&filename, "%s/%s", MPORT_FETCH_STAGING_DIR, e[e_loc]->bundlefile);
+ if (filename == NULL) {
+ mport_index_entry_free_vec(e);
+ RETURN_ERROR(MPORT_ERR_FATAL, "Out of memory.");
+ }
- if (unlink(filename) == 0)
- RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification and was removed.\n");
- else
- RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification, but could not be removed.\n");
- }
-
- ret = mport_install_primative(mport, filename, prefix);
+ if (!mport_file_exists(filename)) {
+ if (mport_fetch_bundle(mport, e[e_loc]->bundlefile) != MPORT_OK) {
+ free(filename);
+ mport_index_entry_free_vec(e);
+ RETURN_CURRENT_ERROR;
+ }
+ }
- free(filename);
- mport_index_entry_free_vec(e);
-
- return ret;
+ if (mport_verify_hash(filename, e[e_loc]->hash) == 0) {
+ free(filename);
+ mport_index_entry_free_vec(e);
+
+ if (unlink(filename) == 0)
+ RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification and was removed.\n");
+ else
+ RETURN_ERROR(MPORT_ERR_FATAL, "Package failed hash verification, but could not be removed.\n");
+ }
+
+ ret = mport_install_primative(mport, filename, prefix);
+
+ free(filename);
+ mport_index_entry_free_vec(e);
+
+ return ret;
}
More information about the Midnightbsd-cvs
mailing list