document

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Mar 4, 2020 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package document defines types to manipulate and compare documents and values.

Comparing values

When comparing values, only compatible types can be compared together, otherwise the result of the comparison will always be false. Here is a list of types than can be compared with each other:

any integer			any integer
any integer			float64
float64			float64
string			string
string			bytes
bytes			bytes
bool			bool
null			null

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrFieldNotFound = errors.New("field not found")

ErrFieldNotFound must be returned by Document implementations, when calling the GetByField method and the field wasn't found in the document.

View Source
var ErrStreamClosed = errors.New("stream closed")

ErrStreamClosed is used to indicate that a stream must be closed.

View Source
var ErrValueNotFound = errors.New("value not found")

ErrValueNotFound must be returned by Array implementations, when calling the GetByIndex method and the index wasn't found in the array.

Functions

func ArrayLength

func ArrayLength(a Array) (int, error)

ArrayLength returns the length of an array.

func ArrayToJSON

func ArrayToJSON(w io.Writer, a Array) error

ArrayToJSON encodes a to w in JSON.

func IteratorToJSON

func IteratorToJSON(w io.Writer, s Iterator) error

IteratorToJSON encodes all the documents of an iterator to JSON stream.

func IteratorToJSONArray

func IteratorToJSONArray(w io.Writer, s Iterator) error

IteratorToJSONArray encodes all the documents of an iterator to a JSON array.

func MapScan

func MapScan(d Document, t interface{}) error

MapScan decodes the document into a map.

func Scan

func Scan(d Document, targets ...interface{}) error

Scan each field of the document into the given variables.

func ScanValue

func ScanValue(v Value, t interface{}) error

ScanValue scans v into t.

func SliceScan

func SliceScan(a Array, t interface{}) error

SliceScan scans a document array into a slice or fixed size array. t must be a pointer to a valid slice or array.

It t is a slice pointer and its capacity is too low, a new slice will be allocated. Otherwise, its length is set to 0 so that its content is overrided.

If t is an array pointer, its capacity must be bigger than the length of a, otherwise an error is returned.

func StructScan

func StructScan(d Document, t interface{}) error

StructScan scans d into t. t is expected to be a pointer to a struct.

By default, each struct field name is lowercased and the document's GetByField method is called with that name. If there is a match, the value is converted to the struct field type when possible, otherwise an error is returned. The decoding of each struct field can be customized by the format string stored under the "genji" key stored in the struct field's tag. The content of the format string is used instead of the struct field name and passed to the GetByField method.

func ToJSON

func ToJSON(w io.Writer, d Document) error

ToJSON encodes d to w in JSON.

Types

type Array

type Array interface {
	// Iterate goes through all the values of the array and calls the given function by passing each one of them.
	// If the given function returns an error, the iteration stops.
	Iterate(fn func(i int, value Value) error) error
	// GetByIndex returns a value by index of the array.
	GetByIndex(i int) (Value, error)
}

An Array contains a set of values.

type Document

type Document interface {
	// Iterate goes through all the fields of the document and calls the given function by passing each one of them.
	// If the given function returns an error, the iteration stops.
	Iterate(fn func(field string, value Value) error) error
	// GetByField returns a value by field name.
	// Must return ErrFieldNotFound if the field doesnt exist.
	GetByField(field string) (Value, error)
}

A Document represents a group of key value pairs.

func NewFromMap

func NewFromMap(m interface{}) (Document, error)

NewFromMap creates a document from a map. Due to the way maps are designed, iteration order is not guaranteed.

func NewFromStruct

func NewFromStruct(s interface{}) (Document, error)

NewFromStruct creates a document from a struct using reflection.

type ErrUnsupportedType added in v0.5.0

type ErrUnsupportedType struct {
	Value interface{}
	Msg   string
}

this error is used to skip struct or array fields that are not supported.

func (*ErrUnsupportedType) Error added in v0.5.0

func (e *ErrUnsupportedType) Error() string

type FieldBuffer

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

FieldBuffer stores a group of fields in memory. It implements the Document interface.

func NewFieldBuffer

func NewFieldBuffer() *FieldBuffer

NewFieldBuffer creates a FieldBuffer.

func (*FieldBuffer) Add

func (fb *FieldBuffer) Add(field string, v Value) *FieldBuffer

Add a field to the buffer.

func (*FieldBuffer) Copy

func (fb *FieldBuffer) Copy(d Document) error

Copy deep copies every value of the document to the buffer. If a value is a document or an array, it will be stored as a FieldBuffer or ValueBuffer respectively.

