Documentation ¶
Overview ¶
Package database provides a universal interface for interacting with the database.
A Lazy Database ¶
The database system can handle Go structs as well as serialized data by the dsd package. While data is in transit within the system, it does not know which form it currently has. Only when it reaches its destination, it must ensure that it is either of a certain type or dump it.
Record Interface ¶
The database system uses the Record interface to transparently handle all types of structs that get saved in the database. Structs include the Base struct to fulfill most parts of the Record interface.
Boilerplate Code:
type Example struct { record.Base sync.Mutex Name string Score int } var ( db = database.NewInterface(nil) ) // GetExample gets an Example from the database. func GetExample(key string) (*Example, error) { r, err := db.Get(key) if err != nil { return nil, err } // unwrap if r.IsWrapped() { // only allocate a new struct, if we need it new := &Example{} err = record.Unwrap(r, new) if err != nil { return nil, err } return new, nil } // or adjust type new, ok := r.(*Example) if !ok { return nil, fmt.Errorf("record not of type *Example, but %T", r) } return new, nil } func (e *Example) Save() error { return db.Put(e) } func (e *Example) SaveAs(key string) error { e.SetKey(key) return db.PutNew(e) }
Index ¶
- Constants
- Variables
- func EnableRegistryPersistence()
- func Initialize(dirStructureRoot *utils.DirStructure) error
- func InitializeWithPath(dirPath string) error
- func Maintain(ctx context.Context) (err error)
- func MaintainRecordStates(ctx context.Context) (err error)
- func MaintainThorough(ctx context.Context) (err error)
- func Shutdown() (err error)
- type Controller
- func (c *Controller) Get(key string) (record.Record, error)
- func (c *Controller) GetMeta(key string) (*record.Meta, error)
- func (c *Controller) Injected() bool
- func (c *Controller) Maintain(ctx context.Context) error
- func (c *Controller) MaintainRecordStates(ctx context.Context, purgeDeletedBefore time.Time) error
- func (c *Controller) MaintainThorough(ctx context.Context) error
- func (c *Controller) Purge(ctx context.Context, q *query.Query, local, internal bool) (int, error)
- func (c *Controller) PushUpdate(r record.Record)
- func (c *Controller) Put(r record.Record) (err error)
- func (c *Controller) PutMany() (chan<- record.Record, <-chan error)
- func (c *Controller) Query(q *query.Query, local, internal bool) (*iterator.Iterator, error)
- func (c *Controller) ReadOnly() bool
- func (c *Controller) Shutdown() error
- func (c *Controller) Withdraw()
- type Database
- type Hook
- type HookBase
- type Interface
- func (i *Interface) ClearCache()
- func (i *Interface) DelayedCacheWriter(ctx context.Context) error
- func (i *Interface) Delete(key string) error
- func (i *Interface) Exists(key string) (bool, error)
- func (i *Interface) FlushCache()
- func (i *Interface) Get(key string) (record.Record, error)
- func (i *Interface) InsertValue(key string, attribute string, value interface{}) error
- func (i *Interface) MakeCrownJewel(key string) error
- func (i *Interface) MakeSecret(key string) error
- func (i *Interface) Purge(ctx context.Context, q *query.Query) (int, error)
- func (i *Interface) Put(r record.Record) (err error)
- func (i *Interface) PutMany(dbName string) (put func(record.Record) error)
- func (i *Interface) PutNew(r record.Record) (err error)
- func (i *Interface) Query(q *query.Query) (*iterator.Iterator, error)
- func (i *Interface) SetAbsoluteExpiry(key string, time int64) error
- func (i *Interface) SetRelativateExpiry(key string, duration int64) error
- func (i *Interface) Subscribe(q *query.Query) (*Subscription, error)
- type Options
- type RegisteredHook
- type Subscription
Constants ¶
const StorageTypeInjected = "injected"
Variables ¶
var ( ErrNotFound = errors.New("database entry not found") ErrPermissionDenied = errors.New("access to database record denied") ErrReadOnly = errors.New("database is read only") ErrShuttingDown = errors.New("database system is shutting down") ErrNotImplemented = errors.New("not implemented by this storage") )
Errors
Functions ¶
func EnableRegistryPersistence ¶ added in v0.7.3
func EnableRegistryPersistence()
EnableRegistryPersistence enables persistence of the database registry.
func Initialize ¶
func Initialize(dirStructureRoot *utils.DirStructure) error
Initialize initializes the database at the specified location using a dir structure.
func InitializeWithPath ¶ added in v0.5.0
InitializeWithPath initializes the database at the specified location using a path.
func MaintainRecordStates ¶
MaintainRecordStates runs record state lifecycle maintenance on all storages.
func MaintainThorough ¶
MaintainThorough runs the MaintainThorough method on all storages.
Types ¶
type Controller ¶
type Controller struct {
// contains filtered or unexported fields
}
A Controller takes care of all the extra database logic.
func InjectDatabase ¶
func InjectDatabase(name string, storageInt storage.Interface) (*Controller, error)
InjectDatabase injects an already running database into the system.
func (*Controller) Get ¶
func (c *Controller) Get(key string) (record.Record, error)
Get returns the record with the given key.
func (*Controller) GetMeta ¶ added in v0.10.0
func (c *Controller) GetMeta(key string) (*record.Meta, error)
Get returns the metadata of the record with the given key.
func (*Controller) Injected ¶
func (c *Controller) Injected() bool
Injected returns whether the storage is injected.
func (*Controller) Maintain ¶
func (c *Controller) Maintain(ctx context.Context) error
Maintain runs the Maintain method on the storage.
func (*Controller) MaintainRecordStates ¶ added in v0.5.2
MaintainRecordStates runs the record state lifecycle maintenance on the storage.
func (*Controller) MaintainThorough ¶
func (c *Controller) MaintainThorough(ctx context.Context) error
MaintainThorough runs the MaintainThorough method on the storage.
func (*Controller) Purge ¶ added in v0.8.3
Purge deletes all records that match the given query. It returns the number of successful deletes and an error.
func (*Controller) PushUpdate ¶
func (c *Controller) PushUpdate(r record.Record)
PushUpdate pushes a record update to subscribers. The caller must hold the record's lock when calling PushUpdate.
func (*Controller) Put ¶
func (c *Controller) Put(r record.Record) (err error)
Put saves a record in the database, executes any registered pre-put hooks and finally send an update to all subscribers. The record must be locked and secured from concurrent access when calling Put().
func (*Controller) PutMany ¶ added in v0.5.0
func (c *Controller) PutMany() (chan<- record.Record, <-chan error)
PutMany stores many records in the database. It does not process any hooks or update subscriptions. Use with care!
func (*Controller) ReadOnly ¶
func (c *Controller) ReadOnly() bool
ReadOnly returns whether the storage is read only.
func (*Controller) Shutdown ¶
func (c *Controller) Shutdown() error
Shutdown shuts down the storage.
func (*Controller) Withdraw ¶ added in v0.12.4
func (c *Controller) Withdraw()
Withdraw withdraws an injected database, but leaves the database registered.
type Database ¶
type Database struct { Name string Description string StorageType string ShadowDelete bool // Whether deleted records should be kept until purged. Registered time.Time LastUpdated time.Time LastLoaded time.Time }
Database holds information about registered databases
type Hook ¶
type Hook interface { // UsesPreGet should return true if the hook's PreGet // should be called prior to loading a database record // from the underlying storage. UsesPreGet() bool // PreGet is called before a database record is loaded from // the underlying storage. A PreGet hookd may be used to // implement more advanced access control on database keys. PreGet(dbKey string) error // UsesPostGet should return true if the hook's PostGet // should be called after loading a database record from // the underlying storage. UsesPostGet() bool // PostGet is called after a record has been loaded form the // underlying storage and may perform additional mutation // or access check based on the records data. // The passed record is already locked by the database system // so users can safely access all data of r. PostGet(r record.Record) (record.Record, error) // UsesPrePut should return true if the hook's PrePut method // should be called prior to saving a record in the database. UsesPrePut() bool // PrePut is called prior to saving (creating or updating) a // record in the database storage. It may be used to perform // extended validation or mutations on the record. // The passed record is already locked by the database system // so users can safely access all data of r. PrePut(r record.Record) (record.Record, error) }
Hook can be registered for a database query and will be executed at certain points during the life cycle of a database record.
type HookBase ¶
type HookBase struct { }
HookBase implements the Hook interface and provides dummy functions to reduce boilerplate.
func (*HookBase) UsesPostGet ¶
UsesPostGet implements the Hook interface and returns false.
func (*HookBase) UsesPreGet ¶
UsesPreGet implements the Hook interface and returns false.
func (*HookBase) UsesPrePut ¶
UsesPrePut implements the Hook interface and returns false.
type Interface ¶
type Interface struct {
// contains filtered or unexported fields
}
Interface provides a method to access the database with attached options.
func NewInterface ¶
NewInterface returns a new Interface to the database.
func (*Interface) ClearCache ¶ added in v0.9.4
func (i *Interface) ClearCache()
ClearCache clears the read cache.
func (*Interface) DelayedCacheWriter ¶ added in v0.9.0
DelayedCacheWriter must be run by the caller of an interface that uses delayed cache writing.
func (*Interface) FlushCache ¶ added in v0.9.4
func (i *Interface) FlushCache()
FlushCache writes (and thus clears) the write cache.
func (*Interface) InsertValue ¶
InsertValue inserts a value into a record.
func (*Interface) MakeCrownJewel ¶
MakeCrownJewel marks a record as a crown jewel, meaning it will only be accessible locally.
func (*Interface) MakeSecret ¶
MakeSecret marks the record as a secret, meaning interfacing processes, such as an UI, are denied access to the record.
func (*Interface) Purge ¶ added in v0.8.3
Purge deletes all records that match the given query. It returns the number of successful deletes and an error.
func (*Interface) PutMany ¶ added in v0.5.0
PutMany stores many records in the database. Warning: This is nearly a direct database access and omits many things: - Record locking - Hooks - Subscriptions - Caching
func (*Interface) PutNew ¶
PutNew saves a record to the database as a new record (ie. with new timestamps).
func (*Interface) SetAbsoluteExpiry ¶
SetAbsoluteExpiry sets an absolute record expiry.
func (*Interface) SetRelativateExpiry ¶
SetRelativateExpiry sets a relative (self-updating) record expiry.
type Options ¶
type Options struct { // Local specifies if the interface is used by an actor on the local device. // Setting both the Local and Internal flags will bring performance // improvements because less checks are needed. Local bool // Internal specifies if the interface is used by an actor within the // software. Setting both the Local and Internal flags will bring performance // improvements because less checks are needed. Internal bool // AlwaysMakeSecret will have the interface mark all saved records as secret. // This means that they will be only accessible by an internal interface. AlwaysMakeSecret bool // AlwaysMakeCrownjewel will have the interface mark all saved records as // crown jewels. This means that they will be only accessible by a local // interface. AlwaysMakeCrownjewel bool // AlwaysSetRelativateExpiry will have the interface set a relative expiry, // based on the current time, on all saved records. AlwaysSetRelativateExpiry int64 // AlwaysSetAbsoluteExpiry will have the interface set an absolute expiry on // all saved records. AlwaysSetAbsoluteExpiry int64 // CacheSize defines that a cache should be used for this interface and // defines it's size. // Caching comes with an important caveat: If database records are changed // from another interface, the cache will not be invalidated for these // records. It will therefore serve outdated data until that record is // evicted from the cache. CacheSize int // DelayCachedWrites defines a database name for which cache writes should // be cached and batched. The database backend must support the Batcher // interface. This option is only valid if used with a cache. // Additionally, this may only be used for internal and local interfaces. // Please note that this means that other interfaces will not be able to // guarantee to serve the latest record if records are written this way. DelayCachedWrites string }
Options holds options that may be set for an Interface instance.
func (*Options) HasAllPermissions ¶ added in v0.9.0
HasAllPermissions returns whether the options specify the highest possible permissions for operations.
type RegisteredHook ¶
type RegisteredHook struct {
// contains filtered or unexported fields
}
RegisteredHook is a registered database hook.
func RegisterHook ¶
func RegisterHook(q *query.Query, hook Hook) (*RegisteredHook, error)
RegisterHook registers a hook for records matching the given query in the database.
func (*RegisteredHook) Cancel ¶
func (h *RegisteredHook) Cancel() error
Cancel unregisteres the hook from the database. Once Cancel returned the hook's methods will not be called anymore for updates that matched the registered query.
type Subscription ¶
Subscription is a database subscription for updates.
func (*Subscription) Cancel ¶
func (s *Subscription) Cancel() error
Cancel cancels the subscription.