database

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

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

Go to latest
Published: Nov 29, 2025 License: MIT Imports: 13 Imported by: 0

README

database

A Go library, used to easily control SQLite database(s)

Documentation

Overview

Package database represents easy to use database without raw SQL, that uses sqlite as default.

There are Provider interface and default implementation: ProviderImpl. I created it to prevent double code each time (I have multiple providers with almost same code). It loads models from the database on initialization of the Provider itself, and saves all models (with closing the database) on Close method (io.Closer).

Index

Constants

This section is empty.

Variables

View Source
var ErrAlreadyClosed = errors.New("already closed")

Functions

This section is empty.

Types

type Database

type Database[M any] struct {
	// contains filtered or unexported fields
}

Database is easy to use database structure that generally uses *gorm.DB.

func New

func New[M any](path string, migrateVal any, l *slog.Logger) (*Database[M], error)

New creates new Database. migrateVal should be an instance of the model type for migration.

func (*Database[M]) Close

func (db *Database[M]) Close() error

Close implements io.Closer.

func (*Database[M]) DeleteEntry

func (db *Database[M]) DeleteEntry(query string, args ...any)

DeleteEntry deletes an entry by queried args. Example: db.DeleteEntry("name = ?", "Bob") WARNING: If no conditions are provided, it will delete ALL entries!

func (*Database[M]) Entries

func (db *Database[M]) Entries() (entries []M)

Entries returns all database entries.

func (*Database[M]) FindEntry

func (db *Database[M]) FindEntry(query string, args ...any) (_ M, _ bool)

FindEntry tries to find entry in database by specified arguments. Example: db.FindEntry("name = ?", "Bob") Returns (entry, true) if found, (zero-value, false) otherwise.

func (*Database[T]) Logger

func (db *Database[T]) Logger() *slog.Logger

Logger returns Database logger.

func (*Database[M]) NewEntry

func (db *Database[M]) NewEntry(entry M)

NewEntry creates new entry in database.

func (*Database[M]) UpdateEntry

func (db *Database[M]) UpdateEntry(new M, query string, args ...any) bool

UpdateEntry updates entry in database. Returns true if update was successful, false if entry not found. Uses query and args for finding the record to prevent ambiguous column errors

type ModelCollectionOptions

type ModelCollectionOptions[K comparable, V any, DB any] struct {
	// IdentifyOwner is function that returns the owner key for grouping models
	IdentifyOwner func(V) K
	// IdentifyModel is function that returns unique identifier for each model
	IdentifyModel func(V) K
	// IdentifyDBModel is same function as above, but for DB models
	IdentifyDBModel func(DB) K
	// ModifyQuery is function that must return arguments (query) to modify
	// model in the database
	ModifyQuery func(DB) (string, []any)
	// CreateDBModel is function that creates database models from entries
	CreateDBModel func(K, V) DB
	// CreateModel should create default model from DB model
	CreateModel func(DB) V
	// CompareModels is function to compare two DB models
	CompareModels func(DB, DB) bool
	// AlwaysUpdate marks if we should always update all models
	AlwaysUpdate bool
	// NeverUpdate marks if provider should never update the database models
	NeverUpdate bool
	// OnLoad is function that is called right before model is going to be
	// added. It can cancel adding model by returning false in this function.
	OnLoad func(ownerKey K, model *V, dbModel DB) bool
}

ModelCollectionOptions is REQUIRED options of the model collection

type ModelOptions

type ModelOptions[K comparable, V any, DB any] struct {
	// Identify is function that allows user by itself get identifier of this
	// model. Without it, models can't be stored by 'map[key]model'.
	IdentifyModel func(V) K
	// IdentifyDBModel is same function as above, but for DB models.
	IdentifyDBModel func(DB) K
	// ModifyQuery is function, that must return arguments (query) to modify
	// model in the database.
	// Example:
	//
	// func (m myModel) modifyQuery() (string, []any) {
	//    return "uuid = ?", []any{m.MyUUID}
	// }
	ModifyQuery func(DB) (string, []any)
	// CreateDBModel is function that is required to create database models
	// from entries (convert models from Provider memory to database models and
	// save them)
	CreateDBModel func(K, V) DB
	// CreateModel should create default model from DB model.
	CreateModel func(DB) V
	// CompareModels is function to compare two DB models. It is required to
	// check, if we need to update model in the database.
	CompareModels func(DB, DB) bool
	// AlwaysUpdate is boolean that marks, if we should always update all
	// models in the database (without comparing). If it is true, CompareModels
	// can be nil.
	AlwaysUpdate bool
	// NeverUpdate is boolean, that marks if provider should never update the
	// database models. Example: database of archived punishments, we're just
	// adding models without modifying them.
	NeverUpdate bool
	// OnLoad is function that is called right before model is going to be
	// added. It can cancel adding model by returning false in this function.
	OnLoad func(K, *V, DB) bool
}

ModelOptions is REQUIRED options of the model. If you'll not enter them Provider will simply panic.

type Provider

type Provider[K comparable, V, DB any] interface {
	// Closer only has "Close() error" method.
	// Close method should save modified models to database and close the
	// parent database.
	io.Closer
	// PutEntry tries to put entry to the provider memory.
	// It returns false, if there's already an entry by this key.
	PutEntry(K, V) bool
	PutEntryUnsafe(K, V) bool
	// SetEntry updates the entry by key (stores to provider memory).
	// It'll override, if there is an entry by this key
	SetEntry(K, V)
	SetEntryUnsafe(K, V)
	// DeleteEntry deletes entry from the provider by its key.
	DeleteEntry(K)
	DeleteEntryUnsafe(K)
	// LoadEntry tries to load the entry from provider.
	LoadEntry(K) (V, bool)
	LoadEntryUnsafe(K) (V, bool)
	// LoadEntryFunc tries to load the entry from provider by iterating across
	// all entries.
	LoadEntryFunc(yield func(K, V) bool) (V, bool)
	LoadEntryFuncUnsafe(yield func(K, V) bool) (V, bool)
	// Entries returns iterator of all provider entries.
	Entries() iter.Seq[V]
	EntriesUnsafe() iter.Seq[V]
	// MapEntries returns key-value iterator of all provider entries.
	MapEntries() iter.Seq2[K, V]
	MapEntriesUnsafe() iter.Seq2[K, V]
	// Load initializes the provider. It loads all models from the database.
	// It can be only called once.
	Load()
	// Database returns database instance of this provider.
	Database() *Database[DB]
	// L returns entries mutex (locker) for this provider.
	L() *sync.RWMutex
}

Provider is the implementation of database provider. It loads and saves database models once. You can read more about it on doc.go.

func NewProvider

func NewProvider[K comparable, V any, DB any](db *Database[DB], opts ModelOptions[K, V, DB], init bool) Provider[K, V, DB]

NewProvider creates new ProviderImpl instance. It requires to Database not be closed.

type ProviderCollection

type ProviderCollection[K comparable, V, DB any] interface {
	io.Closer
	// PutEntry adds an entry to the collection
	// Returns false if an entry with the same model key already exists
	PutEntry(K, V) bool
	PutEntryUnsafe(K, V) bool
	// SetEntry adds or replaces an entry in the collection
	SetEntry(K, V)
	SetEntryUnsafe(K, V)
	// RemoveEntry removes a specific entry from the collection
	RemoveEntry(V)
	RemoveEntryUnsafe(V)
	// RemoveEntryByID removes a specific entry from the collection by
	// its identification.
	RemoveEntryByID(ownerKey, modelKey K)
	RemoveEntryByIDUnsafe(ownerKey, modelKey K)
	// RemoveEntries removes all entries for a specific owner key
	RemoveEntries(K)
	RemoveEntriesUnsafe(K)
	// LoadEntries returns all entries for a specific owner key
	LoadEntries(key K, clone bool) ([]V, bool)
	LoadEntriesUnsafe(key K, clone bool) ([]V, bool)
	// Entries returns iterator of all entries in the collection
	Entries() iter.Seq[V]
	EntriesUnsafe() iter.Seq[V]
	// MapEntries returns key-collection iterator of all provider entries
	MapEntries() iter.Seq2[K, []V]
	MapEntriesUnsafe() iter.Seq2[K, []V]
	// Load initializes the provider collection
	Load()
	// Database returns database instance of this provider.
	Database() *Database[DB]
	// L returns entries mutex (locker) for this provider.
	L() *sync.RWMutex
}

