github.com/Finschia/finschia-sdk@v0.48.1/store/listenkv/store.go (about)

     1  package listenkv
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/Finschia/finschia-sdk/store/types"
     7  )
     8  
     9  var _ types.KVStore = &Store{}
    10  
    11  // Store implements the KVStore interface with listening enabled.
    12  // Operations are traced on each core KVStore call and written to any of the
    13  // underlying listeners with the proper key and operation permissions
    14  type Store struct {
    15  	parent         types.KVStore
    16  	listeners      []types.WriteListener
    17  	parentStoreKey types.StoreKey
    18  }
    19  
    20  // NewStore returns a reference to a new traceKVStore given a parent
    21  // KVStore implementation and a buffered writer.
    22  func NewStore(parent types.KVStore, parentStoreKey types.StoreKey, listeners []types.WriteListener) *Store {
    23  	return &Store{parent: parent, listeners: listeners, parentStoreKey: parentStoreKey}
    24  }
    25  
    26  // Get implements the KVStore interface. It traces a read operation and
    27  // delegates a Get call to the parent KVStore.
    28  func (s *Store) Get(key []byte) []byte {
    29  	value := s.parent.Get(key)
    30  	return value
    31  }
    32  
    33  // Set implements the KVStore interface. It traces a write operation and
    34  // delegates the Set call to the parent KVStore.
    35  func (s *Store) Set(key []byte, value []byte) {
    36  	types.AssertValidKey(key)
    37  	s.parent.Set(key, value)
    38  	s.onWrite(false, key, value)
    39  }
    40  
    41  // Delete implements the KVStore interface. It traces a write operation and
    42  // delegates the Delete call to the parent KVStore.
    43  func (s *Store) Delete(key []byte) {
    44  	s.parent.Delete(key)
    45  	s.onWrite(true, key, nil)
    46  }
    47  
    48  // Has implements the KVStore interface. It delegates the Has call to the
    49  // parent KVStore.
    50  func (s *Store) Has(key []byte) bool {
    51  	return s.parent.Has(key)
    52  }
    53  
    54  // Iterator implements the KVStore interface. It delegates the Iterator call
    55  // the to the parent KVStore.
    56  func (s *Store) Iterator(start, end []byte) types.Iterator {
    57  	return s.iterator(start, end, true)
    58  }
    59  
    60  // ReverseIterator implements the KVStore interface. It delegates the
    61  // ReverseIterator call the to the parent KVStore.
    62  func (s *Store) ReverseIterator(start, end []byte) types.Iterator {
    63  	return s.iterator(start, end, false)
    64  }
    65  
    66  // iterator facilitates iteration over a KVStore. It delegates the necessary
    67  // calls to it's parent KVStore.
    68  func (s *Store) iterator(start, end []byte, ascending bool) types.Iterator {
    69  	var parent types.Iterator
    70  
    71  	if ascending {
    72  		parent = s.parent.Iterator(start, end)
    73  	} else {
    74  		parent = s.parent.ReverseIterator(start, end)
    75  	}
    76  
    77  	return newTraceIterator(parent, s.listeners)
    78  }
    79  
    80  type listenIterator struct {
    81  	parent    types.Iterator
    82  	listeners []types.WriteListener
    83  }
    84  
    85  func newTraceIterator(parent types.Iterator, listeners []types.WriteListener) types.Iterator {
    86  	return &listenIterator{parent: parent, listeners: listeners}
    87  }
    88  
    89  // Domain implements the Iterator interface.
    90  func (li *listenIterator) Domain() (start []byte, end []byte) {
    91  	return li.parent.Domain()
    92  }
    93  
    94  // Valid implements the Iterator interface.
    95  func (li *listenIterator) Valid() bool {
    96  	return li.parent.Valid()
    97  }
    98  
    99  // Next implements the Iterator interface.
   100  func (li *listenIterator) Next() {
   101  	li.parent.Next()
   102  }
   103  
   104  // Key implements the Iterator interface.
   105  func (li *listenIterator) Key() []byte {
   106  	key := li.parent.Key()
   107  	return key
   108  }
   109  
   110  // Value implements the Iterator interface.
   111  func (li *listenIterator) Value() []byte {
   112  	value := li.parent.Value()
   113  	return value
   114  }
   115  
   116  // Close implements the Iterator interface.
   117  func (li *listenIterator) Close() error {
   118  	return li.parent.Close()
   119  }
   120  
   121  // Error delegates the Error call to the parent iterator.
   122  func (li *listenIterator) Error() error {
   123  	return li.parent.Error()
   124  }
   125  
   126  // GetStoreType implements the KVStore interface. It returns the underlying
   127  // KVStore type.
   128  func (s *Store) GetStoreType() types.StoreType {
   129  	return s.parent.GetStoreType()
   130  }
   131  
   132  // CacheWrap implements the KVStore interface. It panics as a Store
   133  // cannot be cache wrapped.
   134  func (s *Store) CacheWrap() types.CacheWrap {
   135  	panic("cannot CacheWrap a ListenKVStore")
   136  }
   137  
   138  // CacheWrapWithTrace implements the KVStore interface. It panics as a
   139  // Store cannot be cache wrapped.
   140  func (s *Store) CacheWrapWithTrace(_ io.Writer, _ types.TraceContext) types.CacheWrap {
   141  	panic("cannot CacheWrapWithTrace a ListenKVStore")
   142  }
   143  
   144  // CacheWrapWithListeners implements the KVStore interface. It panics as a
   145  // Store cannot be cache wrapped.
   146  func (s *Store) CacheWrapWithListeners(_ types.StoreKey, _ []types.WriteListener) types.CacheWrap {
   147  	panic("cannot CacheWrapWithListeners a ListenKVStore")
   148  }
   149  
   150  // onWrite writes a KVStore operation to all of the WriteListeners
   151  func (s *Store) onWrite(delete bool, key, value []byte) {
   152  	for _, l := range s.listeners {
   153  		l.OnWrite(s.parentStoreKey, key, value, delete)
   154  	}
   155  }