mirror of https://github.com/hak5/bolt.git
Add examples.
parent
d361149fa8
commit
0ebef9c0bb
9
db.go
9
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
|
||||
}
|
||||
|
|
19
db_test.go
19
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.
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue