dal

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2023 License: MIT Imports: 11 Imported by: 116

Documentation

Index

Constants

View Source
const (
	// DeleteField is used as a value in a call to Update or Set with merge to indicate
	// that the corresponding child should be deleted.
	DeleteField sentinel = iota

	// ServerTimestamp is used as a value in a call to Update to indicate that the
	// child's value should be set to the time at which the server processed
	// the request.
	//
	// ServerTimestamp must be the value of a field directly; it cannot appear in
	// array or struct values, or in any value that is itself inside an array or
	// struct.
	ServerTimestamp
)

Variables

View Source
var ErrDoesNotExist = errors.New("does not exist")

ErrDoesNotExist indicates a record does not exist

View Source
var ErrNoMoreRecords = errors.New("no more errors")

ErrNoMoreRecords indicates there is no more records

View Source
var ErrNotSupported = errors.New("not supported")

ErrNotSupported - return this if db driver does not support requested operation. (for example no support for transactions)

View Source
var (
	// ErrRecordNotFound is returned when a DB record is not found
	ErrRecordNotFound = errors.New("record not found")
)
View Source
var NoError = errors.New("no error")

Functions

func GetNonTransactionalContext

func GetNonTransactionalContext(ctx context.Context) context.Context

GetNonTransactionalContext returns non transaction context (e.g. parent of transactional context) TODO: This is can be dangerous if child context creates a new context with a deadline for example

func InsertWithRandomID

func InsertWithRandomID(
	c context.Context,
	r Record,
	generateID IDGenerator,
	attempts int,
	exists func(*Key) error,
	insert func(Record) error,
) error

InsertWithRandomID inserts a record with a random ID

func IsNotFound

func IsNotFound(err error) bool

IsNotFound check if underlying error is ErrRecordNotFound

func NewContextWithTransaction

func NewContextWithTransaction(nonTransactionalContext context.Context, tx Transaction) context.Context

NewContextWithTransaction stores transaction and original context into a transactional context

func NewErrNotFoundByKey

func NewErrNotFoundByKey(key *Key, cause error) error

NewErrNotFoundByKey creates an error that indicates that entity was not found by Value

func NewRollbackError

func NewRollbackError(rollbackError, originalError error) error

NewRollbackError creates a rollback error

func WithExistsPrecondition

func WithExistsPrecondition() func(preconditions *preConditions)

WithExistsPrecondition sets exists precondition

func WithLastUpdateTimePrecondition

func WithLastUpdateTimePrecondition(t time.Time) func(preconditions *preConditions)

WithLastUpdateTimePrecondition sets last update time

func WithPrefix

func WithPrefix(prefix string) func(options *randomStringOptions)

WithPrefix sets prefix for a random string

Types

type Changes

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

Changes accumulates DB changes

func (Changes) EntityHolders

func (changes Changes) EntityHolders() (entityHolders []Record)

EntityHolders returns list of entity holders

func (*Changes) FlagAsChanged

func (changes *Changes) FlagAsChanged(record Record)

FlagAsChanged flags a record as changed

func (Changes) HasChanges

func (changes Changes) HasChanges() bool

HasChanges returns true if there are changes

func (Changes) IsChanged

func (changes Changes) IsChanged(entityHolder Record) bool

IsChanged returns true if entity changed

type CollectionRef

type CollectionRef struct {
	Name   string
	Parent *Key
}

CollectionRef points to a collection (e.g. table) in a database

func (CollectionRef) Path

func (v CollectionRef) Path() string

type Database

type Database interface {
	TransactionCoordinator
	ReadSession
}

Database is an interface that defines a DB provider

type ErrDuplicateUser

type ErrDuplicateUser struct {
	// TODO: Should it be moved out of this package to strongo/app/user?
	SearchCriteria   string
	DuplicateUserIDs []int64
}

ErrDuplicateUser indicates there is a duplicate user // TODO: move to strongo/app?

func (ErrDuplicateUser) Error

func (err ErrDuplicateUser) Error() string

Error implements error interface

type ErrNotFoundByKey

type ErrNotFoundByKey interface {
	Key() Key
	Cause() error
	error
}

ErrNotFoundByKey indicates error was not found by Value

type FieldPath