func (*FieldBuffer) Delete

func (fb *FieldBuffer) Delete(field string) error

Delete a field from the buffer.

func (FieldBuffer) GetByField

func (fb FieldBuffer) GetByField(field string) (Value, error)

GetByField returns a value by field. Returns an error if the field doesn't exists.

func (FieldBuffer) Iterate

func (fb FieldBuffer) Iterate(fn func(f string, v Value) error) error

Iterate goes through all the fields of the document and calls the given function by passing each one of them. If the given function returns an error, the iteration stops.

func (FieldBuffer) Len

func (fb FieldBuffer) Len() int

Len of the buffer.

func (*FieldBuffer) MarshalJSON

func (fb *FieldBuffer) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*FieldBuffer) Replace

func (fb *FieldBuffer) Replace(field string, v Value) error

Replace the value of the field by v.

func (*FieldBuffer) Reset

func (fb *FieldBuffer) Reset()

Reset the buffer.

func (*FieldBuffer) ScanDocument

func (fb *FieldBuffer) ScanDocument(d Document) error

ScanDocument copies all the fields of d to the buffer.

func (*FieldBuffer) Set

func (fb *FieldBuffer) Set(f string, v Value)

Set replaces a field if it already exists or creates one if not.

func (*FieldBuffer) UnmarshalJSON

func (fb *FieldBuffer) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

type Iterator

type Iterator interface {
	// Iterate goes through all the documents and calls the given function by passing each one of them.
	// If the given function returns an error, the iteration stops.
	Iterate(func(d Document) error) error
}

An Iterator can iterate over documents.

func NewIterator

func NewIterator(documents ...Document) Iterator

NewIterator creates an iterator that iterates over documents.

type Keyer

type Keyer interface {
	Key() []byte
}

A Keyer returns the key identifying documents in their storage. This is usually implemented by documents read from storages.

type Scanner

type Scanner interface {
	ScanDocument(Document) error
}

A Scanner can iterate over a document and scan all the fields.

type Stream

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

Stream reads documents of an iterator one by one and passes them through a list of functions for transformation.

func NewStream

func NewStream(it Iterator) Stream

NewStream creates a stream using the given iterator.

func (Stream) Append

func (s Stream) Append(it Iterator) Stream

Append adds the given iterator to the stream.

func (Stream) Count

func (s Stream) Count() (int, error)

Count counts all the documents from the stream.

func (Stream) Filter

func (s Stream) Filter(fn func(d Document) (bool, error)) Stream

Filter each received document using fn. If fn returns true, the document is kept, otherwise it is skipped. If fn returns an error, the stream is interrupted.

func (Stream) First

func (s Stream) First() (d Document, err error)

First runs the stream, returns the first document found and closes the stream. If the stream is empty, all return values are nil.

Example
package main

import (
	"fmt"
	"log"

	"github.com/asdine/genji"
	"github.com/asdine/genji/document"
)

func main() {
	db, err := genji.Open(":memory:")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	err = db.Exec("CREATE TABLE user")
	if err != nil {
		log.Fatal(err)
	}

	err = db.Exec("INSERT INTO user (id, name, age) VALUES (?, ?, ?)", 10, "foo", 15)
	if err != nil {
		log.Fatal(err)
	}

	result, err := db.Query("SELECT id, name, age FROM user WHERE name = ?", "foo")
	if err != nil {
		panic(err)
	}
	defer result.Close()

	d, err := result.First()
	if err != nil {
		panic(err)
	}

	var id uint64
	var name string
	var age uint8

	err = document.Scan(d, &id, &name, &age)
	if err != nil {
		panic(err)
	}

	fmt.Println(id, name, age)

}
Output:

10 foo 15

func (Stream) Iterate

func (s Stream) Iterate(fn func(d Document) error) error

Iterate calls the underlying iterator's iterate method. If this stream was created using the Pipe method, it will apply fn to any document passed by the underlying iterator. If fn returns a document, it will be passed to the next stream. If it returns a nil document, the document will be ignored. If it returns an error, the stream will be interrupted and that error will bubble up and returned by fn, unless that error is ErrStreamClosed, in which case the Iterate method will stop the iteration and return nil. It implements the Iterator interface.

Example
package main

import (
	"fmt"
	"log"

	"github.com/asdine/genji"
	"github.com/asdine/genji/document"
)

