O pacote do armazenamento de dados

import "google.golang.org/appengine/datastore"

Introdução

O pacote do armazenamento de dados fornece um cliente para o serviço de armazenamento de dados do Google App Engine.

Operações básicas

As entidades são a unidade de armazenamento e estão associadas a uma chave. Uma chave consiste de uma chave pai opcional, um ID de aplicativo de string, um tipo de string (também conhecido como tipo de entidade) e um StringID ou um IntID. Um StringID também é conhecido como um nome de entidade ou nome de chave.

É válido criar uma chave com um StringID zero e um IntID zero, o que é chamado de chave incompleta e não se refere a nenhuma entidade salva. Colocar uma entidade no armazenamento de dados em uma chave incompleta faz com que uma chave exclusiva seja gerada para a entidade, com um IntID diferente de zero.

Os conteúdos de uma entidade são um mapeamento de nomes de campo que diferenciam maiúsculas e minúsculas para valores. Os tipos de valor válidos são:

- signed integers (int, int8, int16, int32 and int64),
- bool,
- string,
- float32 and float64,
- []byte (up to 1 megabyte in length),
- any type whose underlying type is one of the above predeclared types,
- ByteString,
- *Key,
- time.Time (stored with microsecond precision),
- appengine.BlobKey,
- appengine.GeoPoint,
- structs whose fields are all valid value types,
- slices of any of the above.

As partes dos structs são válidas, assim como os structs que contêm partes. No entanto, se um struct contiver outro, então, no máximo, um deles poderá ser repetido. Isso desqualifica tipos de structs definidos de modo recursivo: qualquer T de struct que, direta ou indiretamente, contenha um []T.

As funções Get e Put carregam e salvam os conteúdos de uma entidade. Os conteúdos de uma entidade são normalmente representados por um ponteiro de struct.

Exemplo de código:

type Entity struct {
    Value string
}

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

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

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

    if _, err := datastore.Put(ctx, k, e); err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

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

GetMulti, PutMulti e DeleteMulti são versões em lote das funções Get, Put e Delete. Eles assumem uma []*Key em vez de uma *Key e podem retornar um appengine.MultiError ao encontrar falhas parciais.

Properties

O conteúdo de uma entidade pode ser representado por vários tipos. Eles são normalmente ponteiros de struct, mas também podem ser qualquer tipo que implemente a interface PropertyLoadSaver. Se estiver usando um ponteiro de struct, você não precisa implementar explicitamente a interface PropertyLoadSaver. O armazenamento de dados se converterá automaticamente por reflexão. Se um ponteiro de struct implementar essa interface, esses métodos serão preferencialmente usados no lugar do comportamento padrão para ponteiros de struct. Os ponteiros de struct são digitados com mais força e são mais fáceis de usar. PropertyLoadSavers são mais flexíveis.

Os tipos reais passados não precisam corresponder entre as chamadas de Get e Put ou mesmo em solicitações diferentes do Google App Engine. É válido colocar um *PropertyList e receber essa mesma entidade como um *myStruct, ou colocar um *myStruct0 e receber um *myStruct1. Conceitualmente, qualquer entidade é salva como uma sequência de propriedades, que são carregadas uma a uma no valor de destino. Ao carregar em um ponteiro de struct, uma entidade que não pode ser completamente representada (como um campo ausente) resultará em um erro ErrFieldMismatch, mas caberá ao autor da chamada decidir se esse erro é fatal, recuperável ou ignorável.

Por padrão, para ponteiros de struct, todas as propriedades são potencialmente indexadas e o nome da propriedade é o mesmo do campo (e, portanto, precisa começar com uma letra maiúscula). Os campos podem ter uma tag `datastore:"name,options"`. O nome da tag é o nome da propriedade, que precisa ser um ou mais identificadores Go válidos, unidos por ".", mas podem começar com uma letra minúscula. Um nome de tag vazio indica que apenas o nome do campo será usado. Um nome de etiqueta "-" significa que o armazenamento de dados ignorará esse campo. Se as opções forem "noindex", o campo não será indexado. Se as opções forem "", a vírgula poderá ser omitida. Não há outras opções reconhecidas.

Os campos (exceto []byte) são indexados por padrão. As strings com mais de 1.500 bytes não podem ser indexadas. Os campos usados para armazenar strings longas precisam ser marcados com "noindex". Da mesma forma, ByteStrings com mais de 1.500 bytes não podem ser indexadas.

Exemplo de código:

// A and B are renamed to a and b.
// A, C and J are not indexed.
// D's tag is equivalent to having no tag at all (E).
// I is ignored entirely by the datastore.
// J has tag information for both the datastore and json packages.
type TaggedStruct struct {
    A int `datastore:"a,noindex"`
    B int `datastore:"b"`
    C int `datastore:",noindex"`
    D int `datastore:""`
    E int
    I int `datastore:"-"`
    J int `datastore:",noindex" json:"j"`
}

Propriedades estruturadas

Se o struct apontado contiver outros structs, os structs aninhados ou incorporados serão nivelados. Por exemplo, leve em conta estas definições:

type Inner1 struct {
    W int32
    X string
}

type Inner2 struct {
    Y float64
}

type Inner3 struct {
    Z bool
}

type Outer struct {
    A int16
    I []Inner1
    J Inner2
    Inner3
}

As propriedades de um Outer seriam equivalentes às de:

type OuterEquivalent struct {
    A     int16
    IDotW []int32  `datastore:"I.W"`
    IDotX []string `datastore:"I.X"`
    JDotY float64  `datastore:"J.Y"`
    Z     bool
}

Se o campo incorporado "Inner3" do Outer foi marcado como `datastore:"Foo"`, o campo equivalente seria, em vez disso, FooDotZ bool `datastore:"Foo.Z".

Se um struct outer for marcado como "noindex", todos os campos nivelados implícitos dele serão efetivamente "noindex".

A interface PropertyLoadSaver

O conteúdo de uma entidade também pode ser representado por qualquer tipo que implemente a interface PropertyLoadSaver. Não é necessário, mas esse tipo pode ser um ponteiro de struct. O pacote do armazenamento de dados chamará Load ao receber o conteúdo da entidade e Save ao colocar o conteúdo da entidade. Os usos possíveis incluem derivar campos não armazenados, verificar campos ou indexar um campo somente se o valor for positivo.

Exemplo de código:

type CustomPropsExample struct {
    I, J int
    // Sum is not stored, but should always be equal to I + J.
    Sum int `datastore:"-"`
}

func (x *CustomPropsExample) Load(ps []datastore.Property) error {
    // Load I and J as usual.
    if err := datastore.LoadStruct(x, ps); err != nil {
        return err
    }
    // Derive the Sum field.
    x.Sum = x.I + x.J
    return nil
}

func (x *CustomPropsExample) Save() ([]datastore.Property, error) {
    // Validate the Sum field.
    if x.Sum != x.I + x.J {
        return errors.New("CustomPropsExample has inconsistent sum")
    }
    // Save I and J as usual. The code below is equivalent to calling
    // "return datastore.SaveStruct(x)", but is done manually for
    // demonstration purposes.
    return []datastore.Property{
        {
            Name:  "I",
            Value: int64(x.I),
        },
        {
            Name:  "J",
            Value: int64(x.J),
        },
    }
}

O tipo *PropertyList implementa PropertyLoadSaver e, portanto, pode ter o conteúdo de uma entidade arbitrária.

Consultas

As consultas recuperam entidades com base nas propriedades delas ou na ascendência da chave. A execução de uma consulta produz um iterador de resultados: chaves ou pares (chave, entidade). As consultas são reutilizáveis, e é seguro chamar Query.Run a partir de goroutines simultâneas. Não é seguro usar iteradores simultaneamente.

As consultas são imutáveis e criadas ao chamar NewQuery, ou derivadas de uma consulta existente ao chamar um método como Filter ou Order, que retorna um novo valor de consulta. Normalmente, uma consulta é construída chamando NewQuery seguido de uma cadeia de zero ou mais desses métodos. Esses métodos são:

- Ancestor and Filter constrain the entities returned by running a query.
- Order affects the order in which they are returned.
- Project constrains the fields returned.
- Distinct de-duplicates projected entities.
- KeysOnly makes the iterator return only keys, not (key, entity) pairs.
- Start, End, Offset and Limit define which sub-sequence of matching entities
  to return. Start and End take cursors, Offset and Limit take integers. Start
  and Offset affect the first result, End and Limit affect the last result.
  If both Start and Offset are set, then the offset is relative to Start.
  If both End and Limit are set, then the earliest constraint wins. Limit is
  relative to Start+Offset, not relative to End. As a special case, a
  negative limit means unlimited.

Exemplo de código:

type Widget struct {
    Description string
    Price       int
}

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

Transações

RunInTransaction executa uma função em uma transação.

Exemplo de código:

type Counter struct {
    Count int
}

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

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

Metadados

O pacote do armazenamento de dados fornece acesso a alguns dos metadados do armazenamento de dados do App Engine. Esses metadados incluem informações sobre grupos de entidades, namespaces, tipos de entidades e propriedades no armazenamento de dados, bem como as representações de cada propriedade.

Exemplo de código:

func handle(w http.ResponseWriter, r *http.Request) {
    // Print all the kinds in the datastore, with all the indexed
    // properties (and their representations) for each.
    ctx := appengine.NewContext(r)

    kinds, err := datastore.Kinds(ctx)
    if err != nil {
        serveError(ctx, w, err)
        return
    }

    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    for _, kind := range kinds {
        fmt.Fprintf(w, "%s:\n", kind)
        props, err := datastore.KindProperties(ctx, kind)
        if err != nil {
            fmt.Fprintln(w, "\t(unable to retrieve properties)")
            continue
        }
        for p, rep := range props {
            fmt.Fprintf(w, "\t-%s (%s)\n", p, strings.Join(", ", rep))
        }
    }
}

Index

Variáveis
func AllocateIDs(c context.Context, kind string, parent *Key, n int) (low, high int64, err error)
func Delete(c context.Context, key *Key) error
func DeleteMulti(c context.Context, key []*Key) error
func Get(c context.Context, key *Key, dst interface{}) error
func GetMulti(c context.Context, key []*Key, dst interface{}) error
func KindProperties(ctx context.Context, kind string) (map[string][]string, error)
func Kinds(ctx context.Context) ([]string, error)
func LoadStruct(dst interface{}, p []Property) error
func Namespaces(ctx context.Context) ([]string, error)
func Put(c context.Context, key *Key, src interface{}) (*Key, error)
func PutMulti(c context.Context, key []*Key, src interface{}) ([]*Key, error)
func RunInTransaction(c context.Context, f func(tc context.Context) error, opts *TransactionOptions) error
func SaveStruct(src interface{}) ([]Property, error)
type ByteString
type Cursor
    func DecodeCursor(s string) (Cursor, error)
    func (c Cursor) String() string
type Entity
type ErrFieldMismatch
    func (e *ErrFieldMismatch) Error() string
type Iterator
    func (t *Iterator) Cursor() (Cursor, error)
    func (t *Iterator) Next(dst interface{}) (*Key, error)
type Key
    func DecodeKey(encoded string) (*Key, error)
    func NewIncompleteKey(c context.Context, kind string, parent *Key) *Key
    func NewKey(c context.Context, kind, stringID string, intID int64, parent *Key) *Key
    func (k *Key) AppID() string
    func (k *Key) Encode() string
    func (k *Key) Equal(o *Key) bool
    func (k *Key) GobDecode(buf []byte) error
    func (k *Key) GobEncode() ([]byte, error)
    func (k *Key) Incomplete() bool
    func (k *Key) IntID() int64
    func (k *Key) Kind() string
    func (k *Key) MarshalJSON() ([]byte, error)
    func (k *Key) Namespace() string
    func (k *Key) Parent() *Key
    func (k *Key) String() string
    func (k *Key) StringID() string
    func (k *Key) UnmarshalJSON(buf []byte) error
type Property
type PropertyList
    func (l *PropertyList) Load(p []Property) error
    func (l *PropertyList) Save() ([]Property, error)
type PropertyLoadSaver
type Query
    func NewQuery(kind string) *Query
    func (q *Query) Ancestor(ancestor *Key) *Query
    func (q *Query) Count(c context.Context) (int, error)
    func (q *Query) Distinct() *Query
    func (q *Query) End(c Cursor) *Query
    func (q *Query) EventualConsistency() *Query
    func (q *Query) Filter(filterStr string, value interface{}) *Query
    func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error)
    func (q *Query) KeysOnly() *Query
    func (q *Query) Limit(limit int) *Query
    func (q *Query) Offset(offset int) *Query
    func (q *Query) Order(fieldName string) *Query
    func (q *Query) Project(fieldNames ...string) *Query
    func (q *Query) Run(c context.Context) *Iterator
    func (q *Query) Start(c Cursor) *Query
type TransactionOptions

Variáveis

var (
    // ErrInvalidEntityType is returned when functions like Get or Next are
    // passed a dst or src argument of invalid type.
    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")
)
var Done = errors.New("datastore: query has no more results")

Done é retornado quando uma iteração de consulta é concluída.

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

ErrConcurrentTransaction é retornado quando uma transação é revertida devido a um conflito com uma transação simultânea.

func AllocateIDs

func AllocateIDs(c context.Context, kind string, parent *Key, n int) (low, high int64, err error)

AllocateIDs retorna um intervalo de n códigos de números inteiros com a combinação de tipo e pai especificada. O tipo não pode estar vazio e o pai pode ser nulo. Os códigos no intervalo retornado não serão usados pelo gerador de sequência de código automático do armazenamento de dados e podem ser usados com NewKey sem gerar conflitos.

O intervalo é inclusivo na extremidade inferior e exclusivo na superior. Em outras palavras, intIDs x válidos satisfazem inferior <= x && x < superior.

Se nenhum erro for retornado, inferior + n == superior.

func Delete

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

Delete exclui a entidade da chave fornecida.

func DeleteMulti

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

DeleteMulti é uma versão em lote de Delete.

func Get

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

Get carrega a entidade armazenada de k em dst, que precisa ser um ponteiro de struct ou implementar PropertyLoadSaver. Se não há essa entidade para a chave, Get retorna ErrNoSuchEntity.

Os valores dos campos de struct não compatíveis do dst não são modificados, e os campos digitados por parte correspondentes não são redefinidos antes de anexá-los. Em particular, recomenda-se que seja passado um ponteiro para um struct de valor zero em cada chamada Get.

ErrFieldMismatch é retornado quando um campo precisa ser carregado em um tipo diferente daquele de onde foi armazenado ou se um campo está ausente ou não foi exportado no struct de destino. ErrFieldMismatch só é retornado se dst é um ponteiro struct.

func GetMulti

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

GetMulti é uma versão em lote de Get.

dst precisa ser um []S, []*S, []I ou []P, para algum tipo de struct S, algum tipo de interface I ou algum tipo P que não seja de ponteiro e de interface, de modo que P ou *P implemente PropertyLoadSaver. Se for []I, cada elemento precisará ser um dst válido para Get: é necessário que seja um ponteiro de struct ou implemente PropertyLoadSaver.

Como um caso especial, PropertyList é um tipo inválido para dst, mesmo que uma PropertyList seja uma parte de structs. É tratado como inválido para evitar ser passado erroneamente no lugar de []PropertyList.

func KindProperties

func KindProperties(ctx context.Context, kind string) (map[string][]string, error)

KindProperties retorna todas as propriedades indexadas para o tipo determinado. As propriedades são retornadas como um mapa de nomes de propriedades para uma parte dos tipos de representação. Os tipos de representação para os tipos de propriedade do Go compatíveis são:

"INT64":     signed integers and time.Time
"DOUBLE":    float32 and float64
"BOOLEAN":   bool
"STRING":    string, []byte and ByteString
"POINT":     appengine.GeoPoint
"REFERENCE": *Key
"USER":      (not used in the Go runtime)

func Kinds

func Kinds(ctx context.Context) ([]string, error)

Kinds retorna os nomes de todos os tipos no namespace atual.

func LoadStruct

func LoadStruct(dst interface{}, p []Property) error

O LoadStruct carrega as propriedades de p para dst. O dst precisa ser um ponteiro de struct.

func Namespaces

func Namespaces(ctx context.Context) ([]string, error)

Namespaces retorna todos os namespaces do armazenamento de dados.

func Put

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

Put salva o src da entidade no armazenamento de dados com a chave k. O src precisa ser um ponteiro de struct ou implementar PropertyLoadSaver. Se for um ponteiro de struct, os campos não exportados desse struct serão ignorados. Se k é uma chave incompleta, a chave retornada é uma chave exclusiva gerada pelo armazenamento de dados.

func PutMulti

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

PutMulti é uma versão em lote de Put.

O src precisa satisfazer as mesmas condições que o argumento dst para o GetMulti.

func RunInTransaction

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

RunInTransaction executa f em uma transação. Chama f com um contexto de transação tc que f deve usar para todas as operações do Google App Engine.

Se f retornar nulo, RunInTransaction tenta confirmar a transação, retornando nulo se for bem-sucedido. Se a confirmação apresenta uma falha por conta de uma transação conflitante, RunInTransaction tenta repetir f, com um novo contexto de transação a cada vez. Ele desiste e retorna ErrConcurrentTransaction depois de três tentativas com falha. O número de tentativas pode ser configurado com a especificação de TransactionOptions.Attempts.

Se f retorna não nil, as alterações no armazenamento de dados não são aplicadas e RunInTransaction retorna o mesmo erro. Não ocorrem novas tentativas da função f.

Observe que quando f retorna, a transação ainda não foi confirmada. O código de chamada precisa ser cuidadoso para não presumir que as alterações de f tenham sido confirmadas até que RunInTransaction retorne nulo.

Como f pode ser chamado várias vezes, normalmente ele precisa ser idempotente. O datastore.Get não é idempotente ao desmembrar campos parciais.

As transações aninhadas não são compatíveis. c pode não ser um contexto de transação.

func SaveStruct

func SaveStruct(src interface{}) ([]Property, error)

SaveStruct retorna as propriedades do src como uma parte das propriedades. O src precisa ser um ponteiro de struct.

type ByteString

type ByteString []byte

ByteString é uma pequena parte de bytes (até 1.500 bytes) que pode ser indexada.

type Cursor

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

Cursor é a posição de um iterador. Pode ser convertido de e para uma string opaca. Um cursor pode ser usado a partir de diferentes solicitações HTTP, mas apenas com uma consulta com o mesmo tipo, ancestral, filtro e restrições de ordem.

func DecodeCursor

func DecodeCursor(s string) (Cursor, error)

Decode decodifica um cursor da própria representação de string de base-64.

func (Cursor) String

func (c Cursor) String() string

String retorna uma representação de string de base-64 de um cursor.

type Entity

type Entity struct {
    Key        *Key
    Properties []Property
}

Uma Entity é o tipo de valor para um struct aninhado. Esse tipo é usado apenas para o valor de uma Propriedade.

type ErrFieldMismatch

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

ErrFieldMismatch é retornado quando um campo precisa ser carregado em um tipo diferente daquele de onde foi armazenado ou se um campo está ausente ou não foi exportado no struct de destino. StructType é o tipo da struct apontada pelo argumento de destino passado para Get ou para Iterator.Next.

func (*ErrFieldMismatch) Error

func (e *ErrFieldMismatch) Error() string

type Iterator

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

Iterator é o resultado de executar uma consulta.

func (*Iterator) Cursor

func (t *Iterator) Cursor() (Cursor, error)

Cursor retorna um cursor para a localização atual do iterador.

func (*Iterator) Next

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

Next retorna a chave do próximo resultado. Quando não há mais resultados, Done é retornado como o erro.

Se a consulta não tiver apenas chaves e o dst não for não nulo, ela também carregará a entidade armazenada para essa chave no ponteiro de struct ou no dst do PropertyLoadSaver, com a mesma semântica e possíveis erros que para a função Get.

type Key

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

Key representa a chave do armazenamento de dados para uma entidade armazenada e é imutável.

func DecodeKey

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

DecodeKey decodifica uma chave da representação opaca retornada pelo Encode.

func NewIncompleteKey

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

NewIncompleteKey cria uma nova chave incompleta. O tipo não pode estar vazio.

func NewKey

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

NewKey cria uma nova chave. O tipo não pode estar vazio. StringID e/ou intID precisam ser zero. Se ambos forem zero, a chave retornada estará incompleta. O pai precisa ser uma chave completa ou nula.

func (*Key) AppID

func (k *Key) AppID() string

AppID retorna o código de aplicação da chave.

func (*Key) Encode

func (k *Key) Encode() string

Encode retorna uma representação opaca da chave adequada para uso em HTML e URLs. Isso é compatível com os tempos de execução do Python e do Java.

func (*Key) Equal

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

Equal retorna se duas chaves são iguais.

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 retorna se a chave não se refere a uma entidade armazenada. Em específico, se a chave tem um StringID zero e um IntID zero.

func (*Key) IntID

func (k *Key) IntID() int64

IntID retorna o código de número inteiro da chave, que pode ser zero.

func (*Key) Kind

func (k *Key) Kind() string

Kind retorna o tipo da chave, também conhecido como tipo de entidade.

func (* chave) MarshalJSON

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

func (*Key) Namespace

func (k *Key) Namespace() string

Namespace retorna o namespace da chave.

func (*Key) Parent

func (k *Key) Parent() *Key

Parent retorna a chave pai da chave, que pode ser nulo.

func (*Key) String

func (k *Key) String() string

String retorna uma representação de string da chave.

func (*Key) StringID

func (k *Key) StringID() string

StringID retorna o código de string da chave (também conhecido como nome da entidade ou nome da chave), que pode ser "".

func (*Key) UnmarshalJSON

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

type Property

type Property struct {
    // Name is the property name.
    Name string
    // Value is the property value. The valid types are:
    //    - int64
    //    - bool
    //    - string
    //    - float64
    //    - ByteString
    //    - *Key
    //    - time.Time
    //    - appengine.BlobKey
    //    - appengine.GeoPoint
    //    - []byte (up to 1 megabyte in length)
    //    - *Entity (representing a nested struct)
    // This set is smaller than the set of valid struct field types that the
    // datastore can load and save. A Property Value cannot be a slice (apart
    // from []byte); use multiple Properties instead. Also, a Value's type
    // must be explicitly on the list above; it is not sufficient for the
    // underlying type to be on that list. For example, a Value of "type
    // myInt64 int64" is invalid. Smaller-width integers and floats are also
    // invalid. Again, this is more restrictive than the set of valid struct
    // field types.
    //
    // A Value will have an opaque type when loading entities from an index,
    // such as via a projection query. Load entities into a struct instead
    // of a PropertyLoadSaver when using a projection query.
    //
    // A Value may also be the nil interface value; this is equivalent to
    // Python's None but not directly representable by a Go struct. Loading
    // a nil-valued property into a struct will set that field to the zero
    // value.
    Value interface{}
    // NoIndex is whether the datastore cannot index this property.
    NoIndex bool
    // Multiple is whether the entity can have multiple properties with
    // the same name. Even if a particular instance only has one property with
    // a certain name, Multiple should be true if a struct would best represent
    // it as a field of type []T instead of type T.
    Multiple bool
}

Property é um par nome/valor mais alguns metadados. O conteúdo de uma entidade de armazenamento de dados é carregado e salvo como uma sequência de propriedades. Uma entidade pode ter várias propriedades com o mesmo nome, desde que p.Multiple seja verdadeiro em todas as propriedades dessa entidade com esse nome.

type PropertyList

type PropertyList []Property

PropertyList converte uma []Property para implementar PropertyLoadSaver.

func (*PropertyList) Load

func (l *PropertyList) Load(p []Property) error

Load carrega todas as propriedades fornecidas em l. Ele não redefine *l primeiro para uma parte vazia.

func (*PropertyList) Save

func (l *PropertyList) Save() ([]Property, error)

Save salva todas as propriedades de l como uma parte ou propriedades.

type PropertyLoadSaver

type PropertyLoadSaver interface {
    Load([]Property) error
    Save() ([]Property, error)
}

PropertyLoadSaver pode ser convertido de e para uma parte de propriedades.

type Query

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

Query representa uma consulta do armazenamento de dados.

func NewQuery

func NewQuery(kind string) *Query

NewQuery cria uma nova Query para um tipo de entidade específico.

Um tipo vazio significa retornar todas as entidades, incluindo entidades criadas e gerenciadas por outros recursos do App Engine, e é chamado de consulta sem tipo. As consultas sem tipo não podem incluir filtros ou ordens de classificação nos valores das propriedades.

func (*Query) Ancestor

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

Ancestor retorna uma consulta derivada com um filtro ancestral. O ancestral não será nulo.

func (*Query) Count

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

Count retorna o número de resultados da consulta.

O tempo de execução e o número de chamadas da API feitas pela escala de Count linearmente com a soma do deslocamento e limite da consulta. A menos que se queira que a contagem de resultados seja pequena, é melhor especificar um limite. Caso contrário, Count continuará até terminar a contagem ou o contexto fornecido expirar.

func (*Query) Distinct

func (q *Query) Distinct() *Query

Distinct retorna uma consulta derivada que produz entidades deduplicadas em relação ao conjunto de campos projetados. É usado apenas para consultas de projeção.

func (*Query) End

func (q *Query) End(c Cursor) *Query

End retorna uma consulta derivada com o ponto de extremidade determinado.

func (*Query) EventualConsistency

func (q *Query) EventualConsistency() *Query

EventualConsistency retorna uma consulta derivada que retorna resultados que acabam sendo consistentes. Só tem efeito sobre as consultas ancestrais.

func (*Query) Filter

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

Filter retorna uma consulta derivada com um filtro baseado em campo. O argumento filterStr precisa ser um nome de campo seguido por um espaço opcional, um operador ou um dos campos ">", "<", ">=", "<=" ou "=" são comparados com o valor fornecido usando o operador. Vários filtros são unidos por AND.

func (*Query) GetAll

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

O GetAll executa a consulta no determinado contexto e retorna todas as chaves que correspondem a essa consulta, anexando também os valores para dst.

O dst precisa ter o tipo *[]S, *[]*S ou *[]P, para algum tipo de struct S ou algum tipo P que não seja de interface e de ponteiro, de modo que P ou *P implemente PropertyLoadSaver.

Como um caso especial, *PropertyList é um tipo inválido para dst, mesmo que uma PropertyList seja uma parte de structs. É tratado como inválido para evitar ser passado erroneamente no lugar de *[]PropertyList.

As chaves retornadas por GetAll estarão em uma correspondência 1-1 com as entidades adicionadas ao dst.

Se q for uma consulta "somente chaves", o GetAll ignorará o dst e retornará somente as chaves.

O tempo de execução e o número de chamadas da API feitas pela escala de GetAll linearmente com a soma do deslocamento e limite da consulta. A menos que se queira que a contagem de resultados seja pequena, é melhor especificar um limite. Caso contrário, GetAll continuará até terminar a coleta de resultados ou o contexto fornecido expirar.

func (*Query) KeysOnly

func (q *Query) KeysOnly() *Query

KeysOnly retorna uma consulta derivada que produz apenas chaves, não chaves e entidades. Não pode ser usado com consultas de projeção.

func (*Query) Limit

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

Limit retorna uma consulta derivada que tem um limite na quantidade de resultados retornados. Um valor negativo significa ilimitado.

func (*Query) Offset

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

Offset retorna uma consulta derivada que tem um deslocamento de quantas chaves ignorar antes de retornar os resultados. Um valor negativo é inválido.

func (*Query) Order

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

Order retorna uma consulta derivada com uma ordem de classificação baseada em campo. Classificações são aplicadas na ordem em que são adicionadas. A classificação padrão é ascendente. Para classificar na ordem descendente, adicione fieldName como prefixo com um sinal de menos (-).

func (*Query) Project

func (q *Query) Project(fieldNames ...string) *Query

Project retorna uma consulta derivada que produz apenas os campos fornecidos. Não pode ser usado com KeysOnly.

func (*Query) Run

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

Run executa a consulta no contexto dado.

func (*Query) Start

func (q *Query) Start(c Cursor) *Query

Start retorna uma consulta derivada com o ponto de partida fornecido.

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
    // Attempts controls the number of retries to perform when commits fail
    // due to a conflicting transaction. If omitted, it defaults to 3.
    Attempts int
}

TransactionOptions são as opções para executar uma transação.