ProviderCollection is the interface for database provider that stores collections of value.s

func NewProviderCollection

func NewProviderCollection[K comparable, V any, DB any](db *Database[DB], opts ModelCollectionOptions[K, V, DB], init bool) ProviderCollection[K, V, DB]

NewProviderCollection creates new ProviderCollectionImpl instance

type ProviderCollectionImpl

type ProviderCollectionImpl[K comparable, V any, DB any] struct {
	// contains filtered or unexported fields
}

ProviderCollectionImpl is default implementation of the ProviderCollection.

func (*ProviderCollectionImpl[K, V, DB]) Close

func (provider *ProviderCollectionImpl[K, V, DB]) Close() error

Close ...

func (*ProviderCollectionImpl[K, V, DB]) Database

func (provider *ProviderCollectionImpl[K, V, DB]) Database() *Database[DB]

Database ...

func (*ProviderCollectionImpl[K, V, DB]) Entries

func (provider *ProviderCollectionImpl[K, V, DB]) Entries() iter.Seq[V]

Entries ...

func (*ProviderCollectionImpl[K, V, DB]) EntriesUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) EntriesUnsafe() iter.Seq[V]

func (*ProviderCollectionImpl[K, V, DB]) L

func (provider *ProviderCollectionImpl[K, V, DB]) L() *sync.RWMutex

L ...

func (*ProviderCollectionImpl[K, V, DB]) Load

func (provider *ProviderCollectionImpl[K, V, DB]) Load()

Load ...

func (*ProviderCollectionImpl[K, V, DB]) LoadEntries

func (provider *ProviderCollectionImpl[K, V, DB]) LoadEntries(ownerKey K, clone bool) ([]V, bool)

LoadEntries ...

func (*ProviderCollectionImpl[K, V, DB]) LoadEntriesUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) LoadEntriesUnsafe(ownerKey K, clone bool) ([]V, bool)

LoadEntriesUnsafe ...

func (*ProviderCollectionImpl[K, V, DB]) MapEntries

func (provider *ProviderCollectionImpl[K, V, DB]) MapEntries() iter.Seq2[K, []V]

MapEntries ...

func (*ProviderCollectionImpl[K, V, DB]) MapEntriesUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) MapEntriesUnsafe() iter.Seq2[K, []V]

func (*ProviderCollectionImpl[K, V, DB]) PutEntry

func (provider *ProviderCollectionImpl[K, V, DB]) PutEntry(ownerKey K, v V) bool

PutEntry ...

func (*ProviderCollectionImpl[K, V, DB]) PutEntryUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) PutEntryUnsafe(ownerKey K, v V) bool

func (*ProviderCollectionImpl[K, V, DB]) RemoveEntries

func (provider *ProviderCollectionImpl[K, V, DB]) RemoveEntries(ownerKey K)

RemoveEntries ...

func (*ProviderCollectionImpl[K, V, DB]) RemoveEntriesUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) RemoveEntriesUnsafe(ownerKey K)

func (*ProviderCollectionImpl[K, V, DB]) RemoveEntry

func (provider *ProviderCollectionImpl[K, V, DB]) RemoveEntry(v V)

RemoveEntry ...

func (*ProviderCollectionImpl[K, V, DB]) RemoveEntryByID

func (provider *ProviderCollectionImpl[K, V, DB]) RemoveEntryByID(ownerKey, modelKey K)

RemoveEntryByID ...

func (*ProviderCollectionImpl[K, V, DB]) RemoveEntryByIDUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) RemoveEntryByIDUnsafe(ownerKey, modelKey K)

