ezdb

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

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

Go to latest
Published: Jul 11, 2024 License: MIT Imports: 11 Imported by: 1

README

EZ DB

This package provides simple interfaces for working with basic key-value document storage in your Go application.

System requirements

Basic usage

The primary interface in EZ DB is Collection[T] which reflects a single key-value store. This is analogous to tables in RDBMS, collections in NoSQL databases etc.

Collections use a generic type T to specify the document type. You can use this to enforce a document schema. This example creates a collection which only accepts Student documents:

package main

import "github.com/annybs/ezdb"

type Student struct {
	Name string
	Age int
}

var db = ezdb.Memory[Student](nil)

func main() {
	db.Open()
	db.Put("annie", Student{Name: "Annie", Age: "32"})
	db.Close()
}

Marshaling data

Some database backends require marshaling and unmarshaling data. The DocumentMarshaler[T1, T2] interface allows you to use whatever marshaler suits your needs or the requirements of your chosen database.

The following marshalers are included in EZ DB:

Supported databases

The following databases are included in EZ DB:

  • LevelDB[T] is fast key-value storage on disk
  • Memory[T] is essentially a wrapper for map[string]T. It can be provided another Collection to use as a persistence backend

Limitations

EZ DB is intended for simple document storage and can work with any addressable data represented as T in your Go app.

This makes it unsuited for working with unaddressable types, such as byte arrays, particularly when a document marshaler is involved.

If you want more control beyond what EZ DB offers, it's best to just use the appropriate database software and connector for your needs.

License

See LICENSE.md

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrClosed     = errors.New("collection is closed")
	ErrInvalidKey = errors.New("invalid key")
	ErrNotFound   = errors.New("not found")
	ErrReleased   = errors.New("iterator has been released")
)

High-level EZ DB error. These are not exhaustive and your chosen implementation of Collection may produce its own errors.

Functions

func ValidateKey

func ValidateKey(key string) error

ValidateKey validates whether a key is valid for putting data into a collection.

Types

type Collection

type Collection[T any] interface {
	Open() error  // Open the collection.
	Close() error // Close the collection.

	Count() int                           // Count the number of documents in the collection.
	Delete(key string) error              // Delete a document by key.
	DeleteAll() error                     // Delete all documents in the collection.
	Get(key string) (value T, err error)  // Get a document by key.
	GetAll() (map[string]T, error)        // Get all documents in the collection.
	GetAllKeys() []string                 // Get all keys in the document.
	Has(key string) (has bool, err error) // Check whether a document exists by key.
	Put(key string, value T) error        // Put a document into the collection.

	Iter() Iterator[T] // Get an iterator for this collection.
}

Collection is a key-value store for documents of any type.

type CollectionTester

type CollectionTester[T any] struct {
	C Collection[T]

	Cmp  func(a, b T) error // Comparison function to assert equivalence between two documents.
	Data map[string]T       // Test data.
}

CollectionTester is a convenience type to help build out collection testing with less boilerplate.

func (*CollectionTester[T]) Close

func (t *CollectionTester[T]) Close() error

func (*CollectionTester[T]) DeleteAll

func (t *CollectionTester[T]) DeleteAll() error

func (*CollectionTester[T]) DeleteOne

func (t *CollectionTester[T]) DeleteOne() error

DeleteOne tests that the collection safely deletes a single document. The document is not reinserted after deletion.

func (*CollectionTester[T]) Get

func (t *CollectionTester[T]) Get() error

Get tests that the collection retrieves all documents. The collection must be initialised.

func (*CollectionTester[T]) GetAll

func (t *CollectionTester[T]) GetAll() error

func (*CollectionTester[T]) Has

func (t *CollectionTester[T]) Has() error

Has tests that the collection has all documents. The collection must be initialised.

func (*CollectionTester[T]) Init

func (t *CollectionTester[T]) Init() error

Init tests that the collection is correctly initialised. This opens the collection, deletes any existing data, and reinserts the test data.

func (*CollectionTester[T]) IterCount

func (t *CollectionTester[T]) IterCount() error

IterCount tests that the iterator counts documents correctly. The collection must be initialised.

func (*CollectionTester[T]) IterSortKeys

func (t *CollectionTester[T]) IterSortKeys() error

IterSortKeys tests that the iterator sorts correctly by key. The collection must be initialised.

func (*CollectionTester[T]) Open

func (t *CollectionTester[T]) Open() error

Open tests that the collection is opened.

func (*CollectionTester[T]) Put

func (t *CollectionTester[T]) Put() error

Put tests that the collection can store all documents.

type DocumentMarshaler

type DocumentMarshaler[T1 any, T2 any] interface {
	Factory() T1                     // Create a new, empty document.
	Marshal(src T1) (T2, error)      // Marshal a document to bytes.
	Unmarshal(src T2, dest T1) error // Unmarshal bytes into a document.
}

DocumentMarshaler facilitates conversion between two types - a document and its storage representation, depending on the implementation of the Collection.

type Errors

type Errors []error

