mirror of
https://github.com/crazy-max/diun.git
synced 2025-01-12 11:38:11 +00:00
80 lines
1.6 KiB
Go
80 lines
1.6 KiB
Go
package db
|
|
|
|
import (
|
|
"reflect"
|
|
"time"
|
|
|
|
"github.com/crazy-max/diun/v4/internal/model"
|
|
"github.com/pkg/errors"
|
|
"github.com/rs/zerolog/log"
|
|
bolt "go.etcd.io/bbolt"
|
|
)
|
|
|
|
// Client represents an active db object
|
|
type Client struct {
|
|
*bolt.DB
|
|
cfg model.Db
|
|
metadata Metadata
|
|
}
|
|
|
|
const (
|
|
dbVersion = 2
|
|
bucketMetadata = "metadata"
|
|
bucketManifest = "manifest"
|
|
)
|
|
|
|
// New creates new db instance
|
|
func New(cfg model.Db) (*Client, error) {
|
|
db, err := bolt.Open(cfg.Path, 0600, &bolt.Options{
|
|
Timeout: 10 * time.Second,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = db.Update(func(tx *bolt.Tx) error {
|
|
_, err := tx.CreateBucketIfNotExists([]byte(bucketMetadata))
|
|
return err
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = db.Update(func(tx *bolt.Tx) error {
|
|
_, err := tx.CreateBucketIfNotExists([]byte(bucketManifest))
|
|
return err
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err = db.View(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket([]byte(bucketManifest))
|
|
stats := b.Stats()
|
|
log.Debug().Msgf("%d entries found in manifest bucket", stats.KeyN)
|
|
return nil
|
|
}); err != nil {
|
|
return nil, errors.Wrap(err, "cannot count entries in manifest bucket")
|
|
}
|
|
|
|
c := &Client{
|
|
DB: db,
|
|
cfg: cfg,
|
|
metadata: Metadata{},
|
|
}
|
|
|
|
if err := c.ReadMetadata(); err != nil {
|
|
return nil, err
|
|
}
|
|
if reflect.DeepEqual(c.metadata, Metadata{}) {
|
|
c.metadata = Metadata{
|
|
Version: 1,
|
|
}
|
|
}
|
|
|
|
log.Debug().Msgf("Current database version: %d", c.metadata.Version)
|
|
return c, nil
|
|
}
|
|
|
|
// Close closes db connection
|
|
func (c *Client) Close() error {
|
|
return c.DB.Close()
|
|
}
|