From 00d9423598d7718db56fb152972ba23e793788f3 Mon Sep 17 00:00:00 2001
From: Benjamin Wenger <ben@elixxir.ioo>
Date: Fri, 5 Mar 2021 14:14:39 -0800
Subject: [PATCH] implemented the upgrade fix, needs fixes

---
 storage/versioned/kv.go | 79 +++++++++++++++++++++--------------------
 ud/registered.go        |  2 +-
 2 files changed, 41 insertions(+), 40 deletions(-)

diff --git a/storage/versioned/kv.go b/storage/versioned/kv.go
index 72e0386de..58e81770f 100644
--- a/storage/versioned/kv.go
+++ b/storage/versioned/kv.go
@@ -12,7 +12,6 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
-	"strings"
 )
 
 const PrefixSeparator = "/"
@@ -30,11 +29,11 @@ func MakePartnerPrefix(id *id.ID) string {
 }
 
 // Upgrade functions must be of this type
-type Upgrade func(key string, oldObject *Object) (*Object,
+type Upgrade func(oldObject *Object) (*Object,
 	error)
 
+
 type root struct {
-	upgradeTable map[string]Upgrade
 	data         ekv.KeyValue
 }
 
@@ -48,29 +47,7 @@ type KV struct {
 func NewKV(data ekv.KeyValue) *KV {
 	newKV := KV{}
 	root := root{}
-	// Add new Upgrade functions to this Upgrade table
-	root.upgradeTable = make(map[string]Upgrade)
-	// All Upgrade functions should Upgrade to the latest version. You can
-	// call older Upgrade functions if you need to. Upgrade functions don't
-	// change the key or store the upgraded version of the data in the
-	// key/value store. There's no mechanism built in for this -- users
-	// should always make the key prefix before calling Set, and if they
-	// want the upgraded data persisted they should call Set with the
-	// upgraded data.
-	root.upgradeTable[MakeKeyWithPrefix("test", "")] = func(key string,
-		oldObject *Object) (*Object, error) {
-		if oldObject.Version == 1 {
-			return oldObject, nil
-		}
-		return &Object{
-			Version: 1,
-			// Upgrade functions don't need to update
-			// the timestamp
-			Timestamp: oldObject.Timestamp,
-			Data: []byte("this object was upgraded from" +
-				" v0 to v1"),
-		}, nil
-	}
+
 	root.data = data
 
 	newKV.r = &root
@@ -81,7 +58,7 @@ func NewKV(data ekv.KeyValue) *KV {
 // Get gets and upgrades data stored in the key/value store
 // Make sure to inspect the version returned in the versioned object
 func (v *KV) Get(key string) (*Object, error) {
-	key = v.prefix + key
+	key = v.makeKey(key)
 	jww.TRACE.Printf("Get %p with key %v", v.r.data, key)
 	// Get raw data
 	result := Object{}
@@ -89,23 +66,43 @@ func (v *KV) Get(key string) (*Object, error) {
 	if err != nil {
 		return nil, err
 	}
-	// If the key starts with a version tag that we can find in the table,
-	// we should call that function to Upgrade it
-	for version, upgrade := range v.r.upgradeTable {
-		if strings.HasPrefix(key, version) {
-			// We should run this Upgrade function
-			// The user of this function must update the key
-			// based on the version returned in this
-			// versioned object!
-			return upgrade(key, &result)
+	return &result, nil
+}
+
+// Get gets and upgrades data stored in the key/value store
+// Make sure to inspect the version returned in the versioned object
+func (v *KV) GetUpgrade(key string, table []Upgrade) (*Object, error) {
+	key = v.makeKey(key)
+	jww.TRACE.Printf("Get %p with key %v", v.r.data, key)
+	// Get raw data
+	result := &Object{}
+	err := v.r.data.Get(key, result)
+	if err != nil {
+		return nil, err
+	}
+
+	initialVersion := result.Version
+	for result.Version<uint64(len(table)){
+		oldVersion := result.Version
+		result, err = table[oldVersion](result)
+		if err!=nil{
+			jww.FATAL.Panicf("failed to upgrade key %s from " +
+				"version %v, initla version %v",  key, oldVersion,
+				initialVersion)
 		}
 	}
-	return &result, nil
+
+	if initialVersion<uint64(len(table)){
+		//save the upgraded file?
+	}
+
+	return result, nil
 }
 
+
 // delete removes a given key from the data store
 func (v *KV) Delete(key string) error {
-	key = v.prefix + key
+	key = v.makeKey(key)
 	jww.TRACE.Printf("delete %p with key %v", v.r.data, key)
 	return v.r.data.Delete(key)
 }
@@ -114,7 +111,7 @@ func (v *KV) Delete(key string) error {
 // When calling this, you are responsible for prefixing the key with the correct
 // type optionally unique id! Call MakeKeyWithPrefix() to do so.
 func (v *KV) Set(key string, object *Object) error {
-	key = v.prefix + key
+	key = v.makeKey(key)
 	jww.TRACE.Printf("Set %p with key %v", v.r.data, key)
 	return v.r.data.Set(key, object)
 }
@@ -132,3 +129,7 @@ func (v *KV) Prefix(prefix string) *KV {
 func (v *KV) GetFullKey(key string) string {
 	return v.prefix + key
 }
+
+func (v *KV)makeKey(key string)string{
+	return v.prefix + key
+}
\ No newline at end of file
diff --git a/ud/registered.go b/ud/registered.go
index 6c1065177..8191f2667 100644
--- a/ud/registered.go
+++ b/ud/registered.go
@@ -18,7 +18,7 @@ func (m *Manager) loadRegistered() {
 	var isReg = uint32(0)
 	obj, err := m.storage.Get(isRegisteredKey)
 	if err != nil {
-		jww.INFO.Printf("Failed to load is registered; "+
+		jww.INFO.Printf("Failed to load is registered, "+
 			"assuming un-registered: %s", err)
 	} else {
 		isReg = binary.BigEndian.Uint32(obj.Data)
-- 
GitLab