stored

package module
v0.0.0-...-e5660c3 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2021 License: Apache-2.0 Imports: 22 Imported by: 0

README

FoundationDB layer

In development. Use with care, schema are about to change in the future.

Init the database

Before you start STORED document, a layer must be inited. This way you will describe all the objects and indexes. Init part should be executed before the actual part of your application. Example:

var dbUser, dbChat *stored.Object
var dbUserChat *stored.Relation
func init() { // init database
  cluster := stored.Connect("./fdb.cluster")
  err := cluster.Err()
  if err != nil {
    fmt.Println("DB Problem", err)
    // no "return" needed, if db will wake up, client library will catch it up
  }
  db := cluster.Directory("test")
  user := db.Object("user", User{})
  chat := db.Object("chat", Chat{})
  dbUserChat = user.N2N(chat)
  dbUser = user.Done() // finish object
  dbChat = chat.Done()
}

It is required to create a variable for each database object. This may seems like unnecessary code but this approach allowes you to have much more control over your source code. For example it makes easy to find all usage of specific object in your codebase.

All the steps will be described below:

Connect to DB
cluster := stored.Connect("./fdb.cluster")
Create directory

All objects should be stored in a directory. Using directories you are able to separate different logical parts of application.

db := cluster.Directory("test")
Define a stored document

STORED could use any struct defined in your app as a schema, all you need is to add annotations, like stored:"online,mutable" mutual tag means this field will be changed often, so should not be packed.

type dbUser struct {
  ID    int64  `stored:"id"`
  Name  string `stored:"name"`
  Login string `stored:"login"`
  Online bool `stored:"online,mutable"`
}

List of options available:

  • mutable indicates that field should kept separately if it going to be changed frequently (not implemented yet)
Objects initialization

Objects is a main workhorse of stored FoundationDB layer. You should init objects for all the objects in your application at the initialization part of application.

user := db.Object("user", User{}) // User could be any struct in your project
Primary keys

Alternative to setting primary in struct define annotation is setting it directly.

user.Primary("id")

Primary index could be multiple, for example:

user.Primary("chat_id", "message_id")

In this case the combination of values will be the primary key. Fields order should not change.

IDDate

This is the best way to generate new indexes for objects with fields like int64. IDDate is most suitable way to generate unique identifiers in most cases. IDDate will generate int64 identifier based on current timestamp plus some random seed. This way ID could serve double purpose storing ID plus storing timestamp of adding the object. Since int64 is not precise enough to completely illuminate collisions, if field is in primary index at the moment of Add STORED will check that no other key with such ID presented.

user.IDDate("id") // field id should be int64 or uint64
IDRandom

You should use IDRandom when you do not want your ID to unveil timestamp of object creation. Since int64 is not precise enough to completely illuminate collisions, if field is in primary index at the moment of Add STORED will check that no other key with such ID presented.

user.IDRandom("id") // field id should be int64 or uint64
AutoIncrement

Autoincrement is an easy way to provide automatically incremented values to an field. At the moment of each Add new object will be written with incremented counter, 1,2,3 etc..

But autoincrement should be used with care, since incrementing of a counter creates collision of transactions you should not use this options when there are more than 100 Adds per second

Any key could be setup as autoincremented.

user.AutoIncrement("id")

this way the value of this field will be set automaticly if Add dbUser.Add(&user) method triggered.

Indexes

Unique creates unique index. You could fetch document directly using this index. Add and Set methods would fail if other item with same unique index presented.

user.Unique("login")

Index creates regular index. Could be many rows with this index. You are able to fetch first row or list of rows.

user.Index("login")
Relations

N2N is the most usefull type of relations between database objects. N2N represents many to many type of connection.

dbUserChat := user.N2N(chat)

In this example dbUserChat represents relation when any user has unlimited amount of connected chats and any chat has unlimited amount of connected users. Also it is available to set any data value to each connection (user to chat and chat to user)

Working with data

If database is successfully inited and schema is set up, you are ok to work with defined database objects. Make sure that init section is triggered once and before any work with database.

Write data to key

This way stored will write user object in set of keys each for each field with stored:"some_key" type annotation

user := User{1, "John", "john"}
err := dbUser.Set(user).Err()

If you have autoincrement option at your primary field you are able to Add new rows

user := User{0, "John", "john"}
err := dbUser.Add(&user).Err() // after this user.ID will be 1
Get data by primary ID

