Saving Arbitrary Structs

Now for loading them
This commit is contained in:
Brian Buller 2023-06-08 09:52:03 -05:00
parent 7c152f1273
commit ac4d008f57
3 changed files with 66 additions and 34 deletions

View File

@ -8,25 +8,44 @@ import (
type any interface{}
func (b *DB) LoadStruct(path []string, dest any) error {
func (b *DB) Load(path []string, dest any) error {
destValue := reflect.ValueOf(dest)
if destValue.Kind().String() != "ptr" {
fmt.Println("Loading:", path, destValue)
if destValue.Kind() != reflect.Pointer {
return errors.New("Destination must be a pointer")
}
d := reflect.Indirect(destValue)
if d.Kind().String() != "struct" {
if d.Kind() != reflect.Struct {
path, name := path[:len(path)-1], path[len(path)-1]
return b.GetForInterface(path, name, dest)
}
entityType := reflect.TypeOf(dest).Elem()
fmt.Println("EntityType:", entityType.String())
var ret error
for i := 0; i < entityType.NumField(); i++ {
structFld := entityType.Field(i)
fldName := FieldName(structFld)
fmt.Printf("Field (%d): %s (%s)\n", i, fldName, structFld.Type)
fmt.Println("Loading Field:", fldName, "->", structFld.Type.Kind())
switch structFld.Type.Kind() {
case reflect.Pointer, reflect.Struct:
var wrk reflect.Value
if structFld.Type.Kind() == reflect.Pointer {
wrk2 := reflect.ValueOf(structFld)
fmt.Println("wrk2:", reflect.TypeOf(wrk2.Interface()))
} else {
wrk = reflect.New(reflect.TypeOf(structFld))
}
fmt.Println("-> Recurse (struct)", reflect.TypeOf(wrk).Kind())
err := b.Load(append(path, fldName), wrk)
if err != nil {
if ret == nil {
ret = err
}
} else {
// Set the value
reflect.ValueOf(dest).Elem().FieldByName(structFld.Name).Set(reflect.ValueOf(wrk))
}
case reflect.String:
var wrk string
err := b.GetForInterface(path, fldName, &wrk)
@ -95,33 +114,39 @@ func (b *DB) LoadStruct(path []string, dest any) error {
return ret
}
func (b *DB) SaveStruct(path []string, src any) error {
func (b *DB) Save(path []string, src any) error {
t := reflect.TypeOf(src)
fmt.Println(t.Kind())
if t.Kind() == reflect.Pointer {
// Save the actual struct
return b.SaveStruct(path, reflect.Indirect(reflect.ValueOf(src)))
elem := reflect.ValueOf(src).Elem()
return b.Save(path, elem.Interface())
}
fields := reflect.VisibleFields(t)
r := reflect.ValueOf(src)
fmt.Println()
for _, fld := range fields {
f := r.FieldByName(fld.Name)
fmt.Println(f, FieldName(fld))
/*
if t.Kind() == reflect.Struct {
fields := reflect.VisibleFields(t)
r := reflect.ValueOf(src)
for _, fld := range fields {
f := r.FieldByName(fld.Name)
if (f.Kind() == reflect.Struct || f.Kind() == reflect.Pointer) && f != src {
fmt.Println("Recursing on Field:", f)
err := b.SaveStruct(append(path, FieldName(fld)), f)
if err != nil {
return err
if f.CanInterface() {
err := b.Save(append(path, FieldName(fld)), f.Interface())
if err != nil {
return err
}
} else {
err := b.Save(append(path, FieldName(fld)), reflect.Indirect(f))
if err != nil {
return err
}
}
} else {
if err := b.Set(path, FieldName(fld), f); err != nil {
return err
}
}
*/
}
} else {
return b.Set(path[:len(path)-1], path[len(path)-1], src)
}
return nil
}

View File

@ -157,7 +157,7 @@ func (b *DB) GetForInterface(path []string, key string, val interface{}) error {
}
return err
}
func (b *DB) Load(path []string, key string, into interface{}) error {
func (b *DB) LoadInto(path []string, key string, into interface{}) error {
var err error
switch v := into.(type) {
case string:

View File

@ -9,8 +9,8 @@ import (
)
func main() {
example1()
fmt.Println()
//example1()
//fmt.Println()
example2()
}
@ -23,7 +23,7 @@ func example1() {
}
fmt.Println("## Saving Struct")
err = db.SaveStruct(
err = db.Save(
[]string{"examples", "example1"},
ExampleType{
Name: "Example 1",
@ -51,7 +51,7 @@ func example1() {
fmt.Println("## Example 1-2: LoadStruct, simple")
var name string
err = db.LoadStruct(
err = db.Load(
[]string{"examples", "example1", "name"},
&name,
)
@ -64,7 +64,7 @@ func example1() {
fmt.Println("## Example 1-3: Struct")
fmt.Println("Loading into Struct")
newStruct := ExampleType{}
err = db.LoadStruct(
err = db.Load(
[]string{"examples", "example1"},
&newStruct,
)
@ -79,23 +79,28 @@ func example2() {
os.Exit(1)
}
fmt.Println("## Saving Struct")
err = db.SaveStruct(
num := 12345
err = db.Save(
[]string{"examples", "example2"},
&ExampleType2{
Name: "Example 2",
Age: 20,
SubType: &ExampleSubType{
SubTypePtr: &ExampleSubType{
SubName: "Example SubType Pointer",
},
SubType: ExampleSubType{
SubName: "Example SubType",
},
Number: &num,
})
if err != nil {
fmt.Printf("Error saving struct: %s\n", err.Error())
os.Exit(1)
}
//newStruct := ExampleType2{}
//err = db.LoadStruct([]string{"examples", "example2"}, &newStruct)
//fmt.Println(newStruct)
newStruct := ExampleType2{}
err = db.Load([]string{"examples", "example2"}, &newStruct)
fmt.Println(newStruct)
}
type ExampleType struct {
@ -109,9 +114,11 @@ func (e ExampleType) String() string {
}
type ExampleType2 struct {
Name string `boltease:"name"`
Age int `boltease:"age"`
SubType *ExampleSubType `boltease:"subtype"`
Name string `boltease:"name"`
Age int `boltease:"age"`
SubTypePtr *ExampleSubType `boltease:"subtypeptr"`
SubType ExampleSubType `boltease:"subtype"`
Number *int `boltease:"number"`
}
func (e ExampleType2) String() string {