diff --git a/database/store/cosmos.go b/database/store/cosmos.go new file mode 100644 index 000000000..c01790573 --- /dev/null +++ b/database/store/cosmos.go @@ -0,0 +1,97 @@ +package store + +import ( + "github.com/cosmos/cosmos-sdk/types" +) + +// CosmosStore is a Cosmos KVStore implementation of Store. +type CosmosStore struct { + store types.KVStore +} + +// NewCosmosStore returns a new Cosmos KVStore wrapper. +func NewCosmosStore(store types.KVStore) *CosmosStore { + return &CosmosStore{ + store: store, + } +} + +// NewIterator returns a new iterator. +func (s *CosmosStore) NewIterator() Iterator { + return NewCosmosIterator(types.KVStorePrefixIterator(s.store, nil)) +} + +// Has returns true if the key is set in the store. +func (s *CosmosStore) Has(key []byte) (bool, error) { + return s.store.Has(key), nil +} + +// Get retrives service from store. It returns ErrNotFound if the store does not contains the key. +func (s *CosmosStore) Get(key []byte) ([]byte, error) { + has, err := s.Has(key) + if err != nil { + return nil, err + } + if !has { + return nil, ErrNotFound + } + return s.store.Get(key), nil +} + +// Delete deletes the value for the given key. Delete will not returns error if key doesn't exist. +func (s *CosmosStore) Delete(key []byte) error { + s.store.Delete(key) + return nil +} + +// Put sets the value for the given key. It overwrites any previous value. +func (s *CosmosStore) Put(key []byte, value []byte) error { + s.store.Set(key, value) + return nil +} + +// Close closes the store. +func (s *CosmosStore) Close() error { + return nil +} + +// CosmosIterator is a Cosmos KVStore's iterator implementation of Iterator. +type CosmosIterator struct { + iter types.Iterator +} + +// NewCosmosIterator returns a new Cosmos KVStore Iterator wrapper. +func NewCosmosIterator(iter types.Iterator) *CosmosIterator { + return &CosmosIterator{ + iter: iter, + } +} + +// Next moves the iterator to the next sequential key in the store. +func (i *CosmosIterator) Next() bool { + if i.iter.Valid() { + i.iter.Next() + return true + } + return false +} + +// Key returns the key of the cursor. +func (i *CosmosIterator) Key() []byte { + return i.iter.Key() +} + +// Value returns the value of the cursor. +func (i *CosmosIterator) Value() []byte { + return i.iter.Value() +} + +// Release releases the Iterator. +func (i *CosmosIterator) Release() { + i.iter.Close() +} + +// Error returns any accumulated error. +func (i *CosmosIterator) Error() error { + return nil +} diff --git a/database/store/interface.go b/database/store/interface.go new file mode 100644 index 000000000..61789f1eb --- /dev/null +++ b/database/store/interface.go @@ -0,0 +1,45 @@ +package store + +import "errors" + +// Store describes the public API of a store. +type Store interface { + // Get retrives service from store. It returns ErrNotFound if the store does not contains the key. + Get(key []byte) ([]byte, error) + + // Has returns true if the key is set in the store. + Has(key []byte) (bool, error) + + // Delete deletes the value for the given key. Delete will not returns error if key doesn't exist. + Delete(key []byte) error + + // Put sets the value for the given key. It overwrites any previous value. + Put(key []byte, value []byte) error + + // NewIterator returns a new iterator. + NewIterator() Iterator + + // Close closes the store. + Close() error +} + +// Iterator describes the public API of an iterator. +type Iterator interface { + // Next moves the iterator to the next sequential key in the store. + Next() bool + + // Key returns the key of the cursor. + Key() []byte + + // Value returns the value of the cursor. + Value() []byte + + // Release releases the Iterator. + Release() + + // Error returns any accumulated error. + Error() error +} + +// ErrNotFound is throw when getting a non-existing key. +var ErrNotFound = errors.New("store: not found") diff --git a/database/store/leveldb.go b/database/store/leveldb.go new file mode 100644 index 000000000..4e6be1c87 --- /dev/null +++ b/database/store/leveldb.go @@ -0,0 +1,58 @@ +package store + +import ( + "github.com/syndtr/goleveldb/leveldb" +) + +// LevelDBStore is a levelDB implementation of Store. +type LevelDBStore struct { + db *leveldb.DB +} + +// NewLevelDBStore returns a new level db wrapper. +func NewLevelDBStore(path string) (*LevelDBStore, error) { + db, err := leveldb.OpenFile(path, nil) + if err != nil { + return nil, err + } + return &LevelDBStore{ + db: db, + }, nil +} + +// NewIterator returns a new iterator. +func (s *LevelDBStore) NewIterator() Iterator { + return s.db.NewIterator(nil, nil) +} + +// Has returns true if the key is set in the store. +func (s *LevelDBStore) Has(key []byte) (bool, error) { + return s.db.Has(key, nil) +} + +// Get retrives service from store. It returns ErrNotFound if the store does not contains the key. +func (s *LevelDBStore) Get(key []byte) ([]byte, error) { + value, err := s.db.Get(key, nil) + if err == leveldb.ErrNotFound { + return nil, ErrNotFound + } + if err != nil { + return nil, err + } + return value, nil +} + +// Delete deletes the value for the given key. Delete will not returns error if key doesn't exist. +func (s *LevelDBStore) Delete(key []byte) error { + return s.db.Delete(key, nil) +} + +// Put sets the value for the given key. It overwrites any previous value. +func (s *LevelDBStore) Put(key []byte, value []byte) error { + return s.db.Put(key, value, nil) +} + +// Close closes the store. +func (s *LevelDBStore) Close() error { + return s.db.Close() +}