clerk

package module
v2.0.2 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2022 License: MIT Imports: 1 Imported by: 0

README

clerk

📒 A minimalistic library for abstracting database operations

Installation

Adding clerk to your Go module is as easy as calling this command in your project

go get github.com/Becklyn/clerk/v2

Supported databases

clerk has builtin support for the following database engines:

  • MongoDB - MongoDB is a document-oriented database

Support for any other engines can be added by implementing their supported operations.
Have a look at the MongoDB implementation in the /mongodb directory as a starting point.

Usage

Being a minimalistic library, clerk only provides the basics. The rest is up to your specific need.
Each operation in clerk consists of a generic operation and uses an operator that is specific to the database engine.
The examples given below all use the MongoDB operators.

Creating a connection
connection, err := mongodb.NewConnection(context.Background(), "mongodb://localhost:27017")
if err != nil {
	panic(err)
}

defer connection.Close(func(err error) {
	if err != nil {
		panic(err)
	}
})
Using a transaction
databaseOperator := mongodb.NewDatabaseOperator(connection)

clerk.NewTransaction(databaseOperator).Run(context.Background(), func(ctx context.Context) error {
    // Add operations that should be executed in a transaction here ...
    return nil
})
Defining a database & collection
database := clerk.NewDatabase("foo")
collection := clerk.NewCollection(database, "bar")
Defining a database operator
tOperator := mongodb.NewOperator[T](connection, collection)

The generic parameter T defines the data type which the operator can interact with. An operator has to be defined for each data type in use with clerk.

Persisting new data in a collection
type Message struct {
    Id   string `bson:"_id"`
    Body string `bson:"body"`
}

messageOperator := mongodb.NewOperator[*Message](connection, collection)

createCtx, createCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer createCancel()

err := clerk.NewCreate[*Message](messageOperator).
    With(&Message{Id: 1, Body: "Hello World"}).
    With(&Message{Id: 2, Body: "Hello Buddy"}).
    Commit(createCtx)
if err != nil {
    panic(err)
}
Querying the collection
type Message struct {
    Id   string `bson:"_id"`
    Body string `bson:"body"`
}

messageOperator := mongodb.NewOperator[*Message](connection, collection)

queryCtx, queryCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer queryCancel()

message, err := clerk.NewQuery[*Message](messageOperator).
    Where(clerk.NewEquals("_id", 1)).
    Single(queryCtx)
if err != nil {
    panic(err)
}

fmt.Printf("Message: %+v", message)
messageOperator := mongodb.NewOperator[*Message](connection, collection)

queryCtx, queryCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer queryCancel()

messages, err := clerk.NewQuery[*Message](messageOperator).
    Where(clerk.NewRegex("body", "^Hello.*$")).
    Sort("_id", clerk.NewAscendingOrder()).
    All(queryCtx)
if err != nil {
    panic(err)
}

for _, message := range messages {
    fmt.Printf("Message: %+v", message)
}

Copyright © 2022 Becklyn GmbH

Documentation

Index

Constants

This section is empty.

Variables

Functions

This section is empty.

Types

type And

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

func NewAnd

func NewAnd(left Filter, right Filter) *And

func (*And) Key

func (l *And) Key() string

func (*And) Left

func (l *And) Left() Filter

func (*And) Right

func (l *And) Right() Filter

func (*And) Value

func (l *And) Value() any

type Collection

type Collection struct {
	Database *Database
	Name     string
}

func NewCollection

func NewCollection(database *Database, name string) *Collection

type Create

type Create[T any] struct {
	Data []T
	// contains filtered or unexported fields
}

func NewCreate

func NewCreate[T any](creator Creator[T]) *Create[T]

func (*Create[T]) Commit

func (c *Create[T]) Commit(ctx context.Context) error

func (*Create[T]) With

func (c *Create[T]) With(data ...T) *Create[T]

type Creator

type Creator[T any] interface {
	ExecuteCreate(ctx context.Context, create *Create[T]) error
}

type Database

type Database struct {
	Name string
}

func NewDatabase

func NewDatabase(name string) *Database

