mirror of https://github.com/etcd-io/bbolt.git
Merge pull request #452 from jrick/restore_errors
Introduce errors package and restore API compatibilitypull/457/head
commit
a2395be6b8
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
"go.etcd.io/bbolt/errors"
|
||||
)
|
||||
|
||||
// flock acquires an advisory lock on a file descriptor.
|
||||
|
@ -38,7 +38,7 @@ func flock(db *DB, exclusive bool, timeout time.Duration) error {
|
|||
|
||||
// If we timed out then return an error.
|
||||
if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
|
||||
return common.ErrTimeout
|
||||
return errors.ErrTimeout
|
||||
}
|
||||
|
||||
// Wait for a bit and try again.
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
"go.etcd.io/bbolt/errors"
|
||||
)
|
||||
|
||||
// fdatasync flushes written data to a file descriptor.
|
||||
|
@ -44,7 +44,7 @@ func flock(db *DB, exclusive bool, timeout time.Duration) error {
|
|||
|
||||
// If we timed oumercit then return an error.
|
||||
if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
|
||||
return common.ErrTimeout
|
||||
return errors.ErrTimeout
|
||||
}
|
||||
|
||||
// Wait for a bit and try again.
|
||||
|
|
51
bucket.go
51
bucket.go
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
|
@ -146,11 +147,11 @@ func (b *Bucket) openBucket(value []byte) *Bucket {
|
|||
// The bucket instance is only valid for the lifetime of the transaction.
|
||||
func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
|
||||
if b.tx.db == nil {
|
||||
return nil, common.ErrTxClosed
|
||||
return nil, errors.ErrTxClosed
|
||||
} else if !b.tx.writable {
|
||||
return nil, common.ErrTxNotWritable
|
||||
return nil, errors.ErrTxNotWritable
|
||||
} else if len(key) == 0 {
|
||||
return nil, common.ErrBucketNameRequired
|
||||
return nil, errors.ErrBucketNameRequired
|
||||
}
|
||||
|
||||
// Move cursor to correct position.
|
||||
|
@ -160,9 +161,9 @@ func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
|
|||
// Return an error if there is an existing key.
|
||||
if bytes.Equal(key, k) {
|
||||
if (flags & common.BucketLeafFlag) != 0 {
|
||||
return nil, common.ErrBucketExists
|
||||
return nil, errors.ErrBucketExists
|
||||
}
|
||||
return nil, common.ErrIncompatibleValue
|
||||
return nil, errors.ErrIncompatibleValue
|
||||
}
|
||||
|
||||
// Create empty, inline bucket.
|
||||
|
@ -190,7 +191,7 @@ func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
|
|||
// The bucket instance is only valid for the lifetime of the transaction.
|
||||
func (b *Bucket) CreateBucketIfNotExists(key []byte) (*Bucket, error) {
|
||||
child, err := b.CreateBucket(key)
|
||||
if err == common.ErrBucketExists {
|
||||
if err == errors.ErrBucketExists {
|
||||
return b.Bucket(key), nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
|
@ -202,9 +203,9 @@ func (b *Bucket) CreateBucketIfNotExists(key []byte) (*Bucket, error) {
|
|||
// Returns an error if the bucket does not exist, or if the key represents a non-bucket value.
|
||||
func (b *Bucket) DeleteBucket(key []byte) error {
|
||||
if b.tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
} else if !b.Writable() {
|
||||
return common.ErrTxNotWritable
|
||||
return errors.ErrTxNotWritable
|
||||
}
|
||||
|
||||
// Move cursor to correct position.
|
||||
|
@ -213,9 +214,9 @@ func (b *Bucket) DeleteBucket(key []byte) error {
|
|||
|
||||
// Return an error if bucket doesn't exist or is not a bucket.
|
||||
if !bytes.Equal(key, k) {
|
||||
return common.ErrBucketNotFound
|
||||
return errors.ErrBucketNotFound
|
||||
} else if (flags & common.BucketLeafFlag) == 0 {
|
||||
return common.ErrIncompatibleValue
|
||||
return errors.ErrIncompatibleValue
|
||||
}
|
||||
|
||||
// Recursively delete all child buckets.
|
||||
|
@ -268,15 +269,15 @@ func (b *Bucket) Get(key []byte) []byte {
|
|||
// Returns an error if the bucket was created from a read-only transaction, if the key is blank, if the key is too large, or if the value is too large.
|
||||
func (b *Bucket) Put(key []byte, value []byte) error {
|
||||
if b.tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
} else if !b.Writable() {
|
||||
return common.ErrTxNotWritable
|
||||
return errors.ErrTxNotWritable
|
||||
} else if len(key) == 0 {
|
||||
return common.ErrKeyRequired
|
||||
return errors.ErrKeyRequired
|
||||
} else if len(key) > MaxKeySize {
|
||||
return common.ErrKeyTooLarge
|
||||
return errors.ErrKeyTooLarge
|
||||
} else if int64(len(value)) > MaxValueSize {
|
||||
return common.ErrValueTooLarge
|
||||
return errors.ErrValueTooLarge
|
||||
}
|
||||
|
||||
// Move cursor to correct position.
|
||||
|
@ -285,7 +286,7 @@ func (b *Bucket) Put(key []byte, value []byte) error {
|
|||
|
||||
// Return an error if there is an existing key with a bucket value.
|
||||
if bytes.Equal(key, k) && (flags&common.BucketLeafFlag) != 0 {
|
||||
return common.ErrIncompatibleValue
|
||||
return errors.ErrIncompatibleValue
|
||||
}
|
||||
|
||||
// Insert into node.
|
||||
|
@ -300,9 +301,9 @@ func (b *Bucket) Put(key []byte, value []byte) error {
|
|||
// Returns an error if the bucket was created from a read-only transaction.
|
||||
func (b *Bucket) Delete(key []byte) error {
|
||||
if b.tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
} else if !b.Writable() {
|
||||
return common.ErrTxNotWritable
|
||||
return errors.ErrTxNotWritable
|
||||
}
|
||||
|
||||
// Move cursor to correct position.
|
||||
|
@ -316,7 +317,7 @@ func (b *Bucket) Delete(key []byte) error {
|
|||
|
||||
// Return an error if there is already existing bucket value.
|
||||
if (flags & common.BucketLeafFlag) != 0 {
|
||||
return common.ErrIncompatibleValue
|
||||
return errors.ErrIncompatibleValue
|
||||
}
|
||||
|
||||
// Delete the node if we have a matching key.
|
||||
|
@ -333,9 +334,9 @@ func (b *Bucket) Sequence() uint64 {
|
|||
// SetSequence updates the sequence number for the bucket.
|
||||
func (b *Bucket) SetSequence(v uint64) error {
|
||||
if b.tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
} else if !b.Writable() {
|
||||
return common.ErrTxNotWritable
|
||||
return errors.ErrTxNotWritable
|
||||
}
|
||||
|
||||
// Materialize the root node if it hasn't been already so that the
|
||||
|
@ -352,9 +353,9 @@ func (b *Bucket) SetSequence(v uint64) error {
|
|||
// NextSequence returns an autoincrementing integer for the bucket.
|
||||
func (b *Bucket) NextSequence() (uint64, error) {
|
||||
if b.tx.db == nil {
|
||||
return 0, common.ErrTxClosed
|
||||
return 0, errors.ErrTxClosed
|
||||
} else if !b.Writable() {
|
||||
return 0, common.ErrTxNotWritable
|
||||
return 0, errors.ErrTxNotWritable
|
||||
}
|
||||
|
||||
// Materialize the root node if it hasn't been already so that the
|
||||
|
@ -375,7 +376,7 @@ func (b *Bucket) NextSequence() (uint64, error) {
|
|||
// the bucket; this will result in undefined behavior.
|
||||
func (b *Bucket) ForEach(fn func(k, v []byte) error) error {
|
||||
if b.tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
}
|
||||
c := b.Cursor()
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
|
@ -388,7 +389,7 @@ func (b *Bucket) ForEach(fn func(k, v []byte) error) error {
|
|||
|
||||
func (b *Bucket) ForEachBucket(fn func(k []byte) error) error {
|
||||
if b.tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
}
|
||||
c := b.Cursor()
|
||||
for k, _, flags := c.first(); k != nil; k, _, flags = c.next() {
|
||||
|
|
|
@ -17,8 +17,8 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
bolt "go.etcd.io/bbolt"
|
||||
berrors "go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/btesting"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
// Ensure that a bucket that gets a non-existent key returns nil.
|
||||
|
@ -247,7 +247,7 @@ func TestBucket_Put_IncompatibleValue(t *testing.T) {
|
|||
if _, err := tx.Bucket([]byte("widgets")).CreateBucket([]byte("foo")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b0.Put([]byte("foo"), []byte("bar")); err != common.ErrIncompatibleValue {
|
||||
if err := b0.Put([]byte("foo"), []byte("bar")); err != berrors.ErrIncompatibleValue {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -273,7 +273,7 @@ func TestBucket_Put_Closed(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := b.Put([]byte("foo"), []byte("bar")); err != common.ErrTxClosed {
|
||||
if err := b.Put([]byte("foo"), []byte("bar")); err != berrors.ErrTxClosed {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ func TestBucket_Put_ReadOnly(t *testing.T) {
|
|||
|
||||
if err := db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte("widgets"))
|
||||
if err := b.Put([]byte("foo"), []byte("bar")); err != common.ErrTxNotWritable {
|
||||
if err := b.Put([]byte("foo"), []byte("bar")); err != berrors.ErrTxNotWritable {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -561,7 +561,7 @@ func TestBucket_Delete_Bucket(t *testing.T) {
|
|||
if _, err := b.CreateBucket([]byte("foo")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b.Delete([]byte("foo")); err != common.ErrIncompatibleValue {
|
||||
if err := b.Delete([]byte("foo")); err != berrors.ErrIncompatibleValue {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -584,7 +584,7 @@ func TestBucket_Delete_ReadOnly(t *testing.T) {
|
|||
}
|
||||
|
||||
if err := db.View(func(tx *bolt.Tx) error {
|
||||
if err := tx.Bucket([]byte("widgets")).Delete([]byte("foo")); err != common.ErrTxNotWritable {
|
||||
if err := tx.Bucket([]byte("widgets")).Delete([]byte("foo")); err != berrors.ErrTxNotWritable {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -610,7 +610,7 @@ func TestBucket_Delete_Closed(t *testing.T) {
|
|||
if err := tx.Rollback(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b.Delete([]byte("foo")); err != common.ErrTxClosed {
|
||||
if err := b.Delete([]byte("foo")); err != berrors.ErrTxClosed {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -781,7 +781,7 @@ func TestBucket_CreateBucket_IncompatibleValue(t *testing.T) {
|
|||
if err := widgets.Put([]byte("foo"), []byte("bar")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := widgets.CreateBucket([]byte("foo")); err != common.ErrIncompatibleValue {
|
||||
if _, err := widgets.CreateBucket([]byte("foo")); err != berrors.ErrIncompatibleValue {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -802,7 +802,7 @@ func TestBucket_DeleteBucket_IncompatibleValue(t *testing.T) {
|
|||
if err := widgets.Put([]byte("foo"), []byte("bar")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := tx.Bucket([]byte("widgets")).DeleteBucket([]byte("foo")); err != common.ErrIncompatibleValue {
|
||||
if err := tx.Bucket([]byte("widgets")).DeleteBucket([]byte("foo")); err != berrors.ErrIncompatibleValue {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -944,7 +944,7 @@ func TestBucket_NextSequence_ReadOnly(t *testing.T) {
|
|||
|
||||
if err := db.View(func(tx *bolt.Tx) error {
|
||||
_, err := tx.Bucket([]byte("widgets")).NextSequence()
|
||||
if err != common.ErrTxNotWritable {
|
||||
if err != berrors.ErrTxNotWritable {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -967,7 +967,7 @@ func TestBucket_NextSequence_Closed(t *testing.T) {
|
|||
if err := tx.Rollback(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := b.NextSequence(); err != common.ErrTxClosed {
|
||||
if _, err := b.NextSequence(); err != berrors.ErrTxClosed {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -1159,7 +1159,7 @@ func TestBucket_ForEach_Closed(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := b.ForEach(func(k, v []byte) error { return nil }); err != common.ErrTxClosed {
|
||||
if err := b.ForEach(func(k, v []byte) error { return nil }); err != berrors.ErrTxClosed {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -1173,10 +1173,10 @@ func TestBucket_Put_EmptyKey(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b.Put([]byte(""), []byte("bar")); err != common.ErrKeyRequired {
|
||||
if err := b.Put([]byte(""), []byte("bar")); err != berrors.ErrKeyRequired {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if err := b.Put(nil, []byte("bar")); err != common.ErrKeyRequired {
|
||||
if err := b.Put(nil, []byte("bar")); err != berrors.ErrKeyRequired {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -1193,7 +1193,7 @@ func TestBucket_Put_KeyTooLarge(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b.Put(make([]byte, 32769), []byte("bar")); err != common.ErrKeyTooLarge {
|
||||
if err := b.Put(make([]byte, 32769), []byte("bar")); err != berrors.ErrKeyTooLarge {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -1216,7 +1216,7 @@ func TestBucket_Put_ValueTooLarge(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := b.Put([]byte("foo"), make([]byte, bolt.MaxValueSize+1)); err != common.ErrValueTooLarge {
|
||||
if err := b.Put([]byte("foo"), make([]byte, bolt.MaxValueSize+1)); err != berrors.ErrValueTooLarge {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"unicode/utf8"
|
||||
|
||||
bolt "go.etcd.io/bbolt"
|
||||
berrors "go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
"go.etcd.io/bbolt/internal/guts_cli"
|
||||
)
|
||||
|
@ -941,12 +942,12 @@ func (cmd *keysCommand) Run(args ...string) error {
|
|||
// Find bucket.
|
||||
var lastbucket *bolt.Bucket = tx.Bucket([]byte(buckets[0]))
|
||||
if lastbucket == nil {
|
||||
return common.ErrBucketNotFound
|
||||
return berrors.ErrBucketNotFound
|
||||
}
|
||||
for _, bucket := range buckets[1:] {
|
||||
lastbucket = lastbucket.Bucket([]byte(bucket))
|
||||
if lastbucket == nil {
|
||||
return common.ErrBucketNotFound
|
||||
return berrors.ErrBucketNotFound
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1017,7 +1018,7 @@ func (cmd *getCommand) Run(args ...string) error {
|
|||
} else if len(buckets) == 0 {
|
||||
return ErrBucketRequired
|
||||
} else if len(key) == 0 {
|
||||
return common.ErrKeyRequired
|
||||
return berrors.ErrKeyRequired
|
||||
}
|
||||
|
||||
// Open database.
|
||||
|
@ -1032,12 +1033,12 @@ func (cmd *getCommand) Run(args ...string) error {
|
|||
// Find bucket.
|
||||
var lastbucket *bolt.Bucket = tx.Bucket([]byte(buckets[0]))
|
||||
if lastbucket == nil {
|
||||
return common.ErrBucketNotFound
|
||||
return berrors.ErrBucketNotFound
|
||||
}
|
||||
for _, bucket := range buckets[1:] {
|
||||
lastbucket = lastbucket.Bucket([]byte(bucket))
|
||||
if lastbucket == nil {
|
||||
return common.ErrBucketNotFound
|
||||
return berrors.ErrBucketNotFound
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"sort"
|
||||
|
||||
"go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
|
@ -138,15 +139,15 @@ func (c *Cursor) Seek(seek []byte) (key []byte, value []byte) {
|
|||
// Delete fails if current key/value is a bucket or if the transaction is not writable.
|
||||
func (c *Cursor) Delete() error {
|
||||
if c.bucket.tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
} else if !c.bucket.Writable() {
|
||||
return common.ErrTxNotWritable
|
||||
return errors.ErrTxNotWritable
|
||||
}
|
||||
|
||||
key, _, flags := c.keyValue()
|
||||
// Return an error if current value is a bucket.
|
||||
if (flags & common.BucketLeafFlag) != 0 {
|
||||
return common.ErrIncompatibleValue
|
||||
return errors.ErrIncompatibleValue
|
||||
}
|
||||
c.node().del(key)
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ import (
|
|||
"testing/quick"
|
||||
|
||||
bolt "go.etcd.io/bbolt"
|
||||
"go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/btesting"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
// Ensure that a cursor can return a reference to the bucket that created it.
|
||||
|
@ -140,7 +140,7 @@ func TestCursor_Delete(t *testing.T) {
|
|||
}
|
||||
|
||||
c.Seek([]byte("sub"))
|
||||
if err := c.Delete(); err != common.ErrIncompatibleValue {
|
||||
if err := c.Delete(); err != errors.ErrIncompatibleValue {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
|
|
19
db.go
19
db.go
|
@ -11,6 +11,7 @@ import (
|
|||
"time"
|
||||
"unsafe"
|
||||
|
||||
berrors "go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
|
@ -233,7 +234,7 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
|
|||
db.pageSize = pgSize
|
||||
} else {
|
||||
_ = db.close()
|
||||
return nil, common.ErrInvalid
|
||||
return nil, berrors.ErrInvalid
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +312,7 @@ func (db *DB) getPageSize() (int, error) {
|
|||
return db.pageSize, nil
|
||||
}
|
||||
|
||||
return 0, common.ErrInvalid
|
||||
return 0, berrors.ErrInvalid
|
||||
}
|
||||
|
||||
// getPageSizeFromFirstMeta reads the pageSize from the first meta page
|
||||
|
@ -324,7 +325,7 @@ func (db *DB) getPageSizeFromFirstMeta() (int, bool, error) {
|
|||
return int(m.PageSize()), metaCanRead, nil
|
||||
}
|
||||
}
|
||||
return 0, metaCanRead, common.ErrInvalid
|
||||
return 0, metaCanRead, berrors.ErrInvalid
|
||||
}
|
||||
|
||||
// getPageSizeFromSecondMeta reads the pageSize from the second meta page
|
||||
|
@ -362,7 +363,7 @@ func (db *DB) getPageSizeFromSecondMeta() (int, bool, error) {
|
|||
}
|
||||
}
|
||||
|
||||
return 0, metaCanRead, common.ErrInvalid
|
||||
return 0, metaCanRead, berrors.ErrInvalid
|
||||
}
|
||||
|
||||
// loadFreelist reads the freelist if it is synced, or reconstructs it
|
||||
|
@ -697,14 +698,14 @@ func (db *DB) beginTx() (*Tx, error) {
|
|||
if !db.opened {
|
||||
db.mmaplock.RUnlock()
|
||||
db.metalock.Unlock()
|
||||
return nil, common.ErrDatabaseNotOpen
|
||||
return nil, berrors.ErrDatabaseNotOpen
|
||||
}
|
||||
|
||||
// Exit if the database is not correctly mapped.
|
||||
if db.data == nil {
|
||||
db.mmaplock.RUnlock()
|
||||
db.metalock.Unlock()
|
||||
return nil, common.ErrInvalidMapping
|
||||
return nil, berrors.ErrInvalidMapping
|
||||
}
|
||||
|
||||
// Create a transaction associated with the database.
|
||||
|
@ -730,7 +731,7 @@ func (db *DB) beginTx() (*Tx, error) {
|
|||
func (db *DB) beginRWTx() (*Tx, error) {
|
||||
// If the database was opened with Options.ReadOnly, return an error.
|
||||
if db.readOnly {
|
||||
return nil, common.ErrDatabaseReadOnly
|
||||
return nil, berrors.ErrDatabaseReadOnly
|
||||
}
|
||||
|
||||
// Obtain writer lock. This is released by the transaction when it closes.
|
||||
|
@ -745,13 +746,13 @@ func (db *DB) beginRWTx() (*Tx, error) {
|
|||
// Exit if the database is not open yet.
|
||||
if !db.opened {
|
||||
db.rwlock.Unlock()
|
||||
return nil, common.ErrDatabaseNotOpen
|
||||
return nil, berrors.ErrDatabaseNotOpen
|
||||
}
|
||||
|
||||
// Exit if the database is not correctly mapped.
|
||||
if db.data == nil {
|
||||
db.rwlock.Unlock()
|
||||
return nil, common.ErrInvalidMapping
|
||||
return nil, berrors.ErrInvalidMapping
|
||||
}
|
||||
|
||||
// Create a transaction associated with the database.
|
||||
|
|
16
db_test.go
16
db_test.go
|
@ -20,8 +20,8 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
bolt "go.etcd.io/bbolt"
|
||||
berrors "go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/btesting"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
// pageSize is the size of one page in the data file.
|
||||
|
@ -137,7 +137,7 @@ func TestOpen_ErrInvalid(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := bolt.Open(path, 0666, nil); err != common.ErrInvalid {
|
||||
if _, err := bolt.Open(path, 0666, nil); err != berrors.ErrInvalid {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ func TestOpen_ErrVersionMismatch(t *testing.T) {
|
|||
}
|
||||
|
||||
// Reopen data file.
|
||||
if _, err := bolt.Open(path, 0666, nil); err != common.ErrVersionMismatch {
|
||||
if _, err := bolt.Open(path, 0666, nil); err != berrors.ErrVersionMismatch {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ func TestOpen_ErrChecksum(t *testing.T) {
|
|||
}
|
||||
|
||||
// Reopen data file.
|
||||
if _, err := bolt.Open(path, 0666, nil); err != common.ErrChecksum {
|
||||
if _, err := bolt.Open(path, 0666, nil); err != berrors.ErrChecksum {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ func TestDB_Open_ReadOnly(t *testing.T) {
|
|||
}
|
||||
|
||||
// Can't launch read-write transaction.
|
||||
if _, err := readOnlyDB.Begin(true); err != common.ErrDatabaseReadOnly {
|
||||
if _, err := readOnlyDB.Begin(true); err != berrors.ErrDatabaseReadOnly {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
|
@ -642,7 +642,7 @@ func TestOpen_RecoverFreeList(t *testing.T) {
|
|||
// Ensure that a database cannot open a transaction when it's not open.
|
||||
func TestDB_Begin_ErrDatabaseNotOpen(t *testing.T) {
|
||||
var db bolt.DB
|
||||
if _, err := db.Begin(false); err != common.ErrDatabaseNotOpen {
|
||||
if _, err := db.Begin(false); err != berrors.ErrDatabaseNotOpen {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -728,7 +728,7 @@ func TestDB_Concurrent_WriteTo(t *testing.T) {
|
|||
// Ensure that opening a transaction while the DB is closed returns an error.
|
||||
func TestDB_BeginRW_Closed(t *testing.T) {
|
||||
var db bolt.DB
|
||||
if _, err := db.Begin(true); err != common.ErrDatabaseNotOpen {
|
||||
if _, err := db.Begin(true); err != berrors.ErrDatabaseNotOpen {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -832,7 +832,7 @@ func TestDB_Update_Closed(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
return nil
|
||||
}); err != common.ErrDatabaseNotOpen {
|
||||
}); err != berrors.ErrDatabaseNotOpen {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
"go.etcd.io/bbolt/errors"
|
||||
)
|
||||
|
||||
func TestOpenWithPreLoadFreelist(t *testing.T) {
|
||||
|
@ -78,7 +78,7 @@ func TestMethodPage(t *testing.T) {
|
|||
name: "readonly mode without preloading free pages",
|
||||
readonly: true,
|
||||
preLoadFreePage: false,
|
||||
expectedError: common.ErrFreePagesNotLoaded,
|
||||
expectedError: errors.ErrFreePagesNotLoaded,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
package bbolt
|
||||
|
||||
import "go.etcd.io/bbolt/errors"
|
||||
|
||||
// These errors can be returned when opening or calling methods on a DB.
|
||||
var (
|
||||
// ErrDatabaseNotOpen is returned when a DB instance is accessed before it
|
||||
// is opened or after it is closed.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrDatabaseNotOpen = errors.ErrDatabaseNotOpen
|
||||
|
||||
// ErrDatabaseOpen is returned when opening a database that is
|
||||
// already open.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrDatabaseOpen = errors.ErrDatabaseOpen
|
||||
|
||||
// ErrInvalid is returned when both meta pages on a database are invalid.
|
||||
// This typically occurs when a file is not a bolt database.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrInvalid = errors.ErrInvalid
|
||||
|
||||
// ErrInvalidMapping is returned when the database file fails to get mapped.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrInvalidMapping = errors.ErrInvalidMapping
|
||||
|
||||
// ErrVersionMismatch is returned when the data file was created with a
|
||||
// different version of Bolt.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrVersionMismatch = errors.ErrVersionMismatch
|
||||
|
||||
// ErrChecksum is returned when either meta page checksum does not match.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrChecksum = errors.ErrChecksum
|
||||
|
||||
// ErrTimeout is returned when a database cannot obtain an exclusive lock
|
||||
// on the data file after the timeout passed to Open().
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrTimeout = errors.ErrTimeout
|
||||
)
|
||||
|
||||
// These errors can occur when beginning or committing a Tx.
|
||||
var (
|
||||
// ErrTxNotWritable is returned when performing a write operation on a
|
||||
// read-only transaction.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrTxNotWritable = errors.ErrTxNotWritable
|
||||
|
||||
// ErrTxClosed is returned when committing or rolling back a transaction
|
||||
// that has already been committed or rolled back.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrTxClosed = errors.ErrTxClosed
|
||||
|
||||
// ErrDatabaseReadOnly is returned when a mutating transaction is started on a
|
||||
// read-only database.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrDatabaseReadOnly = errors.ErrDatabaseReadOnly
|
||||
|
||||
// ErrFreePagesNotLoaded is returned when a readonly transaction without
|
||||
// preloading the free pages is trying to access the free pages.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrFreePagesNotLoaded = errors.ErrFreePagesNotLoaded
|
||||
)
|
||||
|
||||
// These errors can occur when putting or deleting a value or a bucket.
|
||||
var (
|
||||
// ErrBucketNotFound is returned when trying to access a bucket that has
|
||||
// not been created yet.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrBucketNotFound = errors.ErrBucketNotFound
|
||||
|
||||
// ErrBucketExists is returned when creating a bucket that already exists.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrBucketExists = errors.ErrBucketExists
|
||||
|
||||
// ErrBucketNameRequired is returned when creating a bucket with a blank name.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrBucketNameRequired = errors.ErrBucketNameRequired
|
||||
|
||||
// ErrKeyRequired is returned when inserting a zero-length key.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrKeyRequired = errors.ErrKeyRequired
|
||||
|
||||
// ErrKeyTooLarge is returned when inserting a key that is larger than MaxKeySize.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrKeyTooLarge = errors.ErrKeyTooLarge
|
||||
|
||||
// ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrValueTooLarge = errors.ErrValueTooLarge
|
||||
|
||||
// ErrIncompatibleValue is returned when trying create or delete a bucket
|
||||
// on an existing non-bucket key or when trying to create or delete a
|
||||
// non-bucket key on an existing bucket key.
|
||||
//
|
||||
// Deprecated: Use the error variables defined in the bbolt/errors package.
|
||||
ErrIncompatibleValue = errors.ErrIncompatibleValue
|
||||
)
|
|
@ -1,4 +1,6 @@
|
|||
package common
|
||||
// Package errors defines the error variables that may be returned
|
||||
// during bbolt operations.
|
||||
package errors
|
||||
|
||||
import "errors"
|
||||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"hash/fnv"
|
||||
"io"
|
||||
"unsafe"
|
||||
|
||||
"go.etcd.io/bbolt/errors"
|
||||
)
|
||||
|
||||
type Meta struct {
|
||||
|
@ -22,11 +24,11 @@ type Meta struct {
|
|||
// Validate checks the marker bytes and version of the meta page to ensure it matches this binary.
|
||||
func (m *Meta) Validate() error {
|
||||
if m.magic != Magic {
|
||||
return ErrInvalid
|
||||
return errors.ErrInvalid
|
||||
} else if m.version != Version {
|
||||
return ErrVersionMismatch
|
||||
return errors.ErrVersionMismatch
|
||||
} else if m.checksum != m.Sum64() {
|
||||
return ErrChecksum
|
||||
return errors.ErrChecksum
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
11
tx.go
11
tx.go
|
@ -10,6 +10,7 @@ import (
|
|||
"time"
|
||||
"unsafe"
|
||||
|
||||
"go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
|
@ -141,9 +142,9 @@ func (tx *Tx) OnCommit(fn func()) {
|
|||
func (tx *Tx) Commit() error {
|
||||
common.Assert(!tx.managed, "managed tx commit not allowed")
|
||||
if tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
} else if !tx.writable {
|
||||
return common.ErrTxNotWritable
|
||||
return errors.ErrTxNotWritable
|
||||
}
|
||||
|
||||
// TODO(benbjohnson): Use vectorized I/O to write out dirty pages.
|
||||
|
@ -253,7 +254,7 @@ func (tx *Tx) commitFreelist() error {
|
|||
func (tx *Tx) Rollback() error {
|
||||
common.Assert(!tx.managed, "managed tx rollback not allowed")
|
||||
if tx.db == nil {
|
||||
return common.ErrTxClosed
|
||||
return errors.ErrTxClosed
|
||||
}
|
||||
tx.nonPhysicalRollback()
|
||||
return nil
|
||||
|
@ -560,13 +561,13 @@ func (tx *Tx) forEachPageInternal(pgidstack []common.Pgid, fn func(*common.Page,
|
|||
// This is only safe for concurrent use when used by a writable transaction.
|
||||
func (tx *Tx) Page(id int) (*common.PageInfo, error) {
|
||||
if tx.db == nil {
|
||||
return nil, common.ErrTxClosed
|
||||
return nil, errors.ErrTxClosed
|
||||
} else if common.Pgid(id) >= tx.meta.Pgid() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if tx.db.freelist == nil {
|
||||
return nil, common.ErrFreePagesNotLoaded
|
||||
return nil, errors.ErrFreePagesNotLoaded
|
||||
}
|
||||
|
||||
// Build the page info.
|
||||
|
|
26
tx_test.go
26
tx_test.go
|
@ -14,8 +14,8 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
bolt "go.etcd.io/bbolt"
|
||||
berrors "go.etcd.io/bbolt/errors"
|
||||
"go.etcd.io/bbolt/internal/btesting"
|
||||
"go.etcd.io/bbolt/internal/common"
|
||||
)
|
||||
|
||||
// TestTx_Check_ReadOnly tests consistency checking on a ReadOnly database.
|
||||
|
@ -85,7 +85,7 @@ func TestTx_Commit_ErrTxClosed(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != common.ErrTxClosed {
|
||||
if err := tx.Commit(); err != berrors.ErrTxClosed {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ func TestTx_Rollback_ErrTxClosed(t *testing.T) {
|
|||
if err := tx.Rollback(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := tx.Rollback(); err != common.ErrTxClosed {
|
||||
if err := tx.Rollback(); err != berrors.ErrTxClosed {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ func TestTx_Commit_ErrTxNotWritable(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := tx.Commit(); err != common.ErrTxNotWritable {
|
||||
if err := tx.Commit(); err != berrors.ErrTxNotWritable {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Close the view transaction
|
||||
|
@ -166,7 +166,7 @@ func TestTx_CreateBucket_ErrTxNotWritable(t *testing.T) {
|
|||
db := btesting.MustCreateDB(t)
|
||||
if err := db.View(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucket([]byte("foo"))
|
||||
if err != common.ErrTxNotWritable {
|
||||
if err != berrors.ErrTxNotWritable {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -186,7 +186,7 @@ func TestTx_CreateBucket_ErrTxClosed(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := tx.CreateBucket([]byte("foo")); err != common.ErrTxClosed {
|
||||
if _, err := tx.CreateBucket([]byte("foo")); err != berrors.ErrTxClosed {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -294,11 +294,11 @@ func TestTx_CreateBucketIfNotExists(t *testing.T) {
|
|||
func TestTx_CreateBucketIfNotExists_ErrBucketNameRequired(t *testing.T) {
|
||||
db := btesting.MustCreateDB(t)
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
if _, err := tx.CreateBucketIfNotExists([]byte{}); err != common.ErrBucketNameRequired {
|
||||
if _, err := tx.CreateBucketIfNotExists([]byte{}); err != berrors.ErrBucketNameRequired {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
if _, err := tx.CreateBucketIfNotExists(nil); err != common.ErrBucketNameRequired {
|
||||
if _, err := tx.CreateBucketIfNotExists(nil); err != berrors.ErrBucketNameRequired {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ func TestTx_CreateBucket_ErrBucketExists(t *testing.T) {
|
|||
|
||||
// Create the same bucket again.
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
if _, err := tx.CreateBucket([]byte("widgets")); err != common.ErrBucketExists {
|
||||
if _, err := tx.CreateBucket([]byte("widgets")); err != berrors.ErrBucketExists {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -337,7 +337,7 @@ func TestTx_CreateBucket_ErrBucketExists(t *testing.T) {
|
|||
func TestTx_CreateBucket_ErrBucketNameRequired(t *testing.T) {
|
||||
db := btesting.MustCreateDB(t)
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
if _, err := tx.CreateBucket(nil); err != common.ErrBucketNameRequired {
|
||||
if _, err := tx.CreateBucket(nil); err != berrors.ErrBucketNameRequired {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -402,7 +402,7 @@ func TestTx_DeleteBucket_ErrTxClosed(t *testing.T) {
|
|||
if err := tx.Commit(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := tx.DeleteBucket([]byte("foo")); err != common.ErrTxClosed {
|
||||
if err := tx.DeleteBucket([]byte("foo")); err != berrors.ErrTxClosed {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ func TestTx_DeleteBucket_ErrTxClosed(t *testing.T) {
|
|||
func TestTx_DeleteBucket_ReadOnly(t *testing.T) {
|
||||
db := btesting.MustCreateDB(t)
|
||||
if err := db.View(func(tx *bolt.Tx) error {
|
||||
if err := tx.DeleteBucket([]byte("foo")); err != common.ErrTxNotWritable {
|
||||
if err := tx.DeleteBucket([]byte("foo")); err != berrors.ErrTxNotWritable {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
@ -424,7 +424,7 @@ func TestTx_DeleteBucket_ReadOnly(t *testing.T) {
|
|||
func TestTx_DeleteBucket_NotFound(t *testing.T) {
|
||||
db := btesting.MustCreateDB(t)
|
||||
if err := db.Update(func(tx *bolt.Tx) error {
|
||||
if err := tx.DeleteBucket([]byte("widgets")); err != common.ErrBucketNotFound {
|
||||
if err := tx.DeleteBucket([]byte("widgets")); err != berrors.ErrBucketNotFound {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue