2016-11-22 23:50:27 +03:00
|
|
|
package channeldb
|
|
|
|
|
|
|
|
import (
|
2018-03-11 06:00:57 +03:00
|
|
|
"github.com/coreos/bbolt"
|
2016-11-22 23:50:27 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// metaBucket stores all the meta information concerning the state of
|
|
|
|
// the database.
|
|
|
|
metaBucket = []byte("metadata")
|
|
|
|
|
2016-11-23 00:57:26 +03:00
|
|
|
// dbVersionKey is a boltdb key and it's used for storing/retrieving
|
2016-11-22 23:50:27 +03:00
|
|
|
// current database version.
|
|
|
|
dbVersionKey = []byte("dbp")
|
|
|
|
)
|
|
|
|
|
|
|
|
// Meta structure holds the database meta information.
|
|
|
|
type Meta struct {
|
2016-11-23 00:57:26 +03:00
|
|
|
// DbVersionNumber is the current schema version of the database.
|
|
|
|
DbVersionNumber uint32
|
2016-11-22 23:50:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// FetchMeta fetches the meta data from boltdb and returns filled meta
|
2016-11-28 05:44:14 +03:00
|
|
|
// structure.
|
2016-11-22 23:50:27 +03:00
|
|
|
func (d *DB) FetchMeta(tx *bolt.Tx) (*Meta, error) {
|
|
|
|
meta := &Meta{}
|
|
|
|
|
2016-11-28 05:44:14 +03:00
|
|
|
err := d.View(func(tx *bolt.Tx) error {
|
|
|
|
return fetchMeta(meta, tx)
|
|
|
|
})
|
2016-11-22 23:50:27 +03:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return meta, nil
|
|
|
|
}
|
|
|
|
|
2016-11-28 05:44:14 +03:00
|
|
|
// fetchMeta is an internal helper function used in order to allow callers to
|
|
|
|
// re-use a database transaction. See the publicly exported FetchMeta method
|
|
|
|
// for more information.
|
|
|
|
func fetchMeta(meta *Meta, tx *bolt.Tx) error {
|
|
|
|
metaBucket := tx.Bucket(metaBucket)
|
|
|
|
if metaBucket == nil {
|
|
|
|
return ErrMetaNotFound
|
2016-11-22 23:50:27 +03:00
|
|
|
}
|
|
|
|
|
2016-11-28 05:44:14 +03:00
|
|
|
data := metaBucket.Get(dbVersionKey)
|
|
|
|
if data == nil {
|
|
|
|
meta.DbVersionNumber = getLatestDBVersion(dbVersions)
|
2016-11-22 23:50:27 +03:00
|
|
|
} else {
|
2016-11-28 05:44:14 +03:00
|
|
|
meta.DbVersionNumber = byteOrder.Uint32(data)
|
2016-11-22 23:50:27 +03:00
|
|
|
}
|
2016-11-28 05:44:14 +03:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// PutMeta writes the passed instance of the database met-data struct to disk.
|
|
|
|
func (d *DB) PutMeta(meta *Meta) error {
|
|
|
|
return d.Update(func(tx *bolt.Tx) error {
|
|
|
|
return putMeta(meta, tx)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// putMeta is an internal helper function used in order to allow callers to
|
|
|
|
// re-use a database transaction. See the publicly exported PutMeta method for
|
|
|
|
// more information.
|
|
|
|
func putMeta(meta *Meta, tx *bolt.Tx) error {
|
|
|
|
metaBucket, err := tx.CreateBucketIfNotExists(metaBucket)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return putDbVersion(metaBucket, meta)
|
2016-11-22 23:50:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func putDbVersion(metaBucket *bolt.Bucket, meta *Meta) error {
|
|
|
|
scratch := make([]byte, 4)
|
2016-11-23 00:57:26 +03:00
|
|
|
byteOrder.PutUint32(scratch, meta.DbVersionNumber)
|
2017-02-23 21:59:50 +03:00
|
|
|
return metaBucket.Put(dbVersionKey, scratch)
|
2016-11-22 23:50:27 +03:00
|
|
|
}
|