Documentation ¶
Overview ¶
Package driver defines interfaces to be implemented by docstore drivers, which will be used by the docstore package to interact with the underlying services. Application code should use package docstore.
Index ¶
- Constants
- func AsFunc(val interface{}) func(interface{}) bool
- func CompareNumbers(n1, n2 interface{}) (int, error)
- func CompareTimes(t1, t2 time.Time) int
- func Decode(v reflect.Value, d Decoder) error
- func Encode(v reflect.Value, e Encoder) error
- func FieldPathEqualsField(fp []string, s string) bool
- func FieldPathsEqual(fp1, fp2 []string) bool
- func GroupByFieldPath(gets []*Action) [][]*Action
- func IsEmptyValue(v reflect.Value) bool
- func SplitActions(actions []*Action, split func(a, b *Action) bool) [][]*Action
- func UniqueString() string
- type Action
- type ActionKind
- type ActionListError
- type Collection
- type Decoder
- type DeleteQueryer
- type Document
- func (d Document) Decode(dec Decoder) error
- func (d Document) Encode(e Encoder) error
- func (d Document) FieldNames() []string
- func (d Document) Get(fp []string) (interface{}, error)
- func (d Document) GetField(field string) (interface{}, error)
- func (d Document) HasField(field string) bool
- func (d Document) HasFieldFold(field string) bool
- func (d Document) Set(fp []string, val interface{}) error
- func (d Document) SetField(field string, value interface{}) error
- type DocumentIterator
- type Encoder
- type Filter
- type IncOp
- type Mod
- type Query
- type RunActionsOptions
- type Throttle
- type UpdateQueryer
Constants ¶
const EqualOp = "="
EqualOp is the name of the equality operator. It is defined here to avoid confusion between "=" and "==".
Variables ¶
This section is empty.
Functions ¶
func AsFunc ¶
func AsFunc(val interface{}) func(interface{}) bool
AsFunc creates and returns an "as function" that behaves as follows: If its argument is a pointer to the same type as val, the argument is set to val and the function returns true. Otherwise, the function returns false.
func CompareNumbers ¶
CompareNumbers returns -1, 1 or 0 depending on whether n1 is less than, greater than or equal to n2. n1 and n2 must be signed integer, unsigned integer, or floating-point values, but they need not be the same type.
If both types are integers or both floating-point, CompareNumbers behaves like Go comparisons on those types. If one operand is integer and the other is floating-point, CompareNumbers correctly compares the mathematical values of the numbers, without loss of precision.
func CompareTimes ¶
CompareTimes returns -1, 1 or 0 depending on whether t1 is before, after or equal to t2.
func Decode ¶
Decode decodes the value held in the Decoder d into v. Decode creates slices, maps and pointer elements as needed. It treats values that implement encoding.BinaryUnmarshaler, encoding.TextUnmarshaler and proto.Message specially; see Encode.
func Encode ¶
Encode encodes the value using the given Encoder. It traverses the value, iterating over arrays, slices, maps and the exported fields of structs. If it encounters a non-nil pointer, it encodes the value that it points to. Encode treats a few interfaces specially:
If the value implements encoding.BinaryMarshaler, Encode invokes MarshalBinary on it and encodes the resulting byte slice.
If the value implements encoding.TextMarshaler, Encode invokes MarshalText on it and encodes the resulting string.
If the value implements proto.Message, Encode invokes proto.Marshal on it and encodes the resulting byte slice. Here proto is the package "google.golang.org/protobuf/proto".
Not every map key type can be encoded. Only strings, integers (signed or unsigned), and types that implement encoding.TextMarshaler are permitted as map keys. These restrictions match exactly those of the encoding/json package.
func FieldPathEqualsField ¶
FieldPathEqualsField reports whether a field path equals a field. This is a convenience for FieldPathsEqual(fp, []string{s}).
func FieldPathsEqual ¶
FieldPathsEqual reports whether two field paths are equal.
func GroupByFieldPath ¶
GroupByFieldPath collect the Get actions into groups with the same set of field paths.
func IsEmptyValue ¶
IsEmptyValue returns whether or not v is a zero value of its type. Copied from encoding/json, go 1.12.
func SplitActions ¶
SplitActions divides the actions slice into sub-slices much like strings.Split. The split function should report whether two consecutive actions should be split, that is, should be in different sub-slices. The first argument to split is the last action of the sub-slice currently under construction; the second argument is the action being considered for addition to that sub-slice. SplitActions doesn't change the order of the input slice.
func UniqueString ¶
func UniqueString() string
UniqueString generates a string that is unique with high probability. Driver implementations can use it to generate keys for Create actions.
Types ¶
type Action ¶
type Action struct { Kind ActionKind // the kind of action Doc Document // the document on which to perform the action Key interface{} // the document key returned by Collection.Key, to avoid recomputing it FieldPaths [][]string // field paths to retrieve, for Get only Mods []Mod // modifications to make, for Update only Index int // the index of the action in the original action list }
An Action describes a single operation on a single document.
func GroupActions ¶
GroupActions separates actions into four sets: writes, gets that must happen before the writes, gets that must happen after the writes, and gets that can happen concurrently with the writes.
type ActionKind ¶
type ActionKind int
ActionKind describes the type of an action.
const ( Create ActionKind = iota Replace Put Get Delete Update )
Values for ActionKind.
func (ActionKind) String ¶
func (i ActionKind) String() string
type ActionListError ¶
An ActionListError contains all the errors encountered from a call to RunActions, and the positions of the corresponding actions.
func NewActionListError ¶
func NewActionListError(errs []error) ActionListError
NewActionListError creates an ActionListError from a slice of errors. If the ith element err of the slice is non-nil, the resulting ActionListError will have an item {i, err}.
type Collection ¶
type Collection interface { // Key returns the document key, or nil if the document doesn't have one, which // means it is absent or zero value, such as 0, a nil interface value, and any // empty array or string. // // If the collection is able to generate a key for a Create action, then // it should not return an error if the key is missing. If the collection // can't generate a missing key, it should return an error. // // The returned key must be comparable. // // The returned key should not be encoded with the driver's codec; it should // be the user-supplied Go value. Key(Document) (interface{}, error) // RevisionField returns the name of the field used to hold revisions. // If the empty string is returned, docstore.DefaultRevisionField will be used. RevisionField() string // RunActions executes a slice of actions. // // If unordered is false, it must appear as if the actions were executed in the // order they appear in the slice, from the client's point of view. The actions // need not happen atomically, nor does eventual consistency in the service // need to be taken into account. For example, after a write returns // successfully, the driver can immediately perform a read on the same document, // even though the service's semantics does not guarantee that the read will see // the write. RunActions should return immediately after the first action that fails. // The returned slice should have a single element. // // opts controls the behavior of RunActions and is guaranteed to be non-nil. RunActions(ctx context.Context, actions []*Action, opts *RunActionsOptions) ActionListError // RunGetQuery executes a Query. // // Implementations can choose to execute the Query as one single request or // multiple ones, depending on their service offerings. The portable type // exposes OpenCensus metrics for the call to RunGetQuery (but not for // subsequent calls to DocumentIterator.Next), so drivers should prefer to // make at least one RPC during RunGetQuery itself instead of lazily waiting // for the first call to Next. RunGetQuery(context.Context, *Query) (DocumentIterator, error) // QueryPlan returns the plan for the query. QueryPlan(*Query) (string, error) // RevisionToBytes converts a revision to a byte slice. RevisionToBytes(interface{}) ([]byte, error) // BytesToRevision converts a []byte to a revision. BytesToRevision([]byte) (interface{}, error) // As converts i to driver-specific types. // See https://gocloud.dev/concepts/as/ for background information. As(i interface{}) bool // ErrorAs allows drivers to expose driver-specific types for returned // errors. // // See https://gocloud.dev/concepts/as/ for background information. ErrorAs(err error, i interface{}) bool // ErrorCode should return a code that describes the error, which was returned by // one of the other methods in this interface. ErrorCode(error) gcerrors.ErrorCode // Close cleans up any resources used by the Collection. Once Close is called, // there will be no method calls to the Collection other than As, ErrorAs, and // ErrorCode. Close() error }
A Collection is a set of documents.
type Decoder ¶
type Decoder interface { // The AsXXX methods each report whether the value being decoded can be represented as // a particular Go type. If so, the method should return the value as that type, and true; // otherwise it should return the zero value and false. AsString() (string, bool) AsInt() (int64, bool) AsUint() (uint64, bool) AsFloat() (float64, bool) AsBytes() ([]byte, bool) AsBool() (bool, bool) AsNull() bool // ListLen should return the length of the value being decoded and true, if the // value can be decoded into a slice or array. Otherwise, ListLen should return // (0, false). ListLen() (int, bool) // If ListLen returned true, then DecodeList will be called. It should iterate // over the value being decoded in sequence from index 0, invoking the callback // for each element with the element's index and a Decoder for the element. // If the callback returns false, DecodeList should return immediately. DecodeList(func(int, Decoder) bool) // MapLen should return the number of fields of the value being decoded and true, // if the value can be decoded into a map or struct. Otherwise, it should return // (0, false). MapLen() (int, bool) // DecodeMap iterates over the fields of the value being decoded, invoke the // callback on each with field name, a Decoder for the field value, and a bool // to indicate whether or not to use exact match for the field names. It will // be called when MapLen returns true or decoding a struct. If the callback // returns false, DecodeMap should return immediately. DecodeMap(func(string, Decoder, bool) bool) // AsInterface should decode the value into the Go value that best represents it. AsInterface() (interface{}, error) // If the decoder wants to decode a value in a special way it should do so here // and return true, the decoded value, and any error from the decoding. // Otherwise, it should return false. AsSpecial(reflect.Value) (bool, interface{}, error) // String should return a human-readable representation of the Decoder, for error messages. String() string }
A Decoder decodes data that was produced by Encode back into Go values. Each Decoder instance is responsible for decoding one value.
type DeleteQueryer ¶
DeleteQueryer should be implemented by Collections that can handle Query.Delete efficiently. If a Collection does not implement this interface, then Query.Delete will be implemented by calling RunGetQuery and deleting the returned documents.
type Document ¶
type Document struct { Origin interface{} // the argument to NewDocument // contains filtered or unexported fields }
A Document is a lightweight wrapper around either a map[string]interface{} or a struct pointer. It provides operations to get and set fields and field paths.
func NewDocument ¶
NewDocument creates a new document from doc, which must be a non-nil map[string]interface{} or struct pointer.
func (Document) FieldNames ¶
FieldNames returns names of the top-level fields of d.
func (Document) HasFieldFold ¶
HasFieldFold is like HasField but matches case-insensitively for struct field.
type DocumentIterator ¶
type DocumentIterator interface { // Next tries to get the next item in the query result and decodes into Document // with the driver's codec. // When there are no more results, it should return io.EOF. // Once Next returns a non-nil error, it will never be called again. Next(context.Context, Document) error // Stop terminates the iterator before Next return io.EOF, allowing any cleanup // needed. Stop() // As converts i to driver-specific types. // See https://gocloud.dev/concepts/as/ for background information. As(i interface{}) bool }
A DocumentIterator iterates through the results (for Get action).
type Encoder ¶
type Encoder interface { // These methods all encode and store a single Go value. EncodeNil() EncodeBool(bool) EncodeString(string) EncodeInt(int64) EncodeUint(uint64) EncodeFloat(float64) EncodeBytes([]byte) // EncodeList is called when a slice or array is encountered (except for a // []byte, which is handled by EncodeBytes). Its argument is the length of the // slice or array. The encoding algorithm will call the returned Encoder that // many times to encode the successive values of the list. After each such call, // ListIndex will be called with the index of the element just encoded. // // For example, []string{"a", "b"} will result in these calls: // enc2 := enc.EncodeList(2) // enc2.EncodeString("a") // enc2.ListIndex(0) // enc2.EncodeString("b") // enc2.ListIndex(1) EncodeList(n int) Encoder ListIndex(i int) // EncodeMap is called when a map is encountered. Its argument is the number of // fields in the map. The encoding algorithm will call the returned Encoder that // many times to encode the successive values of the map. After each such call, // MapKey will be called with the key of the element just encoded. // // For example, map[string}int{"A": 1, "B": 2} will result in these calls: // enc2 := enc.EncodeMap(2) // enc2.EncodeInt(1) // enc2.MapKey("A") // enc2.EncodeInt(2) // enc2.MapKey("B") // // EncodeMap is also called for structs. The map then consists of the exported // fields of the struct. For struct{A, B int}{1, 2}, if EncodeStruct returns // false, the same sequence of calls as above will occur. EncodeMap(n int) Encoder MapKey(string) // If the encoder wants to encode a value in a special way it should do so here // and return true along with any error from the encoding. Otherwise, it should // return false. EncodeSpecial(v reflect.Value) (bool, error) }
An Encoder encodes Go values in some other form (e.g. JSON, protocol buffers). The encoding protocol is designed to avoid losing type information by passing values using interface{}. An Encoder is responsible for storing the value it is encoding.
Because all drivers must support the same set of values, the encoding methods (with the exception of EncodeStruct) do not return errors. EncodeStruct is special because it is an escape hatch for arbitrary structs, not all of which may be encodable.
type Filter ¶
type Filter struct { FieldPath []string // the field path to filter Op string // the operation, supports =, >, >=, <, <= Value interface{} // the value to compare using the operation }
A Filter defines a filter expression used to filter the query result. If the value is a number type, the filter uses numeric comparison. If the value is a string type, the filter uses UTF-8 string comparison. TODO(#1762): support comparison of other types.
type IncOp ¶
type IncOp struct {
Amount interface{}
}
IncOp is a value representing an increment modification.
type Mod ¶
type Mod struct { FieldPath []string Value interface{} }
A Mod is a modification to a field path in a document. At present, the only modifications supported are: - set the value at the field path, or create the field path if it doesn't exist - delete the field path (when Value is nil)
type Query ¶
type Query struct { // FieldPaths contain a list of field paths the user selects to return in the // query results. The returned documents should only have these fields // populated. FieldPaths [][]string // Filters contain a list of filters for the query. If there are more than one // filter, they should be combined with AND. Filters []Filter // Limit sets the maximum number of results returned by running the query. When // Limit <= 0, the driver implementation should return all possible results. Limit int // OrderByField is the field to use for sorting the results. OrderByField string // OrderAscending specifies the sort direction. OrderAscending bool // BeforeQuery is a callback that must be called exactly once before the // underlying service's query is executed. asFunc allows drivers to expose // driver-specific types. BeforeQuery func(asFunc func(interface{}) bool) error }
A Query defines a query operation to find documents within a collection based on a set of requirements.
type RunActionsOptions ¶
type RunActionsOptions struct { // BeforeDo is a callback that must be called once, sequentially, before each one // or group of the underlying service's actions is executed. asFunc allows // drivers to expose driver-specific types. BeforeDo func(asFunc func(interface{}) bool) error }
RunActionsOptions controls the behavior of RunActions.
type Throttle ¶
type Throttle struct {
// contains filtered or unexported fields
}
Throttle is used to limit the number of outstanding activities, like RPCs. It acts like a combination of a semaphore and a WaitGroup.
func NewThrottle ¶
NewThrottle returns a Throttle that will allow max calls to Acquire that are not matched with Release calls before blocking. If max is <= 0, there is no throttling: Acquire always returns immediately.
func (*Throttle) Acquire ¶
func (t *Throttle) Acquire()
Acquire blocks until a token is available, then acquires it and returns. Acquire is deliberately not sensitive to context.Context, because it assumes that whatever acquires a token will be context-sensitive, and thus will release the token when the context is done.
type UpdateQueryer ¶
UpdateQueryer should be implemented by Collections that can handle Query.Update efficiently. If a Collection does not implement this interface, then Query.Update will be implemented by calling RunGetQuery and updating the returned documents.