Go to file
2024-06-21 21:12:46 -07:00
.github/workflows Feat[backup]: Introduce VerifyBackup method 2024-06-18 21:40:45 -07:00
backup Update README.md 2024-06-21 21:12:46 -07:00
bitcask Update README.md 2024-06-21 21:12:46 -07:00
kv Feat: Implement backups and test all keeper's backup and restore functionality 2024-06-19 01:03:35 -07:00
metadata Update README.md 2024-06-21 21:12:46 -07:00
migrate Update README.md 2024-06-21 21:12:46 -07:00
models Update README.md 2024-06-21 21:12:46 -07:00
pogreb Update README.md 2024-06-21 21:12:46 -07:00
registry Massive, likely breaking (!): Implement test suite, various Keeper fixes/refactoring 2024-06-18 21:15:51 -07:00
test Chore (testing): tidy up 2024-06-19 01:20:21 -07:00
.gitignore Chore: lint 2022-07-23 18:07:09 -07:00
filer.go Add: interface methods + Fix: testing 2022-08-28 23:36:37 -07:00
go.mod Chore: retract bad tag 2024-06-17 04:26:12 -07:00
go.sum Fix: nil bitcask store during withnew when store exists 2023-11-27 16:02:42 -08:00
keeper.go Feat: Migration 2024-06-21 21:02:02 -07:00
LICENSE fix go.mod path, etc 2022-05-21 16:03:59 -07:00
mock.go Feat: Migration 2024-06-21 21:02:02 -07:00
README.md Update README.md 2024-06-21 21:12:46 -07:00
searcher.go Feat: Implement backups and test all keeper's backup and restore functionality 2024-06-19 01:03:35 -07:00
store.go Add: interface methods + Fix: testing 2022-08-28 23:36:37 -07:00

database

Coverage Build Status

import "git.tcp.direct/tcp.direct/database"

Warning

This package is pre-v1 and the API is NOT stable!

Documentation

var ErrKeyNotFound = errors.New("key not found")

type Filer

type Filer interface {

	// Backend returns the underlying key/value store.
	Backend() any

	// Has should return true if the given key has an associated value.
	Has(key []byte) bool
	// Get should retrieve the byte slice corresponding to the given key, and any associated errors upon failure.
	Get(key []byte) ([]byte, error)
	// Put should insert the value data in a way that is associated and can be retrieved by the given key data.
	Put(key []byte, value []byte) error
	// Delete should delete the key and the value associated with the given key, and return an error upon failure.
	Delete(key []byte) error
	// Close should safely end any Filer operations of the given dataStore and close any relevant handlers.
	Close() error
	// Sync should take any volatile data and solidify it somehow if relevant. (ram to disk in most cases)
	Sync() error

	Keys() [][]byte
	Len() int
}

Filer is is a way to implement any generic key/value store. These functions should be plug and play with most of the popular key/value store golang libraries.

NOTE: Many key/value golang libraries will already implement this interface already. This exists for more potential granular control in the case that they don't. Otherwise you'd have to build a wrapper around an existing key/value store to satisfy an overencompassing interface.

type Keeper

type Keeper interface {
	// Path should return the base path where all stores should be stored under. (likely as subdirectories)
	Path() string

	// Init should initialize our Filer at the given path, to be referenced and called by dataStore.
	Init(name string, options ...any) error
	// With provides access to the given dataStore by providing a pointer to the related Filer.
	With(name string) Filer
	// WithNew should initialize a new Filer at the given path and return a pointer to it.
	WithNew(name string, options ...any) Filer

	// Destroy should remove the Filer by the given name.
	// It is up to the implementation to decide if the data should be removed or not.
	Destroy(name string) error

	Discover() ([]string, error)

	AllStores() map[string]Filer

	// BackupAll should create a backup of all [Filer] instances in the [Keeper].
	BackupAll(archivePath string) (models.Backup, error)

	// RestoreAll should restore all [Filer] instances from the given archive.
	RestoreAll(archivePath string) error

	Meta() models.Metadata

	Close(name string) error

	CloseAll() error
	SyncAll() error
	SyncAndCloseAll() error
}

Keeper will be in charge of the more meta operations involving Filers. This includes operations like initialization, syncing to disk if applicable, and backing up.

- When opening a folder of Filers, it should be able to discover and initialize all of them.
- Additionally, it should be able to confirm the type of the underlying key/value store.

type KeeperCreator

type KeeperCreator func(path string) (Keeper, error)

type MockFiler

type MockFiler struct {
}

func (*MockFiler) Backend

func (m *MockFiler) Backend() any

func (*MockFiler) Close

func (m *MockFiler) Close() error

func (*MockFiler) Delete

func (m *MockFiler) Delete(key []byte) error

func (*MockFiler) Get

func (m *MockFiler) Get(key []byte) ([]byte, error)

func (*MockFiler) Has

func (m *MockFiler) Has(key []byte) bool

func (*MockFiler) Keys

func (m *MockFiler) Keys() [][]byte

func (*MockFiler) Len

func (m *MockFiler) Len() int

func (*MockFiler) Put

func (m *MockFiler) Put(key []byte, value []byte) error

func (*MockFiler) Sync

func (m *MockFiler) Sync() error

type MockKeeper

type MockKeeper struct {
}

func NewMockKeeper

func NewMockKeeper(name string) *MockKeeper

func (*MockKeeper) AllStores

func (m *MockKeeper) AllStores() map[string]Filer

func (*MockKeeper) BackupAll

func (m *MockKeeper) BackupAll(archivePath string) (models.Backup, error)

func (*MockKeeper) Close

func (m *MockKeeper) Close(name string) error

func (*MockKeeper) CloseAll

func (m *MockKeeper) CloseAll() error

func (*MockKeeper) Destroy

func (m *MockKeeper) Destroy(name string) error

func (*MockKeeper) Discover

func (m *MockKeeper) Discover() ([]string, error)

func (*MockKeeper) Init

func (m *MockKeeper) Init(name string, options ...any) error

func (*MockKeeper) Meta

func (m *MockKeeper) Meta() models.Metadata

func (*MockKeeper) Path

func (m *MockKeeper) Path() string

func (*MockKeeper) RestoreAll

func (m *MockKeeper) RestoreAll(archivePath string) error

func (*MockKeeper) SyncAll

func (m *MockKeeper) SyncAll() error

func (*MockKeeper) SyncAndCloseAll

func (m *MockKeeper) SyncAndCloseAll() error

func (*MockKeeper) With

func (m *MockKeeper) With(name string) Filer

func (*MockKeeper) WithNew

func (m *MockKeeper) WithNew(name string, options ...any) Filer

type Searcher

type Searcher interface {
	// PrefixScan must retrieve all keys in the datastore and stream them to the given channel.
	PrefixScan(prefix string) (<-chan kv.KeyValue, chan error)
	// Search must be able to search through the value contents of our database and stream the results to the given channel.
	Search(query string) (<-chan kv.KeyValue, chan error)
	// ValueExists searches for an exact match of the given value and returns the key that contains it.
	ValueExists(value []byte) (key []byte, ok bool)
}

Searcher must be able to search through our datastore(s) with strings.

type Store

type Store interface {
	Filer
	Searcher
}

Store is an implementation of a Filer and a Searcher.