db

package module
v0.0.0-...-3cd0c2b Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2021 License: MIT Imports: 5 Imported by: 0

README

Go package strongo/db

Database abstraction layer (DAL) in Go language

Build Status Go Report Card GoDoc

There are 4 main purposes for the package:

  1. To abstract work with data storage so underlying storage engine can be changed.

  2. To allow write less code that is more readable.

  3. To allow easialy add logging & hooks for tx/insert/get/query/update/delete operations across app. Think about preventing updates made outside of transaction or logging automatically what properties have changed.

  4. Allow to write unit tests without dependency on specific implementation. (do no compile AppEngine packages for examples)

The main abstraction is done though interface EntityHolder:

type EntityHolder interface {
	TypeOfID() TypeOfID            // Either `string`, `int`, or `complex`
	Kind() string                  // Defines `table` name of the entity
	NewEntity() interface{}        // Used for `get` operations to create emtity to fill with values.
	Entity() interface{}           // Entity with fields to be stored to DB (without ID)
	SetEntity(entity interface{})  //
	IntID() int64                  // Returns ID for entities identified by integer value
	StrID() string                 // Returns ID for entities identified by string value
	SetIntID(id int64)             // Sets integer ID for entities identified by integer value
	SetStrID(id string)            // Sets string ID for entities identified by string value
}

All methods are working with the EntityHolder.

The Database interface defines an interface to a storage that should be implemented by a specific driver. This repo contains implementation for Google AppEngine Datastore. Contributions for other engines are welcome. If the db driver does not support some of the operations it must return ErrNotSupported.

type Database interface {
	TransactionCoordinator
	Inserter
	Getter
	Updater
	MultiGetter
	MultiUpdater
}

where for example the Getter & MultiGetter interfaces are defined as:

type Getter interface {
	Get(c context.Context, entityHolder EntityHolder) error
}

type MultiGetter interface {
	GetMulti(c context.Context, entityHolders []EntityHolder) error
}

Note that getters are populating entities in place through calling SetEntity(entity interface{}) method.

Originally developed to support work with Google AppEngine Datastore it takes into account its specifics. This should work well for other key-value storages as well.

Used by

This package is used in production by:

Frameworks that utilise this strongo/db package

Documentation

Index

Constants

This section is empty.

Variables

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")
)

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 GetRecordKeyPath

func GetRecordKeyPath(key RecordKey) string

func GetRecordKind

func GetRecordKind(key RecordKey) string

func GetTransaction

func GetTransaction(ctx context.Context) interface{}

GetTransaction returns original transaction object

func InsertWithRandomID

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

func IsNotFound

func IsNotFound(err error) bool

IsNotFound check if underlying error is ErrRecordNotFound

func NewContextWithTransaction

func NewContextWithTransaction(ctx context.Context, tx interface{}) context.Context

NewContextWithTransaction stores transaction and original context into a transactional context

func NewErrNotFoundByKey

func NewErrNotFoundByKey(record Record, cause error) error

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

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 Database

type Database interface {
	TransactionCoordinator
	Session
}

Database is an interface that define a DB provider

type Deleter

type Deleter interface {
	Delete(ctx context.Context, key RecordKey) error
}

Deleter is an interface that describe DB provider that can delete a single record by key

type EntityLoader

type EntityLoader interface {
	Load([]Property) error
}

EntityLoader loads properties to struct

type EntitySaver

type EntitySaver interface {
	Save() ([]Property, error)
}

EntitySaver dumps struct to properties

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() RecordKey
	Cause() error
	error
}

ErrNotFoundByKey indicates error was not found by ID

type Getter

type Getter interface {
	Get(ctx context.Context, record Record) error
}

Getter is an interface that describe DB provider that can get a single record by key

type IDGenerator

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

type InsertOption

type InsertOption func(options *insertOptions)

func WithIDGenerator

func WithIDGenerator(idGenerator IDGenerator) InsertOption

func WithRandomStringID