func main() {
	type User struct {
		ID      int64
		Name    string
		Age     uint32
		Address struct {
			City    string
			ZipCode string
		}
	}

	db, err := genji.Open(":memory:")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	err = db.Exec("CREATE TABLE IF NOT EXISTS user")
	if err != nil {
		log.Fatal(err)
	}

	for i := 1; i <= 10; i++ {
		err = db.Exec("INSERT INTO user VALUES ?", &User{
			ID:   int64(i),
			Name: fmt.Sprintf("foo%d", i),
			Age:  uint32(i * 10),
			Address: struct {
				City    string
				ZipCode string
			}{
				City:    "Lyon",
				ZipCode: fmt.Sprintf("69%03d", i),
			},
		})
		if err != nil {
			log.Fatal(err)
		}
	}

	result, err := db.Query(`SELECT id, name, age, address FROM user WHERE age >= 18`)
	if err != nil {
		panic(err)
	}
	defer result.Close()

	err = result.Iterate(func(d document.Document) error {
		// Scan into a struct
		var u User
		err = document.StructScan(d, &u)
		if err != nil {
			return err
		}

		fmt.Println(u)

		// Or scan individual variables
		// Types of variables don't have to exactly match with the types stored
		var id uint64
		var name []byte
		var age uint8
		var address map[string]string

		err = document.Scan(d, &id, &name, &age, &address)
		if err != nil {
			return err
		}

		fmt.Println(id, string(name), age, address)
		return nil
	})
	if err != nil {
		panic(err)
	}

}
Output:

{2 foo2 20 {Lyon 69002}}
2 foo2 20 map[city:Lyon zipcode:69002]
{3 foo3 30 {Lyon 69003}}
3 foo3 30 map[city:Lyon zipcode:69003]
{4 foo4 40 {Lyon 69004}}
4 foo4 40 map[city:Lyon zipcode:69004]
{5 foo5 50 {Lyon 69005}}
5 foo5 50 map[city:Lyon zipcode:69005]
{6 foo6 60 {Lyon 69006}}
6 foo6 60 map[city:Lyon zipcode:69006]
{7 foo7 70 {Lyon 69007}}
7 foo7 70 map[city:Lyon zipcode:69007]
{8 foo8 80 {Lyon 69008}}
8 foo8 80 map[city:Lyon zipcode:69008]
{9 foo9 90 {Lyon 69009}}
9 foo9 90 map[city:Lyon zipcode:69009]
{10 foo10 100 {Lyon 69010}}
10 foo10 100 map[city:Lyon zipcode:69010]

func (Stream) Limit

func (s Stream) Limit(n int) Stream

Limit interrupts the stream once the number of passed documents have reached n.

func (Stream) Map

func (s Stream) Map(fn func(d Document) (Document, error)) Stream

Map applies fn to each received document and passes it to the next stream. If fn returns an error, the stream is interrupted.

func (Stream) Offset

func (s Stream) Offset(n int) Stream

Offset ignores n documents then passes the subsequent ones to the stream.

func (Stream) Pipe

func (s Stream) Pipe(op StreamOperator) Stream

Pipe creates a new Stream who can read its data from s and apply op to every document passed by its Iterate method.

type StreamOperator

type StreamOperator func() func(d Document) (Document, error)

An StreamOperator is used to modify a stream. If a stream operator returns a document, it will be passed to the next stream. If it returns a nil document, the document will be ignored. If it returns an error, the stream will be interrupted and that error will bubble up and returned by this function, unless that error is ErrStreamClosed, in which case the Iterate method will stop the iteration and return nil. Stream operators can be reused, and thus, any state or side effect should be kept within the operator closure unless the nature of the operator prevents that.

type Value

type Value struct {
	Type ValueType
	V    interface{}
}

A Value stores encoded data alongside its type.

func NewArrayValue

func NewArrayValue(a Array) Value

NewArrayValue returns a value of type Array.

func NewBlobValue added in v0.5.0

func NewBlobValue(x []byte) Value

NewBlobValue encodes x and returns a value.

func NewBoolValue

func NewBoolValue(x bool) Value

NewBoolValue encodes x and returns a value.

func NewDocumentValue

func NewDocumentValue(d Document) Value

NewDocumentValue returns a value of type Document.

func NewDurationValue added in v0.5.0

func NewDurationValue(d time.Duration) Value

NewDurationValue returns a value of type Duration.

func NewFloat64Value

func NewFloat64Value(x float64) Value

NewFloat64Value encodes x and returns a value.

func NewInt16Value

func NewInt16Value(x int16) Value

