Add examples.

master
Ben Johnson 2014-02-14 08:32:42 -07:00
parent d361149fa8
commit 0ebef9c0bb
4 changed files with 161 additions and 13 deletions

9
db.go
View File

@ -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
}

View File

@ -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.

142
example_test.go Normal file
View File

@ -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
}

View File

@ -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()
}
}