The struct datastore.Entity looks very useful, and it's how I want to process entities, but I don't see any API the makes use of it. Most of the functions (such as Get) take an interface{}
that only seems to work if it is struct that is precisely structured like the incoming data.
// https://godoc.org/cloud.google.com/go/datastore#Client.Get
ctx := context.Background()
client, err := datastore.NewClient(ctx, "project-id")
if err != nil {
// TODO: Handle error.
}
type Article struct {
Title string
Description string
Body string `datastore:",noindex"`
Author *datastore.Key
PublishedAt time.Time
}
key := datastore.NameKey("Article", "articled1", nil)
article := &Article{}
if err := client.Get(ctx, key, article); err != nil {
// TODO: Handle error.
}
How would I obtain this entity in a generalized way? What if I don't know the structure perfectly? (More specifically, how do I obtain an instance of datastore.Entity
instead?)
So you want a "general" type that can hold any type of entity? The datastore
package already provides you such a type: datastore.PropertyList
.
This is how you can use it:
var entity datastore.PropertyList
if err := client.Get(ctx, key, &entity); err != nil {
// TODO: Handle error.
}
Relevant docs from datastore
:
Properties
An entity's contents can be represented by a variety of types. These are typically struct pointers, but can also be any type that implements the PropertyLoadSaver interface. If using a struct pointer, you do not have to explicitly implement the PropertyLoadSaver interface; the datastore will automatically convert via reflection. If a struct pointer does implement that interface then those methods will be used in preference to the default behavior for struct pointers. Struct pointers are more strongly typed and are easier to use; PropertyLoadSavers are more flexible.
So you may use any type that implements the datastore.PropertyLoadSaver
interface. This interface type is:
type PropertyLoadSaver interface {
Load([]Property) error
Save() ([]Property, error)
}
Quoting again from package doc:
The PropertyLoadSaver Interface
An entity's contents can also be represented by any type that implements the PropertyLoadSaver interface. This type may be a struct pointer, but it does not have to be. The datastore package will call Load when getting the entity's contents, and Save when putting the entity's contents. Possible uses include deriving non-stored fields, verifying fields, or indexing a field only if its value is positive.
[...] The *PropertyList type implements PropertyLoadSaver, and can therefore hold an arbitrary entity's contents.