type FieldPath []string

A FieldPath is a non-empty sequence of non-empty fields that reference a value.

A FieldPath value should only be necessary if one of the field names contains one of the runes ".˜*/[]". Most methods accept a simpler form of field path as a string in which the individual fields are separated by dots. For example,

[]string{"a", "b"}

is equivalent to the string form

"a.b"

but

[]string{"*"}

has no equivalent string form.

type FieldVal

type FieldVal struct {
	Name  string      `json:"name"`
	Value interface{} `json:"value"`
}

FieldVal hold a reference to a single record within a root or nested recordset.

func (FieldVal) Validate

func (v FieldVal) Validate() error

Validate valodates field value

type IDGenerator

type IDGenerator = func(ctx context.Context, record Record) error

IDGenerator defines a contract for ID generator function

type InsertOption

type InsertOption func(options *insertOptions)

InsertOption defines a contract for an insert option

type InsertOptions

type InsertOptions interface {
	IDGenerator() IDGenerator
}

InsertOptions defines interface for insert options

func NewInsertOptions

func NewInsertOptions(opts ...InsertOption) InsertOptions

NewInsertOptions creates insert options

type Key

type Key struct {
	ID interface{}
	// contains filtered or unexported fields
}

Key represents a full path to a given record (no parent in case of root recordset)

func NewKey

func NewKey(collection string, options ...KeyOption) (key *Key)

NewKey creates a new key

func NewKeyWithFields

func NewKeyWithFields(collection string, fields ...FieldVal) *Key

NewKeyWithFields creates a new record child from a sequence of record's references

func NewKeyWithID

func NewKeyWithID[T comparable](collection string, id T, options ...KeyOption) (key *Key)

NewKeyWithID creates a new key with an ID

func (*Key) Collection

func (k *Key) Collection() string

Collection returns reference to colection

func (*Key) CollectionPath

func (k *Key) CollectionPath() string

CollectionPath return path to parent

func (*Key) Level

func (k *Key) Level() int

Level returns level of key (e.g. how many parents it have)

func (*Key) Parent

func (k *Key) Parent() *Key

Parent return a reference to the parent key

func (*Key) String

func (k *Key) String() string

String returns string representation of a key instance

func (*Key) Validate

func (k *Key) Validate() error

Validate validate key

type KeyOption

type KeyOption = func(*Key)

KeyOption defines contract for key option

func WithFields

func WithFields(fields []FieldVal) KeyOption

WithFields sets a list of field values as key ID

func WithID

func WithID[T comparable](id T) KeyOption

WithID sets ID of a key

func WithIDGenerator

func WithIDGenerator(g IDGenerator) KeyOption

WithIDGenerator sets ID generator for a random string (usually random)

func WithParent

func WithParent(collection string, id interface{}, options ...KeyOption) KeyOption

WithParent sets parent

func WithParentKey

func WithParentKey(parent *Key) KeyOption

WithParentKey sets parent key

func WithRandomStringID

func WithRandomStringID(length int, options ...randomStringOption) KeyOption

WithRandomStringID sets ID generator to random string

func WithStringID

func WithStringID(id string) KeyOption

WithStringID sets ID as a predefined string

type Precondition

type Precondition = func(preconditions *preConditions)

Precondition defines precondition

type Preconditions

type Preconditions interface {
	Exists() bool
}

Preconditions defines preconditions

func GetPreconditions

func GetPreconditions(items ...Precondition) Preconditions

GetPreconditions create Preconditions

type ROTxWorker

type ROTxWorker = func(ctx context.Context, tx ReadTransaction) error

ROTxWorker defines a callback to be called to do work within a readonly transaction

type RWTxWorker

type RWTxWorker = func(ctx context.Context, tx ReadwriteTransaction) error

RWTxWorker defines a callback to be called to do work within a readwrite transaction

type RandomStringOptions

type RandomStringOptions interface {
	Prefix() string
}

RandomStringOptions defines settings for random string

type ReadSession

type ReadSession interface {

	// Get gets a single record from database by key
	Get(ctx context.Context, record Record) error

	// GetMulti gets multiples records from database by keys
	GetMulti(ctx context.Context, records []Record) error

	// Select executes a data retrieval query
	Select(ctx context.Context, query Select) (Reader, error)
}