NewInt16Value encodes x and returns a value.

func NewInt32Value

func NewInt32Value(x int32) Value

NewInt32Value encodes x and returns a value.

func NewInt64Value

func NewInt64Value(x int64) Value

NewInt64Value encodes x and returns a value.

func NewInt8Value

func NewInt8Value(x int8) Value

NewInt8Value encodes x and returns a value.

func NewIntValue

func NewIntValue(x int) Value

NewIntValue encodes x and returns a value whose type depends on the magnitude of x.

func NewNullValue

func NewNullValue() Value

NewNullValue returns a Null value.

func NewTextValue added in v0.5.0

func NewTextValue(x string) Value

NewTextValue encodes x and returns a value.

func NewValue

func NewValue(x interface{}) (Value, error)

NewValue creates a value whose type is infered from x.

func NewZeroValue

func NewZeroValue(t ValueType) Value

NewZeroValue returns a value whose value is equal to the Go zero value of the selected type.

func (Value) Add added in v0.5.0

func (v Value) Add(u Value) (res Value, err error)

Add u to v and return the result. Only numeric values and booleans can be added together.

func (Value) BitwiseAnd added in v0.5.0

func (v Value) BitwiseAnd(u Value) (res Value, err error)

BitwiseAnd calculates v & u and returns the result. Only numeric values and booleans can be calculated together. If both v and u are integers, the result will be an integer.

func (Value) BitwiseOr added in v0.5.0

func (v Value) BitwiseOr(u Value) (res Value, err error)

BitwiseOr calculates v | u and returns the result. Only numeric values and booleans can be calculated together. If both v and u are integers, the result will be an integer.

func (Value) BitwiseXor added in v0.5.0

func (v Value) BitwiseXor(u Value) (res Value, err error)

BitwiseXor calculates v ^ u and returns the result. Only numeric values and booleans can be calculated together. If both v and u are integers, the result will be an integer.

func (Value) Compare added in v0.5.0

func (v Value) Compare(u Value) int

Compare compares two values performing best-effort comparisons Returns > 0 if this value can be considered bigger Returns < 0 if this value can be considered smaller Returns 0 if values can be considered equal

func (Value) ConvertTo

func (v Value) ConvertTo(t ValueType) (Value, error)

ConvertTo decodes v to the selected type when possible.

func (Value) ConvertToArray

func (v Value) ConvertToArray() (Array, error)

ConvertToArray returns an array from the value. It only works if the type of v is ArrayValue.

func (Value) ConvertToBlob added in v0.5.0

func (v Value) ConvertToBlob() ([]byte, error)

ConvertToBlob converts a value of type Text or Blob to a slice of bytes. If fails if it's used with any other type.

func (Value) ConvertToBool

func (v Value) ConvertToBool() (bool, error)

ConvertToBool returns true if v is truthy, otherwise it returns false.

func (Value) ConvertToDocument

func (v Value) ConvertToDocument() (Document, error)

ConvertToDocument returns a document from the value. It only works if the type of v is DocumentValue.

func (Value) ConvertToDuration added in v0.5.0

func (v Value) ConvertToDuration() (time.Duration, error)

ConvertToDuration turns any number into a time.Duration. It doesn't work with other types.

func (Value) ConvertToFloat64

func (v Value) ConvertToFloat64() (float64, error)

ConvertToFloat64 turns any number into a float64. It doesn't work with other types.

func (Value) ConvertToInt64

func (v Value) ConvertToInt64() (int64, error)

ConvertToInt64 turns any number into an int64. It doesn't work with other types.

func (Value) ConvertToText added in v0.5.0

func (v Value) ConvertToText() (string, error)

ConvertToText turns a value of type Text or Blob into a string. If fails if it's used with any other type.

func (Value) Div added in v0.5.0

func (v Value) Div(u Value) (res Value, err error)

Div calculates v / u and returns the result. Only numeric values and booleans can be calculated together. If both v and u are integers, the result will be an integer.

func (Value) IsEqual

func (v Value) IsEqual(other Value) (bool, error)

IsEqual returns true if v is equal to the given value.

func (Value) IsGreaterThan

func (v Value) IsGreaterThan(other Value) (bool, error)

IsGreaterThan returns true if v is greather than the given value.

func (Value) IsGreaterThanOrEqual

func (v Value) IsGreaterThanOrEqual(other Value) (bool, error)

IsGreaterThanOrEqual returns true if v is greather than or equal to the given value.

func (Value) IsLesserThan

