datastore

package
v0.0.0-...-456eabd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2011 License: BSD-3-Clause Imports: 16 Imported by: 0

Documentation

Overview

Package datastore provides a client for App Engine's datastore service.

Entities are the unit of storage and are associated with a key. A key consists of an optional parent key, a string application ID, a string kind (also known as an entity type), and either a StringID or an IntID. A StringID is also known as an entity name or key name.

It is valid to create a key with a zero StringID and a zero IntID; this is called an incomplete key, and does not refer to any saved entity. Putting an entity into the datastore under an incomplete key will cause a unique key to be generated for that entity, with a non-zero IntID.

An entity's contents are a mapping from case-sensitive field names to values. Valid value types are:

  • signed integers (int, int8, int16, int32 and int64),
  • bool,
  • string,
  • float32 and float64,
  • any type whose underlying type is one of the above predeclared types,
  • *Key,
  • appengine.BlobKey,
  • []byte (up to 1 megabyte in length),
  • slices of any of the above.

The Get and Put functions load and save an entity's contents to and from structs or Maps. Structs are more strongly typed, Maps are more flexible. The actual types passed do not have to match between calls or even across different App Engine requests. It is valid to put a Map and get that same entity as a struct, or put a struct of type T0 and get a struct of type T1. Conceptually, an entity is saved from a struct as a map and is loaded into a struct or Map on a field-by-field basis. When loading into a struct, an entity that cannot be completely represented (such as a missing field) will result in an error but it is up to the caller whether this error is fatal, recoverable or ignorable.

Example code:

type Entity struct {
	Value string
}

func handle(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	k := datastore.NewKey(c, "Entity", "stringID", 0, nil)
	e := new(Entity)
	if err := datastore.Get(c, k, e); err != nil {
		serveError(c, w, err)
		return
	}

	old := e.Value
	e.Value = r.URL.Path

	if _, err := datastore.Put(c, k, e); err != nil {
		serveError(c, w, err)
		return
	}

	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	fmt.Fprintf(w, "old=%q\nnew=%q\n", old, e.Value)
}

To derive example code that saves and loads a Map instead of a struct, replace e := new(Entity) and e.Value with e := make(datastore.Map) and e["Value"].

GetMulti, PutMulti and DeleteMulti are batch versions of the Get, Put and Delete functions. They take a []*Key instead of a *Key, and may return an ErrMulti when encountering partial failure.

Queries are created using datastore.NewQuery and are configured by calling its methods. Running a query yields an iterator of results: either an iterator of keys or of (key, entity) pairs. Once initialized, query values can be re-used, and it is safe to call Query.Run from concurrent goroutines.

Example code:

type Widget struct {
	Description string
	Price       int
}

func handle(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	q := datastore.NewQuery("Widget").
		Filter("Price <", 1000).
		Order("-Price")
	b := bytes.NewBuffer(nil)
	for t := q.Run(c); ; {
		var x Widget
		key, err := t.Next(&x)
		if err == datastore.Done {
			break
		}
		if err != nil {
			serveError(c, w, err)
			return
		}
		fmt.Fprintf(b, "Key=%v\nWidget=%#v\n\n", x, key)
	}
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	io.Copy(w, b)
}

RunInTransaction runs a function in a transaction.

Example code:

type Counter struct {
	Count int
}

func inc(c appengine.Context, key *datastore.Key) (int, os.Error) {
	var x Counter
	if err := datastore.Get(c, key, &x); err != nil && err != datastore.ErrNoSuchEntity {
		return 0, err
	}
	x.Count++
	if _, err := datastore.Put(c, key, &x); err != nil {
		return 0, err
	}
	return x.Count, nil
}

func handle(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	var count int
	err := datastore.RunInTransaction(c, func(c appengine.Context) os.Error {
		var err1 os.Error
		count, err1 = inc(c, datastore.NewKey(c, "Counter", "singleton", 0, nil))
		return err1
	}, nil)
	if err != nil {
		serveError(c, w, err)
		return
	}
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	fmt.Fprintf(w, "Count=%d", count)
}

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidEntityType is returned when an invalid destination entity type
	// is passed to Get, GetAll, GetMulti or Next.
	ErrInvalidEntityType = errors.New("datastore: invalid entity type")
	// ErrInvalidKey is returned when an invalid key is presented.
	ErrInvalidKey = errors.New("datastore: invalid key")
	// ErrNoSuchEntity is returned when no entity was found for a given key.
	ErrNoSuchEntity = errors.New("datastore: no such entity")
)
View Source
var Done = errors.New("datastore: query has no more results")