ReadSession defines methods that do not modify database

type ReadTransaction

type ReadTransaction interface {
	Transaction
	ReadSession
}

ReadTransaction defines an interface for a transaction

type ReadTransactionCoordinator

type ReadTransactionCoordinator interface {
	// RunReadonlyTransaction starts readonly transaction
	RunReadonlyTransaction(ctx context.Context, f ROTxWorker, options ...TransactionOption) error
}

ReadTransactionCoordinator creates a readonly transaction

type Reader

type Reader interface {

	// Next returns the next record for a query.
	// If no more records a nil record and ErrNoMoreRecords are returned.
	Next() (Record, error)
}

Reader reads records one by one

type ReadwriteSession

type ReadwriteSession interface {
	ReadSession
	WriteSession
}

ReadwriteSession defines methods that can read & modify database

type ReadwriteTransaction

type ReadwriteTransaction interface {
	Transaction
	ReadwriteSession
}

ReadwriteTransaction defines an interface for a transaction

type ReadwriteTransactionCoordinator

type ReadwriteTransactionCoordinator interface {
	// RunReadwriteTransaction starts read-write transaction
	RunReadwriteTransaction(ctx context.Context, f RWTxWorker, options ...TransactionOption) error
}

ReadwriteTransactionCoordinator creates a read-write transaction

type Record

type Record interface {
	// Key keeps a `table` name of an entity and an ID within that table or a chain of nested keys
	Key() *Key

	// Error keeps an error for the last operation on the record. Not found is not treated as an error
	Error() error

	// Exists indicates if record was found in database. Throws panic if called before a `Get` or `Set`.
	Exists() bool

	// SetError sets error relevant to specific record. Intended to be used only by DALgo DB drivers.
	SetError(err error)

	// Data returns record data (without ID/key).
	// Requires either record to be created by NewRecordWithData()
	// or DataTo() to be called first, otherwise panics.
	Data() interface{}

	// HasChanged & MarkAsChanged are methods of convenience
	HasChanged() bool

	// MarkAsChanged & HasChanged are methods of convenience
	MarkAsChanged()
}

Record is a gateway to a database record.

func NewRecord

func NewRecord(key *Key) Record

NewRecord creates a new record

func NewRecordWithData

func NewRecordWithData(key *Key, data interface{}) Record

NewRecordWithData creates a new record with a data target struct

func NewRecordWithoutKey

func NewRecordWithoutKey(data interface{}) Record

func ReadAll

func ReadAll(_ context.Context, reader Reader, limit int) (records []Record, err error)

ReadAll reads all records from a reader

type Select

type Select struct {

	// From defines target table/collection
	From *CollectionRef

	// Where defines filter condition
	Where query.Condition

	// GroupBy defines expressions to group by
	GroupBy []query.Expression

	// OrderBy defines expressions to order by
	OrderBy []query.Expression

	// Columns defines what columns to return
	Columns []query.Column

	Into func() interface{}

	// Limit specifies maximum number of records to be returned
	Limit int
}

Select holds definition of a query

func (Select) And

func (q Select) And(conditions ...query.Condition) Select

And creates an inherited query by adding AND conditions

func (Select) Or

func (q Select) Or(conditions ...query.Condition) Select

Or creates an inherited query by adding OR conditions

func (Select) String

func (q Select) String() string

type Transaction

type Transaction interface {
	// Options indicates parameters that were requested at time of transaction creation.
	Options() TransactionOptions
}

Transaction defines an instance of DALgo transaction

func GetTransaction

func GetTransaction(ctx context.Context) Transaction

GetTransaction returns original transaction object

type TransactionCoordinator

type TransactionCoordinator interface {
	ReadTransactionCoordinator
	ReadwriteTransactionCoordinator
}

TransactionCoordinator provides methods to work with transactions

type TransactionOption

type TransactionOption func(options *txOptions)

TransactionOption defines contact for transaction option

func TxWithAttempts

func TxWithAttempts(attempts int) TransactionOption

TxWithAttempts specifies number of attempts to execute a transaction

func TxWithCrossGroup

func TxWithCrossGroup() TransactionOption

TxWithCrossGroup requires transaction that spans multiple entity groups

