How do you implement Load() and Save() for googles datastore when you have an array of structs? It is clearly possible, but how?
Firstly, when you allow the datastore itself to serialise a Person
with a list of Phone
objects, you can use reflection to see it internally creates a list of *datastore.Entity
objects:
package main
import (
"fmt"
"reflect"
"cloud.google.com/go/datastore"
)
type Phone struct {
Type string
Number string
}
type Person struct {
Name string
Phone []Phone
}
func main() {
person := Person{Name: "Bob", Phone: []Phone{Phone{"a", "b"}, Phone{"c", "d"}}}
// save here
}
}
Here is my work so far, this saves the name field, but causes an error on the *datastore.Entity
objects. here is my attempt:
func (p *Person) Save() ([]datastore.Property, error) {
props := []datastore.Property{
{
Name: "Name",
Value: p.Name,
},
}
var n []*datastore.Entity
for _, x := range p.Phone {
i1 := datastore.Property{Name: "Type", Value: x.Type}
i2 := datastore.Property{Name: "Number", Value: x.Number}
e := &datastore.Entity{Properties: []datastore.Property{i1, i2}}
n = append(n, e)
}
props = append(props, datastore.Property{Name:"Phone",Value:n})
return props, nil
}
Datastore itself complains with the following error:
invalid Value type []*datastore.Entity for a Property with Name "Phone"
I wonder if anyone can elucidate where I am going wrong? How do I save an array of structs in datastore in the same way datastore itself does?
Sample code above is on go playground: https://play.golang.org/p/AP1oFnlo1jm
After some amount of experimentation it turns out here is how to implement a Save()
method for an object that has structs. The datastore.Property must store an array of []interface{}
holding []*datastore.Entity
rather than a pure []*datastore.Entity
:
func (p *Person) Save() ([]datastore.Property, error) {
props := []datastore.Property{
{
Name: "Name",
Value: p.Name,
},
}
var n []interface{}
for _, x := range p.Phone {
i1 := datastore.Property{Name: "Type", Value: x.Type}
i2 := datastore.Property{Name: "Number", Value: x.Number}
e := &datastore.Entity{Properties: []datastore.Property{i1, i2}}
n = append(n, e)
}
props = append(props, datastore.Property{Name:"Phone",Value:n})
return props, nil
}