func WithRandomStringID(length int) InsertOption

type InsertOptions

type InsertOptions interface {
	IDGenerator() IDGenerator
}

func NewInsertOptions

func NewInsertOptions(opts ...InsertOption) InsertOptions

type Inserter

type Inserter interface {
	Insert(c context.Context, record Record, options InsertOptions) error
}

Inserter is an interface that describe DB provider that can insert a single entity with a specific or random ID

type MultiDeleter

type MultiDeleter interface {
	DeleteMulti(ctx context.Context, keys []RecordKey) error
}

type MultiGetter

type MultiGetter interface {
	GetMulti(ctx context.Context, records []Record) error
}

MultiGetter is an interface that describe DB provider that can get multiple records at once (batch mode)

type MultiSetter

type MultiSetter interface {
	SetMulti(ctx context.Context, records []Record) error
}

MultiSetter is an interface that describe DB provider that can set multiple records at once (batch mode)

type MultiUpdater

type MultiUpdater interface {
	UpdateMulti(c context.Context, records []Record) error
}

MultiUpdater is an interface that describe DB provider that can update multiple records at once (batch mode)

type Property

type Property struct {
	Name    string
	Value   interface{}
	NoIndex bool
}

Property hold property name, value & flag to index

type RandomStringOptions

type RandomStringOptions interface {
	Length() int
}

type Record

type Record interface {
	Key() RecordKey
	Data() Validatable
	SetData(data Validatable)
	Validate() error
}

Record is an interface a struct should satisfy to comply with "strongo/db" library

func CreateEntityHoldersWithIntIDs

func CreateEntityHoldersWithIntIDs(ids []int64, newRecord func() RecordWithIntID) (records []Record)

func NewRecord

func NewRecord(key RecordKey, data Validatable) Record

type RecordKey

type RecordKey = []RecordRef

RecordKey represents a full path to a given record (1 item in case of root recordset)

func NewRecordKey

func NewRecordKey(refs ...RecordRef) RecordKey

NewRecordKey creates a new record key from a sequence of record's references

type RecordRef

type RecordRef struct {
	Kind string      `json:"kind"`
	ID   interface{} `json:"id"` // Usually string or int
}

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

type RecordWithIntID

type RecordWithIntID interface {
	Record
	GetID() int64
	SetIntID(id int64)
}

type RecordWithStrID

type RecordWithStrID interface {
	Record
	GetID() string
	SetStrID(id string)
}

type Session

Session defines interface

type Setter

type Setter interface {
	Set(ctx context.Context, record Record) error
}

Setter is an interface that describe DB provider that can set a single record by key

type Transaction

type Transaction interface {
	Session
}

type TransactionCoordinator

type TransactionCoordinator interface {
	RunInTransaction(
		ctx context.Context,
		f func(ctx context.Context, tx Transaction) error,
		options ...TransactionOption,
	) error
}

TransactionCoordinator provides methods to work with transactions

type TransactionOption

type TransactionOption func(options *transactionOptions)

func WithCrossGroup

func WithCrossGroup() TransactionOption

func WithPassword

func WithPassword(password string) TransactionOption

func WithReadonly

func WithReadonly() TransactionOption

type TransactionOptions

type TransactionOptions interface {
	IsReadonly() bool
	IsCrossGroup() bool
	Password() string
}

func NewTransactionOptions

func NewTransactionOptions(opts ...TransactionOption) TransactionOptions

type TypeOfID

type TypeOfID int

TypeOfID represents type of ID: IsComplexID, IsStringID, IsIntID

type Updater

type Updater interface {
	Update(ctx context.Context, record Record) error
}

Updater is an interface that describe DB provider that can update a single EXISTING record by a key

type Upserter

type Upserter interface {
	Upsert(ctx context.Context, record Record) error
}

Upserter is an interface that describe DB provider that can upsert a single record by key

type Validatable

type Validatable interface {
	Validate() error
}

func VoidData

func VoidData() Validatable

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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