type Delete

type Delete[T any] struct {
	Filters []Filter
	// contains filtered or unexported fields
}

func NewDelete

func NewDelete[T any](deleter Deleter[T]) *Delete[T]

func (*Delete[T]) Commit

func (d *Delete[T]) Commit(ctx context.Context) (int, error)

func (*Delete[T]) Where

func (d *Delete[T]) Where(filter Filter) *Delete[T]

type Deleter

type Deleter[T any] interface {
	ExecuteDelete(ctx context.Context, delete *Delete[T]) (int, error)
}

type Equals

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

func NewEquals

func NewEquals(key string, value any) *Equals

func (*Equals) Key

func (l *Equals) Key() string

func (*Equals) Left

func (l *Equals) Left() Filter

func (*Equals) Right

func (l *Equals) Right() Filter

func (*Equals) Value

func (l *Equals) Value() any

type Event

type Event[T any] struct {
	Operation Operation
	Data      T
}

type Exists

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

func NewExists

func NewExists(value any) *Exists

func (*Exists) Key

func (l *Exists) Key() string

func (*Exists) Left

func (l *Exists) Left() Filter

func (*Exists) Right

func (l *Exists) Right() Filter

func (*Exists) Value

func (l *Exists) Value() any

type Field

type Field struct {
	Key  string
	Type FieldType
}

func NewField

func NewField(key string) *Field

func (*Field) OfTypeSort

func (f *Field) OfTypeSort(order *Order) *Field

func (*Field) OfTypeText

func (f *Field) OfTypeText() *Field

type FieldType

type FieldType int
const (
	FieldTypeAscending FieldType = iota
	FieldTypeDescending
	FieldTypeString
)

func (FieldType) String

func (t FieldType) String() string

type Filter

type Filter interface {
	Left() Filter
	Right() Filter
	Key() string
	Value() any
}

type GreaterThan

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

func NewGreaterThan

func NewGreaterThan(key string, value any) *GreaterThan

func (*GreaterThan) Key

func (l *GreaterThan) Key() string

func (*GreaterThan) Left

func (l *GreaterThan) Left() Filter

func (*GreaterThan) Right

func (l *GreaterThan) Right() Filter

func (*GreaterThan) Value

func (l *GreaterThan) Value() any

type GreaterThanOrEqual

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

func NewGreaterThanOrEqual

func NewGreaterThanOrEqual(key string, value any) *GreaterThanOrEqual

func (*GreaterThanOrEqual) Key

func (l *GreaterThanOrEqual) Key() string

func (*GreaterThanOrEqual) Left

func (l *GreaterThanOrEqual) Left() Filter

func (*GreaterThanOrEqual) Right

func (l *GreaterThanOrEqual) Right() Filter

func (*GreaterThanOrEqual) Value

func (l *GreaterThanOrEqual) Value() any

type Index

type Index struct {
	Fields   []*Field
	Name     string
	IsUnique bool
}

func NewIndex

func NewIndex(name ...string) *Index

func (*Index) AddField

func (i *Index) AddField(field ...*Field) *Index

func (*Index) Unique

func (i *Index) Unique() *Index

type LessThan

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

func NewLessThan

func NewLessThan(key string, value any) *LessThan

func (*LessThan) Key

func (l *LessThan) Key() string

func (*LessThan) Left

func (l *LessThan) Left() Filter

func (*LessThan) Right

func (l *LessThan) Right() Filter

func (*LessThan) Value

func (l *LessThan) Value() any

type LessThanOrEqual

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

func NewLessThanOrEqual

func NewLessThanOrEqual(key string, value any) *LessThanOrEqual

func (*LessThanOrEqual) Key

func (l *LessThanOrEqual) Key() string

func (*LessThanOrEqual) Left

func (l *LessThanOrEqual) Left() Filter

func (*LessThanOrEqual) Right

func (l *LessThanOrEqual) Right() Filter

func (*LessThanOrEqual) Value

func (l *LessThanOrEqual) Value() any

type Operation

type Operation int
const (
	OperationCreate Operation = iota
	OperationUpdate
	OperationDelete
)

func (Operation) String

func (o Operation) String() string

type Or

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

func NewOr

func NewOr(left Filter, right Filter) *Or

func (*Or) Key

func (l *Or) Key() string

func (*Or) Left

func (l *Or) Left() Filter

func (*Or) Right

func (l *Or) Right() Filter

func (*Or) Value

func (l *Or) Value() any

type Order

type Order struct {
	IsAscending bool
}

func NewAscendingOrder

func NewAscendingOrder() *Order

func NewDescendingOrder

func NewDescendingOrder() *Order

type Querier

type Querier[T any] interface {
	ExecuteQuery(ctx context.Context, query *Query[T]) (<-chan T, error)
}

type Query

type Query[T any] struct {
	Filters []Filter
	Sorting map[string]*Order
	Range   *Range
	// contains filtered or unexported fields
}

func NewQuery

func NewQuery[T any](querier Querier[T]) *Query[T]

func (*Query[T]) All

func (q *Query[T]) All(ctx context.Context) ([]T, error)

func (*Query[T]) Channel

func (q *Query[T]) Channel(ctx context.Context) (<-chan T, error)

func (*Query[T]) In

func (q *Query[T]) In(rng *Range) *Query[T]

func (*Query[T]) Single

func (q *Query[T]) Single(ctx context.Context) (T, error)

func (*Query[T]) Sort

func (q *Query[T]) Sort(key string, order ...*Order) *Query[T]

func (*Query[T]) Where

func (q *Query[T]) Where(filter Filter) *Query[T]

type Range

type Range struct {
	SkipValue int
	TakeValue int
}

func NewRange

func NewRange() *Range

func (*Range) Skip

func (r *Range) Skip(skip int) *Range

func (*Range) Take

func (r *Range) Take(take int) *Range

type Regex

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

func NewRegex

func NewRegex(key string, value any) *Regex

func (*Regex) Key

func (l *Regex) Key() string

func (*Regex) Left

func (l *Regex) Left() Filter

func (*Regex) Right

func (l *Regex) Right() Filter

func (*Regex) Value

func (l *Regex) Value() any

type Transaction

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

func NewTransaction

func NewTransaction(transactor Transactor) *Transaction

func (*Transaction) Run

func (t *Transaction) Run(ctx context.Context, fn TransactionFn) error

type TransactionFn

type TransactionFn func(ctx context.Context) error

type Transactor

type Transactor interface {
	ExecuteTransaction(ctx context.Context, fn TransactionFn) error
}

type Update

type Update[T any] struct {
	Filters      []Filter
	ShouldUpsert bool
	Data         T
	// contains filtered or unexported fields
}

func NewUpdate

func NewUpdate[T any](updater Updater[T]) *Update[T]

func (*Update[T]) Commit

func (u *Update[T]) Commit(ctx context.Context) error

func (*Update[T]) Upsert

func (u *Update[T]) Upsert() *Update[T]

func (*Update[T]) Where

func (u *Update[T]) Where(filter Filter) *Update[T]

func (*Update[T]) With

func (u *Update[T]) With(data T) *Update[T]

type Updater

type Updater[T any] interface {
	ExecuteUpdate(ctx context.Context, update *Update[T]) error
}

type Watch

type Watch[T any] struct {
	Operations []Operation
	// contains filtered or unexported fields
}

func NewWatch

func NewWatch[T any](watcher Watcher[T]) *Watch[T]

func (*Watch[T]) Channel

func (w *Watch[T]) Channel(ctx context.Context) (<-chan *Event[T], error)

func (*Watch[T]) Handle

func (w *Watch[T]) Handle(ctx context.Context, handler WatchHandler[T]) error

func (*Watch[T]) On

func (w *Watch[T]) On(operation ...Operation) *Watch[T]

type WatchHandler

type WatchHandler[T any] func(ctx context.Context, event *Event[T])

type Watcher

type Watcher[T any] interface {
	ExecuteWatch(ctx context.Context, watch *Watch[T]) (<-chan *Event[T], error)
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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