Done is returned when a query iteration has completed.

View Source
var ErrConcurrentTransaction = errors.New("datastore: concurrent transaction")

ErrConcurrentTransaction is returned when a transaction is rolled back due to a conflict with a concurrent transaction.

Functions

func Delete

func Delete(c appengine.Context, key *Key) error

Delete deletes the entity for the given key.

func DeleteMulti

func DeleteMulti(c appengine.Context, key []*Key) error

DeleteMulti is a batch version of Delete.

func Get

func Get(c appengine.Context, key *Key, dst interface{}) error

Get loads the entity stored for k into dst, which may be either a struct pointer or a Map. If there is no such entity for the key, Get returns ErrNoSuchEntity.

The values of dst's unmatched struct fields or Map entries are not modified. In particular, it is recommended to pass either a pointer to a zero valued struct or an empty Map on each Get call.

ErrFieldMismatch is returned when a field is to be loaded into a different type than the one it was stored from, or when a field is missing or unexported in the destination struct. ErrFieldMismatch is only returned if dst is a struct pointer.

func GetMulti

func GetMulti(c appengine.Context, key []*Key, dst []interface{}) error

GetMulti is a batch version of Get.

func RunInTransaction

func RunInTransaction(c appengine.Context, f func(tc appengine.Context) error, opts *TransactionOptions) error

RunInTransaction runs f in a transaction. It calls f with a transaction context tc that f should use for all App Engine operations.

If f returns nil, RunInTransaction attempts to commit the transaction, returning nil if it succeeds. If the commit fails due to a conflicting transaction, RunInTransaction retries f, each time with a new transaction context. It gives up and returns ErrConcurrentTransaction after three failed attempts.

If f returns non-nil, then any datastore changes will not be applied and RunInTransaction returns that same error. The function f is not retried.

Note that when f returns, the transaction is not yet committed. Calling code must be careful not to assume that any of f's changes have been committed until RunInTransaction returns nil.

Nested transactions are not supported; c may not be a transaction context.

Types

type ErrFieldMismatch

type ErrFieldMismatch struct {
	Key        *Key
	StructType reflect.Type
	FieldName  string
	Reason     string
}

ErrFieldMismatch is returned when a field is to be loaded into a different type than the one it was stored from, or when a field is missing or unexported in the destination struct. StructType is the type of the struct pointed to by the destination argument passed to Get or to Iterator.Next.

func (*ErrFieldMismatch) Error

func (e *ErrFieldMismatch) Error() string

String returns a string representation of the error.

func (*ErrFieldMismatch) String

func (e *ErrFieldMismatch) String() string

AG: Leaving as it is; Error() should be used to be able to use this struct as an Error String returns a string representation of the error.

type ErrMulti

type ErrMulti []error

ErrMulti indicates that a batch operation failed on at least one element.

func (ErrMulti) Error

func (m ErrMulti) Error() string

String returns a string representation of the error.

type Iterator

type Iterator struct {
	// contains filtered or unexported fields
}

Iterator is the result of running a query.

func (*Iterator) Next

func (t *Iterator) Next(dst interface{}) (*Key, error)

Next returns the key of the next result. When there are no more results, Done is returned as the error. If the query is not keys only, it also loads the entity stored for that key into the struct pointer or Map dst, with the same semantics and possible errors as for the Get function. If the query is keys only, it is valid to pass a nil interface{} for dst.

type Key

type Key struct {
	// contains filtered or unexported fields
}

Key represents the datastore key for a stored entity, and is immutable.

func DecodeKey

func DecodeKey(encoded string) (*Key, error)

DecodeKey decodes a key from the opaque representation returned by Encode.

func NewIncompleteKey

func NewIncompleteKey(c appengine.Context, kind string, parent *Key) *Key

NewIncompleteKey creates a new incomplete key. kind cannot be empty.

func NewKey

func NewKey(c appengine.Context, kind, stringID string, intID int64, parent *Key) *Key

NewKey creates a new key. kind cannot be empty. Either one or both of stringID and intID must be zero. If both are zero, the key returned is incomplete. parent must either be a complete key or nil.

func Put

func Put(c appengine.Context, key *Key, src interface{}) (*Key, error)

Put saves the entity src into the datastore with key k. src may be either a struct pointer or a Map; if the former then any unexported fields of that struct will be skipped. If k is an incomplete key, the returned key will be a unique key generated by the datastore.

func PutMulti

func PutMulti(c appengine.Context, key []*Key, src []interface{}) ([]*Key, error)

PutMulti is a batch version of Put.

func (*Key) AppID

