Documentation

Index

Constants

const KeysOnlyBufSize = 128

const NormalBufSize = 1

Variables

var (
	Equal              = Op("==")
	NotEqual           = Op("!=")
	GreaterThan        = Op(">")
	GreaterThanOrEqual = Op(">=")
	LessThan           = Op("<")
	LessThanOrEqual    = Op("<=")
)

Functions

func Less

func Less(orders []Order, a, b Entry) bool

Less returns true if a comes before b with the requested orderings.

func Sort

func Sort(orders []Order, entries []Entry)

Sort sorts the given entries using the given orders.

Types

type Entry

type Entry struct {
	Key        string    // cant be ds.Key because circular imports ...!!!
	Value      []byte    // Will be nil if KeysOnly has been passed.
	Expiration time.Time // Entry expiration timestamp if requested and supported (see TTLDatastore).
	Size       int       // Might be -1 if the datastore doesn't support listing the size with KeysOnly

}

Entry is a query result entry.

func ResultEntriesFrom

func ResultEntriesFrom(keys []string, vals [][]byte) []Entry

type Filter

type Filter interface {
	// Filter returns whether an entry passes the filter
	Filter(e Entry) bool
}

Filter is an object that tests ResultEntries

type FilterKeyCompare

type FilterKeyCompare struct {
	Op  Op
	Key string
}

func (FilterKeyCompare) Filter

func (f FilterKeyCompare) Filter(e Entry) bool

func (FilterKeyCompare) String

func (f FilterKeyCompare) String() string

type FilterKeyPrefix

type FilterKeyPrefix struct {
	Prefix string
}

func (FilterKeyPrefix) Filter

func (f FilterKeyPrefix) Filter(e Entry) bool

func (FilterKeyPrefix) String

func (f FilterKeyPrefix) String() string

type FilterValueCompare

type FilterValueCompare struct {
	Op    Op
	Value []byte
}

FilterValueCompare is used to signal to datastores they should apply internal comparisons. unfortunately, there is no way to apply comparisons* to interface{} types in Go, so if the datastore doesnt have a special way to handle these comparisons, you must provided the TypedFilter to actually do filtering.

[*] other than == and !=, which use reflect.DeepEqual.

func (FilterValueCompare) Filter

func (f FilterValueCompare) Filter(e Entry) bool

func (FilterValueCompare) String

func (f FilterValueCompare) String() string

type Iterator

type Iterator struct {
	Next  func() (Result, bool)
	Close func() error // note: might be called more than once
}

type Op

type Op string

Op is a comparison operator

type Order

type Order interface {
	Compare(a, b Entry) int
}

Order is an object used to order objects

type OrderByFunction

type OrderByFunction func(a, b Entry) int

OrderByFunction orders the results based on the result of the given function.

func (OrderByFunction) Compare

func (o OrderByFunction) Compare(a, b Entry) int

func (OrderByFunction) String

func (OrderByFunction) String() string

type OrderByKey

type OrderByKey struct{}

OrderByKey

func (OrderByKey) Compare

func (o OrderByKey) Compare(a, b Entry) int

func (OrderByKey) String

func (OrderByKey) String() string

type OrderByKeyDescending

type OrderByKeyDescending struct{}

OrderByKeyDescending

func (OrderByKeyDescending) Compare

func (o OrderByKeyDescending) Compare(a, b Entry) int

func (OrderByKeyDescending) String

func (OrderByKeyDescending) String() string

type OrderByValue

type OrderByValue struct{}

OrderByValue is used to signal to datastores they should apply internal orderings.

func (OrderByValue) Compare

func (o OrderByValue) Compare(a, b Entry) int

func (OrderByValue) String

func (OrderByValue) String() string

type OrderByValueDescending

type OrderByValueDescending struct{}

OrderByValueDescending is used to signal to datastores they should apply internal orderings.

func (OrderByValueDescending) Compare

func (o OrderByValueDescending) Compare(a, b Entry) int

func (OrderByValueDescending) String

func (OrderByValueDescending) String() string

type Query

type Query struct {
	Prefix            string   // namespaces the query to results whose keys have Prefix
	SeekPrefix        string   // seeks the query to a key prefix before returning results
	Filters           []Filter // filter results. apply sequentially
	Orders            []Order  // order results. apply hierarchically
	Limit             int      // maximum number of results
	Offset            int      // skip given number of results
	KeysOnly          bool     // return only keys.
	ReturnExpirations bool     // return expirations (see TTLDatastore)
	ReturnsSizes      bool     // always return sizes. If not set, datastore impl can return

}

Query represents storage for any key-value pair.

tl;dr:

queries are supported across datastores.
Cheap on top of relational dbs, and expensive otherwise.
Pick the right tool for the job!

