[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