kvdb: add postgres

This commit is contained in:
Joost Jager
2021-07-13 12:07:48 +02:00
parent 9264185f5b
commit 3eb80cac97
19 changed files with 2055 additions and 10 deletions

View File

@@ -400,3 +400,224 @@ func testBucketCreateDelete(t *testing.T, db walletdb.DB) {
}, func() {})
require.NoError(t, err)
}
func testTopLevelBucketCreation(t *testing.T, db walletdb.DB) {
require.NoError(t, Update(db, func(tx walletdb.ReadWriteTx) error {
// Try to delete all data (there is none).
err := tx.DeleteTopLevelBucket([]byte("top"))
require.ErrorIs(t, walletdb.ErrBucketNotFound, err)
// Create top level bucket.
top, err := tx.CreateTopLevelBucket([]byte("top"))
require.NoError(t, err)
require.NotNil(t, top)
// Create second top level bucket with special characters.
top2, err := tx.CreateTopLevelBucket([]byte{1, 2, 3})
require.NoError(t, err)
require.NotNil(t, top2)
top2 = tx.ReadWriteBucket([]byte{1, 2, 3})
require.NotNil(t, top2)
// List top level buckets.
var tlKeys [][]byte
require.NoError(t, tx.ForEachBucket(func(k []byte) error {
tlKeys = append(tlKeys, k)
return nil
}))
require.Equal(t, [][]byte{{1, 2, 3}, []byte("top")}, tlKeys)
// Create third top level bucket with special uppercase.
top3, err := tx.CreateTopLevelBucket([]byte("UpperBucket"))
require.NoError(t, err)
require.NotNil(t, top3)
top3 = tx.ReadWriteBucket([]byte("UpperBucket"))
require.NotNil(t, top3)
require.NoError(t, tx.DeleteTopLevelBucket([]byte("top")))
require.NoError(t, tx.DeleteTopLevelBucket([]byte{1, 2, 3}))
require.NoError(t, tx.DeleteTopLevelBucket([]byte("UpperBucket")))
tx.ForEachBucket(func(k []byte) error {
require.Fail(t, "no top level buckets expected")
return nil
})
return nil
}, func() {}))
}
func testBucketOperations(t *testing.T, db walletdb.DB) {
require.NoError(t, Update(db, func(tx walletdb.ReadWriteTx) error {
// Create top level bucket.
top, err := tx.CreateTopLevelBucket([]byte("top"))
require.NoError(t, err)
require.NotNil(t, top)
// Assert that key doesn't exist.
require.Nil(t, top.Get([]byte("key")))
require.NoError(t, top.ForEach(func(k, v []byte) error {
require.Fail(t, "unexpected data")
return nil
}))
// Put key.
require.NoError(t, top.Put([]byte("key"), []byte("val")))
require.Equal(t, []byte("val"), top.Get([]byte("key")))
// Overwrite key.
require.NoError(t, top.Put([]byte("key"), []byte("val2")))
require.Equal(t, []byte("val2"), top.Get([]byte("key")))
// Put nil value.
require.NoError(t, top.Put([]byte("nilkey"), nil))
require.Equal(t, []byte(""), top.Get([]byte("nilkey")))
// Put empty value.
require.NoError(t, top.Put([]byte("nilkey"), []byte{}))
require.Equal(t, []byte(""), top.Get([]byte("nilkey")))
// Try to create bucket with same name as previous key.
_, err = top.CreateBucket([]byte("key"))
require.ErrorIs(t, err, walletdb.ErrIncompatibleValue)
_, err = top.CreateBucketIfNotExists([]byte("key"))
require.ErrorIs(t, err, walletdb.ErrIncompatibleValue)
// Create sub-bucket.
sub2, err := top.CreateBucket([]byte("sub2"))
require.NoError(t, err)
require.NotNil(t, sub2)
// Assert that re-creating the bucket fails.
_, err = top.CreateBucket([]byte("sub2"))
require.ErrorIs(t, err, walletdb.ErrBucketExists)
// Assert that create-if-not-exists succeeds.
_, err = top.CreateBucketIfNotExists([]byte("sub2"))
require.NoError(t, err)
// Assert that fetching the bucket succeeds.
sub2 = top.NestedReadWriteBucket([]byte("sub2"))
require.NotNil(t, sub2)
// Try to put key with same name as bucket.
require.ErrorIs(t, top.Put([]byte("sub2"), []byte("val")), walletdb.ErrIncompatibleValue)
// Put key into sub bucket.
require.NoError(t, sub2.Put([]byte("subkey"), []byte("subval")))
require.Equal(t, []byte("subval"), sub2.Get([]byte("subkey")))
// Overwrite key in sub bucket.
require.NoError(t, sub2.Put([]byte("subkey"), []byte("subval2")))
require.Equal(t, []byte("subval2"), sub2.Get([]byte("subkey")))
// Check for each result.
kvs := make(map[string][]byte)
require.NoError(t, top.ForEach(func(k, v []byte) error {
kvs[string(k)] = v
return nil
}))
require.Equal(t, map[string][]byte{
"key": []byte("val2"),
"nilkey": []byte(""),
"sub2": nil,
}, kvs)
// Delete key.
require.NoError(t, top.Delete([]byte("key")))
// Delete non-existent key.
require.NoError(t, top.Delete([]byte("keynonexistent")))
// Test cursor.
cursor := top.ReadWriteCursor()
k, v := cursor.First()
require.Equal(t, []byte("nilkey"), k)
require.Equal(t, []byte(""), v)
k, v = cursor.Last()
require.Equal(t, []byte("sub2"), k)
require.Nil(t, v)
k, v = cursor.Prev()
require.Equal(t, []byte("nilkey"), k)
require.Equal(t, []byte(""), v)
k, v = cursor.Prev()
require.Nil(t, k)
require.Nil(t, v)
k, v = cursor.Next()
require.Equal(t, []byte("sub2"), k)
require.Nil(t, v)
k, v = cursor.Next()
require.Nil(t, k)
require.Nil(t, v)
k, v = cursor.Seek([]byte("nilkey"))
require.Equal(t, []byte("nilkey"), k)
require.Equal(t, []byte(""), v)
require.NoError(t, sub2.Put([]byte("k1"), []byte("v1")))
require.NoError(t, sub2.Put([]byte("k2"), []byte("v2")))
require.NoError(t, sub2.Put([]byte("k3"), []byte("v3")))
cursor = sub2.ReadWriteCursor()
cursor.First()
for i := 0; i < 4; i++ {
require.NoError(t, cursor.Delete())
}
require.NoError(t, sub2.ForEach(func(k, v []byte) error {
require.Fail(t, "unexpected data")
return nil
}))
_, err = sub2.CreateBucket([]byte("sub3"))
require.NoError(t, err)
require.ErrorIs(t, cursor.Delete(), walletdb.ErrIncompatibleValue)
//Try to delete all data.
require.NoError(t, tx.DeleteTopLevelBucket([]byte("top")))
require.Nil(t, tx.ReadBucket([]byte("top")))
return nil
}, func() {}))
}
func testSubBucketSequence(t *testing.T, db walletdb.DB) {
require.NoError(t, Update(db, func(tx walletdb.ReadWriteTx) error {
// Create top level bucket.
top, err := tx.CreateTopLevelBucket([]byte("top"))
require.NoError(t, err)
require.NotNil(t, top)
// Create sub-bucket.
sub2, err := top.CreateBucket([]byte("sub2"))
require.NoError(t, err)
require.NotNil(t, sub2)
// Test sequence.
require.Equal(t, uint64(0), top.Sequence())
require.NoError(t, top.SetSequence(100))
require.Equal(t, uint64(100), top.Sequence())
require.NoError(t, top.SetSequence(101))
require.Equal(t, uint64(101), top.Sequence())
next, err := top.NextSequence()
require.NoError(t, err)
require.Equal(t, uint64(102), next)
next, err = sub2.NextSequence()
require.NoError(t, err)
require.Equal(t, uint64(1), next)
return nil
}, func() {}))
}