func (k *Key) AppID() string

AppID returns the key's application ID.

func (*Key) Encode

func (k *Key) Encode() string

Encode returns an opaque representation of the key suitable for use in HTML and URLs. This is compatible with the Python and Java runtimes.

func (*Key) Eq

func (k *Key) Eq(o *Key) bool

Eq returns whether two keys are equal.

func (*Key) GobDecode

func (k *Key) GobDecode(buf []byte) error

func (*Key) GobEncode

func (k *Key) GobEncode() ([]byte, error)

func (*Key) Incomplete

func (k *Key) Incomplete() bool

Incomplete returns whether the key does not refer to a stored entity. In particular, whether the key has a zero StringID and a zero IntID.

func (*Key) IntID

func (k *Key) IntID() int64

IntID returns the key's integer ID, which may be 0.

func (*Key) Kind

func (k *Key) Kind() string

Kind returns the key's kind (also known as entity type).

func (*Key) MarshalJSON

func (k *Key) MarshalJSON() ([]byte, error)

func (*Key) Parent

func (k *Key) Parent() *Key

Parent returns the key's parent key, which may be nil.

func (*Key) String

func (k *Key) String() string

String returns a string representation of the key.

func (*Key) StringID

func (k *Key) StringID() string

StringID returns the key's string ID (also known as an entity name or key name), which may be "".

func (*Key) UnmarshalJSON

func (k *Key) UnmarshalJSON(buf []byte) error

type Map

type Map map[string]interface{}

Map is a map representation of an entity's fields. It is more flexible than but not as strongly typed as a struct representation.

type Query

type Query struct {
	// contains filtered or unexported fields
}

Query represents a datastore query.

func NewQuery

func NewQuery(kind string) *Query

NewQuery creates a new Query for a specific entity kind. The kind must be non-empty.

func (*Query) Ancestor

func (q *Query) Ancestor(ancestor *Key) *Query

Ancestor sets the ancestor filter for the Query. The ancestor should not be nil.

func (*Query) Count

func (q *Query) Count(c appengine.Context) (int, error)

Count returns the number of results for the query.

func (*Query) Filter

func (q *Query) Filter(filterStr string, value interface{}) *Query

Filter adds a field-based filter to the Query. The filterStr argument must be a field name followed by optional space, followed by an operator, one of ">", "<", ">=", "<=", or "=". Fields are compared against the provided value using the operator. Multiple filters are AND'ed together. The Query is updated in place and returned for ease of chaining.

func (*Query) GetAll

func (q *Query) GetAll(c appengine.Context, dst interface{}) ([]*Key, error)

GetAll runs the query in the given context and returns all keys that match that query, as well as appending the values to dst. The dst must be a pointer to a slice of structs, struct pointers, or Maps. If q is a “keys-only” query, GetAll ignores dst and only returns the keys.

func (*Query) KeysOnly

func (q *Query) KeysOnly() *Query

KeysOnly configures the query to return just keys, instead of keys and entities.

func (*Query) Limit

func (q *Query) Limit(limit int) *Query

Limit sets the maximum number of keys/entities to return. A zero value means unlimited. A negative value is invalid.

func (*Query) Offset

func (q *Query) Offset(offset int) *Query

Offset sets how many keys to skip over before returning results. A negative value is invalid.

func (*Query) Order

func (q *Query) Order(fieldName string) *Query

Order adds a field-based sort to the query. Orders are applied in the order they are added. The default order is ascending; to sort in descending order prefix the fieldName with a minus sign (-).

func (*Query) Run

func (q *Query) Run(c appengine.Context) *Iterator

Run runs the query in the given context.

type Time

type Time int64

Time is the number of microseconds since the Unix epoch, January 1, 1970 00:00:00 UTC.

It is a distinct type so that loading and saving fields of type Time are displayed correctly in App Engine tools like the Admin Console.

func SecondsToTime

func SecondsToTime(n int64) Time

SecondsToTime converts an int64 number of seconds since to Unix epoch to a Time value.

func (Time) Time

func (t Time) Time() *time.Time

Time returns a *time.Time from a datastore time.

type TransactionOptions

type TransactionOptions struct {
	// XG is whether the transaction can cross multiple entity groups. In
	// comparison, a single group transaction is one where all datastore keys
	// used have the same root key. Note that cross group transactions do not
	// have the same behavior as single group transactions. In particular, it
	// is much more likely to see partially applied transactions in different
	// entity groups, in global queries.
	// It is valid to set XG to true even if the transaction is within a
	// single entity group.
	XG bool
}

TransactionOptions are the options for running a transaction.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL