From 61918f7f99e99693e0cbdf5762f05453f0dcb7ff Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sat, 6 Apr 2019 20:34:55 +0200 Subject: [PATCH] add leveldb as db --- README.md | 2 +- db/leveldb.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++ db/leveldb_test.go | 53 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 db/leveldb.go create mode 100644 db/leveldb_test.go diff --git a/README.md b/README.md index 26836c9..08c77ba 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # slowlorisdb -Slow and decentralized cryptographically consistent database +Slow, decentralized and cryptographically consistent database ![slowloris](https://04019a5a-a-62cb3a1a-s-sites.googlegroups.com/site/jchristensensdigitalportfolio/slow-loris/IO-moth-eating-frozen-apple-sauce.jpg "slowloris") diff --git a/db/leveldb.go b/db/leveldb.go new file mode 100644 index 0000000..69e1f00 --- /dev/null +++ b/db/leveldb.go @@ -0,0 +1,55 @@ +package db + +import ( + "github.com/syndtr/goleveldb/leveldb" +) + +// Db is the database with the specified prefix +type Db struct { + ldb *leveldb.DB + prefix []byte +} + +// New creates a new Db database +func New(path string) (*Db, error) { + ldb, err := leveldb.OpenFile(path, nil) + if err != nil { + return nil, err + } + return &Db{ldb, []byte{}}, nil +} + +// WithPrefix returns a subdatabase with the specified prefix +func (db *Db) WithPrefix(prefix []byte) *Db { + return &Db{db.ldb, append(db.prefix, prefix...)} +} + +// Put adds the key value to the database +func (db *Db) Put(key, value []byte) error { + err := db.ldb.Put(append(db.prefix, key[:]...), value, nil) + return err +} + +// Get retreives a value from the database for a given key +func (db *Db) Get(key []byte) ([]byte, error) { + v, err := db.ldb.Get(append(db.prefix, key[:]...), nil) + if err != nil { + return nil, err + } + return v, nil +} + +// Iterate iterates over the database +func (db *Db) Iterate(f func([]byte, []byte)) error { + snapshot, err := db.ldb.GetSnapshot() + if err != nil { + return err + } + iter := snapshot.NewIterator(nil, nil) + for iter.Next() { + f(iter.Key(), iter.Value()) + } + iter.Release() + err = iter.Error() + return err +} diff --git a/db/leveldb_test.go b/db/leveldb_test.go new file mode 100644 index 0000000..28e4975 --- /dev/null +++ b/db/leveldb_test.go @@ -0,0 +1,53 @@ +package db + +import ( + "io/ioutil" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/syndtr/goleveldb/leveldb/errors" +) + +func TestNew(t *testing.T) { + dir, err := ioutil.TempDir("", "db") + assert.Nil(t, err) + _, err = New(dir) + assert.Nil(t, err) +} +func TestPutAndGet(t *testing.T) { + dir, err := ioutil.TempDir("", "db") + assert.Nil(t, err) + db, err := New(dir) + assert.Nil(t, err) + + k := []byte("test key") + v := []byte("test value") + + err = db.Put(k, v) + assert.Nil(t, err) + + vg, err := db.Get(k) + assert.Nil(t, err) + assert.Equal(t, v, vg) + +} + +func TestPrefix(t *testing.T) { + dir, err := ioutil.TempDir("", "db") + assert.Nil(t, err) + db, err := New(dir) + assert.Nil(t, err) + + dbPrefix := db.WithPrefix([]byte("prefix1")) + + err = dbPrefix.Put([]byte("k1"), []byte("v1")) + assert.Nil(t, err) + + _, err = db.Get([]byte("k1")) + assert.Equal(t, err, errors.ErrNotFound) + + v1, err := dbPrefix.Get([]byte("k1")) + assert.Nil(t, err) + assert.Equal(t, []byte("v1"), v1) +}