diff --git a/internal/test/storage.go b/internal/test/storage.go index 35ecdd00d..b894f4187 100644 --- a/internal/test/storage.go +++ b/internal/test/storage.go @@ -36,6 +36,7 @@ type MockKeyValueStore struct { GetCalled int PutCalled int ListCalled int + ListV2Called int ReverseListCalled int DeleteCalled int CloseCalled int @@ -119,6 +120,12 @@ func (m *MockKeyValueStore) List(startingKey storage.Key, limit storage.Limit) ( return keys, nil } +// ListV2 returns either a list of items for which the MockKeyValueStore has values and an error. +func (m *MockKeyValueStore) ListV2(opts storage.ListOptions) (storage.Items, storage.More, error) { + m.ListV2Called++ + panic("TODO") +} + // GetAll is a noop to adhere to the interface func (m *MockKeyValueStore) GetAll(keys storage.Keys) (values storage.Values, err error) { result := storage.Values{} @@ -163,6 +170,7 @@ func NewMockKeyValueStore(d KvStore) *MockKeyValueStore { GetCalled: 0, PutCalled: 0, ListCalled: 0, + ListV2Called: 0, ReverseListCalled: 0, DeleteCalled: 0, CloseCalled: 0, diff --git a/pkg/pointerdb/kvstore_mock_test.go b/pkg/pointerdb/kvstore_mock_test.go index 2d77a2782..227a89e29 100644 --- a/pkg/pointerdb/kvstore_mock_test.go +++ b/pkg/pointerdb/kvstore_mock_test.go @@ -1,9 +1,7 @@ -// Copyright (C) 2018 Storj Labs, Inc. -// See LICENSE for copying information. // Code generated by MockGen. DO NOT EDIT. // Source: storj.io/storj/storage (interfaces: KeyValueStore) -// Package pointerdb is a generated GoMock package. +// Package mock_storage is a generated GoMock package. package pointerdb import ( @@ -99,6 +97,20 @@ func (mr *MockKeyValueStoreMockRecorder) List(arg0, arg1 interface{}) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockKeyValueStore)(nil).List), arg0, arg1) } +// ListV2 mocks base method +func (m *MockKeyValueStore) ListV2(arg0 storage.ListOptions) (storage.Items, storage.More, error) { + ret := m.ctrl.Call(m, "ListV2", arg0) + ret0, _ := ret[0].(storage.Items) + ret1, _ := ret[1].(storage.More) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ListV2 indicates an expected call of ListV2 +func (mr *MockKeyValueStoreMockRecorder) ListV2(arg0 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListV2", reflect.TypeOf((*MockKeyValueStore)(nil).ListV2), arg0) +} + // Put mocks base method func (m *MockKeyValueStore) Put(arg0 storage.Key, arg1 storage.Value) error { ret := m.ctrl.Call(m, "Put", arg0, arg1) diff --git a/storage/boltdb/client.go b/storage/boltdb/client.go index 91cfd94c3..328acf19e 100644 --- a/storage/boltdb/client.go +++ b/storage/boltdb/client.go @@ -145,6 +145,12 @@ func prevOrNext(reverseList bool, cur *bolt.Cursor) func() ([]byte, []byte) { return cur.Next } +//ListV2 is the new definition and will replace `List` definition +func (c *Client) ListV2(opts storage.ListOptions) (storage.Items, storage.More, error) { + //TODO write the implementation + panic("to do") +} + // Delete deletes a key/value pair from boltdb, for a given the key func (c *Client) Delete(pathKey storage.Key) error { c.logger.Debug("entering bolt delete: " + string(pathKey)) diff --git a/storage/common.go b/storage/common.go index e7885a338..7cc599d08 100644 --- a/storage/common.go +++ b/storage/common.go @@ -25,6 +25,32 @@ type Values []Value // Limit indicates how many keys to return when calling List type Limit int +// More indicates if the result was truncated. If false +// then the result []ListItem includes all requested keys. +// If true then the caller must call List again to get more +// results by setting `StartAfter` or `EndBefore` appropriately. +type More bool + +// ListOptions are items that are optional for the LIST method +type ListOptions struct { + Prefix Key + StartAfter Key + EndBefore Key + Recursive bool + IncludeValue bool + Limit Limit +} + +// Items keeps all ListItem +type Items []ListItem + +// ListItem returns Key, Value, IsPrefix +type ListItem struct { + Key Key + Value Value + IsPrefix bool +} + // KeyValueStore is an interface describing key/value stores like redis and boltdb type KeyValueStore interface { // Put adds a value to the provided key in the KeyValueStore, returning an error on failure. @@ -32,6 +58,7 @@ type KeyValueStore interface { Get(Key) (Value, error) GetAll(Keys) (Values, error) List(Key, Limit) (Keys, error) + ListV2(opts ListOptions) (Items, More, error) ReverseList(Key, Limit) (Keys, error) Delete(Key) error Close() error @@ -72,3 +99,15 @@ func (k *Keys) ByteSlices() [][]byte { func (k *Key) String() string { return string(*k) } + +// GetKeys gets all the Keys in []ListItem and converts them to Keys +func (i *Items) GetKeys() Keys { + if len(*i) == 0 { + return nil + } + var keys Keys + for _, item := range *i { + keys = append(keys, item.Key) + } + return keys +} diff --git a/storage/redis/client.go b/storage/redis/client.go index 45cfaea66..5a336bb1e 100644 --- a/storage/redis/client.go +++ b/storage/redis/client.go @@ -112,6 +112,12 @@ func (c *Client) List(startingKey storage.Key, limit storage.Limit) (storage.Key return listKeys, nil } +//ListV2 is the new definition and will replace `List` definition +func (c *Client) ListV2(opts storage.ListOptions) (storage.Items, storage.More, error) { + //TODO write the implementation + panic("to do") +} + // ReverseList returns either a list of keys for which redis has values or an error. // Starts from startingKey and iterates backwards func (c *Client) ReverseList(startingKey storage.Key, limit storage.Limit) (storage.Keys, error) {