func TxWithIsolationLevel

func TxWithIsolationLevel(isolationLevel TxIsolationLevel) TransactionOption

TxWithIsolationLevel requests transaction with required isolation level

func TxWithReadonly

func TxWithReadonly() TransactionOption

TxWithReadonly requests a readonly transaction

type TransactionOptions

type TransactionOptions interface {

	// IsolationLevel indicates requested isolation level
	IsolationLevel() TxIsolationLevel

	// IsReadonly indicates a readonly transaction
	IsReadonly() bool

	// IsCrossGroup indicates a cross-group transaction. Makes sense for Google App Engine.
	IsCrossGroup() bool

	// Attempts returns number of attempts to execute a transaction. This is used in Google Datastore for example.
	Attempts() int
}

TransactionOptions holds transaction settings

func NewTransactionOptions

func NewTransactionOptions(opts ...TransactionOption) TransactionOptions

NewTransactionOptions creates instance of TransactionOptions

type Transform

type Transform interface {

	// Name returns name of a transform
	Name() string

	// Value returns arguments of transform
	Value() interface{}
}

Transform defines a transform operation

func ArrayUnion

func ArrayUnion(elems ...interface{}) Transform

ArrayUnion specifies elements to be added to whatever array already exists in the server, or to create an array if no value exists.

If a value exists and it's an array, values are appended to it. Any duplicate value is ignored. If a value exists and it's not an array, the value is replaced by an array of the values in the ArrayUnion. If a value does not exist, an array of the values in the ArrayUnion is created.

ArrayUnion must be the value of a field directly; it cannot appear in array or struct values, or in any value that is itself inside an array or struct.

func Increment

func Increment(v int) Transform

Increment defines an increment transform operation

func IsTransform

func IsTransform(v interface{}) (t Transform, ok bool)

type TxIsolationLevel

type TxIsolationLevel int

TxIsolationLevel defines an isolation level for a transaction

const (
	// TxUnspecified indicates transaction level is not specified
	TxUnspecified TxIsolationLevel = iota

	// TxChaos - The pending changes from more highly isolated transactions cannot be overwritten.
	TxChaos

	// TxReadCommitted - Shared locks are held while the data is being read to avoid dirty reads,
	// but the data can be changed before the end of the transaction,
	// resulting in non-repeatable reads or phantom data.
	TxReadCommitted

	// TxReadUncommitted - A dirty read is possible, meaning that no shared locks are issued
	// and no exclusive locks are honored.
	TxReadUncommitted

	// TxRepeatableRead - Locks are placed on all data that is used in a query,
	// preventing other users from updating the data.
	// Prevents non-repeatable reads but phantom rows are still possible.
	TxRepeatableRead

	// TxSerializable - A range lock is placed on the DataSet, preventing other users
	// from updating or inserting rows into the dataset until the transaction is complete.
	TxSerializable

	// TxSnapshot - Reduces blocking by storing a version of data that one application can read
	// while another is modifying the same data.
	// Indicates that from one transaction you cannot see changes made in other transactions,
	// even if you requery.
	TxSnapshot
)

type Update

type Update struct {
	Field     string
	FieldPath FieldPath
	Value     interface{}
}

Update defines an update of a single field

func (Update) Validate

func (v Update) Validate() error

Validate validates the update

type WriteSession

type WriteSession interface {

	// Insert inserts a single record in database
	Insert(c context.Context, record Record, opts ...InsertOption) error

	// Set sets a single record in database by key
	Set(ctx context.Context, record Record) error

	// SetMulti sets multiples records in database by keys
	SetMulti(ctx context.Context, records []Record) error

	// Update updates a single record in database by key
	Update(ctx context.Context, key *Key, updates []Update, preconditions ...Precondition) error

	// UpdateMulti updates multiples records in database by keys
	UpdateMulti(c context.Context, keys []*Key, updates []Update, preconditions ...Precondition) error

	// Delete deletes a single record from database by key
	Delete(ctx context.Context, key *Key) error

	// DeleteMulti deletes multiple records from database by keys
	DeleteMulti(ctx context.Context, keys []*Key) error
}

WriteSession defines methods that can modify database

Jump to

Keyboard shortcuts

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