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  }