You could use method Get to fetch any object from stored by primary key

user := User{1}
err := dbUser.Get(&user).Err()

Also you could perform multiget. This way a lot of items will be requested simultaneously

users := []*User{&User{1},&User{2},&User{3},&User{4}}
err := dbUser.MultiGet(users).Err()
Get data by index
user := User{}
err := dbUser.GetBy("login", "john").Scan(&user)
Add new connection using relation

Before using the connection you should create new relation at #init section

dbUserChat.Set(user, chat)

user and chat objects should contain primary index values There are cases when inside the relation you want to store some data, for example say:

  • in user-chat connection you want to store last message_id user read
  • in chat-user connection you want to store user join date in this chat
dbUserChat.ClientData("last_message") // last_message is the field at the client (Chat) object
dbUserChat.HostData("join_date") // last_message is the field at the client (Chat) object

Data object could be any type, even the struct. But complicated struct object could got

Get list of objects using Relation

Say you have N2N relation between users and chats.

  • GetClients allow you to fetch all objects using host of this relation
chats := []Chat{}
err = dbUserChat.GetClients(user, nil, 100).ScanAll(&chats)
  • GetHosts allow you to fetch all objects using client of this relation
users := []User{}
err = dbUserChat.GetHosts(chat, nil, 100).ScanAll(&users)

Testing

Stored has set of unit tests, you can easily run to check that everything set up properly. Use this simple code snippet to run tests on your database.

dbDriver := stored.Connect("./fdb.cluster")
stored.TestsRun(dbDriver)

TODO

  • Indexes
  • AutoIncrement
  • Multiple primary
  • Store schema inside FoundationDB
  • Schema migration (delete each item with old schema and set with new one)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AssertErrors = []string{}

AssertErrors list of errors

View Source
var AssertMux sync.Mutex

AssertMux mutex for errors

View Source
var ErrAlreadyExist = errors.New("This object already exist")

ErrAlreadyExist Object with this primary index or one of unique indexes already

View Source
var ErrDataCorrupt = errors.New("Data corrupt")

ErrDataCorrupt incorrect data sent

View Source
var ErrNotFound = errors.New("Document not found")

ErrNotFound is an error returned when no rows was found

View Source
var ErrSkip = errors.New("Operation was skipped")

ErrSkip returned in cases when it is necessary to skip operation without cancelling underlying transactions

View Source
var Nan = []byte{}

Nan means no data presented

View Source
var RelationN2N = 1

RelationN2N is main type of relation

Functions

func Complex128

func Complex128(i complex128) []byte

Complex128 convert complex128 to byte array

func Distance

func Distance(lat1, lon1, lat2, lon2 float64) float64

Distance function returns the distance (in meters) between two points of

a given longitude and latitude relatively accurately (using a spherical
approximation of the Earth) through the Haversin Distance Formula for
great arc distance on a sphere with accuracy for small distances

point coordinates are supplied in degrees and converted into rad. in the func

distance returned in meters

func FetchRange

func FetchRange(tr fdb.ReadTransaction, needed []fdb.RangeResult) ([][]fdb.KeyValue, error)

FetchRange will fetch list of range results

func ID64

func ID64() (id int64)

ID64 will return pseudounique ID with int64

func Int

func Int(i int) []byte

Int convert int to byte array

func Int32

func Int32(i int32) []byte

Int32 convert int32 to byte array

func Int64

func Int64(i int64) []byte

Int64 convert int64 to byte array

func TestsCheck

func TestsCheck() []string

TestsCheck will return list of tests result

func TestsRun

func TestsRun(db *Cluster)

TestsRun runs tests for STORED FoundationdDB layer

func ToInt

func ToInt(b []byte) int

ToInt converts byte array to int64

func ToInt32

func ToInt32(b []byte) int32

ToInt32 converts byte array to int64

func ToInt64

func ToInt64(b []byte) int64

ToInt64 converts byte array to int64

Types

type Chain

type Chain func() Chain

Chain is the recursive functions chain

type Cluster

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

Cluster is the main struct for handling work with fdb

func Connect

func Connect(cluster string) *Cluster

Connect is main constructor for creating connections

func (*Cluster) Directory

func (c *Cluster) Directory(name string) *Directory

Directory created an directury that could be used to work with stored

func (*Cluster) Err

func (c *Cluster) Err() error

Err return error if something wrong with cluster