func (v Value) IsLesserThan(other Value) (bool, error)

IsLesserThan returns true if v is lesser than the given value.

func (Value) IsLesserThanOrEqual

func (v Value) IsLesserThanOrEqual(other Value) (bool, error)

IsLesserThanOrEqual returns true if v is lesser than or equal to the given value.

func (Value) IsNotEqual

func (v Value) IsNotEqual(other Value) (bool, error)

IsNotEqual returns true if v is not equal to the given value.

func (Value) IsTruthy

func (v Value) IsTruthy() bool

IsTruthy returns whether v is not equal to the zero value of its type.

func (Value) IsZeroValue

func (v Value) IsZeroValue() bool

IsZeroValue indicates if the value data is the zero value for the value type. This function doesn't perform any allocation.

func (Value) MarshalJSON

func (v Value) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (Value) Mod added in v0.5.0

func (v Value) Mod(u Value) (res Value, err error)

Mod calculates v / u and returns the result. Only numeric values and booleans can be calculated together. If both v and u are integers, the result will be an integer.

func (Value) Mul added in v0.5.0

func (v Value) Mul(u Value) (res Value, err error)

Mul calculates v * u and returns the result. Only numeric values and booleans can be calculated together.

func (Value) Scan

func (v Value) Scan(t interface{}) error

Scan v into t.

func (Value) String

func (v Value) String() string

String returns a string representation of the value. It implements the fmt.Stringer interface.

func (Value) Sub added in v0.5.0

func (v Value) Sub(u Value) (res Value, err error)

Sub calculates v - u and returns the result. Only numeric values and booleans can be calculated together.

type ValueBuffer

type ValueBuffer []Value

ValueBuffer is an array that holds values in memory.

func NewValueBuffer

func NewValueBuffer(values ...Value) ValueBuffer

NewValueBuffer creates a buffer of values.

func (ValueBuffer) Append

func (vb ValueBuffer) Append(v Value) ValueBuffer

Append a value to the buffer and return a new buffer.

func (*ValueBuffer) Copy

func (vb *ValueBuffer) Copy(a Array) error

Copy deep copies all the values from the given array. If a value is a document or an array, it will be stored as a FieldBuffer or ValueBuffer respectively.

func (ValueBuffer) GetByIndex

func (vb ValueBuffer) GetByIndex(i int) (Value, error)

GetByIndex returns a value set at the given index. If the index is out of range it returns an error.

func (ValueBuffer) Iterate

func (vb ValueBuffer) Iterate(fn func(i int, value Value) error) error

Iterate over all the values of the buffer. It implements the Array interface.

func (*ValueBuffer) Replace

func (vb *ValueBuffer) Replace(index int, v Value) error

Replace the value of the index by v.

func (*ValueBuffer) ScanArray

func (vb *ValueBuffer) ScanArray(a Array) error

ScanArray copies all the values of a to the buffer.

func (*ValueBuffer) UnmarshalJSON

func (vb *ValueBuffer) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

type ValuePath

type ValuePath []string

A ValuePath represents the path to a particular value within a document.

func NewValuePath

func NewValuePath(p string) ValuePath

NewValuePath takes a string representation of a value path and returns a ValuePath. It assumes the separator is a dot.

func (ValuePath) GetValue

func (p ValuePath) GetValue(d Document) (Value, error)

GetValue from a document.

func (ValuePath) String

func (p ValuePath) String() string

String joins all the chunks of the path using the dot separator. It implements the Stringer interface.

type ValueType

type ValueType uint8

ValueType represents a value type supported by the database.

const (
	BlobValue ValueType = iota + 1
	TextValue
	BoolValue
	Int8Value
	Int16Value
	Int32Value
	Int64Value
	Float64Value

	NullValue

	DocumentValue
	ArrayValue

	DurationValue
)

List of supported value types.

func (ValueType) IsFloat

func (t ValueType) IsFloat() bool

IsFloat returns true if t is either a Float32 or Float64.

func (ValueType) IsInteger

func (t ValueType) IsInteger() bool

IsInteger returns true if t is a signed or unsigned integer of any size.

func (ValueType) IsNumber

func (t ValueType) IsNumber() bool

IsNumber returns true if t is either an integer of a float.

func (ValueType) String

func (t ValueType) String() string

Directories

Path Synopsis
Package encoding provides types and functions to encode and decode documents and values.
Package encoding provides types and functions to encode and decode documents and values.

Jump to

Keyboard shortcuts

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