In addition to the key-value store get and set semantics, datastore provides an interface to retrieve multiple records at a time through the use of queries. The datastore Query model gleans a common set of operations performed when querying. To avoid pasting here years of database research, let’s summarize the operations datastore supports.

Query Operations, applied in-order:

* prefix - scope the query to a given path prefix
* filters - select a subset of values by applying constraints
* orders - sort the results by applying sort conditions, hierarchically.
* offset - skip a number of results (for efficient pagination)
* limit - impose a numeric limit on the number of results

Datastore combines these operations into a simple Query class that allows applications to define their constraints in a simple, generic, way without introducing datastore specific calls, languages, etc.

However, take heed: not all datastores support efficiently performing these operations. Pick a datastore based on your needs. If you need efficient look-ups, go for a simple key/value store. If you need efficient queries, consider an SQL backed datastore.

Notes:

* Prefix: When a query filters by prefix, it selects keys that are strict
  children of the prefix. For example, a prefix "/foo" would select "/foo/bar"
  but not "/foobar" or "/foo",
* Orders: Orders are applied hierarchically. Results are sorted by the first
  ordering, then entries equal under the first ordering are sorted with the
  second ordering, etc.
* Limits & Offset: Limits and offsets are applied after everything else.

func (Query) String

func (q Query) String() string

String returns a string representation of the Query for debugging/validation purposes. Do not use it for SQL queries.

type Result

type Result struct {
	Entry

	Error error
}

Result is a special entry that includes an error, so that the client may be warned about internal errors. If Error is non-nil, Entry must be empty.

type ResultBuilder

type ResultBuilder struct {
	Query   Query
	Process goprocess.Process
	Output  chan Result
}

ResultBuilder is what implementors use to construct results Implementors of datastores and their clients must respect the Process of the Request:

* clients must call r.Process().Close() on an early exit, so
  implementations can reclaim resources.
* if the Entries are read to completion (channel closed), Process
  should be closed automatically.
* datastores must respect <-Process.Closing(), which intermediates
  an early close signal from the client.

func NewResultBuilder

func NewResultBuilder(q Query) *ResultBuilder

func (*ResultBuilder) Results

func (rb *ResultBuilder) Results() Results

Results returns a Results to to this builder.

type Results

type Results interface {
	Query() Query             // the query these Results correspond to
	Next() <-chan Result      // returns a channel to wait for the next result
	NextSync() (Result, bool) // blocks and waits to return the next result, second parameter returns false when results are exhausted
	Rest() ([]Entry, error)   // waits till processing finishes, returns all entries at once.
	Close() error             // client may call Close to signal early exit

	// Process returns a goprocess.Process associated with these results.
	// most users will not need this function (Close is all they want),
	// but it's here in case you want to connect the results to other
	// goprocess-friendly things.
	Process() goprocess.Process
}

Results is a set of Query results. This is the interface for clients. Example:

qr, _ := myds.Query(q)
for r := range qr.Next() {
  if r.Error != nil {
    // handle.
    break
  }

  fmt.Println(r.Entry.Key, r.Entry.Value)
}

or, wait on all results at once:

qr, _ := myds.Query(q)
es, _ := qr.Rest()
for _, e := range es {
  	fmt.Println(e.Key, e.Value)
}

func NaiveFilter

func NaiveFilter(qr Results, filter Filter) Results

NaiveFilter applies a filter to the results.

func NaiveLimit

func NaiveLimit(qr Results, limit int) Results

NaiveLimit truncates the results to a given int limit

func NaiveOffset

func NaiveOffset(qr Results, offset int) Results

NaiveOffset skips a given number of results

func NaiveOrder

func NaiveOrder(qr Results, orders ...Order) Results

NaiveOrder reorders results according to given orders. WARNING: this is the only non-stream friendly operation!

func NaiveQueryApply

func NaiveQueryApply(q Query, qr Results) Results

func ResultsFromIterator

func ResultsFromIterator(q Query, iter Iterator) Results

func ResultsReplaceQuery

func ResultsReplaceQuery(r Results, q Query) Results

func ResultsWithChan

func ResultsWithChan(q Query, res <-chan Result) Results

ResultsWithChan returns a Results object from a channel of Result entries.

DEPRECATED: This iterator is impossible to cancel correctly. Canceling it will leave anything trying to write to the result channel hanging.

func ResultsWithEntries

func ResultsWithEntries(q Query, res []Entry) Results

ResultsWithEntries returns a Results object from a list of entries

func ResultsWithProcess

func ResultsWithProcess(q Query, proc func(goprocess.Process, chan<- Result)) Results

ResultsWithProcess returns a Results object with the results generated by the passed subprocess.