aboutsummaryrefslogtreecommitdiff
path: root/tx_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tx_test.go')
-rw-r--r--tx_test.go742
1 files changed, 501 insertions, 241 deletions
diff --git a/tx_test.go b/tx_test.go
index 6c8271a..7a274e4 100644
--- a/tx_test.go
+++ b/tx_test.go
@@ -1,8 +1,10 @@
package bolt_test
import (
+ "bytes"
"errors"
"fmt"
+ "log"
"os"
"testing"
@@ -10,331 +12,519 @@ import (
)
// Ensure that committing a closed transaction returns an error.
-func TestTx_Commit_Closed(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- tx, _ := db.Begin(true)
- tx.CreateBucket([]byte("foo"))
- ok(t, tx.Commit())
- equals(t, tx.Commit(), bolt.ErrTxClosed)
+func TestTx_Commit_ErrTxClosed(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ tx, err := db.Begin(true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := tx.CreateBucket([]byte("foo")); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := tx.Commit(); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := tx.Commit(); err != bolt.ErrTxClosed {
+ t.Fatalf("unexpected error: %s", err)
+ }
}
// Ensure that rolling back a closed transaction returns an error.
-func TestTx_Rollback_Closed(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- tx, _ := db.Begin(true)
- ok(t, tx.Rollback())
- equals(t, tx.Rollback(), bolt.ErrTxClosed)
+func TestTx_Rollback_ErrTxClosed(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+
+ tx, err := db.Begin(true)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if err := tx.Rollback(); err != nil {
+ t.Fatal(err)
+ }
+ if err := tx.Rollback(); err != bolt.ErrTxClosed {
+ t.Fatalf("unexpected error: %s", err)
+ }
}
// Ensure that committing a read-only transaction returns an error.
-func TestTx_Commit_ReadOnly(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- tx, _ := db.Begin(false)
- equals(t, tx.Commit(), bolt.ErrTxNotWritable)
+func TestTx_Commit_ErrTxNotWritable(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ tx, err := db.Begin(false)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := tx.Commit(); err != bolt.ErrTxNotWritable {
+ t.Fatal(err)
+ }
}
// Ensure that a transaction can retrieve a cursor on the root bucket.
func TestTx_Cursor(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.CreateBucket([]byte("woojits"))
- c := tx.Cursor()
-
- k, v := c.First()
- equals(t, "widgets", string(k))
- assert(t, v == nil, "")
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if _, err := tx.CreateBucket([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ }
- k, v = c.Next()
- equals(t, "woojits", string(k))
- assert(t, v == nil, "")
+ if _, err := tx.CreateBucket([]byte("woojits")); err != nil {
+ t.Fatal(err)
+ }
- k, v = c.Next()
- assert(t, k == nil, "")
- assert(t, v == nil, "")
+ c := tx.Cursor()
+ if k, v := c.First(); !bytes.Equal(k, []byte("widgets")) {
+ t.Fatalf("unexpected key: %v", k)
+ } else if v != nil {
+ t.Fatalf("unexpected value: %v", v)
+ }
+
+ if k, v := c.Next(); !bytes.Equal(k, []byte("woojits")) {
+ t.Fatalf("unexpected key: %v", k)
+ } else if v != nil {
+ t.Fatalf("unexpected value: %v", v)
+ }
+
+ if k, v := c.Next(); k != nil {
+ t.Fatalf("unexpected key: %v", k)
+ } else if v != nil {
+ t.Fatalf("unexpected value: %v", k)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that creating a bucket with a read-only transaction returns an error.
-func TestTx_CreateBucket_ReadOnly(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.View(func(tx *bolt.Tx) error {
- b, err := tx.CreateBucket([]byte("foo"))
- assert(t, b == nil, "")
- equals(t, bolt.ErrTxNotWritable, err)
+func TestTx_CreateBucket_ErrTxNotWritable(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.View(func(tx *bolt.Tx) error {
+ _, err := tx.CreateBucket([]byte("foo"))
+ if err != bolt.ErrTxNotWritable {
+ t.Fatalf("unexpected error: %s", err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that creating a bucket on a closed transaction returns an error.
-func TestTx_CreateBucket_Closed(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- tx, _ := db.Begin(true)
- tx.Commit()
- b, err := tx.CreateBucket([]byte("foo"))
- assert(t, b == nil, "")
- equals(t, bolt.ErrTxClosed, err)
+func TestTx_CreateBucket_ErrTxClosed(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ tx, err := db.Begin(true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := tx.Commit(); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := tx.CreateBucket([]byte("foo")); err != bolt.ErrTxClosed {
+ t.Fatalf("unexpected error: %s", err)
+ }
}
// Ensure that a Tx can retrieve a bucket.
func TestTx_Bucket(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- b := tx.Bucket([]byte("widgets"))
- assert(t, b != nil, "")
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if _, err := tx.CreateBucket([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ }
+ if tx.Bucket([]byte("widgets")) == nil {
+ t.Fatal("expected bucket")
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that a Tx retrieving a non-existent key returns nil.
-func TestTx_Get_Missing(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
- value := tx.Bucket([]byte("widgets")).Get([]byte("no_such_key"))
- assert(t, value == nil, "")
+func TestTx_Get_NotFound(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ t.Fatal(err)
+ }
+ if b.Get([]byte("no_such_key")) != nil {
+ t.Fatal("expected nil value")
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that a bucket can be created and retrieved.
func TestTx_CreateBucket(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
+ db := MustOpenDB()
+ defer db.MustClose()
// Create a bucket.
- db.Update(func(tx *bolt.Tx) error {
+ if err := db.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucket([]byte("widgets"))
- assert(t, b != nil, "")
- ok(t, err)
+ if err != nil {
+ t.Fatal(err)
+ } else if b == nil {
+ t.Fatal("expected bucket")
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
// Read the bucket through a separate transaction.
- db.View(func(tx *bolt.Tx) error {
- b := tx.Bucket([]byte("widgets"))
- assert(t, b != nil, "")
+ if err := db.View(func(tx *bolt.Tx) error {
+ if tx.Bucket([]byte("widgets")) == nil {
+ t.Fatal("expected bucket")
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that a bucket can be created if it doesn't already exist.
func TestTx_CreateBucketIfNotExists(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- b, err := tx.CreateBucketIfNotExists([]byte("widgets"))
- assert(t, b != nil, "")
- ok(t, err)
-
- b, err = tx.CreateBucketIfNotExists([]byte("widgets"))
- assert(t, b != nil, "")
- ok(t, err)
-
- b, err = tx.CreateBucketIfNotExists([]byte{})
- assert(t, b == nil, "")
- equals(t, bolt.ErrBucketNameRequired, err)
-
- b, err = tx.CreateBucketIfNotExists(nil)
- assert(t, b == nil, "")
- equals(t, bolt.ErrBucketNameRequired, err)
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ // Create bucket.
+ if b, err := tx.CreateBucketIfNotExists([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ } else if b == nil {
+ t.Fatal("expected bucket")
+ }
+
+ // Create bucket again.
+ if b, err := tx.CreateBucketIfNotExists([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ } else if b == nil {
+ t.Fatal("expected bucket")
+ }
+
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
// Read the bucket through a separate transaction.
- db.View(func(tx *bolt.Tx) error {
- b := tx.Bucket([]byte("widgets"))
- assert(t, b != nil, "")
+ if err := db.View(func(tx *bolt.Tx) error {
+ if tx.Bucket([]byte("widgets")) == nil {
+ t.Fatal("expected bucket")
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
+}
+
+// Ensure transaction returns an error if creating an unnamed bucket.
+func TestTx_CreateBucketIfNotExists_ErrBucketNameRequired(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if _, err := tx.CreateBucketIfNotExists([]byte{}); err != bolt.ErrBucketNameRequired {
+ t.Fatalf("unexpected error: %s", err)
+ }
+
+ if _, err := tx.CreateBucketIfNotExists(nil); err != bolt.ErrBucketNameRequired {
+ t.Fatalf("unexpected error: %s", err)
+ }
+
+ return nil
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that a bucket cannot be created twice.
-func TestTx_CreateBucket_Exists(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
+func TestTx_CreateBucket_ErrBucketExists(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+
// Create a bucket.
- db.Update(func(tx *bolt.Tx) error {
- b, err := tx.CreateBucket([]byte("widgets"))
- assert(t, b != nil, "")
- ok(t, err)
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if _, err := tx.CreateBucket([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
// Create the same bucket again.
- db.Update(func(tx *bolt.Tx) error {
- b, err := tx.CreateBucket([]byte("widgets"))
- assert(t, b == nil, "")
- equals(t, bolt.ErrBucketExists, err)
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if _, err := tx.CreateBucket([]byte("widgets")); err != bolt.ErrBucketExists {
+ t.Fatalf("unexpected error: %s", err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that a bucket is created with a non-blank name.
-func TestTx_CreateBucket_NameRequired(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- b, err := tx.CreateBucket(nil)
- assert(t, b == nil, "")
- equals(t, bolt.ErrBucketNameRequired, err)
+func TestTx_CreateBucket_ErrBucketNameRequired(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if _, err := tx.CreateBucket(nil); err != bolt.ErrBucketNameRequired {
+ t.Fatalf("unexpected error: %s", err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that a bucket can be deleted.
func TestTx_DeleteBucket(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
+ db := MustOpenDB()
+ defer db.MustClose()
// Create a bucket and add a value.
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ t.Fatal(err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
// Delete the bucket and make sure we can't get the value.
- db.Update(func(tx *bolt.Tx) error {
- ok(t, tx.DeleteBucket([]byte("widgets")))
- assert(t, tx.Bucket([]byte("widgets")) == nil, "")
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if err := tx.DeleteBucket([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ }
+ if tx.Bucket([]byte("widgets")) != nil {
+ t.Fatal("unexpected bucket")
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
- db.Update(func(tx *bolt.Tx) error {
+ if err := db.Update(func(tx *bolt.Tx) error {
// Create the bucket again and make sure there's not a phantom value.
b, err := tx.CreateBucket([]byte("widgets"))
- assert(t, b != nil, "")
- ok(t, err)
- assert(t, tx.Bucket([]byte("widgets")).Get([]byte("foo")) == nil, "")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if v := b.Get([]byte("foo")); v != nil {
+ t.Fatalf("unexpected phantom value: %v", v)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that deleting a bucket on a closed transaction returns an error.
-func TestTx_DeleteBucket_Closed(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- tx, _ := db.Begin(true)
- tx.Commit()
- equals(t, tx.DeleteBucket([]byte("foo")), bolt.ErrTxClosed)
+func TestTx_DeleteBucket_ErrTxClosed(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+ tx, err := db.Begin(true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := tx.Commit(); err != nil {
+ t.Fatal(err)
+ }
+ if err := tx.DeleteBucket([]byte("foo")); err != bolt.ErrTxClosed {
+ t.Fatalf("unexpected error: %s", err)
+ }
}
// Ensure that deleting a bucket with a read-only transaction returns an error.
func TestTx_DeleteBucket_ReadOnly(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.View(func(tx *bolt.Tx) error {
- equals(t, tx.DeleteBucket([]byte("foo")), bolt.ErrTxNotWritable)
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.View(func(tx *bolt.Tx) error {
+ if err := tx.DeleteBucket([]byte("foo")); err != bolt.ErrTxNotWritable {
+ t.Fatalf("unexpected error: %s", err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that nothing happens when deleting a bucket that doesn't exist.
func TestTx_DeleteBucket_NotFound(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- equals(t, bolt.ErrBucketNotFound, tx.DeleteBucket([]byte("widgets")))
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ if err := tx.DeleteBucket([]byte("widgets")); err != bolt.ErrBucketNotFound {
+ t.Fatalf("unexpected error: %s", err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that no error is returned when a tx.ForEach function does not return
// an error.
func TestTx_ForEach_NoError(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
-
- equals(t, nil, tx.ForEach(func(name []byte, b *bolt.Bucket) error {
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := tx.ForEach(func(name []byte, b *bolt.Bucket) error {
return nil
- }))
+ }); err != nil {
+ t.Fatal(err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that an error is returned when a tx.ForEach function returns an error.
func TestTx_ForEach_WithError(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
-
- err := errors.New("foo")
- equals(t, err, tx.ForEach(func(name []byte, b *bolt.Bucket) error {
- return err
- }))
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ t.Fatal(err)
+ }
+
+ marker := errors.New("marker")
+ if err := tx.ForEach(func(name []byte, b *bolt.Bucket) error {
+ return marker
+ }); err != marker {
+ t.Fatalf("unexpected error: %s", err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
}
// Ensure that Tx commit handlers are called after a transaction successfully commits.
func TestTx_OnCommit(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+
var x int
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
+ if err := db.Update(func(tx *bolt.Tx) error {
tx.OnCommit(func() { x += 1 })
tx.OnCommit(func() { x += 2 })
- _, err := tx.CreateBucket([]byte("widgets"))
- return err
- })
- equals(t, 3, x)
+ if _, err := tx.CreateBucket([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ }
+ return nil
+ }); err != nil {
+ t.Fatal(err)
+ } else if x != 3 {
+ t.Fatalf("unexpected x: %d", x)
+ }
}
// Ensure that Tx commit handlers are NOT called after a transaction rolls back.
func TestTx_OnCommit_Rollback(t *testing.T) {
+ db := MustOpenDB()
+ defer db.MustClose()
+
var x int
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
+ if err := db.Update(func(tx *bolt.Tx) error {
tx.OnCommit(func() { x += 1 })
tx.OnCommit(func() { x += 2 })
- tx.CreateBucket([]byte("widgets"))
+ if _, err := tx.CreateBucket([]byte("widgets")); err != nil {
+ t.Fatal(err)
+ }
return errors.New("rollback this commit")
- })
- equals(t, 0, x)
+ }); err == nil || err.Error() != "rollback this commit" {
+ t.Fatalf("unexpected error: %s", err)
+ } else if x != 0 {
+ t.Fatalf("unexpected x: %d", x)
+ }
}
// Ensure that the database can be copied to a file path.
func TestTx_CopyFile(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- var dest = tempfile()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
- tx.Bucket([]byte("widgets")).Put([]byte("baz"), []byte("bat"))
+ db := MustOpenDB()
+ defer db.MustClose()
+
+ path := tempfile()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("baz"), []byte("bat")); err != nil {
+ t.Fatal(err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
- ok(t, db.View(func(tx *bolt.Tx) error { return tx.CopyFile(dest, 0600) }))
+ if err := db.View(func(tx *bolt.Tx) error {
+ return tx.CopyFile(path, 0600)
+ }); err != nil {
+ t.Fatal(err)
+ }
- db2, err := bolt.Open(dest, 0600, nil)
- ok(t, err)
- defer db2.Close()
+ db2, err := bolt.Open(path, 0600, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
- db2.View(func(tx *bolt.Tx) error {
- equals(t, []byte("bar"), tx.Bucket([]byte("widgets")).Get([]byte("foo")))
- equals(t, []byte("bat"), tx.Bucket([]byte("widgets")).Get([]byte("baz")))
+ if err := db2.View(func(tx *bolt.Tx) error {
+ if v := tx.Bucket([]byte("widgets")).Get([]byte("foo")); !bytes.Equal(v, []byte("bar")) {
+ t.Fatalf("unexpected value: %v", v)
+ }
+ if v := tx.Bucket([]byte("widgets")).Get([]byte("baz")); !bytes.Equal(v, []byte("bat")) {
+ t.Fatalf("unexpected value: %v", v)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := db2.Close(); err != nil {
+ t.Fatal(err)
+ }
}
type failWriterError struct{}
@@ -360,63 +550,107 @@ func (f *failWriter) Write(p []byte) (n int, err error) {
// Ensure that Copy handles write errors right.
func TestTx_CopyFile_Error_Meta(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
- tx.Bucket([]byte("widgets")).Put([]byte("baz"), []byte("bat"))
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("baz"), []byte("bat")); err != nil {
+ t.Fatal(err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
- err := db.View(func(tx *bolt.Tx) error { return tx.Copy(&failWriter{}) })
- equals(t, err.Error(), "meta copy: error injected for tests")
+ if err := db.View(func(tx *bolt.Tx) error {
+ return tx.Copy(&failWriter{})
+ }); err == nil || err.Error() != "meta copy: error injected for tests" {
+ t.Fatal("unexpected error: %s", err)
+ }
}
// Ensure that Copy handles write errors right.
func TestTx_CopyFile_Error_Normal(t *testing.T) {
- db := NewTestDB()
- defer db.Close()
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
- tx.Bucket([]byte("widgets")).Put([]byte("baz"), []byte("bat"))
+ db := MustOpenDB()
+ defer db.MustClose()
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ t.Fatal(err)
+ }
+ if err := b.Put([]byte("baz"), []byte("bat")); err != nil {
+ t.Fatal(err)
+ }
return nil
- })
+ }); err != nil {
+ t.Fatal(err)
+ }
- err := db.View(func(tx *bolt.Tx) error { return tx.Copy(&failWriter{3 * db.Info().PageSize}) })
- equals(t, err.Error(), "error injected for tests")
+ if err := db.View(func(tx *bolt.Tx) error {
+ return tx.Copy(&failWriter{3 * db.Info().PageSize})
+ }); err == nil || err.Error() != "error injected for tests" {
+ t.Fatal("unexpected error: %s", err)
+ }
}
func ExampleTx_Rollback() {
// Open the database.
- db, _ := bolt.Open(tempfile(), 0666, nil)
+ db, err := bolt.Open(tempfile(), 0666, nil)
+ if err != nil {
+ log.Fatal(err)
+ }
defer os.Remove(db.Path())
- defer db.Close()
// Create a bucket.
- db.Update(func(tx *bolt.Tx) error {
+ if err := db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucket([]byte("widgets"))
return err
- })
+ }); err != nil {
+ log.Fatal(err)
+ }
// Set a value for a key.
- db.Update(func(tx *bolt.Tx) error {
+ if err := db.Update(func(tx *bolt.Tx) error {
return tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
- })
+ }); err != nil {
+ log.Fatal(err)
+ }
// Update the key but rollback the transaction so it never saves.
- tx, _ := db.Begin(true)
+ tx, err := db.Begin(true)
+ if err != nil {
+ log.Fatal(err)
+ }
b := tx.Bucket([]byte("widgets"))
- b.Put([]byte("foo"), []byte("baz"))
- tx.Rollback()
+ if err := b.Put([]byte("foo"), []byte("baz")); err != nil {
+ log.Fatal(err)
+ }
+ if err := tx.Rollback(); err != nil {
+ log.Fatal(err)
+ }
// Ensure that our original value is still set.
- db.View(func(tx *bolt.Tx) error {
+ if err := db.View(func(tx *bolt.Tx) error {
value := tx.Bucket([]byte("widgets")).Get([]byte("foo"))
fmt.Printf("The value for 'foo' is still: %s\n", value)
return nil
- })
+ }); err != nil {
+ log.Fatal(err)
+ }
+
+ // Close database to release file lock.
+ if err := db.Close(); err != nil {
+ log.Fatal(err)
+ }
// Output:
// The value for 'foo' is still: bar
@@ -424,32 +658,58 @@ func ExampleTx_Rollback() {
func ExampleTx_CopyFile() {
// Open the database.
- db, _ := bolt.Open(tempfile(), 0666, nil)
+ db, err := bolt.Open(tempfile(), 0666, nil)
+ if err != nil {
+ log.Fatal(err)
+ }
defer os.Remove(db.Path())
- defer db.Close()
// Create a bucket and a key.
- db.Update(func(tx *bolt.Tx) error {
- tx.CreateBucket([]byte("widgets"))
- tx.Bucket([]byte("widgets")).Put([]byte("foo"), []byte("bar"))
+ if err := db.Update(func(tx *bolt.Tx) error {
+ b, err := tx.CreateBucket([]byte("widgets"))
+ if err != nil {
+ return err
+ }
+ if err := b.Put([]byte("foo"), []byte("bar")); err != nil {
+ return err
+ }
return nil
- })
+ }); err != nil {
+ log.Fatal(err)
+ }
// Copy the database to another file.
toFile := tempfile()
- db.View(func(tx *bolt.Tx) error { return tx.CopyFile(toFile, 0666) })
+ if err := db.View(func(tx *bolt.Tx) error {
+ return tx.CopyFile(toFile, 0666)
+ }); err != nil {
+ log.Fatal(err)
+ }
defer os.Remove(toFile)
// Open the cloned database.
- db2, _ := bolt.Open(toFile, 0666, nil)
- defer db2.Close()
+ db2, err := bolt.Open(toFile, 0666, nil)
+ if err != nil {
+ log.Fatal(err)
+ }
// Ensure that the key exists in the copy.
- db2.View(func(tx *bolt.Tx) error {
+ if err := db2.View(func(tx *bolt.Tx) error {
value := tx.Bucket([]byte("widgets")).Get([]byte("foo"))
fmt.Printf("The value for 'foo' in the clone is: %s\n", value)
return nil
- })
+ }); err != nil {
+ log.Fatal(err)
+ }
+
+ // Close database to release file lock.
+ if err := db.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ if err := db2.Close(); err != nil {
+ log.Fatal(err)
+ }
// Output:
// The value for 'foo' in the clone is: bar