ec7c16fdc1
This commit renames the variables dbName to towerDBName and dbVersions to towerDBVersions, to distinguish between the upcoming clientDBName clientDBVersions. We also move resusable portions of the database initialization and default endianness to its own file so that it can be shared between both tower and client databases.
93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package wtdb
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/coreos/bbolt"
|
|
)
|
|
|
|
const (
|
|
// dbFilePermission requests read+write access to the db file.
|
|
dbFilePermission = 0600
|
|
)
|
|
|
|
var (
|
|
// metadataBkt stores all the meta information concerning the state of
|
|
// the database.
|
|
metadataBkt = []byte("metadata-bucket")
|
|
|
|
// dbVersionKey is a static key used to retrieve the database version
|
|
// number from the metadataBkt.
|
|
dbVersionKey = []byte("version")
|
|
|
|
// ErrUninitializedDB signals that top-level buckets for the database
|
|
// have not been initialized.
|
|
ErrUninitializedDB = errors.New("db not initialized")
|
|
|
|
// ErrNoDBVersion signals that the database contains no version info.
|
|
ErrNoDBVersion = errors.New("db has no version")
|
|
|
|
// byteOrder is the default endianness used when serializing integers.
|
|
byteOrder = binary.BigEndian
|
|
)
|
|
|
|
// fileExists returns true if the file exists, and false otherwise.
|
|
func fileExists(path string) bool {
|
|
if _, err := os.Stat(path); err != nil {
|
|
if os.IsNotExist(err) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// createDBIfNotExist opens the boltdb database at dbPath/name, creating one if
|
|
// one doesn't exist. The boolean returned indicates if the database did not
|
|
// exist before, or if it has been created but no version metadata exists within
|
|
// it.
|
|
func createDBIfNotExist(dbPath, name string) (*bbolt.DB, bool, error) {
|
|
path := filepath.Join(dbPath, name)
|
|
|
|
// If the database file doesn't exist, this indicates we much initialize
|
|
// a fresh database with the latest version.
|
|
firstInit := !fileExists(path)
|
|
if firstInit {
|
|
// Ensure all parent directories are initialized.
|
|
err := os.MkdirAll(dbPath, 0700)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
}
|
|
|
|
bdb, err := bbolt.Open(path, dbFilePermission, nil)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
// If the file existed previously, we'll now check to see that the
|
|
// metadata bucket is properly initialized. It could be the case that
|
|
// the database was created, but we failed to actually populate any
|
|
// metadata. If the metadata bucket does not actually exist, we'll
|
|
// set firstInit to true so that we can treat is initialize the bucket.
|
|
if !firstInit {
|
|
var metadataExists bool
|
|
err = bdb.View(func(tx *bbolt.Tx) error {
|
|
metadataExists = tx.Bucket(metadataBkt) != nil
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
|
|
if !metadataExists {
|
|
firstInit = true
|
|
}
|
|
}
|
|
|
|
return bdb, firstInit, nil
|
|
}
|