<pre style='margin:0'>
Umesh Singla (umeshksingla) pushed a commit to branch gsoc17-migrate
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/320b5754381baef3b90e886794d7e9b6c4799e28">https://github.com/macports/macports-base/commit/320b5754381baef3b90e886794d7e9b6c4799e28</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 320b5754381baef3b90e886794d7e9b6c4799e28
</span>Author: Umesh Singla <umeshksingla@macports.org>
AuthorDate: Sat Aug 26 16:42:01 2017 +0530

<span style='display:block; white-space:pre;color:#404040;'>    Initialize restore module
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Write fetching a snapshot and details method using snapshot-id
</span><span style='display:block; white-space:pre;color:#404040;'>    in sqlite registry
</span>---
 src/cregistry/snapshot.c     | 51 +++++++++++++++++++++++++++++++++--
 src/cregistry/snapshot.h     |  8 +++---
 src/macports1.0/macports.tcl | 15 +++++++++++
 src/macports1.0/restore.tcl  | 63 ++++++++++++++++++++++++++++++++++++++++++++
 src/macports1.0/snapshot.tcl |  5 ++--
 src/port/port.tcl            |  9 ++++++-
 src/registry2.0/snapshot.c   | 51 +++++++++++++++++------------------
 7 files changed, 168 insertions(+), 34 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/snapshot.c b/src/cregistry/snapshot.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 24cd878..2fff7eb 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -68,6 +68,54 @@ int get_parsed_variants(char* variants_str, variant* all_variants,
</span> }
 
 /**
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Opens an existing snapshot in the registry.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * NOTE: This function is actually not required but only to make sure that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *       the user has input a valid sqlite id for snapshot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [in] reg      registry to open snapshot in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [in] id       snapshot id as in registrydb
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @param [out] errPtr  on error, a description of the error that occurred
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @return              the snapshot if success; NULL if failure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+reg_snapshot* reg_snapshot_open(reg_registry* reg, sqlite_int64 id, reg_error* errPtr) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    sqlite3_stmt* stmt = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reg_snapshot* snapshot = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int lower_bound = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    char* query = "SELECT id FROM registry.snapshots WHERE id=?";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((sqlite3_prepare_v2(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            && (sqlite3_bind_int64(stmt, 1, id) == SQLITE_OK)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        int r;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        do {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            r = sqlite3_step(stmt);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            switch (r) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                case SQLITE_ROW:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    snapshot = (reg_snapshot*)malloc(sizeof(reg_snapshot));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    snapshot->id = sqlite3_column_int64(stmt, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    snapshot->reg = reg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    snapshot->proc = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                case SQLITE_DONE:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    errPtr->code = REG_NOT_FOUND;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    errPtr->description = sqlite3_mprintf("no snapshot found for id=%s", id);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    errPtr->free = (reg_error_destructor*) sqlite3_free;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                case SQLITE_BUSY:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    reg_sqlite_error(reg->db, errPtr, query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } while (r == SQLITE_BUSY);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_sqlite_error(reg->db, errPtr, query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (stmt) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        sqlite3_finalize(stmt);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return snapshot;
</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>  * Creates a new snapshot in the snapshots registry.
  *
  * @param [in] reg      the registry to create the entry in
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -100,13 +148,12 @@ reg_snapshot* reg_snapshot_create(reg_registry* reg, char* note, reg_error* errP
</span> 
                         switch (ports_saved) {
                             case 1:
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                                // TODO: pass the custom SUCCESS messages
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                // TODO: pass the custom SUCCESS message
</span>                                 break;
                             case 0:
                                 reg_sqlite_error(reg->db, errPtr, query);
                                 break;
                         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>                     }
                     break;
                 case SQLITE_BUSY:
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/snapshot.h b/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;color:#808080;'>index 3854e0e..c54faf4 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -64,7 +64,9 @@ typedef struct {
</span> // helper to parse variants into 'struct variant' form
 int get_parsed_variants(char* variants_str, variant* all_variants,
     char* delim, int* variant_count);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+// get snapshot using id
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+reg_snapshot* reg_snapshot_open(reg_registry* reg, sqlite_int64 id,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_error* errPtr);
</span> // create snapshot method
 reg_snapshot* reg_snapshot_create(reg_registry* reg, char* note,
         reg_error* errPtr);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -74,13 +76,13 @@ int snapshot_store_ports(reg_registry* reg, reg_snapshot* snapshot,
</span> // helper method for storing variants for a port in a snapshot
 int snapshot_store_port_variants(reg_registry* reg, reg_entry* port_entry,
         int snapshot_ports_id, reg_error* errPtr);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> // snapshot properties retrieval methods
 int reg_snapshot_propget(reg_snapshot* snapshot, char* key, char** value,
         reg_error* errPtr);
 int reg_snapshot_ports_get(reg_snapshot* snapshot, port*** ports,
         reg_error* errPtr);
 int reg_snapshot_ports_get_helper(reg_registry* reg,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        sqlite_int64 snapshot_port_id, variant*** variants, reg_error* errPtr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        sqlite_int64 snapshot_port_id, variant*** variants,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_error* errPtr);
</span> 
 #endif /* _CSNAPSHOT_H */
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/macports.tcl b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index d21ffac..e0e8073 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -39,6 +39,7 @@ package require diagnose 1.0
</span> package require reclaim 1.0
 package require selfupdate 1.0
 package require snapshot 1.0
