mirror of https://github.com/etcd-io/bbolt.git
Introduce errors package and restore API compatibility
This moves the error variables that had been moved to the internal/common package during recent refactoring to a non-internal errors package, once again allowing consumers to test for particular error conditions. To preserve API compatibility with bbolt v1.3, these error variables are also redefined in the bbolt package, with deprecation notice to migrate to bbolt/errors. Signed-off-by: Josh Rickmar <jrick@zettaport.com>pull/452/head
parent
6cce7485aa
commit
7a957f94b2
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"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.
|
// 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 we timed out then return an error.
|
||||||
if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
|
if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
|
||||||
return common.ErrTimeout
|
return errors.ErrTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for a bit and try again.
|
// Wait for a bit and try again.
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
"go.etcd.io/bbolt/internal/common"
|
"go.etcd.io/bbolt/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fdatasync flushes written data to a file descriptor.
|
// 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 we timed oumercit then return an error.
|
||||||
if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
|
if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
|
||||||
return common.ErrTimeout
|
return errors.ErrTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for a bit and try again.
|
// Wait for a bit and try again.
|
||||||
|
|
51
bucket.go
51
bucket.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
"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.
|
// The bucket instance is only valid for the lifetime of the transaction.
|
||||||
func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
|
func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return nil, common.ErrTxClosed
|
return nil, errors.ErrTxClosed
|
||||||
} else if !b.tx.writable {
|
} else if !b.tx.writable {
|
||||||
return nil, common.ErrTxNotWritable
|
return nil, errors.ErrTxNotWritable
|
||||||
} else if len(key) == 0 {
|
} else if len(key) == 0 {
|
||||||
return nil, common.ErrBucketNameRequired
|
return nil, errors.ErrBucketNameRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move cursor to correct position.
|
// 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.
|
// Return an error if there is an existing key.
|
||||||
if bytes.Equal(key, k) {
|
if bytes.Equal(key, k) {
|
||||||
if (flags & common.BucketLeafFlag) != 0 {
|
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.
|
// 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.
|
// The bucket instance is only valid for the lifetime of the transaction.
|
||||||
func (b *Bucket) CreateBucketIfNotExists(key []byte) (*Bucket, error) {
|
func (b *Bucket) CreateBucketIfNotExists(key []byte) (*Bucket, error) {
|
||||||
child, err := b.CreateBucket(key)
|
child, err := b.CreateBucket(key)
|
||||||
if err == common.ErrBucketExists {
|
if err == errors.ErrBucketExists {
|
||||||
return b.Bucket(key), nil
|
return b.Bucket(key), nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, err
|
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.
|
// 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 {
|
func (b *Bucket) DeleteBucket(key []byte) error {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
} else if !b.Writable() {
|
} else if !b.Writable() {
|
||||||
return common.ErrTxNotWritable
|
return errors.ErrTxNotWritable
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move cursor to correct position.
|
// 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.
|
// Return an error if bucket doesn't exist or is not a bucket.
|
||||||
if !bytes.Equal(key, k) {
|
if !bytes.Equal(key, k) {
|
||||||
return common.ErrBucketNotFound
|
return errors.ErrBucketNotFound
|
||||||
} else if (flags & common.BucketLeafFlag) == 0 {
|
} else if (flags & common.BucketLeafFlag) == 0 {
|
||||||
return common.ErrIncompatibleValue
|
return errors.ErrIncompatibleValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively delete all child buckets.
|
// 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.
|
// 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 {
|
func (b *Bucket) Put(key []byte, value []byte) error {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
} else if !b.Writable() {
|
} else if !b.Writable() {
|
||||||
return common.ErrTxNotWritable
|
return errors.ErrTxNotWritable
|
||||||
} else if len(key) == 0 {
|
} else if len(key) == 0 {
|
||||||
return common.ErrKeyRequired
|
return errors.ErrKeyRequired
|
||||||
} else if len(key) > MaxKeySize {
|
} else if len(key) > MaxKeySize {
|
||||||
return common.ErrKeyTooLarge
|
return errors.ErrKeyTooLarge
|
||||||
} else if int64(len(value)) > MaxValueSize {
|
} else if int64(len(value)) > MaxValueSize {
|
||||||
return common.ErrValueTooLarge
|
return errors.ErrValueTooLarge
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move cursor to correct position.
|
// 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.
|
// Return an error if there is an existing key with a bucket value.
|
||||||
if bytes.Equal(key, k) && (flags&common.BucketLeafFlag) != 0 {
|
if bytes.Equal(key, k) && (flags&common.BucketLeafFlag) != 0 {
|
||||||
return common.ErrIncompatibleValue
|
return errors.ErrIncompatibleValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert into node.
|
// 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.
|
// Returns an error if the bucket was created from a read-only transaction.
|
||||||
func (b *Bucket) Delete(key []byte) error {
|
func (b *Bucket) Delete(key []byte) error {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
} else if !b.Writable() {
|
} else if !b.Writable() {
|
||||||
return common.ErrTxNotWritable
|
return errors.ErrTxNotWritable
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move cursor to correct position.
|
// 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.
|
// Return an error if there is already existing bucket value.
|
||||||
if (flags & common.BucketLeafFlag) != 0 {
|
if (flags & common.BucketLeafFlag) != 0 {
|
||||||
return common.ErrIncompatibleValue
|
return errors.ErrIncompatibleValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the node if we have a matching key.
|
// 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.
|
// SetSequence updates the sequence number for the bucket.
|
||||||
func (b *Bucket) SetSequence(v uint64) error {
|
func (b *Bucket) SetSequence(v uint64) error {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
} else if !b.Writable() {
|
} else if !b.Writable() {
|
||||||
return common.ErrTxNotWritable
|
return errors.ErrTxNotWritable
|
||||||
}
|
}
|
||||||
|
|
||||||
// Materialize the root node if it hasn't been already so that the
|
// 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.
|
// NextSequence returns an autoincrementing integer for the bucket.
|
||||||
func (b *Bucket) NextSequence() (uint64, error) {
|
func (b *Bucket) NextSequence() (uint64, error) {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return 0, common.ErrTxClosed
|
return 0, errors.ErrTxClosed
|
||||||
} else if !b.Writable() {
|
} 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
|
// 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.
|
// the bucket; this will result in undefined behavior.
|
||||||
func (b *Bucket) ForEach(fn func(k, v []byte) error) error {
|
func (b *Bucket) ForEach(fn func(k, v []byte) error) error {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
}
|
}
|
||||||
c := b.Cursor()
|
c := b.Cursor()
|
||||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
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 {
|
func (b *Bucket) ForEachBucket(fn func(k []byte) error) error {
|
||||||
if b.tx.db == nil {
|
if b.tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
}
|
}
|
||||||
c := b.Cursor()
|
c := b.Cursor()
|
||||||
for k, _, flags := c.first(); k != nil; k, _, flags = c.next() {
|
for k, _, flags := c.first(); k != nil; k, _, flags = c.next() {
|
||||||
|
|
|
@ -17,8 +17,8 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
|
berrors "go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/btesting"
|
"go.etcd.io/bbolt/internal/btesting"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure that a bucket that gets a non-existent key returns nil.
|
// 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 {
|
if _, err := tx.Bucket([]byte("widgets")).CreateBucket([]byte("foo")); err != nil {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -273,7 +273,7 @@ func TestBucket_Put_Closed(t *testing.T) {
|
||||||
t.Fatal(err)
|
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)
|
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 {
|
if err := db.View(func(tx *bolt.Tx) error {
|
||||||
b := tx.Bucket([]byte("widgets"))
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -561,7 +561,7 @@ func TestBucket_Delete_Bucket(t *testing.T) {
|
||||||
if _, err := b.CreateBucket([]byte("foo")); err != nil {
|
if _, err := b.CreateBucket([]byte("foo")); err != nil {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -584,7 +584,7 @@ func TestBucket_Delete_ReadOnly(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := db.View(func(tx *bolt.Tx) error {
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -610,7 +610,7 @@ func TestBucket_Delete_Closed(t *testing.T) {
|
||||||
if err := tx.Rollback(); err != nil {
|
if err := tx.Rollback(); err != nil {
|
||||||
t.Fatal(err)
|
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)
|
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 {
|
if err := widgets.Put([]byte("foo"), []byte("bar")); err != nil {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -802,7 +802,7 @@ func TestBucket_DeleteBucket_IncompatibleValue(t *testing.T) {
|
||||||
if err := widgets.Put([]byte("foo"), []byte("bar")); err != nil {
|
if err := widgets.Put([]byte("foo"), []byte("bar")); err != nil {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -944,7 +944,7 @@ func TestBucket_NextSequence_ReadOnly(t *testing.T) {
|
||||||
|
|
||||||
if err := db.View(func(tx *bolt.Tx) error {
|
if err := db.View(func(tx *bolt.Tx) error {
|
||||||
_, err := tx.Bucket([]byte("widgets")).NextSequence()
|
_, err := tx.Bucket([]byte("widgets")).NextSequence()
|
||||||
if err != common.ErrTxNotWritable {
|
if err != berrors.ErrTxNotWritable {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -967,7 +967,7 @@ func TestBucket_NextSequence_Closed(t *testing.T) {
|
||||||
if err := tx.Rollback(); err != nil {
|
if err := tx.Rollback(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if _, err := b.NextSequence(); err != common.ErrTxClosed {
|
if _, err := b.NextSequence(); err != berrors.ErrTxClosed {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1159,7 +1159,7 @@ func TestBucket_ForEach_Closed(t *testing.T) {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1173,10 +1173,10 @@ func TestBucket_Put_EmptyKey(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -1193,7 +1193,7 @@ func TestBucket_Put_KeyTooLarge(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -1216,7 +1216,7 @@ func TestBucket_Put_ValueTooLarge(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
|
berrors "go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
"go.etcd.io/bbolt/internal/common"
|
||||||
"go.etcd.io/bbolt/internal/guts_cli"
|
"go.etcd.io/bbolt/internal/guts_cli"
|
||||||
)
|
)
|
||||||
|
@ -941,12 +942,12 @@ func (cmd *keysCommand) Run(args ...string) error {
|
||||||
// Find bucket.
|
// Find bucket.
|
||||||
var lastbucket *bolt.Bucket = tx.Bucket([]byte(buckets[0]))
|
var lastbucket *bolt.Bucket = tx.Bucket([]byte(buckets[0]))
|
||||||
if lastbucket == nil {
|
if lastbucket == nil {
|
||||||
return common.ErrBucketNotFound
|
return berrors.ErrBucketNotFound
|
||||||
}
|
}
|
||||||
for _, bucket := range buckets[1:] {
|
for _, bucket := range buckets[1:] {
|
||||||
lastbucket = lastbucket.Bucket([]byte(bucket))
|
lastbucket = lastbucket.Bucket([]byte(bucket))
|
||||||
if lastbucket == nil {
|
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 {
|
} else if len(buckets) == 0 {
|
||||||
return ErrBucketRequired
|
return ErrBucketRequired
|
||||||
} else if len(key) == 0 {
|
} else if len(key) == 0 {
|
||||||
return common.ErrKeyRequired
|
return berrors.ErrKeyRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open database.
|
// Open database.
|
||||||
|
@ -1032,12 +1033,12 @@ func (cmd *getCommand) Run(args ...string) error {
|
||||||
// Find bucket.
|
// Find bucket.
|
||||||
var lastbucket *bolt.Bucket = tx.Bucket([]byte(buckets[0]))
|
var lastbucket *bolt.Bucket = tx.Bucket([]byte(buckets[0]))
|
||||||
if lastbucket == nil {
|
if lastbucket == nil {
|
||||||
return common.ErrBucketNotFound
|
return berrors.ErrBucketNotFound
|
||||||
}
|
}
|
||||||
for _, bucket := range buckets[1:] {
|
for _, bucket := range buckets[1:] {
|
||||||
lastbucket = lastbucket.Bucket([]byte(bucket))
|
lastbucket = lastbucket.Bucket([]byte(bucket))
|
||||||
if lastbucket == nil {
|
if lastbucket == nil {
|
||||||
return common.ErrBucketNotFound
|
return berrors.ErrBucketNotFound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
"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.
|
// Delete fails if current key/value is a bucket or if the transaction is not writable.
|
||||||
func (c *Cursor) Delete() error {
|
func (c *Cursor) Delete() error {
|
||||||
if c.bucket.tx.db == nil {
|
if c.bucket.tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
} else if !c.bucket.Writable() {
|
} else if !c.bucket.Writable() {
|
||||||
return common.ErrTxNotWritable
|
return errors.ErrTxNotWritable
|
||||||
}
|
}
|
||||||
|
|
||||||
key, _, flags := c.keyValue()
|
key, _, flags := c.keyValue()
|
||||||
// Return an error if current value is a bucket.
|
// Return an error if current value is a bucket.
|
||||||
if (flags & common.BucketLeafFlag) != 0 {
|
if (flags & common.BucketLeafFlag) != 0 {
|
||||||
return common.ErrIncompatibleValue
|
return errors.ErrIncompatibleValue
|
||||||
}
|
}
|
||||||
c.node().del(key)
|
c.node().del(key)
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"testing/quick"
|
"testing/quick"
|
||||||
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
|
"go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/btesting"
|
"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.
|
// 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"))
|
c.Seek([]byte("sub"))
|
||||||
if err := c.Delete(); err != common.ErrIncompatibleValue {
|
if err := c.Delete(); err != errors.ErrIncompatibleValue {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
19
db.go
19
db.go
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
berrors "go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
"go.etcd.io/bbolt/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -233,7 +234,7 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
|
||||||
db.pageSize = pgSize
|
db.pageSize = pgSize
|
||||||
} else {
|
} else {
|
||||||
_ = db.close()
|
_ = 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 db.pageSize, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, common.ErrInvalid
|
return 0, berrors.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPageSizeFromFirstMeta reads the pageSize from the first meta page
|
// 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 int(m.PageSize()), metaCanRead, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0, metaCanRead, common.ErrInvalid
|
return 0, metaCanRead, berrors.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPageSizeFromSecondMeta reads the pageSize from the second meta page
|
// 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
|
// loadFreelist reads the freelist if it is synced, or reconstructs it
|
||||||
|
@ -697,14 +698,14 @@ func (db *DB) beginTx() (*Tx, error) {
|
||||||
if !db.opened {
|
if !db.opened {
|
||||||
db.mmaplock.RUnlock()
|
db.mmaplock.RUnlock()
|
||||||
db.metalock.Unlock()
|
db.metalock.Unlock()
|
||||||
return nil, common.ErrDatabaseNotOpen
|
return nil, berrors.ErrDatabaseNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit if the database is not correctly mapped.
|
// Exit if the database is not correctly mapped.
|
||||||
if db.data == nil {
|
if db.data == nil {
|
||||||
db.mmaplock.RUnlock()
|
db.mmaplock.RUnlock()
|
||||||
db.metalock.Unlock()
|
db.metalock.Unlock()
|
||||||
return nil, common.ErrInvalidMapping
|
return nil, berrors.ErrInvalidMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a transaction associated with the database.
|
// Create a transaction associated with the database.
|
||||||
|
@ -730,7 +731,7 @@ func (db *DB) beginTx() (*Tx, error) {
|
||||||
func (db *DB) beginRWTx() (*Tx, error) {
|
func (db *DB) beginRWTx() (*Tx, error) {
|
||||||
// If the database was opened with Options.ReadOnly, return an error.
|
// If the database was opened with Options.ReadOnly, return an error.
|
||||||
if db.readOnly {
|
if db.readOnly {
|
||||||
return nil, common.ErrDatabaseReadOnly
|
return nil, berrors.ErrDatabaseReadOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain writer lock. This is released by the transaction when it closes.
|
// 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.
|
// Exit if the database is not open yet.
|
||||||
if !db.opened {
|
if !db.opened {
|
||||||
db.rwlock.Unlock()
|
db.rwlock.Unlock()
|
||||||
return nil, common.ErrDatabaseNotOpen
|
return nil, berrors.ErrDatabaseNotOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit if the database is not correctly mapped.
|
// Exit if the database is not correctly mapped.
|
||||||
if db.data == nil {
|
if db.data == nil {
|
||||||
db.rwlock.Unlock()
|
db.rwlock.Unlock()
|
||||||
return nil, common.ErrInvalidMapping
|
return nil, berrors.ErrInvalidMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a transaction associated with the database.
|
// 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"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
|
berrors "go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/btesting"
|
"go.etcd.io/bbolt/internal/btesting"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// pageSize is the size of one page in the data file.
|
// pageSize is the size of one page in the data file.
|
||||||
|
@ -137,7 +137,7 @@ func TestOpen_ErrInvalid(t *testing.T) {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ func TestOpen_ErrVersionMismatch(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reopen data file.
|
// 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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ func TestOpen_ErrChecksum(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reopen data file.
|
// 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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,7 +553,7 @@ func TestDB_Open_ReadOnly(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't launch read-write transaction.
|
// 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)
|
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.
|
// Ensure that a database cannot open a transaction when it's not open.
|
||||||
func TestDB_Begin_ErrDatabaseNotOpen(t *testing.T) {
|
func TestDB_Begin_ErrDatabaseNotOpen(t *testing.T) {
|
||||||
var db bolt.DB
|
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)
|
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.
|
// Ensure that opening a transaction while the DB is closed returns an error.
|
||||||
func TestDB_BeginRW_Closed(t *testing.T) {
|
func TestDB_BeginRW_Closed(t *testing.T) {
|
||||||
var db bolt.DB
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,7 +832,7 @@ func TestDB_Update_Closed(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}); err != common.ErrDatabaseNotOpen {
|
}); err != berrors.ErrDatabaseNotOpen {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"go.etcd.io/bbolt/internal/common"
|
"go.etcd.io/bbolt/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestOpenWithPreLoadFreelist(t *testing.T) {
|
func TestOpenWithPreLoadFreelist(t *testing.T) {
|
||||||
|
@ -78,7 +78,7 @@ func TestMethodPage(t *testing.T) {
|
||||||
name: "readonly mode without preloading free pages",
|
name: "readonly mode without preloading free pages",
|
||||||
readonly: true,
|
readonly: true,
|
||||||
preLoadFreePage: false,
|
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"
|
import "errors"
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"io"
|
"io"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"go.etcd.io/bbolt/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Meta struct {
|
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.
|
// Validate checks the marker bytes and version of the meta page to ensure it matches this binary.
|
||||||
func (m *Meta) Validate() error {
|
func (m *Meta) Validate() error {
|
||||||
if m.magic != Magic {
|
if m.magic != Magic {
|
||||||
return ErrInvalid
|
return errors.ErrInvalid
|
||||||
} else if m.version != Version {
|
} else if m.version != Version {
|
||||||
return ErrVersionMismatch
|
return errors.ErrVersionMismatch
|
||||||
} else if m.checksum != m.Sum64() {
|
} else if m.checksum != m.Sum64() {
|
||||||
return ErrChecksum
|
return errors.ErrChecksum
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
11
tx.go
11
tx.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
"go.etcd.io/bbolt/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -141,9 +142,9 @@ func (tx *Tx) OnCommit(fn func()) {
|
||||||
func (tx *Tx) Commit() error {
|
func (tx *Tx) Commit() error {
|
||||||
common.Assert(!tx.managed, "managed tx commit not allowed")
|
common.Assert(!tx.managed, "managed tx commit not allowed")
|
||||||
if tx.db == nil {
|
if tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
} else if !tx.writable {
|
} else if !tx.writable {
|
||||||
return common.ErrTxNotWritable
|
return errors.ErrTxNotWritable
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(benbjohnson): Use vectorized I/O to write out dirty pages.
|
// 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 {
|
func (tx *Tx) Rollback() error {
|
||||||
common.Assert(!tx.managed, "managed tx rollback not allowed")
|
common.Assert(!tx.managed, "managed tx rollback not allowed")
|
||||||
if tx.db == nil {
|
if tx.db == nil {
|
||||||
return common.ErrTxClosed
|
return errors.ErrTxClosed
|
||||||
}
|
}
|
||||||
tx.nonPhysicalRollback()
|
tx.nonPhysicalRollback()
|
||||||
return nil
|
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.
|
// This is only safe for concurrent use when used by a writable transaction.
|
||||||
func (tx *Tx) Page(id int) (*common.PageInfo, error) {
|
func (tx *Tx) Page(id int) (*common.PageInfo, error) {
|
||||||
if tx.db == nil {
|
if tx.db == nil {
|
||||||
return nil, common.ErrTxClosed
|
return nil, errors.ErrTxClosed
|
||||||
} else if common.Pgid(id) >= tx.meta.Pgid() {
|
} else if common.Pgid(id) >= tx.meta.Pgid() {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if tx.db.freelist == nil {
|
if tx.db.freelist == nil {
|
||||||
return nil, common.ErrFreePagesNotLoaded
|
return nil, errors.ErrFreePagesNotLoaded
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the page info.
|
// Build the page info.
|
||||||
|
|
26
tx_test.go
26
tx_test.go
|
@ -14,8 +14,8 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
|
berrors "go.etcd.io/bbolt/errors"
|
||||||
"go.etcd.io/bbolt/internal/btesting"
|
"go.etcd.io/bbolt/internal/btesting"
|
||||||
"go.etcd.io/bbolt/internal/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestTx_Check_ReadOnly tests consistency checking on a ReadOnly database.
|
// TestTx_Check_ReadOnly tests consistency checking on a ReadOnly database.
|
||||||
|
@ -85,7 +85,7 @@ func TestTx_Commit_ErrTxClosed(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tx.Commit(); err != common.ErrTxClosed {
|
if err := tx.Commit(); err != berrors.ErrTxClosed {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ func TestTx_Rollback_ErrTxClosed(t *testing.T) {
|
||||||
if err := tx.Rollback(); err != nil {
|
if err := tx.Rollback(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := tx.Rollback(); err != common.ErrTxClosed {
|
if err := tx.Rollback(); err != berrors.ErrTxClosed {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ func TestTx_Commit_ErrTxNotWritable(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := tx.Commit(); err != common.ErrTxNotWritable {
|
if err := tx.Commit(); err != berrors.ErrTxNotWritable {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// Close the view transaction
|
// Close the view transaction
|
||||||
|
@ -166,7 +166,7 @@ func TestTx_CreateBucket_ErrTxNotWritable(t *testing.T) {
|
||||||
db := btesting.MustCreateDB(t)
|
db := btesting.MustCreateDB(t)
|
||||||
if err := db.View(func(tx *bolt.Tx) error {
|
if err := db.View(func(tx *bolt.Tx) error {
|
||||||
_, err := tx.CreateBucket([]byte("foo"))
|
_, err := tx.CreateBucket([]byte("foo"))
|
||||||
if err != common.ErrTxNotWritable {
|
if err != berrors.ErrTxNotWritable {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -186,7 +186,7 @@ func TestTx_CreateBucket_ErrTxClosed(t *testing.T) {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,11 +294,11 @@ func TestTx_CreateBucketIfNotExists(t *testing.T) {
|
||||||
func TestTx_CreateBucketIfNotExists_ErrBucketNameRequired(t *testing.T) {
|
func TestTx_CreateBucketIfNotExists_ErrBucketNameRequired(t *testing.T) {
|
||||||
db := btesting.MustCreateDB(t)
|
db := btesting.MustCreateDB(t)
|
||||||
if err := db.Update(func(tx *bolt.Tx) error {
|
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)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ func TestTx_CreateBucket_ErrBucketExists(t *testing.T) {
|
||||||
|
|
||||||
// Create the same bucket again.
|
// Create the same bucket again.
|
||||||
if err := db.Update(func(tx *bolt.Tx) error {
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -337,7 +337,7 @@ func TestTx_CreateBucket_ErrBucketExists(t *testing.T) {
|
||||||
func TestTx_CreateBucket_ErrBucketNameRequired(t *testing.T) {
|
func TestTx_CreateBucket_ErrBucketNameRequired(t *testing.T) {
|
||||||
db := btesting.MustCreateDB(t)
|
db := btesting.MustCreateDB(t)
|
||||||
if err := db.Update(func(tx *bolt.Tx) error {
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -402,7 +402,7 @@ func TestTx_DeleteBucket_ErrTxClosed(t *testing.T) {
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
t.Fatal(err)
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ func TestTx_DeleteBucket_ErrTxClosed(t *testing.T) {
|
||||||
func TestTx_DeleteBucket_ReadOnly(t *testing.T) {
|
func TestTx_DeleteBucket_ReadOnly(t *testing.T) {
|
||||||
db := btesting.MustCreateDB(t)
|
db := btesting.MustCreateDB(t)
|
||||||
if err := db.View(func(tx *bolt.Tx) error {
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -424,7 +424,7 @@ func TestTx_DeleteBucket_ReadOnly(t *testing.T) {
|
||||||
func TestTx_DeleteBucket_NotFound(t *testing.T) {
|
func TestTx_DeleteBucket_NotFound(t *testing.T) {
|
||||||
db := btesting.MustCreateDB(t)
|
db := btesting.MustCreateDB(t)
|
||||||
if err := db.Update(func(tx *bolt.Tx) error {
|
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)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue