walletdb: add sequence methods to main interface, update bdb to implement
In this commit, we add the trio of sequence based methods that bbolt ships with to the main bucket interface. We do this in order to easily allow walletdb as is to be slotted into place where bbolt is currently used, without sacrificing any functionality.
This commit is contained in:
parent
eb2582bbde
commit
0bcbb4cc4a
4 changed files with 84 additions and 9 deletions
|
@ -68,7 +68,7 @@ func (tx *transaction) ReadWriteBucket(key []byte) walletdb.ReadWriteBucket {
|
|||
}
|
||||
|
||||
func (tx *transaction) CreateTopLevelBucket(key []byte) (walletdb.ReadWriteBucket, error) {
|
||||
boltBucket, err := tx.boltTx.CreateBucket(key)
|
||||
boltBucket, err := tx.boltTx.CreateBucketIfNotExists(key)
|
||||
if err != nil {
|
||||
return nil, convertErr(err)
|
||||
}
|
||||
|
@ -231,6 +231,21 @@ func (b *bucket) Tx() walletdb.ReadWriteTx {
|
|||
}
|
||||
}
|
||||
|
||||
// NextSequence returns an autoincrementing integer for the bucket.
|
||||
func (b *bucket) NextSequence() (uint64, error) {
|
||||
return (*bbolt.Bucket)(b).NextSequence()
|
||||
}
|
||||
|
||||
// SetSequence updates the sequence number for the bucket.
|
||||
func (b *bucket) SetSequence(v uint64) error {
|
||||
return (*bbolt.Bucket)(b).SetSequence(v)
|
||||
}
|
||||
|
||||
// Sequence returns the current integer for the bucket without incrementing it.
|
||||
func (b *bucket) Sequence() uint64 {
|
||||
return (*bbolt.Bucket)(b).Sequence()
|
||||
}
|
||||
|
||||
// cursor represents a cursor over key/value pairs and nested buckets of a
|
||||
// bucket.
|
||||
//
|
||||
|
|
|
@ -23,7 +23,7 @@ func TestCreateOpenFail(t *testing.T) {
|
|||
// Ensure that attempting to open a database that doesn't exist returns
|
||||
// the expected error.
|
||||
wantErr := walletdb.ErrDbDoesNotExist
|
||||
if _, err := walletdb.Open(dbType, "noexist.db"); err != wantErr {
|
||||
if _, err := walletdb.Open(dbType, "noexist.db", true); err != wantErr {
|
||||
t.Errorf("Open: did not receive expected error - got %v, "+
|
||||
"want %v", err, wantErr)
|
||||
return
|
||||
|
@ -32,7 +32,7 @@ func TestCreateOpenFail(t *testing.T) {
|
|||
// Ensure that attempting to open a database with the wrong number of
|
||||
// parameters returns the expected error.
|
||||
wantErr = fmt.Errorf("invalid arguments to %s.Open -- expected "+
|
||||
"database path", dbType)
|
||||
"database path and no-freelist-sync option", dbType)
|
||||
if _, err := walletdb.Open(dbType, 1, 2, 3); err.Error() != wantErr.Error() {
|
||||
t.Errorf("Open: did not receive expected error - got %v, "+
|
||||
"want %v", err, wantErr)
|
||||
|
@ -43,7 +43,7 @@ func TestCreateOpenFail(t *testing.T) {
|
|||
// the first parameter returns the expected error.
|
||||
wantErr = fmt.Errorf("first argument to %s.Open is invalid -- "+
|
||||
"expected database path string", dbType)
|
||||
if _, err := walletdb.Open(dbType, 1); err.Error() != wantErr.Error() {
|
||||
if _, err := walletdb.Open(dbType, 1, true); err.Error() != wantErr.Error() {
|
||||
t.Errorf("Open: did not receive expected error - got %v, "+
|
||||
"want %v", err, wantErr)
|
||||
return
|
||||
|
@ -52,7 +52,7 @@ func TestCreateOpenFail(t *testing.T) {
|
|||
// Ensure that attempting to create a database with the wrong number of
|
||||
// parameters returns the expected error.
|
||||
wantErr = fmt.Errorf("invalid arguments to %s.Create -- expected "+
|
||||
"database path", dbType)
|
||||
"database path and no-freelist-sync option", dbType)
|
||||
if _, err := walletdb.Create(dbType, 1, 2, 3); err.Error() != wantErr.Error() {
|
||||
t.Errorf("Create: did not receive expected error - got %v, "+
|
||||
"want %v", err, wantErr)
|
||||
|
@ -63,7 +63,7 @@ func TestCreateOpenFail(t *testing.T) {
|
|||
// the first parameter returns the expected error.
|
||||
wantErr = fmt.Errorf("first argument to %s.Create is invalid -- "+
|
||||
"expected database path string", dbType)
|
||||
if _, err := walletdb.Create(dbType, 1); err.Error() != wantErr.Error() {
|
||||
if _, err := walletdb.Create(dbType, 1, true); err.Error() != wantErr.Error() {
|
||||
t.Errorf("Create: did not receive expected error - got %v, "+
|
||||
"want %v", err, wantErr)
|
||||
return
|
||||
|
@ -72,7 +72,7 @@ func TestCreateOpenFail(t *testing.T) {
|
|||
// Ensure operations against a closed database return the expected
|
||||
// error.
|
||||
dbPath := "createfail.db"
|
||||
db, err := walletdb.Create(dbType, dbPath)
|
||||
db, err := walletdb.Create(dbType, dbPath, true)
|
||||
if err != nil {
|
||||
t.Errorf("Create: unexpected error: %v", err)
|
||||
return
|
||||
|
@ -93,7 +93,7 @@ func TestCreateOpenFail(t *testing.T) {
|
|||
func TestPersistence(t *testing.T) {
|
||||
// Create a new database to run tests against.
|
||||
dbPath := "persistencetest.db"
|
||||
db, err := walletdb.Create(dbType, dbPath)
|
||||
db, err := walletdb.Create(dbType, dbPath, true)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create test database (%s) %v", dbType, err)
|
||||
return
|
||||
|
|
|
@ -126,6 +126,16 @@ type ReadWriteBucket interface {
|
|||
|
||||
// Tx returns the bucket's transaction.
|
||||
Tx() ReadWriteTx
|
||||
|
||||
// NextSequence returns an autoincrementing integer for the bucket.
|
||||
NextSequence() (uint64, error)
|
||||
|
||||
// SetSequence updates the sequence number for the bucket.
|
||||
SetSequence(v uint64) error
|
||||
|
||||
// Sequence returns the current integer for the bucket without
|
||||
// incrementing it.
|
||||
Sequence() uint64
|
||||
}
|
||||
|
||||
// ReadCursor represents a bucket cursor that can be positioned at the start or
|
||||
|
|
|
@ -104,6 +104,51 @@ func testNestedReadWriteBucket(tc *testContext, testBucket walletdb.ReadWriteBuc
|
|||
return true
|
||||
}
|
||||
|
||||
// testSequence tests that the sequence related methods work as expected.
|
||||
func testSequence(tc *testContext, testBucket walletdb.ReadWriteBucket) bool {
|
||||
// Obtaining the current sequence twice should give us the same value.
|
||||
seqNo1 := testBucket.Sequence()
|
||||
seqNo2 := testBucket.Sequence()
|
||||
if seqNo1 != seqNo2 {
|
||||
tc.t.Errorf("Sequence: seq has incremented")
|
||||
return false
|
||||
}
|
||||
|
||||
// Incrementing to the next sequence should give us a value one larger
|
||||
// than the prior number.
|
||||
seqNo3, err := testBucket.NextSequence()
|
||||
if err != nil {
|
||||
tc.t.Errorf("Sequence: unexpected error: %v", err)
|
||||
return false
|
||||
}
|
||||
if seqNo3 != seqNo2+1 {
|
||||
tc.t.Errorf("Sequence: expected seq no of %v, instead got %v",
|
||||
seqNo2+1, seqNo3)
|
||||
return false
|
||||
}
|
||||
|
||||
// We should be able to modify the sequence base number.
|
||||
newBase := uint64(100)
|
||||
if err := testBucket.SetSequence(newBase); err != nil {
|
||||
tc.t.Errorf("Sequence: unexpected error: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// Any offset from this new sequence should now be properly reflected.
|
||||
seqNo4, err := testBucket.NextSequence()
|
||||
if err != nil {
|
||||
tc.t.Errorf("Sequence: unexpected error: %v", err)
|
||||
return false
|
||||
}
|
||||
if seqNo4 != newBase+1 {
|
||||
tc.t.Errorf("Sequence: expected seq no of %v, instead got %v",
|
||||
newBase+1, seqNo4)
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// testReadWriteBucketInterface ensures the bucket interface is working properly by
|
||||
// exercising all of its functions.
|
||||
func testReadWriteBucketInterface(tc *testContext, bucket walletdb.ReadWriteBucket) bool {
|
||||
|
@ -164,6 +209,11 @@ func testReadWriteBucketInterface(tc *testContext, bucket walletdb.ReadWriteBuck
|
|||
return false
|
||||
}
|
||||
|
||||
// Test that the sequence methods work as expected.
|
||||
if !testSequence(tc, bucket) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Ensure creating a new bucket works as expected.
|
||||
testBucketName := []byte("testbucket")
|
||||
testBucket, err := bucket.CreateBucket(testBucketName)
|
||||
|
@ -678,7 +728,7 @@ func testAdditionalErrors(tc *testContext) bool {
|
|||
|
||||
// TestInterface performs all interfaces tests for this database driver.
|
||||
func TestInterface(t Tester, dbType, dbPath string) {
|
||||
db, err := walletdb.Create(dbType, dbPath)
|
||||
db, err := walletdb.Create(dbType, dbPath, true)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create test database (%s) %v", dbType, err)
|
||||
return
|
||||
|
|
Loading…
Reference in a new issue