Skip to content

Commit

Permalink
feat(examples): add upgrade pattern d example (gnolang#2151)
Browse files Browse the repository at this point in the history
Signed-off-by: moul <[email protected]>
  • Loading branch information
moul authored and omarsy committed Jun 3, 2024
1 parent 8856859 commit 1129217
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Lazy Migration Example

This example demonstrates lazy migrations from v1 to v2 of a data structure in Gno.

## Notes

Uses AVL trees, but storage can vary since public Get functions are used.

v1 can be made pausable and readonly during migration.
34 changes: 34 additions & 0 deletions examples/gno.land/r/x/manfred_upgrade_patterns/upgrade_d/v1/v1.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package v1

import (
"strconv"

"gno.land/p/demo/avl"
)

var myTree avl.Tree

type MyStruct struct {
FieldA string
FieldB int
}

func (s *MyStruct) String() string {
if s == nil {
return "nil"
}
return "v1:" + s.FieldA + ":" + strconv.Itoa(s.FieldB)
}

func Get(key string) *MyStruct {
ret, ok := myTree.Get(key)
if !ok {
return nil
}
return ret.(*MyStruct)
}

func init() {
myTree.Set("a", &MyStruct{FieldA: "a", FieldB: 1})
myTree.Set("b", &MyStruct{FieldA: "b", FieldB: 2})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"fmt"

"gno.land/r/x/manfred_upgrade_patterns/upgrade_d/v1"
)

func main() {
println("a", v1.Get("a"))
println("b", v1.Get("b"))
println("c", v1.Get("c"))
}

// Output:
// a v1:a:1
// b v1:b:2
// c nil
51 changes: 51 additions & 0 deletions examples/gno.land/r/x/manfred_upgrade_patterns/upgrade_d/v2/v2.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package v1

import (
"gno.land/p/demo/avl"
"gno.land/p/demo/ufmt"
"gno.land/r/x/manfred_upgrade_patterns/upgrade_d/v1"
)

var myTree avl.Tree

// MyStruct represents the structure with fields that may have been migrated from v1.
type MyStruct struct {
FieldA string // Appending "imported-from-v1" if migrating from v1.
FieldB uint64 // Switching from int to uint64 and multiplying by 1000 if migrating from v1.
FieldC bool // Adding a boolean field which is true by default for v1 objects.
}

// String returns a string representation of MyStruct.
func (s *MyStruct) String() string {
if s == nil {
return "nil"
}
return ufmt.Sprintf("v2:%s:%d:%t", s.FieldA, s.FieldB, s.FieldC)
}

// Get retrieves a MyStruct from the tree by key. If the key does not exist in the current version,
// it attempts to retrieve and migrate the structure from v1.
func Get(key string) *MyStruct {
ret, ok := myTree.Get(key)
if !ok {
v1Struct := v1.Get(key)
if v1Struct == nil {
return nil
}
// Lazy migration code: convert v1 structure to v2 structure.
v2Struct := &MyStruct{
FieldA: v1Struct.FieldA + "-imported-from-v1",
FieldB: uint64(v1Struct.FieldB * 1000),
FieldC: true,
}
myTree.Set(key, v2Struct)
return v2Struct
}
return ret.(*MyStruct)
}

// init initializes the tree with some default values.
func init() {
myTree.Set("c", &MyStruct{FieldA: "c", FieldB: 3, FieldC: true})
myTree.Set("d", &MyStruct{FieldA: "d", FieldB: 4, FieldC: false})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"fmt"

"gno.land/r/x/manfred_upgrade_patterns/upgrade_d/v2"
)

func main() {
println("a", v1.Get("a"))
println("b", v1.Get("b"))
println("c", v1.Get("c"))
println("d", v1.Get("d"))
println("e", v1.Get("e"))
}

// Output:
// a v2:a-imported-from-v1:1000:true
// b v2:b-imported-from-v1:2000:true
// c v2:c:3:true
// d v2:d:4:false
// e nil

0 comments on commit 1129217

Please sign in to comment.