<span style='display:block; white-space:pre;background:#e0ffe0;'>+package require restore 1.0
</span> package require migrate 1.0
 package require Tclx
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4421,6 +4422,20 @@ proc macports::snapshot_main {opts} {
</span>     return 0
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# restores a snapshot.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc macports::restore_main {opts} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Calls the main function for the 'port restore' command.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Args:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #           $opts having a 'snapshot-id' but not compulsorily
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Returns:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #           0 on successful execution.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    restore::main $opts
</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> proc macports::migrate_main {opts} {
 
     # Calls the main function for the 'port migrate' command.
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/restore.tcl b/src/macports1.0/restore.tcl
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..b17f4a5
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/restore.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,63 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#!@TCLSH@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Copyright (c) 2017 The MacPorts Project
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# All rights reserved.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Redistribution and use in source and binary forms, with or without
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# modification, are permitted provided that the following conditions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# are met:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 1. Redistributions of source code must retain the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    notice, this list of conditions and the following disclaimer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 2. Redistributions in binary form must reproduce the above copyright
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    notice, this list of conditions and the following disclaimer in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    documentation and/or other materials provided with the distribution.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# 3. Neither the name of Apple Inc. nor the names of its contributors
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    may be used to endorse or promote products derived from this software
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    without specific prior written permission.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# POSSIBILITY OF SUCH DAMAGE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package provide restore 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require macports 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require registry 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require snapshot 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+namespace eval restore {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   proc main {opts} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           array set options $opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if ([info exists options(ports_restore_snapshot-id)]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # use that snapshot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set snapshot [fetch_snapshot $options(ports_restore_snapshot-id)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            puts $snapshot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            puts [$snapshot note]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            puts [$snapshot created_at]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            puts [$snapshot ports]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # TODO: fetch the list of snapshots
</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><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   proc fetch_snapshot {snapshot_id} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           return [registry::snapshot get_by_id $snapshot_id]
</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;'>+    proc fetch_snapshot_details {snapshot} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span>\ No newline at end of file
<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 1b5f082..12a263c 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;'>@@ -31,7 +31,7 @@ namespace eval snapshot {
</span>             # An option used by user while creating snapshot manually
             # to identify a snapshot, usually followed by `port restore`
             if {[info exists options(ports_snapshot_note)]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                set note ports_snapshot_note
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set note $options(ports_snapshot_note)
</span>             } else {
                 set note "snapshot created for migration"
             }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -44,10 +44,9 @@ namespace eval snapshot {
</span>     proc all_snapshots {opts} {
         # List the snapshots
         puts "listing"
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc latest_snapshot {opts} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc fetch_snapshot {opts} {
</span>         # Get the latest snapshot
         return [registry::entry get_snapshot]
     }
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/port/port.tcl b/src/port/port.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 104b54b..dbb8201 100755
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/port/port.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/port/port.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2807,6 +2807,11 @@ proc action_snapshot { action portlist opts} {
</span>   return 0
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+proc action_restore { action portlist opts} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    macports::restore_main $opts
</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> proc action_migrate { action portlist opts} {
     macports::migrate_main $opts
     return 0
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4356,7 +4361,8 @@ array set action_array [list \
</span>     pkg         [list action_target         [ACTION_ARGS_PORTS]] \
     \
     snapshot    [list action_snapshot       [ACTION_ARGS_STRINGS]] \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    migrate    [list action_migrate       [ACTION_ARGS_STRINGS]] \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    restore    [list action_restore         [ACTION_ARGS_STRINGS]] \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    migrate    [list action_migrate         [ACTION_ARGS_STRINGS]] \
</span>     \
     quit        [list action_exit           [ACTION_ARGS_NONE]] \
     exit        [list action_exit           [ACTION_ARGS_NONE]] \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4463,6 +4469,7 @@ array set cmd_opts_array {
</span>     diagnose    {quiet}
     reclaim     {enable-reminders disable-reminders}
     snapshot    {{note 1}}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    restore     {{snapshot-id 1}}
</span> }
 
 ##
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/snapshot.c b/src/registry2.0/snapshot.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 8213feb..2cc59dc 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -95,31 +95,32 @@ static int snapshot_create(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[])
</span>     }
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-// static int get_snapshot_by_id(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//     printf("getting snapshot\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * registry::snaphot get snapshot_id
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * snapshot_id is required
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int snapshot_get(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-//     reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//     if (objc > 3) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         Tcl_WrongNumArgs(interp, 2, objv, "get_by_id ?snapshot_id?");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//     } else if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//     } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         sqlite_int64 id = atoll(Tcl_GetString(objv[2]));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         reg_error error;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         reg_snapshot* snapshot = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         int port_count = reg_snapshot_get(snapshot, id, snapshot, &error);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         if (snapshot != NULL && port_count >= 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//             Tcl_Obj* resultObj;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//             if (snapshot_to_obj(interp, &resultObj, snapshot, NULL, &error)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//                 Tcl_SetObjResult(interp, resultObj);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//                 return TCL_OK;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//             }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//         return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-//     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-// }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reg_registry* reg = registry_for(interp, reg_attached);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (objc > 3) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        Tcl_WrongNumArgs(interp, 2, objv, "get_by_id ?snapshot_id?");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else if (reg == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return TCL_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        sqlite_int64 id = atoll(Tcl_GetString(objv[2]));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_error error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        reg_snapshot* snapshot = reg_snapshot_open(reg, id, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (snapshot != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            Tcl_Obj* result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (snapshot_to_obj(interp, &result, snapshot, NULL, &error)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                Tcl_SetObjResult(interp, result);
</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><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return registry_failed(interp, &error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
 typedef struct {
     char* name;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -129,7 +130,7 @@ typedef struct {
</span> static snapshot_cmd_type snapshot_cmds[] = {
     /* Global commands */
     { "create", snapshot_create},
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    // { "get_by_id", get_snapshot_by_id},
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    { "get_by_id", snapshot_get},
</span>     { NULL, NULL }
 };
 
</pre><pre style='margin:0'>

</pre>