aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Johnson <benbjohnson@yahoo.com>2014-02-14 08:35:31 -0700
committerBen Johnson <benbjohnson@yahoo.com>2014-02-14 08:35:31 -0700
commitaf5b9182f1009af018b60cd19eb7ee19cfda995f (patch)
tree2b025229ec9c14e3945c0cf1bfb00d63472559ab
parentAdd godoc badge. (diff)
parentAdd examples. (diff)
downloaddedo-af5b9182f1009af018b60cd19eb7ee19cfda995f.tar.gz
dedo-af5b9182f1009af018b60cd19eb7ee19cfda995f.tar.xz
Merge pull request #30 from benbjohnson/examples
Examples
-rw-r--r--db.go9
-rw-r--r--db_test.go19
-rw-r--r--example_test.go142
-rw-r--r--rwtransaction_test.go4
4 files changed, 161 insertions, 13 deletions
diff --git a/db.go b/db.go
index 88c3065..bb9bbf6 100644
--- a/db.go
+++ b/db.go
@@ -37,11 +37,6 @@ type DB struct {
mmaplock sync.RWMutex // Protects mmap access during remapping.
}
-// NewDB creates a new DB instance.
-func NewDB() *DB {
- return &DB{}
-}
-
// Path returns the path to currently open database file.
func (db *DB) Path() string {
return db.path
@@ -460,8 +455,8 @@ func (db *DB) Copy(w io.Writer) error {
// CopyFile copies the entire database to file at the given path.
// A reader transaction is maintained during the copy so it is safe to continue
// using the database while a copy is in progress.
-func (db *DB) CopyFile(path string) error {
- f, err := os.Create(path)
+func (db *DB) CopyFile(path string, mode os.FileMode) error {
+ f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
if err != nil {
return err
}
diff --git a/db_test.go b/db_test.go
index 51b76d5..2682f55 100644
--- a/db_test.go
+++ b/db_test.go
@@ -140,6 +140,17 @@ func TestDBTransactionDatabaseNotOpenError(t *testing.T) {
})
}
+// Ensure that a bucket that gets a non-existent key returns nil.
+func TestDBGetNonExistent(t *testing.T) {
+ withOpenDB(func(db *DB, path string) {
+ db.CreateBucket("widgets")
+ value, err := db.Get("widgets", []byte("foo"))
+ if assert.NoError(t, err) {
+ assert.Nil(t, value)
+ }
+ })
+}
+
// Ensure that a bucket can write a key/value.
func TestDBPut(t *testing.T) {
withOpenDB(func(db *DB, path string) {
@@ -207,17 +218,17 @@ func withDB(fn func(*DB, string)) {
os.Remove(path)
defer os.RemoveAll(path)
- db := NewDB()
- fn(db, path)
+ var db DB
+ fn(&db, path)
}
// withMockDB executes a function with a database reference and a mock filesystem.
func withMockDB(fn func(*DB, *mockos, *mocksyscall, string)) {
os, syscall := &mockos{}, &mocksyscall{}
- db := NewDB()
+ var db DB
db.os = os
db.syscall = syscall
- fn(db, os, syscall, "/mock/db")
+ fn(&db, os, syscall, "/mock/db")
}
// withOpenDB executes a function with an already opened database.
diff --git a/example_test.go b/example_test.go
new file mode 100644
index 0000000..892807e
--- /dev/null
+++ b/example_test.go
@@ -0,0 +1,142 @@
+package bolt
+
+import (
+ "fmt"
+ "os"
+)
+
+func init() {
+ os.RemoveAll("/tmp/bolt")
+ os.MkdirAll("/tmp/bolt", 0777)
+}
+
+func ExampleDB_Put() {
+ // Open the database.
+ var db DB
+ db.Open("/tmp/bolt/db_put.db", 0666)
+ defer db.Close()
+
+ // Create a bucket.
+ db.CreateBucket("widgets")
+
+ // Set the value "bar" for the key "foo".
+ db.Put("widgets", []byte("foo"), []byte("bar"))
+
+ // Retrieve the key back from the database and verify it.
+ value, _ := db.Get("widgets", []byte("foo"))
+ fmt.Printf("The value of 'foo' is: %s\n", string(value))
+
+ // Output:
+ // The value of 'foo' is: bar
+}
+
+func ExampleDB_Delete() {
+ // Open the database.
+ var db DB
+ db.Open("/tmp/bolt/db_delete.db", 0666)
+ defer db.Close()
+
+ // Create a bucket.
+ db.CreateBucket("widgets")
+
+ // Set the value "bar" for the key "foo".
+ db.Put("widgets", []byte("foo"), []byte("bar"))
+
+ // Retrieve the key back from the database and verify it.
+ value, _ := db.Get("widgets", []byte("foo"))
+ fmt.Printf("The value of 'foo' was: %s\n", string(value))
+
+ // Delete the "foo" key.
+ db.Delete("widgets", []byte("foo"))
+
+ // Retrieve the key again.
+ value, _ = db.Get("widgets", []byte("foo"))
+ if value == nil {
+ fmt.Printf("The value of 'foo' is now: nil\n")
+ }
+
+ // Output:
+ // The value of 'foo' was: bar
+ // The value of 'foo' is now: nil
+}
+
+func ExampleRWTransaction() {
+ // Open the database.
+ var db DB
+ db.Open("/tmp/bolt/rwtransaction.db", 0666)
+ defer db.Close()
+
+ // Create a bucket.
+ db.CreateBucket("widgets")
+
+ // Create several keys in a transaction.
+ rwtxn, _ := db.RWTransaction()
+ rwtxn.Put("widgets", []byte("john"), []byte("blue"))
+ rwtxn.Put("widgets", []byte("abby"), []byte("red"))
+ rwtxn.Put("widgets", []byte("zephyr"), []byte("purple"))
+ rwtxn.Commit()
+
+ // Iterate over the values in sorted key order.
+ txn, _ := db.Transaction()
+ c, _ := txn.Cursor("widgets")
+ for k, v := c.First(); k != nil; k, v = c.Next() {
+ fmt.Printf("%s likes %s\n", string(k), string(v))
+ }
+ txn.Close()
+
+ // Output:
+ // abby likes red
+ // john likes blue
+ // zephyr likes purple
+}
+
+func ExampleRWTransaction_rollback() {
+ // Open the database.
+ var db DB
+ db.Open("/tmp/bolt/rwtransaction_rollback.db", 0666)
+ defer db.Close()
+
+ // Create a bucket.
+ db.CreateBucket("widgets")
+
+ // Set a value for a key.
+ db.Put("widgets", []byte("foo"), []byte("bar"))
+
+ // Update the key but rollback the transaction so it never saves.
+ rwtxn, _ := db.RWTransaction()
+ rwtxn.Put("widgets", []byte("foo"), []byte("baz"))
+ rwtxn.Rollback()
+
+ // Ensure that our original value is still set.
+ value, _ := db.Get("widgets", []byte("foo"))
+ fmt.Printf("The value for 'foo' is still: %s\n", string(value))
+
+ // Output:
+ // The value for 'foo' is still: bar
+}
+
+func ExampleDB_CopyFile() {
+ // Open the database.
+ var db DB
+ db.Open("/tmp/bolt/db_copy.db", 0666)
+ defer db.Close()
+
+ // Create a bucket and a key.
+ db.CreateBucket("widgets")
+ db.Put("widgets", []byte("foo"), []byte("bar"))
+
+ // Copy the database to another file.
+ db.CopyFile("/tmp/bolt/db_copy_2.db", 0666)
+
+ // Open the cloned database.
+ var db2 DB
+ db2.Open("/tmp/bolt/db_copy_2.db", 0666)
+ defer db2.Close()
+
+ // Ensure that the key exists in the copy.
+ value, _ := db2.Get("widgets", []byte("foo"))
+ fmt.Printf("The value for 'foo' in the clone is: %s\n", string(value))
+
+ // Output:
+ // The value for 'foo' in the clone is: bar
+}
diff --git a/rwtransaction_test.go b/rwtransaction_test.go
index 67855be..1ce3f70 100644
--- a/rwtransaction_test.go
+++ b/rwtransaction_test.go
@@ -119,7 +119,7 @@ func TestRWTransactionPutSingle(t *testing.T) {
panic("get error: " + err.Error())
}
if !bytes.Equal(value, v) {
- db.CopyFile("/tmp/bolt.put.single.db")
+ db.CopyFile("/tmp/bolt.put.single.db", 0666)
t.Fatalf("value mismatch [run %d] (%d of %d):\nkey: %x\ngot: %x\nexp: %x", index, i, len(m), []byte(k), value, v)
}
i++
@@ -155,7 +155,7 @@ func TestRWTransactionPutMultiple(t *testing.T) {
value, err := txn.Get("widgets", item.Key)
assert.NoError(t, err)
if !assert.Equal(t, item.Value, value) {
- db.CopyFile("/tmp/bolt.put.multiple.db")
+ db.CopyFile("/tmp/bolt.put.multiple.db", 0666)
t.FailNow()
}
}