func (*Cluster) Status

func (c *Cluster) Status() (*ClusterStatus, error)

Status will return fdb cluster status

type ClusterStatus

type ClusterStatus struct {
	Client struct {
		ClusterFile struct {
			Path     string `json:"path"`
			UpToDate bool   `json:"up_to_date"`
		} `json:"cluster_file"`
		Coordinators struct {
			Coordinators []struct {
				Address   string `json:"address"`
				Reachable bool   `json:"reachable"`
			} `json:"coordinators"`
			QuorumReachable bool `json:"quorum_reachable"`
		} `json:"coordinators"`
		DatabaseStatus struct {
			Available bool `json:"available"`
			Healthy   bool `json:"healthy"`
		} `json:"database_status"`
		Messages []struct {
			Description string `json:"description"`
			Name        string `json:"name"`
		} `json:"messages"`
	} `json:"client"`
}

ClusterStatus is status command fdb format

type Counter

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

Counter allow you to operate different counters inside your object

func (*Counter) Get

func (c *Counter) Get(data interface{}) *Promise

Get will get counter data

type Directory

type Directory struct {
	Name     string
	Cluster  *Cluster
	Subspace directory.DirectorySubspace
	// contains filtered or unexported fields
}

Directory is wrapper around foundation db directories, main entry point for working with STORED

func (*Directory) Clear

func (d *Directory) Clear() error

Clear removes all content inside directory

func (*Directory) Multi

func (d *Directory) Multi() *MultiChain

Multi creates reference object for multi requests

func (*Directory) Object

func (d *Directory) Object(name string, schemeObj interface{}) *ObjectBuilder

Object declares new object for document layer

func (*Directory) Parallel

func (d *Directory) Parallel(tasks ...PromiseAny) *Transaction

Parallel will create read transaction to perform multi gets

func (*Directory) Read

func (d *Directory) Read(callback func(*Transaction)) *Transaction

Read will run callback in read transaction

func (*Directory) Write

func (d *Directory) Write(callback func(*Transaction)) *Transaction

Write will run callback in write transaction

type Field

type Field struct {
	Name    string
	Num     int
	Kind    reflect.Kind
	SubKind reflect.Kind
	Type    reflect.StructField
	Value   reflect.Value

	AutoIncrement bool
	GenID         GenIDType // type of ID autogeneration, IDDate, IDRandom

	UnStored bool // means this field would not be stored inside main object
	// contains filtered or unexported fields
}

Field is main field structure

func (*Field) BytesFromObject

func (f *Field) BytesFromObject(objectValue interface{}) ([]byte, error)

BytesFromObject return bytes using full object instead of field value

func (*Field) GenerateID

func (f *Field) GenerateID() []byte

GenerateID will return ID bytes for type specified

func (*Field) GetDefault

func (f *Field) GetDefault() interface{}

GetDefault return default value for this field

func (*Field) ParseTag

func (f *Field) ParseTag() *Tag

ParseTag converts object stored tag to sturct with options

func (*Field) SetAutoIncrement

func (f *Field) SetAutoIncrement()

SetAutoIncrement checks if everything ok for autoincrements

func (*Field) SetID

func (f *Field) SetID(idType GenIDType)

SetID sets unique id before the add write

func (*Field) ToBytes

func (f *Field) ToBytes(val interface{}) ([]byte, error)

ToBytes packs interface field value to bytes

func (*Field) ToInterface

func (f *Field) ToInterface(obj []byte) interface{}

ToInterface decodes field value

type GenIDType

type GenIDType int

GenIDType is type for ID generators

const (
	// GenIDNone is no generateID options set
	GenIDNone GenIDType = iota
	// GenIDDate is option for generating unique id using unix timestamp and random combined,
	GenIDDate
	// GenIDRandom if you do not want unix timestamp in your ids
	GenIDRandom
)

type Index

type Index struct {
	Name   string
	Unique bool
	Geo    int // geo precision used to
	// contains filtered or unexported fields
}

Index represend all indexes sored has

func (*Index) ClearAll

func (i *Index) ClearAll() error

ClearAll will remove all data for specific index

func (*Index) Delete

func (i *Index) Delete(tr fdb.Transaction, primaryTuple tuple.Tuple, key tuple.Tuple)

Delete removes selected index

func (*Index) Options

func (i *Index) Options(options ...IndexOption)

Options allow to set list of options

func (*Index) Reindex

func (i *Index) Reindex()

Reindex will reindex index data

func (*Index) ReindexUnsafe

func (i *Index) ReindexUnsafe(data interface{}) *PromiseErr

ReindexUnsafe will update index info (NOT consistency safe function) this function will use data provited by th object so should be used with care

func (*Index) SetOption

func (i *Index) SetOption(option IndexOption)

SetOption allow to set option

func (*Index) Write

func (i *Index) Write(tr fdb.Transaction, primaryTuple tuple.Tuple, input, oldObject *Struct) error

Write writes index related keys

type IndexGeo

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

IndexGeo does all the Index does but also geo

func (*IndexGeo) GetGeo

func (ig *IndexGeo) GetGeo(lat float64, long float64) *PromiseSlice

GetGeo will return elements by geo index

type IndexOption

type IndexOption struct {
	// CheckHandler describes should index be written for specific object or not
	CheckHandler func(obj interface{}) bool
}

IndexOption is in option struct which allow to set differnt options

type IndexSearch

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

IndexSearch provide substring search index for strings. That means you can search by part of the word this index is fast but could leave significant memory footpring on your database

func (*IndexSearch) ClearAll

func (is *IndexSearch) ClearAll() error

ClearAll will remove index data

func (*IndexSearch) Reindex

func (is *IndexSearch) Reindex()

Reindex will reindex index data

func (*IndexSearch) Search

func (is *IndexSearch) Search(name string) *PromiseSlice

Search is main function to search using search index

type Key

type Key = []byte

Key is main type for byte array keys

type KeyElement

type KeyElement interface{}

A KeyElement is one of the types that may be encoded in FoundationDB tuples. Although the Go compiler cannot enforce this, it is a programming error to use an unsupported types as a KeyElement (and will typically result in a runtime panic).

The valid types for KeyElement are []byte (or fdb.KeyConvertible), string, int64 (or int), float, double, bool, UUID, Tuple, and nil.

type KeyTuple

type KeyTuple []KeyElement

KeyTuple is the list of keys

func (KeyTuple) Pack

func (kt KeyTuple) Pack() []byte

Pack will return packed KeyTuple as bytearray

type MultiChain

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

MultiChain allow to select multiple objects simultaniusly

func (*MultiChain) Get

func (m *MultiChain) Get(o *Object, objOrID interface{}) *Value

Get wiil get all objects with this object

func (*MultiChain) Need

func (m *MultiChain) Need(o *Object, objOrID interface{}) *Value

Need means this object should be fetched

type Object

type Object struct {
	Relations []*Relation
	// contains filtered or unexported fields
}

Object is an abstraction for working with objects

func (*Object) Add

func (o *Object) Add(data interface{}) *PromiseErr

Add writes data even in primary key is empty, by setting it. Take a look at autoincrement tag

func (*Object) Clear

func (o *Object) Clear() error

Clear clears all info in object storage

func (*Object) ClearAllIndexes

func (o *Object) ClearAllIndexes() error

ClearAllIndexes clears all indexes data

func (*Object) Delete

func (o *Object) Delete(objOrID interface{}) *PromiseErr

Delete removes data

func (*Object) Get

func (o *Object) Get(objectPtr interface{}) *PromiseErr

Get fetch object using primary id

func (*Object) GetBy

func (o *Object) GetBy(objectPtr interface{}, indexKeys ...string) *PromiseErr

GetBy fetch one row using index bye name or name of the index field

func (*Object) GetField

func (o *Object) GetField(objectPtr interface{}, fieldName string) *PromiseErr

GetField will fill fetch the mutable field data, and fill the passed object

func (*Object) IncFieldUnsafe

func (o *Object) IncFieldUnsafe(objOrID interface{}, fieldName string, incVal interface{}) *PromiseErr

IncFieldUnsafe increment field of an object does not implement indexes in the moment would not increment field of passed object, take care

func (*Object) IncGetField

func (o *Object) IncGetField(objOrID interface{}, fieldName string, incVal interface{}) *Promise

IncGetField increment field and return new value moved to IncFieldAtomic

func (*Object) List

func (o *Object) List(primary ...interface{}) *Query

List queries list of items using primary key subspace. Pass no params if fetching all objects

func (*Object) ListAll

func (o *Object) ListAll() *Query

ListAll queries list all items inside. Pass no params if fetching all objects

func (*Object) Migrate

func (o *Object) Migrate(migrateTo *Object)

Migrate will move date from one storage to another

func (*Object) MultiGet

func (o *Object) MultiGet(sliceObjectPtr interface{}) *PromiseErr

MultiGet fetch list of objects using primary id

func (*Object) Reindex

func (o *Object) Reindex()

Reindex will go around all data and delete add every row

func (*Object) Set

func (o *Object) Set(objectPtr interface{}) *PromiseErr

Set writes data, would return error if primary key is empty

func (*Object) SetField

func (o *Object) SetField(objectPtr interface{}, fieldName string) *PromiseErr

SetField sets any value to requested field

func (*Object) Update

func (o *Object) Update(data interface{}, callback func() error) *PromiseErr

Update writes data, only if row already exist

func (*Object) UpdateField

func (o *Object) UpdateField(objOrID interface{}, fieldName string, callback func(value interface{}) (interface{}, error)) *Promise

UpdateField updates object field via callback with old value moved to ChangeField

func (*Object) Use

func (o *Object) Use(indexFieldNames ...string) *Query

Use is an index selector for query building

func (*Object) Write

func (o *Object) Write(data interface{}) *PromiseErr

Write writes data, only if row already exist

type ObjectBuilder

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

ObjectBuilder is main interface to declare objects

func (*ObjectBuilder) AutoIncrement

func (ob *ObjectBuilder) AutoIncrement(name string) *ObjectBuilder

AutoIncrement make defined field autoincremented before adding new objects

func (*ObjectBuilder) Counter

func (ob *ObjectBuilder) Counter(fieldNames ...string) *Counter

Counter will count all objects with same value of passed fields

func (*ObjectBuilder) Done

func (ob *ObjectBuilder) Done() *Object

Done will finish the object

func (*ObjectBuilder) FastIndex

func (ob *ObjectBuilder) FastIndex(names ...string) *ObjectBuilder

FastIndex will set index storing copy of object, performing denormalisation

func (*ObjectBuilder) IDDate

func (ob *ObjectBuilder) IDDate(fieldName string) *ObjectBuilder

IDDate is unique id generated using date as first part, this approach is usefull if date index necessary too field type should be int64

func (*ObjectBuilder) IDRandom

func (ob *ObjectBuilder) IDRandom(fieldName string) *ObjectBuilder

IDRandom is unique id generated using random number, this approach is usefull if you whant randomly distribute objects, and you do not whant to unveil data object

func (*ObjectBuilder) Index

func (ob *ObjectBuilder) Index(names ...string) *ObjectBuilder

Index add an simple index for specific key or set of keys

func (*ObjectBuilder) IndexCustom

func (ob *ObjectBuilder) IndexCustom(key string, cb func(object interface{}) KeyTuple) *Index

IndexCustom add an custom index generated dynamicly using callback function custom indexes in an general way to implement any index on top of it

func (*ObjectBuilder) IndexGeo

func (ob *ObjectBuilder) IndexGeo(latKey string, longKey string, geoPrecision int) *IndexGeo

IndexGeo will add and geohash based index to allow geographicly search objects geoPrecision 0 means full precision: 10 < 1m, 9 ~ 7.5m, 8 ~ 21m, 7 ~ 228m, 6 ~ 1.8km, 5 ~ 7.2km, 4 ~ 60km, 3 ~ 234km, 2 ~ 1890km, 1 ~ 7500km

func (*ObjectBuilder) IndexOptional

func (ob *ObjectBuilder) IndexOptional(names ...string) *ObjectBuilder

IndexOptional is the simple index which will be written only if field is not empty

func (*ObjectBuilder) IndexSearch

func (ob *ObjectBuilder) IndexSearch(key string, options ...IndexOption) *IndexSearch

IndexSearch will add serchable index which will allow

func (*ObjectBuilder) N2N

func (ob *ObjectBuilder) N2N(client *ObjectBuilder, name string) *Relation

N2N Creates object to object relation between current object and other one. Other words it represents relations when unlimited number of host objects connected to unlimited amount of client objects

func (*ObjectBuilder) Primary

func (ob *ObjectBuilder) Primary(names ...string) *ObjectBuilder

Primary sets primary field in case it wasnot set with annotations

func (*ObjectBuilder) Unique

func (ob *ObjectBuilder) Unique(names ...string) *ObjectBuilder

Unique index: if object with same field value already presented, Set and Add will return an ErrAlreadyExist

