2019-11-10 23:50:50 +00:00
|
|
|
package yamldb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
// YamlDB represents a YAML file database instance
|
|
|
|
type YamlDB struct {
|
|
|
|
Path string
|
|
|
|
PathNew string
|
|
|
|
lock sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
// Transaction executes the given callback and safely saves
|
|
|
|
// the data after they are modified within the callback
|
2019-11-12 15:50:25 +00:00
|
|
|
func (db *YamlDB) Transaction(callback func() bool, marshaller func() ([]byte, error)) error {
|
2019-11-10 23:50:50 +00:00
|
|
|
log.Debug("Enter transaction")
|
|
|
|
db.lock.Lock()
|
|
|
|
defer func() {
|
|
|
|
db.lock.Unlock()
|
|
|
|
log.Debug("Exit transaction")
|
|
|
|
}()
|
|
|
|
|
2019-11-12 15:50:25 +00:00
|
|
|
isDataChanged := callback()
|
|
|
|
|
|
|
|
if isDataChanged {
|
|
|
|
yamlData, err := marshaller()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "Data marshalling error")
|
|
|
|
}
|
|
|
|
err = ioutil.WriteFile(db.PathNew, yamlData, 0644)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "YamlDB write failure")
|
|
|
|
}
|
|
|
|
err = os.Rename(db.PathNew, db.Path)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "Couldn't rewrite an old YamlDB file")
|
|
|
|
}
|
2019-11-10 23:50:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|