<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/acf66bed9fd264a8fda8a1275c803a357f0fcab0">https://github.com/macports/macports-base/commit/acf66bed9fd264a8fda8a1275c803a357f0fcab0</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new acf66bed9 Implement snapshot deletion
</span>acf66bed9 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit acf66bed9fd264a8fda8a1275c803a357f0fcab0
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Thu Jun 6 11:46:53 2024 +1000

<span style='display:block; white-space:pre;color:#404040;'>    Implement snapshot deletion
</span>---
 src/cregistry/sql.c               | 27 ++++++++++++++++++++++++++-
 src/macports1.0/snapshot.tcl      | 30 +++++++++++++++++++++++++++++-
 src/registry2.0/registry.c        | 12 ++++++++++++
 src/registry2.0/registry_util.tcl |  4 +++-
 4 files changed, 70 insertions(+), 3 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/sql.c b/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;color:#808080;'>index dfd88969e..a5803a3c1 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -237,6 +237,7 @@ int create_tables(sqlite3* db, reg_error* errPtr) {
</span>             " ON DELETE CASCADE"
             ")",
         "CREATE INDEX registry.snapshot_file_path ON snapshot_files(path)",
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        "CREATE INDEX registry.snapshot_file_id ON snapshot_files(id)",
</span> 
         "COMMIT",
         NULL
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1045,6 +1046,30 @@ int update_db(sqlite3* db, reg_error* errPtr) {
</span>             continue;
         }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (sql_version(NULL, -1, version, -1, "1.215") < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            static char* version_1_215_queries[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "CREATE INDEX registry.snapshot_file_id ON snapshot_files(id)",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                /* Update version and commit */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "UPDATE registry.metadata SET value = '1.215' WHERE key = 'version'",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                "COMMIT",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                NULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            sqlite3_finalize(stmt);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            stmt = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (!do_queries(db, version_1_215_queries, errPtr)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                rollback_db(db);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            did_update = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>         /* add new versions here, but remember to:
          *  - finalize the version query statement and set stmt to NULL
          *  - do _not_ use "BEGIN" in your query list, since a transaction has
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1054,7 +1079,7 @@ int update_db(sqlite3* db, reg_error* errPtr) {
</span>          *  - update the current version number below
          */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if (sql_version(NULL, -1, version, -1, "1.214") > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (sql_version(NULL, -1, version, -1, "1.215") > 0) {
</span>             /* the registry was already upgraded to a newer version and cannot be used anymore */
             reg_throw(errPtr, REG_INVALID, "Version number in metadata table is newer than expected.");
             sqlite3_finalize(stmt);
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/snapshot.tcl b/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 533486c6f..169e2f01e 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -164,7 +164,7 @@ namespace eval snapshot {
</span>                 ui_msg [string trimright $note "\n"]
             }
             "delete" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_error "delete operation not implemented"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return [delete_snapshot $opts]
</span>             }
         }
     }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -206,6 +206,34 @@ namespace eval snapshot {
</span>         return $snapshot
     }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Remove a snapshot from the registry. Not called 'delete' to avoid
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # confusion with the proc in portutil.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc delete_snapshot {opts} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        global registry::tdbc_connection
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![info exists tdbc_connection]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            registry::tdbc_connect
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set snapshot_id [dict get $opts ports_snapshot_delete]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[catch {registry::snapshot get_by_id $snapshot_id}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_error "No such snapshot ID: $snapshot_id"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # relies on cascading delete to also remove snapshot ports and files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set query {DELETE FROM snapshots WHERE id = :snapshot_id}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set stmt [$tdbc_connection prepare $query]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        $tdbc_connection transaction {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set results [$stmt execute]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[$results rowcount] < 1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_warn "delete_snapshot: no rows were deleted for snapshot ID: $snapshot_id"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            registry::set_needs_vacuum
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        $results close
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        $stmt close
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>     # Get the port name that owns the given file path in the given snapshot.
     proc file_owner {path snapshot_id} {
         global registry::tdbc_connection
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/registry.c b/src/registry2.0/registry.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 2df0507f0..47c304ea8 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/registry.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/registry.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -390,6 +390,17 @@ int metadata_cmd(ClientData clientData UNUSED, Tcl_Interp* interp, int objc,
</span>     return TCL_ERROR;
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Allow setting the needs_vacuum flag from scripts. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int set_needs_vacuum_cmd(ClientData clientData UNUSED, Tcl_Interp* interp, int objc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_Obj* const objv[]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc != 1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_WrongNumArgs(interp, 1, objv, "cmd");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Tcl_SetAssocData(interp, "registry::needs_vacuum", NULL, (ClientData)1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return TCL_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /**
  * Initializer for the registry lib.
  *
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -409,6 +420,7 @@ int Registry_Init(Tcl_Interp* interp) {
</span>     Tcl_CreateObjCommand(interp, "registry::file", file_cmd, NULL, NULL);
     Tcl_CreateObjCommand(interp, "registry::portgroup", portgroup_cmd, NULL, NULL);
     Tcl_CreateObjCommand(interp, "registry::metadata", metadata_cmd, NULL, NULL);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    Tcl_CreateObjCommand(interp, "registry::set_needs_vacuum", set_needs_vacuum_cmd, NULL, NULL);
</span>     if (Tcl_PkgProvide(interp, "registry2", "2.0") != TCL_OK) {
         return TCL_ERROR;
     }
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/registry_util.tcl b/src/registry2.0/registry_util.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 1b1e163b3..f2f01a8c0 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/registry_util.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/registry_util.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -177,7 +177,9 @@ proc tdbc_connect {} {
</span>     variable tdbc_connection
     set reg_path [::file join ${macports::registry.path} registry registry.db]
     set tdbc_connection [tdbc::sqlite3::connection new $reg_path]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set stmt [$tdbc_connection prepare {PRAGMA foreign_keys = ON}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    $stmt execute
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    $stmt close
</span> }
 
 ## Delete the given dependencies for the given entry
</pre><pre style='margin:0'>

</pre>