func (*ObjectBuilder) UniqueOptional

func (ob *ObjectBuilder) UniqueOptional(names ...string) *ObjectBuilder

UniqueOptional index: if object with same field value already presented, Set and Add will return an ErrAlreadyExist If the value is empty index do not set

type Promise

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

Promise is an basic promise object

func (*Promise) After

func (p *Promise) After(do func() PromiseAny) *Promise

After will perform an additional promise right after current one will be finised This works in transactions as well as in standalone promises, child promise will be executed in same transaction as parent

func (*Promise) Bool

func (p *Promise) Bool() (bool, error)

Bool return bool value if promise contins true or false

func (*Promise) Check

func (p *Promise) Check(t *Transaction)

Check will perform promise in parallel with other promises whithin transaction without returning the result. But if Promise will return error full transaction will be cancelled and error will be returned

func (*Promise) Do

func (p *Promise) Do(t *Transaction) *Promise

Do will attach promise to transaction, so promise will be called within passed transaction Promise should be inside an transaction callback, because transaction could be resent

func (*Promise) Err

func (p *Promise) Err() error

Err will execute the promise and return error

func (*Promise) Int64

func (p *Promise) Int64() (int64, error)

Int64 return Int64 value if promise contin int64 data

func (*Promise) Submit

func (p *Promise) Submit(t *Transaction, onDone func(err error) error)

Submit will submit promise to transaction. Once promise is completed callback will be called. If callback function will return error – the transaction will be cancelled.

func (*Promise) Try

func (p *Promise) Try(t *Transaction)

Try will perform promise in parallel with other promises within transaction without returning the result. But if Promise will return error, transaction will be performed as everythig is ok, error will be ignored

type PromiseAny

type PromiseAny interface {
	// contains filtered or unexported methods
}

PromiseAny describes any type of promise

type PromiseErr

type PromiseErr struct {
	Promise
}

PromiseErr is implements everything promise implements but more

func (*PromiseErr) Do

func (p *PromiseErr) Do(t *Transaction) *PromiseErr

Do will attach promise to transaction, so promise will be called within passed transaction Promise should be inside an transaction callback, because transaction could be resent

func (*PromiseErr) Err

func (p *PromiseErr) Err() error

Err values inside promise

type PromiseSlice

type PromiseSlice struct {
	Promise
	// contains filtered or unexported fields
}

PromiseSlice is implements everything promise implements but more

func (*PromiseSlice) CheckAll

func (p *PromiseSlice) CheckAll(t *Transaction, slicePointer interface{})

CheckAll will perform promise in parallel with other promises whithin transaction without returning the result. But if Promise will return error full transaction will be cancelled and error will be returned. Only when promise will be finished – slicePointer will be filled with data.

func (*PromiseSlice) Do

Do will attach promise to transaction, so promise will be called within passed transaction Promise should be inside an transaction callback, because transaction could be resent

func (*PromiseSlice) Limit

func (p *PromiseSlice) Limit(limit int) *PromiseSlice

Limit is meant to set limit of the query this

func (*PromiseSlice) Reverse

func (p *PromiseSlice) Reverse(reverse bool) *PromiseSlice

Reverse allow to reverse value of slice query if querying function support this

func (*PromiseSlice) ScanAll

func (p *PromiseSlice) ScanAll(slicePointer interface{}) error

ScanAll values inside promise

func (*PromiseSlice) Slice

func (p *PromiseSlice) Slice() *Slice

Slice will return slice pointer

func (*PromiseSlice) TryAll

func (p *PromiseSlice) TryAll(t *Transaction, slicePointer interface{})

TryAll will perform promise in parallel with other promises within transaction without returning the result. But if Promise will return error, transaction will be performed as everythig is ok, error will be ignored. Only when promise will be finished – slicePointer will be filled with data.

type PromiseValue

type PromiseValue struct {
	Promise
}

PromiseValue is implements everything promise implements but also values

func (*PromiseValue) Do

Do will attach promise to transaction, so promise will be called within passed transaction Promise should be inside an transaction callback, because transaction could be resent

func (*PromiseValue) Scan

func (p *PromiseValue) Scan(obj interface{}) error

Scan appened passed object with fetched fields

type Query

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

Query is interface for query building

func (*Query) Do

func (q *Query) Do(tr *Transaction) *PromiseSlice

Do will return the primise for the query for current transaction

