driver

package
v0.43.0 Latest Latest
Warning

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

Go to latest
Published: May 15, 2019 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package driver defines a set of interfaces that the docstore package uses to interact with the underlying services.

Index

Constants

View Source
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 Decode

func Decode(v reflect.Value, d Decoder) error

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

func Encode(v reflect.Value, e Encoder) error

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 "github.com/golang/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 SplitActions

func SplitActions(actions []*Action, split func(a, b *Action) bool) [][]*Action

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
	FieldPaths [][]string // field paths to retrieve, for Get only
	Mods       []Mod      // modifications to make, for Update only
}

An Action describes a single operation on a single document.

type ActionKind

type ActionKind int

ActionKind describes the type of an action.

const (
	Create ActionKind = iota
	Replace
	Put
	Get
	Delete
	Update
)

type ActionListError

type ActionListError []struct {
	Index int
	Err   error
}

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 {
	// 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 provider
	// system 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 provider'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.
	RunGetQuery(context.Context, *Query) (DocumentIterator, error)

	// RunDeleteQuery deletes every document matched by the query.
	RunDeleteQuery(context.Context, *Query) error

	// QueryPlan returns the plan for the query.
	QueryPlan(*Query) (string, error)

	// As converts i to provider-specific types.
	// See https://godoc.org/github.com/eliben/gocdkx#hdr-As for background information.
	As(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) gcerr.ErrorCode
}

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)
	AsComplex() (complex128, 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)

	// If MapLen returned true, the DecodeMap will be called. It should iterate over
	// the fields of the value being decoded, invoking the callback on each with the
	// field name and a Decoder for the field value. If the callback returns false,
	// DecodeMap should return immediately.
	DecodeMap(func(string, Decoder) 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 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

func NewDocument(doc interface{}) (Document, error)

Create a new document from doc, which must be a non-nil map[string]interface{} or struct pointer.

func (Document) Decode

func (d Document) Decode(dec Decoder) error

Decode decodes the document using the given Decoder.

func (Document) Encode

func (d Document) Encode(e Encoder) error

Encode encodes the document using the given Encoder.

func (Document) Get

func (d Document) Get(fp []string) (interface{}, error)

Get returns the value of the given field path in the document.

func (Document) GetField

func (d Document) GetField(field string) (interface{}, error)

GetField returns the value of the named document field.

func (Document) Set

func (d Document) Set(fp []string, val interface{}) error

Set sets the value of the field path in the document. This creates sub-maps as necessary, if possible.

func (Document) SetField

func (d Document) SetField(field string, value interface{}) error

SetField sets the field to value in the document.

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 provider-specific types.
	// See https://godoc.org/github.com/eliben/gocdkx#hdr-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)
	EncodeComplex(complex128)
	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 providers 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 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

	// BeforeQuery is a callback that must be called exactly once before the
	// underlying provider's query is executed. asFunc allows providers to expose
	// provider-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 {
	// Unordered let the actions be executed in any order, perhaps concurrently.
	// All of the actions should be executed, even if some fail. The returned
	// ActionListError should have an element for each action that fails.
	Unordered bool

	// BeforeDo is a callback that must be called exactly once before each one or
	// group of the underlying provider's actions is executed. asFunc allows
	// providers to expose provider-specific types.
	BeforeDo func(asFunc func(interface{}) bool) error
}

RunActionsOptions controls the behavior of RunActions.

Jump to

Keyboard shortcuts

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