Errors collates one or more errors. It is mainly used for testing.

func (Errors) Error

func (e Errors) Error() string

func (Errors) Resolve

func (e Errors) Resolve() error

Resolve a Errors to an error or nil, if it is empty.

type FilterFunc

type FilterFunc[T any] func(key string, value T) bool

FilterFunc processes a document as part of a filter operation. This function returns true if the document passes all checks defined in the filter.

type Iterator

type Iterator[T any] interface {
	First() bool // Move the iterator to the first document. Returns false if there is no first document.
	Last() bool  // Move the iterator to the last document. Returns false if there is no last document.
	Next() bool  // Move the iterator to the next document. Returns false if there is no next document.
	Prev() bool  // Move the iterator to the previous document. Returns false if there is no previous document.

	Release() // Release the iterator and any associated resources, including those of previous iterators.

	Count() int // Count the number of documents in the iterator.

	Get() (key string, value T, err error) // Get the key and value of the current document.
	Key() string                           // Get the key of the current document.
	Value() (T, error)                     // Get the value of the current document.

	GetAll() (map[string]T, error) // Get all documents as a key-value map.
	GetAllKeys() []string          // Get all document keys.

	Filter(f FilterFunc[T]) Iterator[T]      // Create a new iterator with a subset of documents. The previous iterator will not be affected.
	Sort(f SortFunc[T]) Iterator[T]          // Create a new iterator with sorted documents. The previous iterator will not be affected.
	SortKeys(f SortFunc[string]) Iterator[T] // Create a new iterator with documents sorted by key. The previous iterator will not be affected.
}

Iterator provides functionality to explore a collection.

Be mindful that the order of documents is not assured by any Collection implementation. Use the Sort or SortKeys function before iterating over documents to ensure deterministic sort.

type JSONMarshaler

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

JSONMarshaler is a DocumentMarshaler that converts documents to JSON data.

func JSON

func JSON[T any](factory func() T) *JSONMarshaler[T]

JSON creates a DocumentMarshaler that converts documents to JSON data.

func (*JSONMarshaler[T]) Factory

func (m *JSONMarshaler[T]) Factory() T

func (*JSONMarshaler[T]) Marshal

func (m *JSONMarshaler[T]) Marshal(src T) ([]byte, error)

func (*JSONMarshaler[T]) Unmarshal

func (m *JSONMarshaler[T]) Unmarshal(src []byte, dest T) error

type LevelDBCollection

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

func LevelDB

func LevelDB[T any](path string, m DocumentMarshaler[T, []byte], o *LevelDBOptions) *LevelDBCollection[T]

LevelDB creates a new collection using LevelDB storage.

func (*LevelDBCollection[T]) Close

func (c *LevelDBCollection[T]) Close() error

func (*LevelDBCollection[T]) Count

func (c *LevelDBCollection[T]) Count() int

func (*LevelDBCollection[T]) Delete

func (c *LevelDBCollection[T]) Delete(key string) error

func (*LevelDBCollection[T]) DeleteAll

func (c *LevelDBCollection[T]) DeleteAll() error

func (*LevelDBCollection[T]) Destroy

func (c *LevelDBCollection[T]) Destroy() error

Destroy the database completely, removing it from disk.

func (*LevelDBCollection[T]) Get

func (c *LevelDBCollection[T]) Get(key string) (T, error)

func (*LevelDBCollection[T]) GetAll

func (c *LevelDBCollection[T]) GetAll() (map[string]T, error)

func (*LevelDBCollection[T]) GetAllKeys

func (c *LevelDBCollection[T]) GetAllKeys() []string

func (*LevelDBCollection[T]) Has

func (c *LevelDBCollection[T]) Has(key string) (bool, error)

func (*LevelDBCollection[T]) Iter

func (c *LevelDBCollection[T]) Iter() Iterator[T]

func (*LevelDBCollection[T]) Open

func (c *LevelDBCollection[T]) Open() error

func (*LevelDBCollection[T]) Put

func (c *LevelDBCollection[T]) Put(key string, src T) error

type LevelDBIterator

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

func (*LevelDBIterator[T]) Count

func (i *LevelDBIterator[T]) Count() int

func (*LevelDBIterator[T]) Filter

func (i *LevelDBIterator[T]) Filter(f FilterFunc[T]) Iterator[T]

func (*LevelDBIterator[T]) First

func (i *LevelDBIterator[T]) First() bool

func (*LevelDBIterator[T]) Get

func (i *LevelDBIterator[T]) Get() (string, T, error)

func (*LevelDBIterator[T]) GetAll

func (i *LevelDBIterator[T]) GetAll() (map[string]T, error)

func (*LevelDBIterator[T]) GetAllKeys

func (i *LevelDBIterator[T]) GetAllKeys() []string

func (*LevelDBIterator[T]) Key

func (i *LevelDBIterator[T]) Key() string

func (*LevelDBIterator[T]) Last

func (i *LevelDBIterator[T]) Last() bool

func (*LevelDBIterator[T]) Next