func (*Query) From

func (q *Query) From(values ...interface{}) *Query

From sets the part of primary key of item starting from which result will be returned primary key part passed to List param should be excluded

func (*Query) Limit

func (q *Query) Limit(limit int) *Query

Limit sets limit for the query

func (*Query) List

func (q *Query) List(values ...interface{}) *Query

List queries list of items using primary key subspace. Pass no params if fetching all objects

func (*Query) Next

func (q *Query) Next() bool

Next sets from identifier from nextFrom; return true if more data could be fetched

func (*Query) OnlyPrimary

func (q *Query) OnlyPrimary() *Query

OnlyPrimary allow you to fetch just primary values of object, without retreaving everything else this mode allow you to fetch data much faster if you do not need all additional fields of object in the list

func (*Query) Promise

func (q *Query) Promise() *PromiseSlice

Promise will return the primise for the query

func (*Query) Reverse

func (q *Query) Reverse() *Query

Reverse reverse the query order

func (*Query) ScanAll

func (q *Query) ScanAll(slicePointer interface{}) error

ScanAll scans the query result into the passed

func (*Query) SetReverse

func (q *Query) SetReverse(reverse bool) *Query

SetReverse set reverse value from param

func (*Query) Slice

func (q *Query) Slice() *Slice

Slice will return slice object

func (*Query) To

func (q *Query) To(values ...interface{}) *Query

To sets the part of primary key which returning list should be ended primary key part passed to List param should be excluded

func (*Query) TryAll

func (q *Query) TryAll(tr *Transaction, slicePointer interface{})

TryAll scans the query result within the transaction

func (*Query) Use

func (q *Query) Use(indexFieldNames ...string) *Query

Use is an index selector for query building

type Relation

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

Relation is main struct to represent Relation

func (*Relation) Add

func (r *Relation) Add(hostOrID interface{}, clientOrID interface{}) *PromiseErr

Add writes new relation beween objects (return ErrAlreadyExist if exists)

func (*Relation) Check

func (r *Relation) Check(hostOrID interface{}, clientOrID interface{}) *Promise

Check return true if relation is set (false) if not set

func (*Relation) Clear

func (r *Relation) Clear() error

Clear will remove all data from relation

func (*Relation) ClientData

func (r *Relation) ClientData(fieldName string)

ClientData will set cliet data field name

func (*Relation) Counter

func (r *Relation) Counter(on bool)

Counter will start count objects count within relation

func (*Relation) CounterClient

func (r *Relation) CounterClient(object *ObjectBuilder, fieldName string)

CounterClient will set external field

func (*Relation) Delete

func (r *Relation) Delete(hostOrID interface{}, clientOrID interface{}) *PromiseErr

Delete removes relation between objects

func (*Relation) FillClientData

func (r *Relation) FillClientData(hostOrID interface{}, client interface{}) *PromiseErr

FillClientData fetch client data, so it will be written into the data field of client object

func (*Relation) FillHostData

func (r *Relation) FillHostData(host interface{}, clientOrID interface{}) *PromiseErr

FillHostData fetch client data and fill it to host object

func (*Relation) GetClientData

func (r *Relation) GetClientData(hostOrID interface{}, clientOrID interface{}) *PromiseValue

GetClientData fetch client data

func (*Relation) GetClientDataIDs

func (r *Relation) GetClientDataIDs(hostOrID interface{}, clientOrID interface{}) ([]byte, error)

GetClientDataIDs returns client data bytes

func (*Relation) GetClientIDs

func (r *Relation) GetClientIDs(objOrID interface{}, from interface{}, limit int) *SliceIDs

GetClientIDs will fetch only primary values of client objects

func (*Relation) GetClients

func (r *Relation) GetClients(objOrID interface{}, from interface{}) *PromiseSlice

GetClients fetch slice of client objects using host

func (*Relation) GetClientsCount

func (r *Relation) GetClientsCount(hostOrID interface{}) *Promise

GetClientsCount fetches counter

func (*Relation) GetHostData

func (r *Relation) GetHostData(hostOrID interface{}, clientOrID interface{}) *PromiseValue

GetHostData fetch client data

func (*Relation) GetHostIDs

func (r *Relation) GetHostIDs(objOrID interface{}, from interface{}, limit int) *SliceIDs

GetHostIDs will fetch only primary values of host objects

func (*Relation) GetHosts

