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 func (db *YamlDB) Transaction(callback func() bool, marshaller func() ([]byte, error)) error { log.Debug("Enter transaction") db.lock.Lock() defer func() { db.lock.Unlock() log.Debug("Exit transaction") }() isDataChanged := callback() if isDataChanged { yamlData, err := marshaller() log.Debugf("Marshalled YAML: %#v", string(yamlData)) 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") } } return nil }