func (i *LevelDBIterator[T]) Next() bool

func (*LevelDBIterator[T]) Prev

func (i *LevelDBIterator[T]) Prev() bool

func (*LevelDBIterator[T]) Release

func (i *LevelDBIterator[T]) Release()

func (*LevelDBIterator[T]) Sort

func (i *LevelDBIterator[T]) Sort(f SortFunc[T]) Iterator[T]

func (*LevelDBIterator[T]) SortKeys

func (i *LevelDBIterator[T]) SortKeys(f SortFunc[string]) Iterator[T]

func (*LevelDBIterator[T]) Value

func (i *LevelDBIterator[T]) Value() (T, error)

type LevelDBOptions

type LevelDBOptions struct {
	Open  *opt.Options
	Read  *opt.ReadOptions
	Write *opt.WriteOptions
}

func (*LevelDBOptions) GetOpen

func (o *LevelDBOptions) GetOpen() *opt.Options

func (*LevelDBOptions) GetRead

func (o *LevelDBOptions) GetRead() *opt.ReadOptions

func (*LevelDBOptions) GetWrite

func (o *LevelDBOptions) GetWrite() *opt.WriteOptions

type MemoryCollection

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

func Memory

func Memory[T any](c Collection[T]) *MemoryCollection[T]

Memory creates an in-memory collection, which offers fast access without a document marshaler.

If the collection c is non-nil, it will be used as a persistence backend.

If T is a pointer type, the same pointer will be used whenever a document is read from this collection. Take care not to modify documents retrieved from a memory collection.

func (*MemoryCollection[T]) Close

func (c *MemoryCollection[T]) Close() error

func (*MemoryCollection[T]) Count

func (c *MemoryCollection[T]) Count() int

func (*MemoryCollection[T]) Delete

func (c *MemoryCollection[T]) Delete(key string) error

func (*MemoryCollection[T]) DeleteAll

func (c *MemoryCollection[T]) DeleteAll() error

func (*MemoryCollection[T]) Get

func (c *MemoryCollection[T]) Get(key string) (T, error)

func (*MemoryCollection[T]) GetAll

func (c *MemoryCollection[T]) GetAll() (map[string]T, error)

func (*MemoryCollection[T]) GetAllKeys

func (c *MemoryCollection[T]) GetAllKeys() []string

func (*MemoryCollection[T]) Has

func (c *MemoryCollection[T]) Has(key string) (bool, error)

func (*MemoryCollection[T]) Iter

func (c *MemoryCollection[T]) Iter() Iterator[T]

func (*MemoryCollection[T]) Open

func (c *MemoryCollection[T]) Open() error

func (*MemoryCollection[T]) Put

func (c *MemoryCollection[T]) Put(key string, value T) error

type MemoryIterator

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

func MemoryIter

func MemoryIter[T any](m map[string]T, k []string, prev Iterator[T]) *MemoryIterator[T]

MemoryIter creates an in-memory iterator for any data. k must have a direct relation to m, representing the sorting of keys in the map, otherwise results may be unpredictable.

If the iterator prev is non-nil, it will be released when this iterator is released.

func (*MemoryIterator[T]) Count

func (i *MemoryIterator[T]) Count() int

func (*MemoryIterator[T]) Filter

func (i *MemoryIterator[T]) Filter(f FilterFunc[T]) Iterator[T]

func (*MemoryIterator[T]) First

func (i *MemoryIterator[T]) First() bool

func (*MemoryIterator[T]) Get

func (i *MemoryIterator[T]) Get() (string, T, error)

func (*MemoryIterator[T]) GetAll

func (i *MemoryIterator[T]) GetAll() (map[string]T, error)

func (*MemoryIterator[T]) GetAllKeys

func (i *MemoryIterator[T]) GetAllKeys() []string

func (*MemoryIterator[T]) Key

func (i *MemoryIterator[T]) Key() string

func (*MemoryIterator[T]) Last

func (i *MemoryIterator[T]) Last() bool

func (*MemoryIterator[T]) Next

func (i *MemoryIterator[T]) Next() bool

func (*MemoryIterator[T]) Prev

func (i *MemoryIterator[T]) Prev() bool

func (*MemoryIterator[T]) Release

func (i *MemoryIterator[T]) Release()

func (*MemoryIterator[T]) Reset

func (i *MemoryIterator[T]) Reset()

func (*MemoryIterator[T]) Sort

func (i *MemoryIterator[T]) Sort(f SortFunc[T]) Iterator[T]

func (*MemoryIterator[T]) SortKeys

func (i *MemoryIterator[T]) SortKeys(f SortFunc[string]) Iterator[T]

func (*MemoryIterator[T]) Value

func (i *MemoryIterator[T]) Value() (T, error)

type SortFunc

type SortFunc[T any] func(a T, b T) bool

SortFunc compares two documents as part of a sort operation. This function returns false if a is less than b.

Directories

Path Synopsis
ezleveldb module

Jump to

Keyboard shortcuts

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