func (*ProviderCollectionImpl[K, V, DB]) RemoveEntryUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) RemoveEntryUnsafe(v V)

func (*ProviderCollectionImpl[K, V, DB]) SetEntry

func (provider *ProviderCollectionImpl[K, V, DB]) SetEntry(ownerKey K, v V)

SetEntry ...

func (*ProviderCollectionImpl[K, V, DB]) SetEntryUnsafe

func (provider *ProviderCollectionImpl[K, V, DB]) SetEntryUnsafe(ownerKey K, v V)

type ProviderImpl

type ProviderImpl[K comparable, V any, DB any] struct {
	// contains filtered or unexported fields
}

ProviderImpl is default implementation of the Provider.

func (*ProviderImpl[K, V, DB]) Close

func (provider *ProviderImpl[K, V, DB]) Close() error

Close ...

func (*ProviderImpl[K, V, DB]) Database

func (provider *ProviderImpl[K, V, DB]) Database() *Database[DB]

Database ...

func (*ProviderImpl[K, V, DB]) DeleteEntry

func (provider *ProviderImpl[K, V, DB]) DeleteEntry(k K)

DeleteEntry ...

func (*ProviderImpl[K, V, DB]) DeleteEntryUnsafe

func (provider *ProviderImpl[K, V, DB]) DeleteEntryUnsafe(k K)

func (*ProviderImpl[K, V, DB]) Entries

func (provider *ProviderImpl[K, V, DB]) Entries() iter.Seq[V]

Entries ...

func (*ProviderImpl[K, V, DB]) EntriesUnsafe

func (provider *ProviderImpl[K, V, DB]) EntriesUnsafe() iter.Seq[V]

func (*ProviderImpl[K, V, DB]) L

func (provider *ProviderImpl[K, V, DB]) L() *sync.RWMutex

L ...

func (*ProviderImpl[K, V, DB]) Load

func (provider *ProviderImpl[K, V, DB]) Load()

Load loads all entries from database and stores them to the Provider memory. This function must be called on initialize, since it won't lock mutex, because user didn't even receive the Provider instance.

func (*ProviderImpl[K, V, DB]) LoadEntry

func (provider *ProviderImpl[K, V, DB]) LoadEntry(k K) (V, bool)

LoadEntry ...

func (*ProviderImpl[K, V, DB]) LoadEntryFunc

func (provider *ProviderImpl[K, V, DB]) LoadEntryFunc(yield func(K, V) bool) (V, bool)

LoadEntryFunc ...

func (*ProviderImpl[K, V, DB]) LoadEntryFuncUnsafe

func (provider *ProviderImpl[K, V, DB]) LoadEntryFuncUnsafe(yield func(K, V) bool) (V, bool)

func (*ProviderImpl[K, V, DB]) LoadEntryUnsafe

func (provider *ProviderImpl[K, V, DB]) LoadEntryUnsafe(k K) (V, bool)

func (*ProviderImpl[K, V, DB]) MapEntries

func (provider *ProviderImpl[K, V, DB]) MapEntries() iter.Seq2[K, V]

MapEntries ...

func (*ProviderImpl[K, V, DB]) MapEntriesUnsafe

func (provider *ProviderImpl[K, V, DB]) MapEntriesUnsafe() iter.Seq2[K, V]

func (*ProviderImpl[K, V, DB]) PutEntry

func (provider *ProviderImpl[K, V, DB]) PutEntry(k K, v V) bool

PutEntry ...

func (*ProviderImpl[K, V, DB]) PutEntryUnsafe

func (provider *ProviderImpl[K, V, DB]) PutEntryUnsafe(k K, v V) bool

func (*ProviderImpl[K, V, DB]) SetEntry

func (provider *ProviderImpl[K, V, DB]) SetEntry(k K, v V)

SetEntry ...

func (*ProviderImpl[K, V, DB]) SetEntryUnsafe

func (provider *ProviderImpl[K, V, DB]) SetEntryUnsafe(k K, v V)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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