Something went wrong on our end
-
Christian Pointner authoredChristian Pointner authored
store.go 2.89 KiB
//
// tank
//
// Import and Playlist Daemon for autoradio project
//
//
// Copyright (C) 2017 Christian Pointner <equinox@helsinki.at>
//
// This file is part of tank.
//
// tank is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// tank is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with tank. If not, see <http://www.gnu.org/licenses/>.
//
package store
import (
"errors"
"fmt"
"os"
"path/filepath"
"time"
"github.com/coreos/bbolt"
)
const (
StoreVersion = 1
)
type Store struct {
version int
db *bolt.DB
basePath string
}
//
// Initialization and Destruction
//
func openDB(dbPath string, readOnly bool) (db *bolt.DB, version int, err error) {
if _, err = os.Stat(dbPath); err != nil {
if os.IsNotExist(err) {
err = nil
}
return
}
opts := &bolt.Options{Timeout: 100 * time.Millisecond, ReadOnly: readOnly}
db, err = bolt.Open(dbPath, 0600, opts)
if err != nil {
return
}
err = db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(infoBn))
if b == nil {
return errors.New("store: failed to open, bucket '" + infoBn + "'does not exist.")
}
bVersion := b.Get([]byte(storeVersionKey))
if bVersion == nil {
return errors.New("store: failed to open, no version found.")
}
version = btoi(bVersion)
if version != StoreVersion {
return fmt.Errorf("store: failed to open, wrong version: %d (expected: %d)", version, StoreVersion)
}
// TODO: check all group buckets??
return nil
})
if err != nil {
db.Close()
}
return
}
func createDB(dbPath string) (db *bolt.DB, version int, err error) {
db, err = bolt.Open(dbPath, 0600, &bolt.Options{Timeout: 100 * time.Millisecond})
if err != nil {
return
}
err = db.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucket([]byte(infoBn))
if err != nil {
return err
}
version = StoreVersion
if err := b.Put([]byte(storeVersionKey), itob(version)); err != nil {
return err
}
b, err = tx.CreateBucket([]byte(groupsBn))
if err != nil {
return err
}
_, err = newGroup(b, publicGroupBn)
return err
})
if err != nil {
db.Close()
}
return
}
func NewStore(cfg *Config) (*Store, error) {
dbpath := filepath.Join(cfg.BasePath, ".db.bolt")
db, version, err := openDB(dbpath, false)
if err != nil {
return nil, err
}
if db != nil {
return &Store{version, db, cfg.BasePath}, nil
}
db, version, err = createDB(dbpath)
if err != nil {
return nil, err
}
return &Store{version, db, cfg.BasePath}, nil
}
func (st *Store) Close() {
st.db.Close()
}