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 }