Das Paket Datastore bietet einen Client für den Datenspeicherdienst von App Engine.
Grundlegende Vorgänge
Entitäten sind Speichereinheiten. Sie sind mit einem Schlüssel verknüpft. Ein Schlüssel besteht aus einem optionalen übergeordneten Schlüssel, einer Zeichenkettenanwendungs-ID, einem Stringtyp (auch als Entitätstyp bezeichnet) und entweder einer StringID oder einer IntID. StringIDs werden auch als Entitätsnamen bzw. Schlüsselnamen bezeichnet.
Es ist zulässig, einen Schlüssel mit "StringID" null und "IntID" null zu erstellen. Ein derartiger Schlüssel wird als unvollständiger Schlüssel bezeichnet und bezieht sich nicht auf gespeicherte Entitäten. Wenn eine Entität unter einem unvollständigen Schlüssel im Datenspeicher abgelegt wird, wird für diese Entität ein eindeutiger Schlüssel mit einer "IntID" ungleich null erstellt.
Der Inhalt von Entitäten besteht aus Feldnamen, denen Werte zugeordnet sind. Bei den Feldnamen wird die Groß- und Kleinschreibung berücksichtigt. Folgende Werttypen sind gültig:
- Ganzzahlen mit Vorzeichen (int, int8, int16, int32 und int64).
- boolsche Werte
- String
- float32 und float64
- []Byte (bis zu einer Länge von 1 Megabyte)
- jeder Typ, dessen zugrunde liegender Typ einer der oben genannten Typen ist
- ByteString
- *Schlüssel
- time.Time (mit Mikrosekundenpräzision gespeichert),
- appengine.BlobKey-Werte
- appengine.geopoint
- Structs, deren Felder alle gültigen Werttypen sind
- Segmente der obigen Typen
Segmente von Strukturen sind ebenso gültig wie Strukturen, die Segmente enthalten. Wenn jedoch eine Struktur eine andere enthält, kann höchstens eine von diesen wiederholt werden. Rekursiv definierte Strukturtypen sind dadurch ausgeschlossen, also jede Struktur "T", die direkt oder indirekt "[]T" enthält.
Die Funktionen "Get" und "Put" laden und speichern den Inhalt einer Entität. Der Inhalt einer Entität wird meist durch einen Strukturzeiger repräsentiert.
Beispielcode:
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" und "DeleteMulti" sind Batch-Versionen der Funktionen "Get", "Put" und "Delete". Sie verwenden "[]*Key" statt "*Key" und können "appengine.MultiError" zurückgeben, wenn ein teilweiser Fehler auftritt.
Eigenschaften
Der Inhalt einer Entität kann durch verschiedene Typen repräsentiert werden. Meist sind dies Strukturzeiger, aber es kann auch ein beliebiger Typ sein, der die "PropertyLoadSaver"-Schnittstelle implementiert. Wenn Sie einen Strukturzeiger verwenden, müssen Sie die "PropertyLoadSaver"-Schnittstelle nicht explizit implementieren. Der Datenspeicher wird per Reflexion automatisch umgewandelt. Wenn ein Strukturzeiger diese Schnittstelle implementiert, werden diese Methoden gegenüber dem Standardverhalten für Strukturzeiger bevorzugt verwendet. Strukturzeiger sind stärker typisiert und einfacher zu verwenden. "PropertyLoadSaver"-Schnittstellen sind flexibler.
Die tatsächlich übergebenen Typen brauchen weder zwischen "Get"- und "Put"-Aufrufen noch zwischen verschiedenen Aufrufen für den Datenspeicher übereinzustimmen. Es ist zulässig, einen "Put"-Aufruf für "*PropertyList" durchzuführen und dieselbe Entität als "*myStruct" abzurufen oder einen "Put"-Aufruf für "*myStruct0" durchzuführen und "*myStruct1" abzurufen. Konzeptionell wird jede Entität als Folge von Eigenschaften gespeichert und Eigenschaft für Eigenschaft in den Zielwert geladen. Während des Ladens in einen Strukturzeiger führt eine Entität, die nicht vollständig repräsentiert werden kann (z. B. ein fehlendes Feld), zu einem Fehler des Typs "ErrFieldMismatch". Es hängt aber vom Aufrufer ab, ob dieser Fehler schwerwiegend oder behebbar ist oder ignoriert werden kann.
Standardmäßig sind für Strukturzeiger alle Eigenschaften potenziell indexiert. Der Eigenschaftsname stimmt mit dem Feldnamen überein und muss daher mit einem Großbuchstaben beginnen.
Felder können ein datastore:"name,options"
-Tag haben. Der Tag-Name ist der Eigenschaftsname. Dieser muss aus einer oder mehreren gültigen Go-Kennzeichnungen bestehen, die durch "." verknüpft sind, aber mit einem Kleinbuchstaben beginnen. Ein leerer Tag-Name bedeutet, dass einfach der Feldname verwendet werden soll. Der Tag-Name "-" gibt an, dass der Datenspeicher dieses Feld ignoriert.
Die einzigen gültigen Optionen sind "omitempty" und "noindex".
Wenn die Optionen "oleempty" beinhalten und der Wert des Felds leer ist, wird das Feld beim Speichern ignoriert. Die leeren Werte sind "false", "0", ein beliebiger Schnittstellenwert null sowie ein Array, Segment, Map oder String beliebiger Art der Länge null. Struct-Feldwerte sind nie leer.
Wenn die Optionen "noindex" beinhalten, wird das Feld nicht indexiert. Alle Felder sind standardmäßig indexiert. Strings oder Bytesegmente, die länger als 1.500 Byte sind, können nicht indexiert werden. Felder, die zum Speichern langer Strings und Bytesegmente verwendet werden, müssen mit "noindex" getaggt sein, da sie sonst bei Put-Vorgängen fehlschlagen.
Wenn Sie mehrere Optionen gemeinsam verwenden möchten, müssen Sie sie durch ein Komma trennen. Die Reihenfolge spielt dabei keine Rolle.
Wenn für die Optionen "" angegeben ist, kann das Komma weggelassen werden.
Beispielcode:
// 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"` }
Strukturierte Eigenschaften
Wenn die Struktur, auf die gezeigt wird, andere Strukturen enthält, werden die verschachtelten oder eingebetteten Strukturen vereinfacht. Wenn zum Beispiel diese Definitionen vorliegen:
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 }
wären die Eigenschaften von "Outer" mit den folgenden äquivalent:
type OuterEquivalent struct { A int16 IDotW []int32 `datastore:"I.W"` IDotX []string `datastore:"I.X"` JDotY float64 `datastore:"J.Y"` Z bool }
Wenn das eingebettete Feld "Inner3" von "Outer" mit datastore:"Foo"
getaggt ist, ist das äquivalente Feld stattdessen FooDotZ bool datastore:"Foo.Z"
.
Wenn eine äußere Struktur mit "noindex" getaggt ist, sind alle ihre impliziten vereinfachten Felder de facto "noindex".
Die "PropertyLoadSaver"-Schnittstelle
Der Inhalt einer Entität kann auch durch einen beliebigen Typ repräsentiert werden, der die "PropertyLoadSaver"-Schnittstelle implementiert. Dieser Typ kann ein Strukturzeiger sein, muss es aber nicht. Das Paket Datastore ruft "Load" auf, wenn es den Inhalt der Entität abruft, und "Save", wenn es für den Inhalt der Entität einen "Put"-Aufruf durchführt. Verwendungsmöglichkeiten sind das Ableiten nicht gespeicherter Felder, das Überprüfen von Feldern oder das Indexieren eines Felds, sofern sein Wert positiv ist.
Beispielcode:
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 nil, 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), }, }, nil }
Der Typ "*PropertyList" implementiert "PropertyLoadSaver" und kann deshalb den Inhalt einer beliebigen Entität enthalten.
Abfragen
Mit Abfragen werden Entitäten basierend auf ihren Eigenschaften oder der Herkunft des Schlüssels abgerufen. Das Ausführen einer Abfrage führt zu einem Iterator mit Ergebnissen, entweder in Form eines Schlüssels oder von Paaren aus Schlüsseln und Entitäten ("key, entity"). Abfragen können wiederverwendet werden und es ist sicher, "Query.Run" aus gleichzeitigen goroutines aufzurufen. Iteratoren sind für die gleichzeitige Verwendung nicht sicher.
Abfragen sind unveränderlich und werden entweder durch Aufrufen von "NewQuery" erstellt oder von einer vorhandenen Abfrage abgeleitet, indem eine Methode wie "Filter" oder "Order" aufgerufen wird, die einen neuen Abfragewert zurückgibt. Eine Abfrage wird in der Regel erstellt, indem "NewQuery" gefolgt von einer Kette von null, einer oder mehreren solchen Methoden aufgerufen wird. Diese Methoden sind:
- "Ancestor" und "Filter" beschränken die von einer Abfrage zurückgegebenen Entitäten.
- "Order" bestimmt die Reihenfolge, in der sie zurückgegeben werden.
- "Project" schränkt die zurückgegebenen Felder ein.
- "Distinct" dedupliziert projizierte Entitäten.
- "KeysOnly" bewirkt, dass der Iterator nur Schlüssel zurückgibt, keine Paare (Schlüssel, Entität).
- "Start", "End", "Offset" und "Limit" definieren, welche Untersequenz übereinstimmender Entitäten zurückgegeben wird. "Start" und "End" verwenden Cursors, "Offset" und "Limit" nutzen Ganzzahlen. "Start" und "Offset" wirken sich auf das erste Ergebnis aus, "End" und "Limit" auf das letzte Ergebnis. Wenn sowohl "Start" als auch "Offset" festgelegt sind, gilt der Offset relativ zum Start. Wenn sowohl "End" als auch "Limit" festgelegt sind, gilt die erste Einschränkung. "Limit" ist relativ zu "Start"+"Offset", aber nicht relativ zu "End". Als Sonderfall bedeutet ein negatives Limit unbegrenzte Werte.
Beispielcode:
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) }
Transaktionen
"RunInTransaction" führt eine Funktion in einer Transaktion aus.
Beispielcode:
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) }
Metadaten
Das Paket Datastore bietet Zugriff auf einige der Datenspeichermetadaten von App Engine. Diese Metadaten enthalten Informationen zu den Entitätsgruppen, Namespaces, Entitätsarten und Eigenschaften im Datenspeicher sowie die Eigenschaftsdarstellungen für jede Eigenschaft.
Beispielcode:
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, ", ")) } } }
Variablen
ErrInvalidEntityType, ErrInvalidKey, ErrNoSuchEntity
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")
)
Fertig
"Done" wird zurückgegeben, wenn eine Abfrageiteration abgeschlossen wurde.
ErrConcurrentTransaction
"ErrConcurrentTransaction" wird zurückgegeben, wenn aufgrund eines Konflikts mit einer gleichzeitigen Transaktion ein Rollback einer Transaktion durchgeführt wird.
Funktionen
func AllocateIDRange
AllocateIDRange Weist einen Bereich von IDs mit spezifischen Endpunkten zu. Der Bereich umfasst das untere als auch das obere Ende. Nachdem diese IDs zugeordnet wurden, können Sie sie manuell neu erstellten Entitäten zuweisen.
Der automatische ID-Allocator des Datenspeichers weist niemals einen Schlüssel zu, der bereits zugewiesen wurde (entweder durch automatische ID-Zuweisung oder durch einen expliziten Aufruf von AllocateIDs). Aus diesem Grund werden Entitäten im angegebenen Schlüsselbereich niemals überschrieben. Allerdings können durch das Schreiben von Entitäten mit manuell zugewiesenen Schlüsseln in diesem Bereich vorhandene Entitäten (oder neue Entitäten, die mit einer separaten Anfrage geschrieben wurden) überschrieben werden, je nachdem, welcher Fehler zurückgegeben wird.
Verwenden Sie dies nur, wenn Sie einen vorhandenen numerischen ID-Bereich haben, den Sie reservieren möchten (z. B. zum massenhaften Laden von Entitäten, die bereits IDs haben). Wenn die IDs, die Sie erhalten, für Sie keine Rolle spielen, verwenden Sie stattdessen AllocateIDs.
AltocateIDRange gibt "nil" zurück, wenn der Bereich erfolgreich zugewiesen wurde. Wenn eine oder mehrere Entitäten mit einer ID im angegebenen Bereich bereits vorhanden sind, wird ein KeyRangeCollisionError zurückgegeben. Wenn der Datenspeicher in diesem Bereich bereits IDs im Cache gespeichert hat (z. B. aus einem vorherigen Aufruf von AllocateIDRange), wird ein KeyRangeContentionError zurückgegeben. Fehler anderer Typen weisen auf Probleme mit Argumenten oder auf einen Fehler hin, der direkt aus dem Datenspeicher zurückgegeben wurde.
func AllocateIDs
"AllocateIDs" gibt einen Bereich von n Ganzzahl-IDs mit der angegebenen Kombination von "kind" und "parent" zurück. "kind" kann nicht leer sein. "parent" kann "nil" sein. Die IDs im zurückgegebenen Bereich werden nicht vom automatischen ID-Sequenzgenerator des Datenspeichers genutzt und können ohne Konflikt mit "NewKey" verwendet werden.
Der Bereich ist inklusiv am unteren Ende (low) und exklusiv am oberen Ende (high). Für intIDs x gilt also: low <= x && x < high.
Wenn kein Fehler zurückgegeben wird, gilt: low + n == high.
func Delete
"Delete" löscht die Entität für den betreffenden Schlüssel.
func DeleteMulti
"DeleteMulti" ist eine Batch-Version von "Delete".
func EnableKeyConversion
"EnableKeyConversion" ermöglicht eine codierte Schlüsselkompatibilität mit der Cloud Datastore-Clientbibliothek (cloud.google.com/go/datastore). Codierte Schlüssel, die von der Cloud Datastore-Clientbibliothek generiert werden, werden in App Engine-Datenspeicherschlüssel decodiert.
Der angegebene Kontext muss ein App Engine-Kontext sein, wenn er in App Engine-Laufzeiten der ersten Generation ausgeführt wird. Dies kann mit dem Handler /_ah/start aufgerufen werden. Der Aufruf lässt sich problemlos mehrmals kostengünstig ausführen und daher auch als Middleware einfügen.
Die Aktivierung der Schlüsselkompatibilität wirkt sich nicht auf das von Key.Encode verwendete Codierungsformat aus. Es erweitert lediglich den Typ der Schlüssel, die mit DecodeKey decodiert werden können.
func Get
"Get" lädt die für "k" gespeicherte Entität in "dst", das ein Strukturzeiger sein oder "PropertyLoadSaver" implementieren muss. Wenn keine derartige Entität für den Schlüssel vorhanden ist, gibt "Get" "ErrNoSuchEntity" zurück.
Die Werte der nicht zugeordneten Strukturfelder von "dst" werden nicht geändert und übereinstimmende Felder vom Typ Segment werden nicht zurückgesetzt, bevor etwas an sie angefügt wird. Insbesondere wird empfohlen, bei jedem "Get"-Aufruf einen Zeiger auf eine Struktur mit dem Wert null zu übergeben.
"ErrFieldMismatch" wird zurückgegeben, wenn ein Feld in einen anderen Typ geladen werden soll als den, aus dem es gespeichert wurde, oder wenn ein Feld fehlt oder in der Zielstruktur nicht exportiert wurde. "ErrFieldMismatch" wird nur zurückgegeben, wenn es sich bei "dst" um einen Strukturzeiger handelt.
func GetMulti
"GetMulti" ist eine Batch-Version von "Get".
Für einen Strukturtyp "S", einen Schnittstellentyp "I" oder einen Typ "P", der weder Schnittstelle noch Zeiger ist, muss "dst" ein "[]S", "[]*S", "[]I" oder "[]P" sein, sodass "P" oder "*P" "PropertyLoadSaver" implementiert. Wenn es ein "[]I" ist, muss jedes Element ein gültiges "dst" für "Get" sein: Es muss ein Strukturzeiger sein oder "PropertyLoadSaver" implementieren.
In einem Sonderfall ist "PropertyList" ein ungültiger Typ für "dst", obwohl eine "PropertyList" ein Segment mit Strukturen ist. Es wird als ungültig behandelt, um nicht fälschlicherweise übergeben zu werden, wenn "[]PropertyList" beabsichtigt war.
func KindProperties
"KindProperties" gibt alle indexierten Eigenschaften für die angegebene Art zurück. Die Eigenschaften werden als Zuordnung von Eigenschaftsnamen zu einem Segment der Darstellungstypen zurückgegeben. Die Darstellungstypen für die unterstützten Go-Eigenschaftstypen sind:
"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
"Kinds" gibt die Namen aller Arten im aktuellen Namespace zurück.
func LoadStruct
LoadStruct lädt die Attribute von „p” nach „dst”. „dst” muss ein Strukturzeiger sein.
func Namespaces
"Namespaces" gibt alle Datenspeicher-Namespaces zurück.
func RunInTransaction
func RunInTransaction(c context.Context, f func(tc context.Context) error, opts *TransactionOptions) error
"RunInTransaction" führt "f" in einer Transaktion aus. "f" wird mit dem Transaktionskontext "tc" aufgerufen, den "f" für alle App Engine-Vorgänge verwenden soll.
Wenn "f" den Wert "nil" zurückgibt, versucht "RunInTransaction" einen Commit-Vorgang für die Transaktion auszuführen, wobei bei erfolgreicher Ausführung "nil" zurückgegeben wird. Wenn der Commit-Vorgang aufgrund einer in Konflikt stehenden Transaktion nicht ausgeführt werden kann, wiederholt "RunInTransaction" die Ausführungsversuche für "f" und verwendet dabei jedes Mal einen neuen Transaktionskontext. Nach drei Fehlversuchen werden die Versuche aufgegeben und es wird "ErrConcurrentTransaction" ausgegeben. Die Anzahl der Versuche kann durch Angeben von "TransactionOptions.Attempts" konfiguriert werden.
Wenn "f" einen anderen Wert als "nil" zurückgibt, werden keine Datenspeicheränderungen angewendet und "RunInTransaction" gibt denselben Fehler zurück. Es wird nicht noch einmal versucht, die Funktion "f" auszuführen.
Beachten Sie, dass noch kein Commit-Vorgang für die Transaktion ausgeführt wurde, wenn "f" einen Wert zurückgibt. Beim Aufrufcode muss sorgfältig darauf geachtet werden, solange nicht davon auszugehen, dass für Änderungen von "f" ein Commit-Vorgang durchgeführt wurde, bis "RunInTransaction" den Wert "nil" zurückgibt.
Da "f" mehrmals aufgerufen werden kann, sollte "f" in der Regel idempotent sein. "datastore.Get" ist nicht idempotent, wenn ein Unmarshalling von Segmentfeldern ausgeführt wird.
Verschachtelte Transaktionen werden nicht unterstützt. Bei "c" darf es sich nicht um einen Transaktionskontext handeln.
ByteString
type ByteString []byte
"ByteString" ist ein kurzes Bytesegment von bis zu 1.500 Byte, das indexiert werden kann.
Cursor
type Cursor struct {
// contains filtered or unexported fields
}
"Cursor" ist die Position eines Iterators. Es kann in einen intransparenten String konvertiert und aus einem solchen wieder zurückkonvertiert werden. Ein Cursor kann von verschiedenen HTTP-Requests verwendet werden, aber nur bei einer Abfrage, die dieselben Art-, Ancestor-, Filter- und Reihenfolgebeschränkungen aufweist.
func DecodeCursor
DecodeCursor decodiert einen Cursor aus seiner base-64-Stringdarstellung.
func (Cursor) String
"String" gibt eine base-64-Stringdarstellung eines Cursors zurück.
Entität
"Entity" ist der Werttyp für eine verschachtelte Struktur. Dieser Typ wird nur für den Wert eines "Property"-Elements verwendet.
ErrFieldMismatch
"ErrFieldMismatch" wird zurückgegeben, wenn ein Feld in einen anderen Typ geladen werden soll als den, aus dem es gespeichert wurde, oder wenn ein Feld fehlt oder in der Zielstruktur nicht exportiert wurde. "StructType" ist der Typ der Struktur, auf die vom Zielargument gezeigt wird, das an "Get" oder an "Iterator.Next" übergeben wird.
func (*ErrFieldMismatch) Error
func (e *ErrFieldMismatch) Error() string
Iterator
type Iterator struct {
// contains filtered or unexported fields
}
"Iterator" ist das Ergebnis der Ausführung einer Abfrage.
func (*Iterator) Cursor
"Cursor" gibt einen Cursor für die aktuelle Position des Iterators zurück.
func (*Iterator) Next
"Next" gibt den Schlüssel des nächsten Ergebnisses zurück. Wenn keine weiteren Ergebnisse vorliegen, wird "Done" als Fehler zurückgegeben.
Wenn die Abfrage nicht ausschließlich schlüsselbasiert ist und "dst" nicht "nil" ist, wird auch die für diesen Schlüssel gespeicherte Entität in den Strukturzeiger oder in "dst" von "PropertyLoadSaver" geladen, und zwar mit derselben Semantik und möglicherweise denselben Fehlern wie für die "Get"-Funktion.
Schlüssel
type Key struct {
// contains filtered or unexported fields
}
"Key" steht für den Datenspeicherschlüssel für eine gespeicherte Entität und ist unveränderlich.
func DecodeKey
"DecodeKey" decodiert einen Schlüssel aus der intransparenten Darstellung, die von "Encode" zurückgegeben wird.
func NewIncompleteKey
Mit „NewIncompleteKey” wird ein neuer unvollständiger Schlüssel erstellt. Die Art darf nicht leer sein.
func NewKey
NewKey erstellt einen neuen Schlüssel. Die Art darf nicht leer sein. "stringID" oder "intID" (oder beide) muss null sein. Wenn beide Werte null sind, ist der zurückgegebene Schlüssel unvollständig. Das übergeordnete Element muss ein vollständiger Schlüssel oder null sein.
func Put
"Put" speichert die Entität "src" im Datenspeicher mit dem Schlüssel "k". "src" muss ein Strukturzeiger sein oder "PropertyLoadSaver" implementieren. Wenn es ein Strukturzeiger ist, werden alle nicht exportierten Felder dieser Struktur übersprungen. Wenn "k" ein unvollständiger Schlüssel ist, ist der zurückgegebene Schlüssel ein vom Datenspeicher erstellter eindeutiger Schlüssel.
func PutMulti
"PutMulti" ist eine Batch-Version von "Put".
"src" muss dieselben Bedingungen wie das "dst"-Argument von "GetMulti" erfüllen.
func (*Key) AppID
"AppID" gibt die Anwendungs-ID des Schlüssels zurück.
func (*Key) Encode
"Encode" gibt eine intransparente Darstellung des Schlüssels zurück, die für die Verwendung in HTML und in URLs geeignet ist. Dies ist mit der Python- und der Java-Laufzeit kompatibel.
func (*Key) Equal
"Equal" gibt zurück, ob zwei Schlüssel gleich sind.
func (*Key) GobDecode
func (*Key) GobEncode
func (*Key) Incomplete
"Incomplete" gibt zurück, ob der Schlüssel auf eine gespeicherte Entität verweist oder nicht. Insbesondere wird angegeben, ob bei dem Schlüssel "StringID" und "IntID" gleich null sind.
func (*Key) IntID
"IntID" gibt die ganzzahlige ID des Schlüssels zurück, die 0 sein kann.
func (*Key) Kind
"Kind" gibt den Typ des Schlüssels zurück (dieser wird auch als Entitätstyp bezeichnet).
func (*Key) MarshalJSON
func (*Key) Namespace
"Namespace" gibt den Namespace des Schlüssels zurück.
func (*Key) Parent
"Parent" gibt den übergeordneten Schlüssel des Schlüssels zurück. Dieser kann "nil" sein.
func (*Key) String
"String" gibt eine Stringdarstellung des Schlüssels zurück.
func (*Key) StringID
"StringID" gibt die String-ID des Schlüssels (auch als Entitätsname oder Schlüsselname bezeichnet) zurück. Diese kann "" sein.
func (*Key) UnmarshalJSON
KeyRangeCollisionError
type KeyRangeCollisionError struct {
// contains filtered or unexported fields
}
func (*KeyRangeCollisionError) Error
func (e *KeyRangeCollisionError) Error() string
KeyRangeContentionError
type KeyRangeContentionError struct {
// contains filtered or unexported fields
}
func (*KeyRangeContentionError) Error
func (e *KeyRangeContentionError) Error() string
Attribut
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" umfasst ein Name/Wert-Paar sowie einige Metadaten. Der Inhalt einer Datenspeicherentität wird als Folge von Eigenschaften geladen und gespeichert. Eine Entität kann mehrere Eigenschaften mit demselben Namen haben, sofern "p.Multiple" für alle Eigenschaften dieser Entität mit diesem Namen den Wert "true" hat.
func SaveStruct
"SaveStruct" gibt die Eigenschaften von "src" als Eigenschaftssegment zurück. "src" muss ein Strukturzeiger sein.
PropertyList
type PropertyList []Property
"PropertyList" wandelt "[]Property" um, um "PropertyLoadSaver" zu implementieren.
func (*PropertyList) Load
func (l *PropertyList) Load(p []Property) error
"Load" lädt alle bereitgestellten Eigenschaften in "l". Es setzt "*l" nicht zuerst auf ein leeres Segment zurück.
func (*PropertyList) Save
func (l *PropertyList) Save() ([]Property, error)
"Save" speichert alle Eigenschaften von "l" als Segment oder als "Property"-Elemente.
PropertyLoadSaver
"PropertyLoadSaver" kann in ein Segment von "Property"-Elementen konvertiert und aus einem solchem zurückkonvertiert werden.
Query
type Query struct {
// contains filtered or unexported fields
}
"Query" stellt eine Datenspeicherabfrage dar.
func NewQuery
"NewQuery" erstellt eine neue Abfrage für eine bestimmte Entitätsart.
Eine leere Art bedeutet, dass alle Entitäten zurückgegeben werden, einschließlich jener, die von anderen App Engine-Funktionen erstellt und verwaltet werden. Dies wird als typlose Abfrage bezeichnet. Typlose Abfragen können keine Filter und keine Sortierreihenfolgen für Eigenschaftswerte enthalten.
func (*Query) Ancestor
"Ancestor" gibt eine abgeleitete Abfrage mit einem Ancestor-Filter zurück. Der Ancestor sollte nicht "nil" sein.
func (*Query) BatchSize
BatchSize gibt eine abgeleitete Abfrage zurück, um die angegebene Anzahl von Ergebnissen gleichzeitig abzurufen. Dieser Wert sollte größer als null sein und höchstens den Wert von "Limit" haben.
func (*Query) Count
"Count" gibt die Anzahl der Ergebnisse für die Abfrage zurück.
Die Ausführungszeit und die Anzahl der von "Count" durchgeführten API-Aufrufe skalieren linear mit der Summe des Offsets und des Limits der Abfrage. Wenn keine kleine Ergebniszahl zu erwarten ist, empfiehlt es sich, ein Limit anzugeben. Andernfalls wird "Count" fortgesetzt, bis die Zählung abgeschlossen ist oder der bereitgestellte Kontext abläuft.
func (*Query) Distinct
"Distinct" gibt eine abgeleitete Abfrage zurück, die deduplizierte Entitäten in Bezug auf den Satz an projizierten Feldern ergibt. Es wird nur für Projektionsabfragen verwendet. "Distinct" kann nicht mit DistinctOn verwendet werden.
func (*Query) DistinctOn
"DistinctOn" gibt eine abgeleitete Abfrage zurück, die unter Berücksichtigung des Satzes der angegebenen Felder deduplizierte Entitäten liefert. Es wird nur für Projektionsabfragen verwendet. Die Feldliste sollte eine Teilmenge der projizierten Feldliste sein. "DistinctOn" kann nicht mit Distinct verwendet werden.
func (*Query) End
"End" gibt eine abgeleitete Abfrage mit dem angegebenen Endpunkt zurück.
func (*Query) EventualConsistency
"EventualConsistency" gibt eine abgeleitete Abfrage zurück, die schließlich konsistente Ergebnisse liefert. Es wirkt sich nur auf Ancestor-Abfragen aus.
func (*Query) Filter
"Filter" gibt eine abgeleitete Abfrage mit einem feldbasierten Filter zurück. Das Argument "filterStr" muss ein Feldname sein, gefolgt von einem optionalen Leerzeichen, gefolgt von einem der Operatoren ">", "<", ">=", "<=", oder "=". Felder werden mithilfe des Operators mit dem angegebenen Wert verglichen. Mehrere Filter werden durch "AND" miteinander verknüpft.
func (*Query) GetAll
"GetAll" führt die Abfrage im angegebenen Kontext aus und gibt alle Schlüssel zurück, die mit dieser Abfrage übereinstimmen. Außerdem werden die Werte an "dst" angefügt.
Für einen Strukturtyp "S" oder einen Typ "P", der weder Schnittstelle noch Zeiger ist, muss "dst" den Typ *[]S", *[]*S oder *[]P haben, sodass "P" oder "*P" PropertyLoadSaver implementiert.
In einem Sonderfall ist "*PropertyList" ein ungültiger Typ für "dst", obwohl eine "PropertyList" ein Segment mit Strukturen ist. Es wird als ungültig behandelt, um nicht fälschlicherweise übergeben zu werden, wenn "*[]PropertyList" beabsichtigt war.
Die von "GetAll" zurückgegebenen Schlüssel entsprechen 1:1 den "dst" hinzugefügten Entitäten.
Wenn "q" eine ausschließlich schlüsselbasierte Abfrage ist, ignoriert "GetAll" "dst" und gibt nur die Schlüssel zurück.
Die Ausführungszeit und die Anzahl der von "GetAll" ausgeführten API-Aufrufe skalieren linear mit der Summe des Offsets und des Limits der Abfrage. Wenn keine kleine Ergebniszahl zu erwarten ist, empfiehlt es sich, ein Limit anzugeben. Andernfalls wird "GetAll" fortgesetzt, bis die Erfassung der Ergebnisse abgeschlossen ist oder der bereitgestellte Kontext abläuft.
func (*Query) KeysOnly
"KeysOnly" gibt eine abgeleitete Abfrage zurück, die nur Schlüssel und nicht sowohl Schlüssel als auch Entitäten ergibt. Es kann nicht in Verbindung mit Projektionsabfragen verwendet werden.
func (*Query) Limit
"Limit" gibt eine abgeleitete Abfrage zurück, bei der die Anzahl der zurückgegebenen Ergebnisse begrenzt ist. Ein negativer Wert bedeutet, dass die Anzahl unbegrenzt ist.
func (*Query) Offset
"Offset" gibt eine abgeleitete Abfrage zurück, bei der ein Offset angibt, wie viele Schlüssel übersprungen werden sollen, bevor Ergebnisse zurückgegeben werden. Ein negativer Wert ist ungültig.
func (*Query) Order
"Order" gibt eine abgeleitete Abfrage mit einer feldbasierten Sortierreihenfolge zurück. "Order"-Elemente werden in der Reihenfolge angewendet, in der sie hinzugefügt wurden. Die Standardsortierreihenfolge ist aufsteigend. Um in absteigender Reihenfolge zu sortieren, müssen Sie "fieldName" ein Minuszeichen (-) voranstellen.
func (*Query) Project
"Project" gibt eine abgeleitete Abfrage zurück, die nur die angegebenen Felder ergibt. Es kann nicht mit "KeysOnly" verwendet werden.
func (*Query) Run
"Run" führt die Abfrage im betreffenden Kontext aus.
func (*Query) Start
"Start" gibt eine abgeleitete Abfrage mit dem angegebenen Startpunkt zurück.
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
// ReadOnly controls whether the transaction is a read only transaction.
// Read only transactions are potentially more efficient.
ReadOnly bool
}
"TransactionOptions" sind die Optionen zum Ausführen einer Transaktion.