github.com/s7techlab/cckit@v0.10.5/state/mapping/state.go (about) 1 package mapping 2 3 import ( 4 "fmt" 5 6 "go.uber.org/zap" 7 8 pb "github.com/hyperledger/fabric-protos-go/peer" 9 "github.com/pkg/errors" 10 11 "github.com/s7techlab/cckit/state" 12 "github.com/s7techlab/cckit/state/schema" 13 ) 14 15 type ( 16 MappedState interface { 17 state.State 18 19 // ListWith allows to refine search criteria by adding to namespace key parts 20 ListWith(schema interface{}, key state.Key) (result interface{}, err error) 21 22 // ListPaginatedWith allows to refine search criteria by adding to namespace key parts with pagination 23 ListPaginatedWith(schema interface{}, key state.Key, pageSize int32, bookmark string) ( 24 result interface{}, metadata *pb.QueryResponseMetadata, err error) 25 26 // GetByUniqKey return one entry 27 // Deprecated: use GetByKey 28 GetByUniqKey(schema interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) 29 30 // GetByKey 31 GetByKey(schema interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) 32 } 33 34 Impl struct { 35 state.State 36 mappings StateMappings 37 } 38 ) 39 40 func WrapState(s state.State, mappings StateMappings) *Impl { 41 return &Impl{ 42 State: s, 43 mappings: mappings, 44 } 45 } 46 47 func (s *Impl) MappingNamespace(schema interface{}) (state.Key, error) { 48 m, err := s.mappings.Get(schema) 49 if err != nil { 50 return nil, err 51 } 52 53 return m.Namespace(), nil 54 } 55 56 func (s *Impl) Get(entry interface{}, target ...interface{}) (interface{}, error) { 57 mapped, err := s.mappings.Map(entry) 58 if err != nil { // mapping is not exists 59 return s.State.Get(entry, target...) // return as is 60 } 61 62 // target was not set, but we can knew about target from mapping 63 if len(target) == 0 { 64 var targetFromMapping interface{} 65 if mapped.Mapper().KeyerFor() != nil { 66 targetFromMapping = mapped.Mapper().KeyerFor() 67 } else { 68 targetFromMapping = mapped.Mapper().Schema() 69 } 70 target = append(target, targetFromMapping) 71 } 72 73 return s.State.Get(mapped, target...) 74 } 75 76 func (s *Impl) GetHistory(entry interface{}, target interface{}) (state.HistoryEntryList, error) { 77 mapped, err := s.mappings.Map(entry) 78 if err != nil { // mapping is not exists 79 return s.State.GetHistory(entry, target) // return as is 80 } 81 82 return s.State.GetHistory(mapped, target) 83 } 84 85 func (s *Impl) Exists(entry interface{}) (bool, error) { 86 mapped, err := s.mappings.Map(entry) 87 if err != nil { // mapping is not exists 88 return s.State.Exists(entry) // return as is 89 } 90 91 return s.State.Exists(mapped) 92 } 93 94 func (s *Impl) Put(entry interface{}, value ...interface{}) error { 95 mapped, err := s.mappings.Map(entry) 96 if err != nil { // mapping is not exists 97 return s.State.Put(entry, value...) // return as is 98 } 99 100 // update ref keys 101 if len(mapped.Mapper().Indexes()) > 0 { 102 keyRefs, err := mapped.Keys() // key refs based on current entry value, defined by mapping indexes 103 if err != nil { 104 return errors.Wrap(err, `put mapping key refs`) 105 } 106 107 var insertKeyRefs, deleteKeyRefs []state.KeyValue 108 //get previous entry value 109 prevEntry, err := s.Get(entry) 110 111 if err == nil { // prev exists 112 113 // prev entry exists, calculate refs to delete and to insert 114 prevMapped, err := s.mappings.Map(prevEntry) 115 if err != nil { 116 return errors.Wrap(err, `get prev`) 117 } 118 prevKeyRefs, err := prevMapped.Keys() // key refs based on current entry value, defined by mapping indexes 119 if err != nil { 120 return errors.Wrap(err, `previ keys`) 121 } 122 123 deleteKeyRefs, insertKeyRefs, err = KeyRefsDiff(prevKeyRefs, keyRefs) 124 if err != nil { 125 return errors.Wrap(err, `calculate ref keys diff`) 126 } 127 128 } else { 129 // prev entry not exists, all current key refs should be inserted 130 insertKeyRefs = keyRefs 131 } 132 133 // delete previous key refs if key exists 134 for _, kr := range deleteKeyRefs { 135 if err = s.State.Delete(kr); err != nil { 136 return errors.Wrap(err, `delete previous mapping key ref`) 137 } 138 } 139 140 // insert new key refs 141 for _, kr := range insertKeyRefs { 142 if err = s.State.Insert(kr); err != nil { 143 return fmt.Errorf(`%s: %s`, ErrMappingUniqKeyExists, err) 144 } 145 } 146 } 147 148 return s.State.Put(mapped) 149 } 150 151 func (s *Impl) Insert(entry interface{}, value ...interface{}) error { 152 mapped, err := s.mappings.Map(entry) 153 if err != nil { // mapping is not exists 154 return s.State.Insert(entry, value...) // return as is 155 } 156 157 keyRefs, err := mapped.Keys() // key refs, defined by mapping indexes 158 if err != nil { 159 return err 160 } 161 162 // insert key refs, if key already exists - error returned 163 for _, kr := range keyRefs { 164 if err = s.State.Insert(kr); err != nil { 165 return fmt.Errorf(`%s: %s`, ErrMappingUniqKeyExists, err) 166 } 167 } 168 169 return s.State.Insert(mapped) 170 } 171 172 func (s *Impl) List(entry interface{}, target ...interface{}) (interface{}, error) { 173 if !s.mappings.Exists(entry) { 174 return s.State.List(entry, target...) 175 } 176 177 m, err := s.mappings.Get(entry) 178 if err != nil { 179 return nil, errors.Wrap(err, `mapping`) 180 } 181 182 namespace := m.Namespace() 183 s.Logger().Debug(`state mapped LIST`, zap.String(`namespace`, namespace.String())) 184 185 return s.State.List(namespace, m.Schema(), m.List()) 186 } 187 188 func (s *Impl) ListPaginated(entry interface{}, pageSize int32, bookmark string, target ...interface{}) ( 189 interface{}, *pb.QueryResponseMetadata, error) { 190 if !s.mappings.Exists(entry) { 191 return s.State.ListPaginated(entry, pageSize, bookmark, target...) 192 } 193 194 m, err := s.mappings.Get(entry) 195 if err != nil { 196 return nil, nil, errors.Wrap(err, `mapping`) 197 } 198 199 namespace := m.Namespace() 200 s.Logger().Debug(`state mapped LIST`, zap.String(`namespace`, namespace.String()), 201 zap.Int32("pageSize", pageSize), zap.String("bookmark", bookmark)) 202 203 return s.State.ListPaginated(namespace, pageSize, bookmark, m.Schema(), m.List()) 204 } 205 206 func (s *Impl) ListWith(entry interface{}, key state.Key) (result interface{}, err error) { 207 if !s.mappings.Exists(entry) { 208 return nil, ErrStateMappingNotFound 209 } 210 m, err := s.mappings.Get(entry) 211 if err != nil { 212 return nil, errors.Wrap(err, `mapping`) 213 } 214 215 namespace := m.Namespace() 216 s.Logger().Debug(`state mapped LIST`, zap.String(`namespace`, namespace.String()), zap.String(`list`, namespace.Append(key).String())) 217 218 return s.State.List(namespace.Append(key), m.Schema(), m.List()) 219 } 220 221 func (s *Impl) ListPaginatedWith( 222 schema interface{}, key state.Key, pageSize int32, bookmark string) ( 223 result interface{}, metadata *pb.QueryResponseMetadata, err error) { 224 if !s.mappings.Exists(schema) { 225 return nil, nil, ErrStateMappingNotFound 226 } 227 m, err := s.mappings.Get(schema) 228 if err != nil { 229 return nil, nil, errors.Wrap(err, `mapping`) 230 } 231 232 namespace := m.Namespace() 233 s.Logger().Debug(`state mapped LIST`, 234 zap.String(`namespace`, namespace.String()), zap.String(`list`, namespace.Append(key).String()), 235 zap.Int32("pageSize", pageSize), zap.String("bookmark", bookmark)) 236 237 return s.State.ListPaginated(namespace.Append(key), pageSize, bookmark, m.Schema(), m.List()) 238 } 239 240 func (s *Impl) GetByUniqKey( 241 entry interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) { 242 return s.GetByKey(entry, idx, idxVal, target...) 243 } 244 245 func (s *Impl) GetByKey( 246 entry interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) { 247 248 if !s.mappings.Exists(entry) { 249 return nil, ErrStateMappingNotFound 250 } 251 252 keyRef, err := s.State.Get(NewKeyRefIDInstance(entry, idx, idxVal), &schema.KeyRef{}) 253 if err != nil { 254 return nil, errors.Errorf(`%s: {%s}.%s: %s`, ErrIndexReferenceNotFound, mapKey(entry), idx, err) 255 } 256 257 return s.State.Get(keyRef.(*schema.KeyRef).PKey, target...) 258 } 259 260 func (s *Impl) Delete(entry interface{}) error { 261 if !s.mappings.Exists(entry) { 262 return s.State.Delete(entry) // return as is 263 } 264 265 // we need full entry data fro state 266 // AND entry can be record to delete or reference to record 267 // If entry is keyer entity for another entry (reference) 268 entry, err := s.Get(entry) 269 if err != nil { 270 return err 271 } 272 273 mapped, err := s.mappings.Map(entry) 274 if err != nil { 275 return err 276 } 277 278 keyRefs, err := mapped.Keys() // additional keys 279 if err != nil { 280 return err 281 } 282 283 // delete uniq key refs 284 for _, kr := range keyRefs { 285 if err = s.State.Delete(kr); err != nil { 286 return errors.Wrap(err, `delete ref key`) 287 } 288 } 289 290 return s.State.Delete(mapped) 291 } 292 293 func (s *Impl) Logger() *zap.Logger { 294 return s.State.Logger() 295 } 296 297 func (s *Impl) UseKeyTransformer(kt state.KeyTransformer) { 298 s.State.UseKeyTransformer(kt) 299 } 300 301 func (s *Impl) GetPrivate(collection string, entry interface{}, target ...interface{}) (result interface{}, err error) { 302 mapped, err := s.mappings.Map(entry) 303 if err != nil { // mapping is not exists 304 return s.State.GetPrivate(collection, entry, target...) // return as is 305 } 306 307 return s.State.GetPrivate(collection, mapped, target...) 308 } 309 310 func (s *Impl) DeletePrivate(collection string, entry interface{}) (err error) { 311 312 mapped, err := s.mappings.Map(entry) 313 if err != nil { // mapping is not exists 314 return s.State.DeletePrivate(collection, entry) // return as is 315 } 316 317 return s.State.DeletePrivate(collection, mapped) 318 } 319 320 func (s *Impl) ListPrivate(collection string, usePrivateDataIterator bool, namespace interface{}, target ...interface{}) (result interface{}, err error) { 321 if !s.mappings.Exists(namespace) { 322 return s.State.ListPrivate(collection, usePrivateDataIterator, namespace, target...) 323 } 324 m, err := s.mappings.Get(namespace) 325 if err != nil { 326 return nil, errors.Wrap(err, `mapping`) 327 } 328 329 namespace = m.Namespace() 330 s.Logger().Debug(`private state mapped LIST`, zap.Reflect(`namespace`, namespace)) 331 return s.State.ListPrivate(collection, usePrivateDataIterator, namespace, target[0], m.List()) 332 } 333 334 func (s *Impl) InsertPrivate(collection string, entry interface{}, value ...interface{}) (err error) { 335 mapped, err := s.mappings.Map(entry) 336 if err != nil { // mapping is not exists 337 return s.State.InsertPrivate(collection, entry, value...) // return as is 338 } 339 340 keyRefs, err := mapped.Keys() // additional keys 341 if err != nil { 342 return 343 } 344 345 // insert uniq key refs. if key already exists - error returned 346 for _, kr := range keyRefs { 347 if err = s.State.InsertPrivate(collection, kr); err != nil { 348 return fmt.Errorf(`%s: %s`, ErrMappingUniqKeyExists, err) 349 } 350 } 351 352 return s.State.InsertPrivate(collection, mapped) 353 } 354 355 func (s *Impl) PutPrivate(collection string, entry interface{}, value ...interface{}) (err error) { 356 mapped, err := s.mappings.Map(entry) 357 if err != nil { // mapping is not exists 358 return s.State.PutPrivate(collection, entry, value...) // return as is 359 } 360 361 keyRefs, err := mapped.Keys() // additional keys 362 if err != nil { 363 return 364 } 365 366 // delete previous key refs if key exists 367 368 // put uniq key refs. if key already exists - error returned 369 for _, kr := range keyRefs { 370 if err = s.State.PutPrivate(collection, kr); err != nil { 371 return fmt.Errorf(`%s: %s`, ErrMappingUniqKeyExists, err) 372 } 373 } 374 375 return s.State.PutPrivate(collection, mapped) 376 } 377 378 func (s *Impl) ExistsPrivate(collection string, entry interface{}) (exists bool, err error) { 379 mapped, err := s.mappings.Map(entry) 380 if err != nil { // mapping is not exists 381 return s.State.ExistsPrivate(collection, entry) // return as is 382 } 383 384 return s.State.ExistsPrivate(collection, mapped) 385 }