85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
package database
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"go.jolheiser.com/vanity/go-vanity"
|
|
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
var packageBucket = []byte("packages")
|
|
|
|
type Database struct {
|
|
db *bbolt.DB
|
|
}
|
|
|
|
func Load(dbPath string) (*Database, error) {
|
|
if err := os.MkdirAll(filepath.Dir(dbPath), os.ModePerm); err != nil {
|
|
return nil, err
|
|
}
|
|
db, err := bbolt.Open(dbPath, os.ModePerm, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Database{
|
|
db: db,
|
|
}, db.Update(func(tx *bbolt.Tx) error {
|
|
_, err := tx.CreateBucketIfNotExists(packageBucket)
|
|
return err
|
|
})
|
|
}
|
|
|
|
func (d *Database) Package(name string) (vanity.Package, error) {
|
|
var pkg vanity.Package
|
|
data, err := d.PackageJSON(name)
|
|
if err != nil {
|
|
return pkg, err
|
|
}
|
|
return pkg, json.NewDecoder(bytes.NewReader(data)).Decode(&pkg)
|
|
}
|
|
|
|
func (d *Database) PackageJSON(name string) (pkg []byte, err error) {
|
|
return pkg, d.db.View(func(tx *bbolt.Tx) error {
|
|
pkg = tx.Bucket(packageBucket).Get([]byte(name))
|
|
if pkg == nil {
|
|
return ErrPackageNotFound{
|
|
Name: name,
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (d *Database) Packages() (pkgs []vanity.Package, err error) {
|
|
return pkgs, d.db.View(func(tx *bbolt.Tx) error {
|
|
return tx.Bucket(packageBucket).ForEach(func(key, val []byte) error {
|
|
var pkg vanity.Package
|
|
if err := json.NewDecoder(bytes.NewReader(val)).Decode(&pkg); err != nil {
|
|
return err
|
|
}
|
|
pkgs = append(pkgs, pkg)
|
|
return nil
|
|
})
|
|
})
|
|
}
|
|
|
|
func (d *Database) PutPackage(pkg vanity.Package) error {
|
|
return d.db.Update(func(tx *bbolt.Tx) error {
|
|
data, err := json.Marshal(pkg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return tx.Bucket(packageBucket).Put([]byte(pkg.Name), data)
|
|
})
|
|
}
|
|
|
|
func (d *Database) RemovePackage(name string) error {
|
|
return d.db.Update(func(tx *bbolt.Tx) error {
|
|
return tx.Bucket(packageBucket).Delete([]byte(name))
|
|
})
|
|
}
|