func (r *Relation) GetHosts(objOrID interface{}, from interface{}) *PromiseSlice

GetHosts fetch slice of client objects using host

func (*Relation) GetHostsCount

func (r *Relation) GetHostsCount(clientOrID interface{}) *Promise

GetHostsCount fetches counter

func (*Relation) HostData

func (r *Relation) HostData(fieldName string)

HostData will set host data field name

func (*Relation) Set

func (r *Relation) Set(hostOrID interface{}, clientOrID interface{}) *PromiseErr

Set writes new relation beween objects, you could use objects or values with same types as primary key

func (*Relation) SetClientData

func (r *Relation) SetClientData(hostOrID interface{}, clientObj interface{}) *Promise

SetClientData writed new data from host object (host data could be )

func (*Relation) SetData

func (r *Relation) SetData(hostObj interface{}, clientObj interface{}) *Promise

SetData writed new data for both host and client index storages, return fail if object nor exist

func (*Relation) SetHostData

func (r *Relation) SetHostData(hostObj interface{}, clientOrID interface{}) *Promise

SetHostData writed new data from host object (host data could be )

func (*Relation) SetHostsCounterUnsafe

func (r *Relation) SetHostsCounterUnsafe(clientObject interface{}, count int64) error

SetHostsCounterUnsafe set hosts counter unsafely. User with care

func (*Relation) UpdateClientData

func (r *Relation) UpdateClientData(hostObj interface{}, clientObj interface{}, callback func()) *Promise

UpdateClientData will atomicly update only client index storage data using callback

func (*Relation) UpdateData

func (r *Relation) UpdateData(hostObj interface{}, clientObj interface{}, callback func()) *Promise

UpdateData will atomicly update host and client index storage data using callback

func (*Relation) UpdateHostData

func (r *Relation) UpdateHostData(hostObj interface{}, clientObj interface{}, callback func()) *Promise

UpdateHostData will atomicly update only host index storage data using callback

type Slice

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

Slice used for iteration over list of values

func (*Slice) Append

func (s *Slice) Append(val *Value)

Append push value inside slice

func (*Slice) Each

func (s *Slice) Each(cb func(item interface{}))

Each will go through all elements in slice

func (*Slice) Len

func (s *Slice) Len() int

Len return number of elements in slice

func (*Slice) ScanAll

func (s *Slice) ScanAll(slicePointer interface{}) (e error)

ScanAll fetches all rows from slice

type SliceIDs

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

SliceIDs is slice that contain only int64 data

func (*SliceIDs) Int64

func (s *SliceIDs) Int64() (map[int64][]byte, error)

Int64 will format response as int64 map if possible

func (*SliceIDs) ScanAll

func (s *SliceIDs) ScanAll(slicePointer interface{}) (e error)

ScanAll will scan all results for slice pointer

type Struct

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

Struct used for work with input structure

func (*Struct) Fill

func (s *Struct) Fill(o *Object, v *Value)

Fill will use data inside value object to fill struct

func (*Struct) Get

func (s *Struct) Get(field *Field) interface{}

Get return field as interface

func (*Struct) GetBytes

func (s *Struct) GetBytes(field *Field) []byte

GetBytes return field as byteSlice

type Tag

type Tag struct {
	Name    string
	Primary bool

	AutoIncrement bool
	UnStored      bool // means this field doesn't stored inside main object data
	// contains filtered or unexported fields
}

Tag is general object for tag parsing

type Transaction

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

Transaction allow you to join several Promises into one transaction also parallel executes promises effectively trying to parallel where its possible

func (*Transaction) Err

func (t *Transaction) Err() error

Err will perform all promises and return err if any of them failed

func (*Transaction) Fail

func (t *Transaction) Fail(err error)

Fail will set the transaction error, so

type Value

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

Value is representation of the fetched raw object from the db

func (*Value) Err

func (v *Value) Err() error

Err returns an error

func (*Value) FromKeyValue

func (v *Value) FromKeyValue(sub subspace.Subspace, rows []fdb.KeyValue)

FromKeyValue pasrses key value from foundationdb

func (*Value) Interface

func (v *Value) Interface() interface{}

Interface returns an interface

func (*Value) Reflect

func (v *Value) Reflect() (reflect.Value, error)

Reflect returns link to reflact value of object

func (*Value) Scan

func (v *Value) Scan(objectPtr interface{}) error

Scan fills object with data from value

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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