package persistence import ( "encoding/json" "git.openprivacy.ca/openprivacy/libricochet-go/log" bolt "go.etcd.io/bbolt" ) // BoltPersistence creates a persistence services backed by an on-disk bolt database type BoltPersistence struct { db *bolt.DB } // Open opens a database func (bp *BoltPersistence) Open(handle string) error { db, err := bolt.Open(handle, 0600, nil) bp.db = db log.Debugf("Loaded the Database") return err } // Setup initializes the given buckets if they do not exist in the database func (bp *BoltPersistence) Setup(buckets []string) error { return bp.db.Update(func(tx *bolt.Tx) error { for _, bucket := range buckets { tx.CreateBucketIfNotExists([]byte(bucket)) } return nil }) } // Close closes the databases func (bp *BoltPersistence) Close() { bp.db.Close() } // Persist stores a record in the database func (bp *BoltPersistence) Persist(bucket string, name string, value interface{}) error { valueBytes, _ := json.Marshal(value) return bp.db.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(bucket)) b.Put([]byte(name), valueBytes) return nil }) } // Check returns true if the record exists in the given bucket. func (bp *BoltPersistence) Check(bucket string, name string) (bool, error) { log.Debugf("Checking database: %v %v", bucket, name) var val []byte err := bp.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(bucket)) val = b.Get([]byte(name)) return nil }) if err != nil { return false, err } else if val != nil { return true, nil } return false, nil } // Load reads a value from a given bucket. func (bp *BoltPersistence) Load(bucket string, name string, value interface{}) error { var val []byte err := bp.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(bucket)) val = b.Get([]byte(name)) return nil }) if err != nil { return err } return json.Unmarshal(val, &value) }