From 5f4539f05a0fd87445860f37fdf148b27399c4ab Mon Sep 17 00:00:00 2001 From: Victor Nosov Date: Mon, 9 Dec 2019 16:52:27 +0300 Subject: [PATCH] State multi keys (#35) entry index with multiple values (key instances) --- examples/cpaper_asservice/service/service.go | 2 +- examples/cpaper_extended/chaincode.go | 2 +- router/param/defparam/type.go | 4 + state/mapping/README.md | 16 + state/mapping/errors.go | 8 +- state/mapping/mapping_test.go | 303 ++++++++++------ state/mapping/state.go | 90 +++-- state/mapping/state_keyref.go | 2 +- state/mapping/state_mapping.go | 123 +++++-- state/mapping/state_mapping_opt.go | 131 +++++-- state/mapping/testdata/cc_composite_id.go | 85 +++++ state/mapping/testdata/cc_indexes.go | 91 +++++ state/mapping/testdata/cc_proto_entity.go | 93 ----- .../mapping/testdata/schema/complex_id.pb.go | 111 ------ .../testdata/schema/proto_schema.pb.go | 208 ----------- .../testdata/schema/proto_schema.proto | 37 -- state/mapping/testdata/schema/slice_id.pb.go | 58 --- .../testdata/schema/with_complex_id.pb.go | 141 ++++++++ ...complex_id.proto => with_complex_id.proto} | 0 .../testdata/schema/with_composite_id.pb.go | 330 ++++++++++++++++++ .../testdata/schema/with_composite_id.proto | 38 ++ .../testdata/schema/with_indexes.pb.go | 314 +++++++++++++++++ .../testdata/schema/with_indexes.proto | 49 +++ .../testdata/schema/with_slice_id.pb.go | 89 +++++ .../{slice_id.proto => with_slice_id.proto} | 0 state/mapping/testdata/testdata.go | 31 +- state/state.go | 20 +- 27 files changed, 1659 insertions(+), 717 deletions(-) create mode 100644 state/mapping/README.md create mode 100644 state/mapping/testdata/cc_composite_id.go create mode 100644 state/mapping/testdata/cc_indexes.go delete mode 100644 state/mapping/testdata/cc_proto_entity.go delete mode 100644 state/mapping/testdata/schema/complex_id.pb.go delete mode 100644 state/mapping/testdata/schema/proto_schema.pb.go delete mode 100644 state/mapping/testdata/schema/proto_schema.proto delete mode 100644 state/mapping/testdata/schema/slice_id.pb.go create mode 100644 state/mapping/testdata/schema/with_complex_id.pb.go rename state/mapping/testdata/schema/{complex_id.proto => with_complex_id.proto} (100%) create mode 100644 state/mapping/testdata/schema/with_composite_id.pb.go create mode 100644 state/mapping/testdata/schema/with_composite_id.proto create mode 100644 state/mapping/testdata/schema/with_indexes.pb.go create mode 100644 state/mapping/testdata/schema/with_indexes.proto create mode 100644 state/mapping/testdata/schema/with_slice_id.pb.go rename state/mapping/testdata/schema/{slice_id.proto => with_slice_id.proto} (100%) diff --git a/examples/cpaper_asservice/service/service.go b/examples/cpaper_asservice/service/service.go index 9368f10b..dc06ebf6 100644 --- a/examples/cpaper_asservice/service/service.go +++ b/examples/cpaper_asservice/service/service.go @@ -59,7 +59,7 @@ func (cc *CPaperImpl) Get(ctx router.Context, id *schema.CommercialPaperId) (*sc } func (cc *CPaperImpl) GetByExternalId(ctx router.Context, id *schema.ExternalId) (*schema.CommercialPaper, error) { - if res, err := cc.state(ctx).GetByUniqKey( + if res, err := cc.state(ctx).GetByKey( &schema.CommercialPaper{}, "ExternalId", []string{id.Id}, &schema.CommercialPaper{}); err != nil { return nil, err } else { diff --git a/examples/cpaper_extended/chaincode.go b/examples/cpaper_extended/chaincode.go index 8deee62d..e5e6644d 100644 --- a/examples/cpaper_extended/chaincode.go +++ b/examples/cpaper_extended/chaincode.go @@ -85,7 +85,7 @@ func queryCPaperGetByExternalId(c router.Context) (interface{}, error) { var ( externalId = c.ParamString("externalId") ) - return c.State().(m.MappedState).GetByUniqKey(&schema.CommercialPaper{}, "ExternalId", []string{externalId}) + return c.State().(m.MappedState).GetByKey(&schema.CommercialPaper{}, "ExternalId", []string{externalId}) } func invokeCPaperIssue(c router.Context) (res interface{}, err error) { diff --git a/router/param/defparam/type.go b/router/param/defparam/type.go index 24074439..c933a37f 100644 --- a/router/param/defparam/type.go +++ b/router/param/defparam/type.go @@ -8,3 +8,7 @@ import ( func Proto(target interface{}, argPoss ...int) router.MiddlewareFunc { return param.Proto(router.DefaultParam, target, argPoss...) } + +func String(argPoss ...int) router.MiddlewareFunc { + return param.String(router.DefaultParam, argPoss...) +} diff --git a/state/mapping/README.md b/state/mapping/README.md new file mode 100644 index 00000000..b50c74fe --- /dev/null +++ b/state/mapping/README.md @@ -0,0 +1,16 @@ +# State mappings + + +## Primary key + +### Primary key based on one or multiple fields + +### Entity (schema) as primary keyer + + + +## Additional indexes (keys) + +### Unique key + +### Unique Key with multiple values \ No newline at end of file diff --git a/state/mapping/errors.go b/state/mapping/errors.go index 2fa6ba61..b2ea46f3 100644 --- a/state/mapping/errors.go +++ b/state/mapping/errors.go @@ -6,7 +6,7 @@ var ( // ErrEntryTypeNotSupported entry type has no appropriate mapper type ErrEntryTypeNotSupported = errors.New(`entry type not supported for mapping`) - // ErrStateMappingNotFound occurs when mapping for state entry is not defined + // ErrStateMappingNotFound occurs when mapping for state entry is not defined ErrStateMappingNotFound = errors.New(`state mapping not found`) // ErrEventMappingNotFound occurs when mapping for event is not defined @@ -19,4 +19,10 @@ var ( ErrFieldNotExists = errors.New(`field is not exists`) ErrPrimaryKeyerNotDefined = errors.New(`primary keyer is not defined`) + + // ErrIndexAlreadyExists occurs when when trying to add index to mapping with existent name + ErrIndexAlreadyExists = errors.New(`index already exists`) + + // ErrIndexReferenceNotFound occurs when trying to find entry by index + ErrIndexReferenceNotFound = errors.New(`index reference not found`) ) diff --git a/state/mapping/mapping_test.go b/state/mapping/mapping_test.go index fbdfcc58..5f76f668 100644 --- a/state/mapping/mapping_test.go +++ b/state/mapping/mapping_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/gogo/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/hyperledger/fabric/protos/peer" identitytestdata "github.com/s7techlab/cckit/identity/testdata" @@ -25,8 +26,7 @@ func TestState(t *testing.T) { } var ( - protoCC, complexIDCC, sliceIDCC *testcc.MockStub - err error + compositeIDCC, complexIDCC, sliceIDCC, indexesCC *testcc.MockStub Owner = identitytestdata.Certificates[0].MustIdentity(`SOME_MSP`) ) @@ -34,163 +34,110 @@ var _ = Describe(`Mapping`, func() { BeforeSuite(func() { - protoCC = testcc.NewMockStub(`cpapers`, testdata.NewProtoCC()) - protoCC.From(Owner).Init() + compositeIDCC = testcc.NewMockStub(`proto`, testdata.NewCompositeIdCC()) + compositeIDCC.From(Owner).Init() - complexIDCC = testcc.NewMockStub(`complexid`, testdata.NewComplexIdCC()) + complexIDCC = testcc.NewMockStub(`complex_id`, testdata.NewComplexIdCC()) complexIDCC.From(Owner).Init() - sliceIDCC = testcc.NewMockStub(`sliceid`, testdata.NewSliceIdCC()) + sliceIDCC = testcc.NewMockStub(`slice_id`, testdata.NewSliceIdCC()) sliceIDCC.From(Owner).Init() + + indexesCC = testcc.NewMockStub(`indexes`, testdata.NewIndexesCC()) + indexesCC.From(Owner).Init() }) - Describe(`Commercial paper extended, protobuf based schema with additional keys`, func() { - issueMock1 := testdata.ProtoIssueMocks[0] - issueMock2 := testdata.ProtoIssueMocks[1] - issueMock3 := testdata.ProtoIssueMocks[2] - issueMockExistingExternal := testdata.ProtoIssueMockExistingExternal - issueMockExistingPrimary := testdata.ProtoIssueMockExistingPrimary + Describe(`Entity with composite id`, func() { + create1 := testdata.CreateEntityWithCompositeId[0] + create2 := testdata.CreateEntityWithCompositeId[1] + create3 := testdata.CreateEntityWithCompositeId[2] It("Allow to get mapping data by namespace", func() { - mapping, err := testdata.ProtoStateMapping.GetByNamespace(state.Key{`ProtoEntity`}) + mapping, err := testdata.EntityWithCompositeIdStateMapping.GetByNamespace(state.Key{`EntityWithCompositeId`}) Expect(err).NotTo(HaveOccurred()) - Expect(mapping.Schema()).To(BeEquivalentTo(&schema.ProtoEntity{})) + Expect(mapping.Schema()).To(BeEquivalentTo(&schema.EntityWithCompositeId{})) }) It("Allow to add data to chaincode state", func(done Done) { - events := protoCC.EventSubscription() - expectcc.ResponseOk(protoCC.Invoke(`issue`, &issueMock1)) + events := compositeIDCC.EventSubscription() + expectcc.ResponseOk(compositeIDCC.Invoke(`create`, create1)) Expect(<-events).To(BeEquivalentTo(&peer.ChaincodeEvent{ - EventName: `IssueProtoEntity`, - Payload: testcc.MustProtoMarshal(&issueMock1), + EventName: `CreateEntityWithCompositeId`, + Payload: testcc.MustProtoMarshal(create1), })) - expectcc.ResponseOk(protoCC.Invoke(`issue`, &issueMock2)) - expectcc.ResponseOk(protoCC.Invoke(`issue`, &issueMock3)) + expectcc.ResponseOk(compositeIDCC.Invoke(`create`, create2)) + expectcc.ResponseOk(compositeIDCC.Invoke(`create`, create3)) close(done) - }, 0.2) - - It("Disallow to insert entries with same uniq AND primary keys", func() { - expectcc.ResponseError(protoCC.Invoke(`issue`, &issueMock1)) - }) - - It("Disallow to add data to chaincode state with same uniq key fields", func() { - // errored on checking uniq key - expectcc.ResponseError( - protoCC.Invoke(`issue`, &issueMockExistingExternal), - mapping.ErrMappingUniqKeyExists) }) - It("Disallow adding data to chaincode state with same primary key fields", func() { - // errored obn checkong primary key - expectcc.ResponseError( - protoCC.Invoke(`issue`, &issueMockExistingPrimary), - state.ErrKeyAlreadyExists) + It("Disallow to insert entries with same primary key", func() { + expectcc.ResponseError(compositeIDCC.Invoke(`create`, create1), state.ErrKeyAlreadyExists) }) It("Allow to get entry list", func() { - entities := expectcc.PayloadIs(protoCC.Query(`list`), - &schema.ProtoEntityList{}).(*schema.ProtoEntityList) + entities := expectcc.PayloadIs(compositeIDCC.Query(`list`), + &schema.EntityWithCompositeIdList{}).(*schema.EntityWithCompositeIdList) Expect(len(entities.Items)).To(Equal(3)) - Expect(entities.Items[0].Name).To(Equal(issueMock1.Name)) - Expect(entities.Items[0].Value).To(BeNumerically("==", 0)) - Expect(entities.Items[0].ExternalId).To(Equal(issueMock1.ExternalId)) - }) - - It("Allow finding data by uniq key", func() { - - cpaperFromCCByExtID := expectcc.PayloadIs( - protoCC.Query(`getByExternalId`, issueMock1.ExternalId), - &schema.ProtoEntity{}).(*schema.ProtoEntity) - - cpaperFromCC := expectcc.PayloadIs( - protoCC.Query(`get`, &schema.ProtoEntityId{ - IdFirstPart: issueMock1.IdFirstPart, - IdSecondPart: issueMock1.IdSecondPart}, - ), - &schema.ProtoEntity{}).(*schema.ProtoEntity) - - Expect(cpaperFromCCByExtID).To(BeEquivalentTo(cpaperFromCC)) - }) - - It("Allow to get idx state key by uniq key", func() { - idxKey, err := testdata.ProtoStateMapping.IdxKey(&schema.ProtoEntity{}, `ExternalId`, []string{issueMock1.ExternalId}) - Expect(err).NotTo(HaveOccurred()) - - Expect(idxKey).To(BeEquivalentTo([]string{ - mapping.KeyRefNamespace, - strings.Join(mapping.SchemaNamespace(&schema.ProtoEntity{}), `-`), - `ExternalId`, - issueMock1.ExternalId, - })) - }) - - It("Disallow finding data by non existent uniq key", func() { - expectcc.ResponseError( - protoCC.Query(`getByExternalId`, `some-non-existent-id`), `uniq index`) + Expect(entities.Items[0].Name).To(Equal(create1.Name)) + Expect(entities.Items[0].Value).To(BeNumerically("==", create1.Value)) }) It("Allow to get entry raw protobuf", func() { - cpaperProtoFromCC := protoCC.Query(`get`, - &schema.ProtoEntityId{ - IdFirstPart: issueMock1.IdFirstPart, - IdSecondPart: issueMock1.IdSecondPart}, + dataFromCC := compositeIDCC.Query(`get`, + &schema.EntityCompositeId{ + IdFirstPart: create1.IdFirstPart, + IdSecondPart: create1.IdSecondPart}, ).Payload - stateProtoEntity := &schema.ProtoEntity{ - IdFirstPart: issueMock1.IdFirstPart, - IdSecondPart: issueMock1.IdSecondPart, - Name: issueMock1.Name, - Value: 0, - ExternalId: issueMock1.ExternalId, + e := &schema.EntityWithCompositeId{ + IdFirstPart: create1.IdFirstPart, + IdSecondPart: create1.IdSecondPart, + Name: create1.Name, + Value: create1.Value, } - Expect(cpaperProtoFromCC).To(Equal(testcc.MustProtoMarshal(stateProtoEntity))) + Expect(dataFromCC).To(Equal(testcc.MustProtoMarshal(e))) }) It("Allow update data in chaincode state", func() { - expectcc.ResponseOk(protoCC.Invoke(`increment`, &schema.IncrementProtoEntity{ - IdFirstPart: issueMock1.IdFirstPart, - IdSecondPart: issueMock1.IdSecondPart, - Name: issueMock1.Name, + expectcc.ResponseOk(compositeIDCC.Invoke(`update`, &schema.UpdateEntityWithCompositeId{ + IdFirstPart: create1.IdFirstPart, + IdSecondPart: create1.IdSecondPart, + Name: `New name`, + Value: 1000, })) entityFromCC := expectcc.PayloadIs( - protoCC.Query(`get`, &schema.ProtoEntityId{ - IdFirstPart: issueMock1.IdFirstPart, - IdSecondPart: issueMock1.IdSecondPart, + compositeIDCC.Query(`get`, &schema.EntityCompositeId{ + IdFirstPart: create1.IdFirstPart, + IdSecondPart: create1.IdSecondPart, }), - &schema.ProtoEntity{}).(*schema.ProtoEntity) + &schema.EntityWithCompositeId{}).(*schema.EntityWithCompositeId) // state is updated - Expect(entityFromCC.Value).To(BeNumerically("==", 1)) + Expect(entityFromCC.Name).To(Equal(`New name`)) + Expect(entityFromCC.Value).To(BeNumerically("==", 1000)) }) It("Allow to delete entry", func() { - toDelete := &schema.ProtoEntityId{ - IdFirstPart: issueMock1.IdFirstPart, - IdSecondPart: issueMock1.IdSecondPart, + toDelete := &schema.EntityCompositeId{ + IdFirstPart: create1.IdFirstPart, + IdSecondPart: create1.IdSecondPart, } - expectcc.ResponseOk(protoCC.Invoke(`delete`, toDelete)) - cpapers := expectcc.PayloadIs( - protoCC.Invoke(`list`), - &schema.ProtoEntityList{}, - ).(*schema.ProtoEntityList) + expectcc.ResponseOk(compositeIDCC.Invoke(`delete`, toDelete)) + ee := expectcc.PayloadIs( + compositeIDCC.Invoke(`list`), + &schema.EntityWithCompositeIdList{}).(*schema.EntityWithCompositeIdList) - Expect(len(cpapers.Items)).To(Equal(2)) - expectcc.ResponseError(protoCC.Invoke(`get`, toDelete), state.ErrKeyNotFound) + Expect(len(ee.Items)).To(Equal(2)) + expectcc.ResponseError(compositeIDCC.Invoke(`get`, toDelete), state.ErrKeyNotFound) }) It("Allow to insert entry once more time", func() { - expectcc.ResponseOk(protoCC.Invoke(`issue`, &issueMock1)) - - cpaperFromCCByExtID := expectcc.PayloadIs( - protoCC.Query(`getByExternalId`, issueMock1.ExternalId), - &schema.ProtoEntity{}).(*schema.ProtoEntity) - - Expect(cpaperFromCCByExtID.IdFirstPart).To(Equal(issueMock1.IdFirstPart)) + expectcc.ResponseOk(compositeIDCC.Invoke(`create`, create1)) }) }) @@ -254,4 +201,138 @@ var _ = Describe(`Mapping`, func() { Expect(listFromCC.Items[0].Value).To(Equal(testcc.MustProtoMarshal(ent2))) }) }) + + Describe(`Entity with indexes`, func() { + + create1 := testdata.CreateEntityWithIndexes[0] + create2 := testdata.CreateEntityWithIndexes[1] + + It("Allow to add data with single external id", func() { + expectcc.ResponseOk(indexesCC.Invoke(`create`, create1)) + }) + + It("Disallow to add data to chaincode state with same uniq key fields", func() { + createWithNewId := proto.Clone(create1).(*schema.CreateEntityWithIndexes) + createWithNewId.Id = `abcdef` // id is really new + + // errored on checking uniq key + expectcc.ResponseError( + indexesCC.Invoke(`create`, create1), + mapping.ErrMappingUniqKeyExists) + }) + + It("Allow finding data by uniq key", func() { + fromCCByExtId := expectcc.PayloadIs( + indexesCC.Query(`getByExternalId`, create1.ExternalId), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + fromCCById := expectcc.PayloadIs( + indexesCC.Query(`get`, create1.Id), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + Expect(fromCCByExtId).To(BeEquivalentTo(fromCCById)) + }) + + It("Allow to get idx state key by uniq key", func() { + idxKey, err := testdata.EntityWithIndexesStateMapping.IdxKey( + &schema.EntityWithIndexes{}, `ExternalId`, []string{create1.ExternalId}) + Expect(err).NotTo(HaveOccurred()) + + Expect(idxKey).To(BeEquivalentTo([]string{ + mapping.KeyRefNamespace, + strings.Join(mapping.SchemaNamespace(&schema.EntityWithIndexes{}), `-`), + `ExternalId`, + create1.ExternalId, + })) + }) + + It("Disallow finding data by non existent uniq key", func() { + expectcc.ResponseError( + indexesCC.Query(`getByExternalId`, `some-non-existent-id`), + mapping.ErrIndexReferenceNotFound) + }) + + It("Allow to add data with multiple external id", func() { + expectcc.ResponseOk(indexesCC.Invoke(`create`, create2)) + }) + + It("Allow to find data by multi key", func() { + fromCCByExtId1 := expectcc.PayloadIs( + indexesCC.Query(`getByOptMultiExternalId`, create2.OptionalExternalIds[0]), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + fromCCByExtId2 := expectcc.PayloadIs( + indexesCC.Query(`getByOptMultiExternalId`, create2.OptionalExternalIds[1]), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + fromCCById := expectcc.PayloadIs( + indexesCC.Query(`get`, create2.Id), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + Expect(fromCCByExtId1).To(BeEquivalentTo(fromCCById)) + Expect(fromCCByExtId2).To(BeEquivalentTo(fromCCById)) + }) + + It("Allow update indexes value", func() { + update2 := &schema.UpdateEntityWithIndexes{ + Id: create2.Id, + ExternalId: `some_new_external_id`, + OptionalExternalIds: []string{create2.OptionalExternalIds[0], `AND SOME NEW`}, + } + expectcc.ResponseOk(indexesCC.Invoke(`update`, update2)) + }) + + It("Allow to find data by updated multi key", func() { + fromCCByExtId1 := expectcc.PayloadIs( + indexesCC.Query(`getByOptMultiExternalId`, create2.OptionalExternalIds[0]), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + fromCCByExtId2 := expectcc.PayloadIs( + indexesCC.Query(`getByOptMultiExternalId`, `AND SOME NEW`), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + Expect(fromCCByExtId1.Id).To(Equal(create2.Id)) + Expect(fromCCByExtId2.Id).To(Equal(create2.Id)) + + Expect(fromCCByExtId2.OptionalExternalIds).To( + BeEquivalentTo([]string{create2.OptionalExternalIds[0], `AND SOME NEW`})) + }) + + It("Disallow to find data by previous multi key", func() { + expectcc.ResponseError( + indexesCC.Query(`getByOptMultiExternalId`, create2.OptionalExternalIds[1]), + mapping.ErrIndexReferenceNotFound) + }) + + It("Allow to find data by updated uniq key", func() { + fromCCByExtId := expectcc.PayloadIs( + indexesCC.Query(`getByExternalId`, `some_new_external_id`), + &schema.EntityWithIndexes{}).(*schema.EntityWithIndexes) + + Expect(fromCCByExtId.Id).To(Equal(create2.Id)) + Expect(fromCCByExtId.ExternalId).To(Equal(`some_new_external_id`)) + }) + + It("Disallow to find data by previous uniq key", func() { + expectcc.ResponseError( + indexesCC.Query(`getByExternalId`, create2.ExternalId), + mapping.ErrIndexReferenceNotFound) + }) + + It("Allow to delete entry", func() { + expectcc.ResponseOk(indexesCC.Invoke(`delete`, create2.Id)) + + ee := expectcc.PayloadIs( + indexesCC.Invoke(`list`), + &schema.EntityWithIndexesList{}).(*schema.EntityWithIndexesList) + + Expect(len(ee.Items)).To(Equal(1)) + expectcc.ResponseError(indexesCC.Invoke(`get`, create2.Id), state.ErrKeyNotFound) + }) + + It("Allow to insert entry once more time", func() { + expectcc.ResponseOk(indexesCC.Invoke(`create`, create2)) + }) + + }) }) diff --git a/state/mapping/state.go b/state/mapping/state.go index 706db795..315d5862 100644 --- a/state/mapping/state.go +++ b/state/mapping/state.go @@ -17,10 +17,11 @@ type ( ListWith(schema interface{}, key state.Key) (result interface{}, err error) // GetByUniqKey return one entry + // Deprecated: use GetByKey GetByUniqKey(schema interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) - // GetByUniqKey return list of entries - //GetByKey(schema interface{}, key string, keyValue []interface{}) (result interface{}, err error) + // GetByKey + GetByKey(schema interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) } Impl struct { @@ -93,17 +94,51 @@ func (s *Impl) Put(entry interface{}, value ...interface{}) error { return s.state.Put(entry, value...) // return as is } - keyRefs, err := mapped.Keys() // additional keys - if err != nil { - return err - } + // update ref keys + if len(mapped.Mapper().Indexes()) > 0 { + keyRefs, err := mapped.Keys() // key refs based on current entry value, defined by mapping indexes + if err != nil { + return errors.Wrap(err, `put mapping key refs`) + } - // delete previous key refs if key exists + var insertKeyRefs, deleteKeyRefs []state.KeyValue + //get previous entry value + prevEntry, err := s.Get(entry) - // put uniq key refs. if key already exists - error returned - for _, kr := range keyRefs { - if err = s.state.Put(kr); err != nil { - return fmt.Errorf(`%s: %s`, ErrMappingUniqKeyExists, err) + if err == nil { // prev exists + + // prev entry exists, calculate refs to delete and to insert + prevMapped, err := s.mappings.Map(prevEntry) + if err != nil { + return errors.Wrap(err, `get prev`) + } + prevKeyRefs, err := prevMapped.Keys() // key refs based on current entry value, defined by mapping indexes + if err != nil { + return errors.Wrap(err, `previ keys`) + } + + deleteKeyRefs, insertKeyRefs, err = KeyRefsDiff(prevKeyRefs, keyRefs) + if err != nil { + return errors.Wrap(err, `calculate ref keys diff`) + } + + } else { + // prev entry not exists, all current key refs should be inserted + insertKeyRefs = keyRefs + } + + // delete previous key refs if key exists + for _, kr := range deleteKeyRefs { + if err = s.state.Delete(kr); err != nil { + return errors.Wrap(err, `delete previous mapping key ref`) + } + } + + // insert new key refs + for _, kr := range insertKeyRefs { + if err = s.state.Insert(kr); err != nil { + return fmt.Errorf(`%s: %s`, ErrMappingUniqKeyExists, err) + } } } @@ -116,12 +151,12 @@ func (s *Impl) Insert(entry interface{}, value ...interface{}) error { return s.state.Insert(entry, value...) // return as is } - keyRefs, err := mapped.Keys() // additional keys + keyRefs, err := mapped.Keys() // key refs, defined by mapping indexes if err != nil { return err } - // insert uniq key refs. if key already exists - error returned + // insert key refs, if key already exists - error returned for _, kr := range keyRefs { if err = s.state.Insert(kr); err != nil { return fmt.Errorf(`%s: %s`, ErrMappingUniqKeyExists, err) @@ -164,6 +199,11 @@ func (s *Impl) ListWith(entry interface{}, key state.Key) (result interface{}, e func (s *Impl) GetByUniqKey( entry interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) { + return s.GetByKey(entry, idx, idxVal, target...) +} + +func (s *Impl) GetByKey( + entry interface{}, idx string, idxVal []string, target ...interface{}) (result interface{}, err error) { if !s.mappings.Exists(entry) { return nil, ErrStateMappingNotFound @@ -171,30 +211,28 @@ func (s *Impl) GetByUniqKey( keyRef, err := s.state.Get(NewKeyRefIDMapped(entry, idx, idxVal), &schema.KeyRef{}) if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf(`uniq index: {%s}.%s`, mapKey(entry), idx)) + return nil, errors.Errorf(`%s: {%s}.%s: %s`, ErrIndexReferenceNotFound, mapKey(entry), idx, err) } return s.state.Get(keyRef.(*schema.KeyRef).PKey, target...) } func (s *Impl) Delete(entry interface{}) error { - mapped, err := s.mappings.Map(entry) - if err != nil { // mapping is not exists + if !s.mappings.Exists(entry) { return s.state.Delete(entry) // return as is } - // Entry can be record to delete or reference to record + // we need full entry data fro state + // AND entry can be record to delete or reference to record // If entry is keyer entity for another entry (reference) - if mapped.Mapper().KeyerFor() != nil { - referenceEntry, err := s.Get(entry) - if err != nil { - return err - } + entry, err := s.Get(entry) + if err != nil { + return err + } - mapped, err = s.mappings.Map(referenceEntry) - if err != nil { - return err - } + mapped, err := s.mappings.Map(entry) + if err != nil { + return err } keyRefs, err := mapped.Keys() // additional keys diff --git a/state/mapping/state_keyref.go b/state/mapping/state_keyref.go index b0634c0e..899ab22e 100644 --- a/state/mapping/state_keyref.go +++ b/state/mapping/state_keyref.go @@ -11,7 +11,7 @@ import ( const KeyRefNamespace = `_idx` // KeyRefIDKeyer keyer for KeyRef entity -var KeyRefIDKeyer = attrsPKeyer([]string{`Schema`, `Idx`, `RefKey`}) +var KeyRefIDKeyer = attrsKeyer([]string{`Schema`, `Idx`, `RefKey`}) var KeyRefMapper = &StateMapping{ schema: &schema.KeyRef{}, diff --git a/state/mapping/state_mapping.go b/state/mapping/state_mapping.go index e1121b77..d981244b 100644 --- a/state/mapping/state_mapping.go +++ b/state/mapping/state_mapping.go @@ -27,10 +27,12 @@ type ( PrimaryKey(instance interface{}) (key state.Key, err error) Keys(instance interface{}) (key []state.KeyValue, err error) KeyerFor() interface{} + Indexes() []*StateIndex } // InstanceKeyer returns key of an state entry instance - InstanceKeyer func(instance interface{}) (key state.Key, err error) + InstanceKeyer func(instance interface{}) (state.Key, error) + InstanceMultiKeyer func(instance interface{}) ([]state.Key, error) StateMapped interface { state.KeyValue // entry key and value @@ -40,17 +42,27 @@ type ( // StateMapping defines metadata for mapping from schema to state keys/values StateMapping struct { schema interface{} - namespace state.Key - keyerForSchema interface{} //schema is keyer for another schema ( for example *schema.StaffId for *schema.Staff ) - primaryKeyer InstanceKeyer - list interface{} - uniqKeys []*StateKeyDefinition + namespace state.Key // prefix for primary key + keyerForSchema interface{} // schema is keyer for another schema ( for example *schema.StaffId for *schema.Staff ) + primaryKeyer InstanceKeyer // primary key always one + list interface{} // list schema + indexes []*StateIndex // additional keys } - // StateKeyDefinition - StateKeyDefinition struct { - Name string - Attrs []string + // StateIndex additional index of entity instance + StateIndex struct { + Name string + Uniq bool + Required bool + Keyer InstanceMultiKeyer // index can have multiple keys + } + + StateIndexDef struct { + Name string + Fields []string + Required bool + Multi bool + Keyer InstanceMultiKeyer } StateMappings map[string]*StateMapping @@ -135,6 +147,7 @@ func (smm StateMappings) Map(entry interface{}) (mapped StateMapped, err error) } } +// func (smm *StateMappings) IdxKey(entity interface{}, idx string, idxVal state.Key) (state.Key, error) { keyMapped := NewKeyRefIDMapped(entity, idx, idxVal) return keyMapped.Key() @@ -143,6 +156,11 @@ func (smm *StateMappings) IdxKey(entity interface{}, idx string, idxVal state.Ke func (sm *StateMapping) Namespace() state.Key { return sm.namespace } + +func (sm *StateMapping) Indexes() []*StateIndex { + return sm.indexes +} + func (sm *StateMapping) Schema() interface{} { return sm.schema } @@ -163,30 +181,93 @@ func (sm *StateMapping) PrimaryKey(entity interface{}) (state.Key, error) { return append(sm.namespace, key...), nil } -func (sm *StateMapping) Keys(entity interface{}) (kv []state.KeyValue, err error) { - if len(sm.uniqKeys) == 0 { - return +// Indexes prepares primary and additional uniq/non-uniq keys for storage +func (sm *StateMapping) Keys(entity interface{}) ([]state.KeyValue, error) { + if len(sm.indexes) == 0 { + return nil, nil } - pk, err := sm.PrimaryKey(entity) + pk, err := sm.PrimaryKey(entity) // primary key, all additional keys refers to primary key if err != nil { - return + return nil, err } - for _, k := range sm.uniqKeys { + var stateKeys []state.KeyValue + for _, idx := range sm.indexes { // uniq key attr values - refKey, err := attrsPKeyer(k.Attrs)(entity) + idxKeys, err := idx.Keyer(entity) if err != nil { - return nil, fmt.Errorf(`uniq key %s: %s`, k.Name, err) + return nil, errors.Errorf(`uniq key %s: %s`, idx.Name, err) + } + + for _, key := range idxKeys { + // key will be <`_idx`,{SchemaName},{idxName}, {Key[1]},... {Key[n}}>s + stateKeys = append(stateKeys, NewKeyRefMapped(sm.schema, idx.Name, key, pk)) } + } - // key will be <`_idx`,{SchemaName},{idxName}, {Key[1]},... {Key[n}}>s - kv = append(kv, NewKeyRefMapped(sm.schema, k.Name, refKey, pk)) + return stateKeys, nil +} + +func (sm *StateMapping) AddIndex(idx *StateIndex) error { + if exists := sm.Index(idx.Name); exists != nil { + return ErrIndexAlreadyExists } - return + sm.indexes = append(sm.indexes, idx) + return nil +} + +func (sm *StateMapping) Index(name string) *StateIndex { + for _, idx := range sm.indexes { + if idx.Name == name { + return idx + } + } + + return nil } func (sm *StateMapping) KeyerFor() interface{} { return sm.keyerForSchema } + +// KeyRefsDiff calculates diff between key reference set +func KeyRefsDiff(prevKeys []state.KeyValue, newKeys []state.KeyValue) (deleted, inserted []state.KeyValue, err error) { + + var ( + prevK = make(map[string]int) + newK = make(map[string]int) + ) + for i, kv := range prevKeys { + k, err := kv.Key() + if err != nil { + return nil, nil, errors.Wrap(err, `prev ref key`) + } + + prevK[k.String()] = i + } + + for i, kv := range newKeys { + k, err := kv.Key() + if err != nil { + return nil, nil, errors.Wrap(err, `new ref key`) + } + + newK[k.String()] = i + } + + for k, i := range prevK { + if _, ok := newK[k]; !ok { + deleted = append(deleted, prevKeys[i]) + } + } + + for k, i := range newK { + if _, ok := prevK[k]; !ok { + inserted = append(inserted, newKeys[i]) + } + } + + return deleted, inserted, nil +} diff --git a/state/mapping/state_mapping_opt.go b/state/mapping/state_mapping_opt.go index ce89be40..1fc6b340 100644 --- a/state/mapping/state_mapping_opt.go +++ b/state/mapping/state_mapping_opt.go @@ -29,13 +29,48 @@ func List(list proto.Message) StateMappingOpt { } } -func UniqKey(name string, attrs ...[]string) StateMappingOpt { +// UniqKey defined uniq key in entity +func UniqKey(name string, fields ...[]string) StateMappingOpt { + var ff []string + if len(fields) > 0 { + ff = fields[0] + } + return WithIndex(&StateIndexDef{ + Name: name, + Fields: ff, + Required: true, + Multi: false, + }) +} + +func WithIndex(idx *StateIndexDef) StateMappingOpt { return func(sm *StateMapping, smm StateMappings) { - aa := []string{name} - if len(attrs) > 0 { - aa = attrs[0] + if idx.Name == `` { + return } - sm.uniqKeys = append(sm.uniqKeys, &StateKeyDefinition{Name: name, Attrs: aa}) + + var keyer InstanceMultiKeyer + if idx.Keyer != nil { + keyer = idx.Keyer + } else { + aa := []string{idx.Name} + if len(idx.Fields) > 0 { + aa = idx.Fields + } + + if idx.Multi { + keyer = attrMultiKeyer(aa[0]) + } else { + keyer = keyerAsMulti(attrsKeyer(aa)) + } + } + + _ = sm.AddIndex(&StateIndex{ + Name: idx.Name, + Uniq: true, + Required: idx.Required, + Keyer: keyer, + }) } } @@ -45,7 +80,7 @@ func PKeySchema(pkeySchema interface{}) StateMappingOpt { attrs := attrsFrom(pkeySchema) return func(sm *StateMapping, smm StateMappings) { - sm.primaryKeyer = attrsPKeyer(attrs) + sm.primaryKeyer = attrsKeyer(attrs) //add mapping namespace for id schema same as schema smm.Add(pkeySchema, StateNamespace(SchemaNamespace(sm.schema)), PKeyAttr(attrs...), KeyerFor(sm.schema)) @@ -54,7 +89,7 @@ func PKeySchema(pkeySchema interface{}) StateMappingOpt { func PKeyAttr(attrs ...string) StateMappingOpt { return func(sm *StateMapping, smm StateMappings) { - sm.primaryKeyer = attrsPKeyer(attrs) + sm.primaryKeyer = attrsKeyer(attrs) } } @@ -76,7 +111,7 @@ func PKeyConst(key state.Key) StateMappingOpt { // with namespace from mapping schema func PKeyComplexId(pkeySchema interface{}) StateMappingOpt { return func(sm *StateMapping, smm StateMappings) { - sm.primaryKeyer = attrsPKeyer([]string{`Id`}) + sm.primaryKeyer = attrsKeyer([]string{`Id`}) smm.Add(pkeySchema, StateNamespace(SchemaNamespace(sm.schema)), PKeyAttr(attrsFrom(pkeySchema)...), @@ -105,36 +140,75 @@ func attrsFrom(schema interface{}) (attrs []string) { return } -func attrsPKeyer(attrs []string) InstanceKeyer { - return func(instance interface{}) (key state.Key, err error) { +// attrsKeyer creates instance keyer +func attrsKeyer(attrs []string) InstanceKeyer { + return func(instance interface{}) (state.Key, error) { + var key = state.Key{} inst := reflect.Indirect(reflect.ValueOf(instance)) - var pkey state.Key + for _, attr := range attrs { + v := inst.FieldByName(attr) if !v.IsValid() { return nil, fmt.Errorf(`%s: %s`, ErrFieldNotExists, attr) } - if key, err = keyFromValue(v); err != nil { + keyPart, err := keyFromValue(v) + if err != nil { return nil, fmt.Errorf(`key from field %s.%s: %s`, mapKey(instance), attr, err) } - pkey = pkey.Append(key) + key = key.Append(keyPart) + } + return key, nil + } +} + +// attrMultiKeyer creates keyer based of one field and can return multiple keyss +func attrMultiKeyer(attr string) InstanceMultiKeyer { + return func(instance interface{}) ([]state.Key, error) { + inst := reflect.Indirect(reflect.ValueOf(instance)) + + v := inst.FieldByName(attr) + if !v.IsValid() { + return nil, fmt.Errorf(`%s: %s`, ErrFieldNotExists, attr) + } + + return keysFromValue(v) + } +} + +// keyerAsMulti adapter keyer to multiKeyer +func keyerAsMulti(keyer InstanceKeyer) InstanceMultiKeyer { + return func(instance interface{}) (key []state.Key, err error) { + k, err := keyer(instance) + if err != nil { + return nil, err } - return pkey, nil + + return []state.Key{k}, nil } } -func keyFromValue(v reflect.Value) (key state.Key, err error) { +// multi - returns multiple key if value type allows it +func keysFromValue(v reflect.Value) ([]state.Key, error) { + var keys []state.Key + switch v.Type().String() { - case `string`, `int32`, `bool`: - return state.Key{v.String()}, nil case `[]string`: for i := 0; i < v.Len(); i++ { - key = append(key, v.Index(i).String()) + keys = append(keys, state.Key{v.Index(i).String()}) } - return key, nil + + default: + return nil, ErrFieldTypeNotSupportedForKeyExtraction } + return keys, nil +} + +func keyFromValue(v reflect.Value) (state.Key, error) { + var key state.Key + if v.Kind() == reflect.Ptr { s := reflect.ValueOf(v.Interface()).Elem().Type() // get all field values from struct @@ -143,8 +217,25 @@ func keyFromValue(v reflect.Value) (key state.Key, err error) { key = append(key, reflect.Indirect(v).Field(i).String()) } } + return key, nil } - return nil, ErrFieldTypeNotSupportedForKeyExtraction + switch v.Type().String() { + + case `string`, `int32`, `bool`: + // multi key possible + key = state.Key{v.String()} + + case `[]string`: + // every slice element is a part of one key + for i := 0; i < v.Len(); i++ { + key = append(key, v.Index(i).String()) + } + + default: + return nil, ErrFieldTypeNotSupportedForKeyExtraction + } + + return key, nil } diff --git a/state/mapping/testdata/cc_composite_id.go b/state/mapping/testdata/cc_composite_id.go new file mode 100644 index 00000000..f6277bd8 --- /dev/null +++ b/state/mapping/testdata/cc_composite_id.go @@ -0,0 +1,85 @@ +package testdata + +import ( + "github.com/s7techlab/cckit/extensions/debug" + "github.com/s7techlab/cckit/extensions/owner" + "github.com/s7techlab/cckit/router" + "github.com/s7techlab/cckit/router/param/defparam" + "github.com/s7techlab/cckit/state/mapping" + "github.com/s7techlab/cckit/state/mapping/testdata/schema" +) + +var ( + EntityWithCompositeIdStateMapping = mapping.StateMappings{}. + Add(&schema.EntityWithCompositeId{}, + mapping.PKeySchema(&schema.EntityCompositeId{}), + mapping.List(&schema.EntityWithCompositeIdList{})) +) + +func NewCompositeIdCC() *router.Chaincode { + r := router.New("composite_id") + + r.Use(mapping.MapStates(EntityWithCompositeIdStateMapping)) + + r.Use(mapping.MapEvents(mapping.EventMappings{}. + Add(&schema.CreateEntityWithCompositeId{}). + Add(&schema.UpdateEntityWithCompositeId{}))) + + r.Init(owner.InvokeSetFromCreator) + debug.AddHandlers(r, "debug", owner.Only) + + r. + Query("list", queryListComposite). + Query("get", queryByIdComposite, defparam.Proto(&schema.EntityCompositeId{})). + Invoke("create", invokeCreateComposite, defparam.Proto(&schema.CreateEntityWithCompositeId{})). + Invoke("update", invokeUpdateComposite, defparam.Proto(&schema.UpdateEntityWithCompositeId{})). + Invoke("delete", invokeDeleteComposite, defparam.Proto(&schema.EntityCompositeId{})) + + return router.NewChaincode(r) +} + +func queryByIdComposite(c router.Context) (interface{}, error) { + return c.State().Get(c.Param().(*schema.EntityCompositeId)) +} + +func queryListComposite(c router.Context) (interface{}, error) { + return c.State().List(&schema.EntityWithCompositeId{}) +} + +func invokeCreateComposite(c router.Context) (interface{}, error) { + create := c.Param().(*schema.CreateEntityWithCompositeId) + entity := &schema.EntityWithCompositeId{ + IdFirstPart: create.IdFirstPart, + IdSecondPart: create.IdSecondPart, + Name: create.Name, + Value: create.Value, + } + + if err := c.Event().Set(create); err != nil { + return nil, err + } + + return entity, c.State().Insert(entity) +} + +func invokeUpdateComposite(c router.Context) (interface{}, error) { + update := c.Param().(*schema.UpdateEntityWithCompositeId) + entity, _ := c.State().Get( + &schema.EntityCompositeId{IdFirstPart: update.IdFirstPart, IdSecondPart: update.IdSecondPart}, + &schema.EntityWithCompositeId{}) + + e := entity.(*schema.EntityWithCompositeId) + + e.Name = update.Name + e.Value = update.Value + + if err := c.Event().Set(update); err != nil { + return nil, err + } + + return e, c.State().Put(e) +} + +func invokeDeleteComposite(c router.Context) (interface{}, error) { + return nil, c.State().Delete(c.Param().(*schema.EntityCompositeId)) +} diff --git a/state/mapping/testdata/cc_indexes.go b/state/mapping/testdata/cc_indexes.go new file mode 100644 index 00000000..be935435 --- /dev/null +++ b/state/mapping/testdata/cc_indexes.go @@ -0,0 +1,91 @@ +package testdata + +import ( + "github.com/s7techlab/cckit/extensions/owner" + "github.com/s7techlab/cckit/router" + "github.com/s7techlab/cckit/router/param/defparam" + "github.com/s7techlab/cckit/state/mapping" + "github.com/s7techlab/cckit/state/mapping/testdata/schema" +) + +var ( + EntityWithIndexesStateMapping = mapping.StateMappings{}. + Add(&schema.EntityWithIndexes{}, + mapping.PKeyId(), + mapping.List(&schema.EntityWithIndexesList{}), + mapping.UniqKey(`ExternalId`), + mapping.WithIndex(&mapping.StateIndexDef{ + Name: `OptionalExternalIds`, + Required: false, + Multi: true, + })) +) + +func NewIndexesCC() *router.Chaincode { + r := router.New("indexes") + + r.Use(mapping.MapStates(EntityWithIndexesStateMapping)) + + r.Init(owner.InvokeSetFromCreator) + + r. + Query("list", queryListIndexes). + Query("get", queryByIdIndexes, defparam.String()). + Query("getByExternalId", queryByExternalId, defparam.String()). + Query("getByOptMultiExternalId", queryByOptMultiExternalId, defparam.String()). + Invoke("create", invokeCreateIndexes, defparam.Proto(&schema.CreateEntityWithIndexes{})). + Invoke("update", invokeUpdateIndexes, defparam.Proto(&schema.UpdateEntityWithIndexes{})). + Invoke("delete", invokeDeleteIndexes, defparam.String()) + + return router.NewChaincode(r) +} + +func queryByIdIndexes(c router.Context) (interface{}, error) { + return c.State().Get(&schema.EntityWithIndexes{Id: c.Param().(string)}) +} + +func queryListIndexes(c router.Context) (interface{}, error) { + return c.State().List(&schema.EntityWithIndexes{}) +} + +func invokeCreateIndexes(c router.Context) (interface{}, error) { + create := c.Param().(*schema.CreateEntityWithIndexes) + entity := &schema.EntityWithIndexes{ + Id: create.Id, + ExternalId: create.ExternalId, + RequiredExternalIds: create.RequiredExternalIds, + OptionalExternalIds: create.OptionalExternalIds, + Value: create.Value, + } + + return entity, c.State().Insert(entity) +} + +func invokeUpdateIndexes(c router.Context) (interface{}, error) { + update := c.Param().(*schema.UpdateEntityWithIndexes) + entity := &schema.EntityWithIndexes{ + Id: update.Id, + ExternalId: update.ExternalId, + RequiredExternalIds: update.RequiredExternalIds, + OptionalExternalIds: update.OptionalExternalIds, + Value: update.Value, + } + + return entity, c.State().Put(entity) +} + +func invokeDeleteIndexes(c router.Context) (interface{}, error) { + return nil, c.State().(mapping.MappedState).Delete(&schema.EntityWithIndexes{Id: c.Param().(string)}) +} + +func queryByExternalId(c router.Context) (interface{}, error) { + externalId := c.Param().(string) + return c.State().(mapping.MappedState).GetByKey( + &schema.EntityWithIndexes{}, "ExternalId", []string{externalId}) +} + +func queryByOptMultiExternalId(c router.Context) (interface{}, error) { + externalId := c.Param().(string) + return c.State().(mapping.MappedState).GetByKey( + &schema.EntityWithIndexes{}, "OptionalExternalIds", []string{externalId}) +} diff --git a/state/mapping/testdata/cc_proto_entity.go b/state/mapping/testdata/cc_proto_entity.go deleted file mode 100644 index bda0ec0d..00000000 --- a/state/mapping/testdata/cc_proto_entity.go +++ /dev/null @@ -1,93 +0,0 @@ -package testdata - -import ( - "github.com/s7techlab/cckit/extensions/debug" - "github.com/s7techlab/cckit/extensions/owner" - "github.com/s7techlab/cckit/router" - "github.com/s7techlab/cckit/router/param" - "github.com/s7techlab/cckit/router/param/defparam" - "github.com/s7techlab/cckit/state/mapping" - "github.com/s7techlab/cckit/state/mapping/testdata/schema" -) - -var ( - ProtoStateMapping = mapping.StateMappings{}. - Add(&schema.ProtoEntity{}, - mapping.PKeySchema(&schema.ProtoEntityId{}), - mapping.List(&schema.ProtoEntityList{}), - mapping.UniqKey("ExternalId"), - ) - - ProtoEventMapping = mapping.EventMappings{}. - Add(&schema.IssueProtoEntity{}). - Add(&schema.IncrementProtoEntity{}) -) - -func NewProtoCC() *router.Chaincode { - r := router.New("proto_test") - r.Use(mapping.MapStates(ProtoStateMapping)) - r.Use(mapping.MapEvents(ProtoEventMapping)) - r.Init(owner.InvokeSetFromCreator) - debug.AddHandlers(r, "debug", owner.Only) - - r. - Query("list", queryList). - Query("get", queryById, defparam.Proto(&schema.ProtoEntityId{})). - Query("getByExternalId", queryByExternalId, param.String("externalId")). - Invoke("issue", invokeIssue, defparam.Proto(&schema.IssueProtoEntity{})). - Invoke("increment", invokeIncrement, defparam.Proto(&schema.IncrementProtoEntity{})). - Invoke("delete", invokeDelte, defparam.Proto(&schema.ProtoEntityId{})) - - return router.NewChaincode(r) -} - -func queryById(c router.Context) (interface{}, error) { - return c.State().Get(c.Param().(*schema.ProtoEntityId)) -} - -func queryByExternalId(c router.Context) (interface{}, error) { - externalId := c.ParamString("externalId") - return c.State().(mapping.MappedState).GetByUniqKey(&schema.ProtoEntity{}, "ExternalId", []string{externalId}) -} - -func queryList(c router.Context) (interface{}, error) { - return c.State().List(&schema.ProtoEntity{}) -} - -func invokeIssue(c router.Context) (interface{}, error) { - issueData := c.Param().(*schema.IssueProtoEntity) - entity := &schema.ProtoEntity{ - IdFirstPart: issueData.IdFirstPart, - IdSecondPart: issueData.IdSecondPart, - Name: issueData.Name, - Value: 0, - ExternalId: issueData.ExternalId, - } - - if err := c.Event().Set(issueData); err != nil { - return nil, err - } - - return entity, c.State().Insert(entity) -} - -func invokeIncrement(c router.Context) (interface{}, error) { - incrementData := c.Param().(*schema.IncrementProtoEntity) - entity, _ := c.State().Get( - &schema.ProtoEntityId{IdFirstPart: incrementData.IdFirstPart, IdSecondPart: incrementData.IdSecondPart}, - &schema.ProtoEntity{}) - - protoEntity := entity.(*schema.ProtoEntity) - - protoEntity.Value = protoEntity.Value + 1 - - if err := c.Event().Set(incrementData); err != nil { - return nil, err - } - - return protoEntity, c.State().Put(protoEntity) -} - -func invokeDelte(c router.Context) (interface{}, error) { - return nil, c.State().Delete(c.Param().(*schema.ProtoEntityId)) -} diff --git a/state/mapping/testdata/schema/complex_id.pb.go b/state/mapping/testdata/schema/complex_id.pb.go deleted file mode 100644 index 7cacb103..00000000 --- a/state/mapping/testdata/schema/complex_id.pb.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: complex_id.proto - -/* -Package schema is a generated protocol buffer package. - -It is generated from these files: - complex_id.proto - proto_schema.proto - slice_id.proto - -It has these top-level messages: - EntityWithComplexId - EntityComplexId - ProtoEntity - ProtoEntityId - ProtoEntityList - IssueProtoEntity - IncrementProtoEntity - EntityWithSliceId -*/ -package schema - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type EntityWithComplexId struct { - Id *EntityComplexId `protobuf:"bytes,1,opt,name=Id" json:"Id,omitempty"` - SomeDate *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=some_date,json=someDate" json:"some_date,omitempty"` -} - -func (m *EntityWithComplexId) Reset() { *m = EntityWithComplexId{} } -func (m *EntityWithComplexId) String() string { return proto.CompactTextString(m) } -func (*EntityWithComplexId) ProtoMessage() {} -func (*EntityWithComplexId) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *EntityWithComplexId) GetId() *EntityComplexId { - if m != nil { - return m.Id - } - return nil -} - -func (m *EntityWithComplexId) GetSomeDate() *google_protobuf.Timestamp { - if m != nil { - return m.SomeDate - } - return nil -} - -// EntityComplexId -type EntityComplexId struct { - IdPart1 string `protobuf:"bytes,1,opt,name=idPart1" json:"idPart1,omitempty"` - IdPart2 string `protobuf:"bytes,2,opt,name=idPart2" json:"idPart2,omitempty"` -} - -func (m *EntityComplexId) Reset() { *m = EntityComplexId{} } -func (m *EntityComplexId) String() string { return proto.CompactTextString(m) } -func (*EntityComplexId) ProtoMessage() {} -func (*EntityComplexId) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *EntityComplexId) GetIdPart1() string { - if m != nil { - return m.IdPart1 - } - return "" -} - -func (m *EntityComplexId) GetIdPart2() string { - if m != nil { - return m.IdPart2 - } - return "" -} - -func init() { - proto.RegisterType((*EntityWithComplexId)(nil), "schema.EntityWithComplexId") - proto.RegisterType((*EntityComplexId)(nil), "schema.EntityComplexId") -} - -func init() { proto.RegisterFile("complex_id.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 194 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x48, 0xce, 0xcf, 0x2d, - 0xc8, 0x49, 0xad, 0x88, 0xcf, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, 0x4e, - 0xce, 0x48, 0xcd, 0x4d, 0x94, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x07, 0x8b, 0x26, - 0x95, 0xa6, 0xe9, 0x97, 0x64, 0xe6, 0xa6, 0x16, 0x97, 0x24, 0xe6, 0x16, 0x40, 0x14, 0x2a, 0x95, - 0x73, 0x09, 0xbb, 0xe6, 0x95, 0x64, 0x96, 0x54, 0x86, 0x67, 0x96, 0x64, 0x38, 0x43, 0x8c, 0xf1, - 0x4c, 0x11, 0x52, 0xe7, 0x62, 0xf2, 0x4c, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x12, 0xd7, - 0x83, 0x18, 0xa6, 0x07, 0x51, 0x08, 0x57, 0x14, 0xc4, 0xe4, 0x99, 0x22, 0x64, 0xce, 0xc5, 0x59, - 0x9c, 0x9f, 0x9b, 0x1a, 0x9f, 0x92, 0x58, 0x92, 0x2a, 0xc1, 0x04, 0x56, 0x2f, 0xa5, 0x07, 0xb1, - 0x54, 0x0f, 0x66, 0xa9, 0x5e, 0x08, 0xcc, 0xd2, 0x20, 0x0e, 0x90, 0x62, 0x97, 0xc4, 0x92, 0x54, - 0x25, 0x57, 0x2e, 0x7e, 0x34, 0xf3, 0x84, 0x24, 0xb8, 0xd8, 0x33, 0x53, 0x02, 0x12, 0x8b, 0x4a, - 0x0c, 0xc1, 0x36, 0x73, 0x06, 0xc1, 0xb8, 0x08, 0x19, 0x23, 0xb0, 0x1d, 0x70, 0x19, 0xa3, 0x24, - 0x36, 0xb0, 0x25, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe2, 0xfd, 0x0b, 0x12, 0x03, 0x01, - 0x00, 0x00, -} diff --git a/state/mapping/testdata/schema/proto_schema.pb.go b/state/mapping/testdata/schema/proto_schema.pb.go deleted file mode 100644 index 1cc13057..00000000 --- a/state/mapping/testdata/schema/proto_schema.pb.go +++ /dev/null @@ -1,208 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: proto_schema.proto - -package schema - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// ProtoEntity -type ProtoEntity struct { - IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart" json:"id_first_part,omitempty"` - IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart" json:"id_second_part,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` - Value int32 `protobuf:"varint,4,opt,name=value" json:"value,omitempty"` - ExternalId string `protobuf:"bytes,5,opt,name=external_id,json=externalId" json:"external_id,omitempty"` -} - -func (m *ProtoEntity) Reset() { *m = ProtoEntity{} } -func (m *ProtoEntity) String() string { return proto.CompactTextString(m) } -func (*ProtoEntity) ProtoMessage() {} -func (*ProtoEntity) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } - -func (m *ProtoEntity) GetIdFirstPart() string { - if m != nil { - return m.IdFirstPart - } - return "" -} - -func (m *ProtoEntity) GetIdSecondPart() string { - if m != nil { - return m.IdSecondPart - } - return "" -} - -func (m *ProtoEntity) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *ProtoEntity) GetValue() int32 { - if m != nil { - return m.Value - } - return 0 -} - -func (m *ProtoEntity) GetExternalId() string { - if m != nil { - return m.ExternalId - } - return "" -} - -// ProtoEntityId -type ProtoEntityId struct { - IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart" json:"id_first_part,omitempty"` - IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart" json:"id_second_part,omitempty"` -} - -func (m *ProtoEntityId) Reset() { *m = ProtoEntityId{} } -func (m *ProtoEntityId) String() string { return proto.CompactTextString(m) } -func (*ProtoEntityId) ProtoMessage() {} -func (*ProtoEntityId) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } - -func (m *ProtoEntityId) GetIdFirstPart() string { - if m != nil { - return m.IdFirstPart - } - return "" -} - -func (m *ProtoEntityId) GetIdSecondPart() string { - if m != nil { - return m.IdSecondPart - } - return "" -} - -// ProtoEntityList -type ProtoEntityList struct { - Items []*ProtoEntity `protobuf:"bytes,1,rep,name=items" json:"items,omitempty"` -} - -func (m *ProtoEntityList) Reset() { *m = ProtoEntityList{} } -func (m *ProtoEntityList) String() string { return proto.CompactTextString(m) } -func (*ProtoEntityList) ProtoMessage() {} -func (*ProtoEntityList) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } - -func (m *ProtoEntityList) GetItems() []*ProtoEntity { - if m != nil { - return m.Items - } - return nil -} - -// IssueProtoEntity -type IssueProtoEntity struct { - IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart" json:"id_first_part,omitempty"` - IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart" json:"id_second_part,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` - ExternalId string `protobuf:"bytes,5,opt,name=external_id,json=externalId" json:"external_id,omitempty"` -} - -func (m *IssueProtoEntity) Reset() { *m = IssueProtoEntity{} } -func (m *IssueProtoEntity) String() string { return proto.CompactTextString(m) } -func (*IssueProtoEntity) ProtoMessage() {} -func (*IssueProtoEntity) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} } - -func (m *IssueProtoEntity) GetIdFirstPart() string { - if m != nil { - return m.IdFirstPart - } - return "" -} - -func (m *IssueProtoEntity) GetIdSecondPart() string { - if m != nil { - return m.IdSecondPart - } - return "" -} - -func (m *IssueProtoEntity) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *IssueProtoEntity) GetExternalId() string { - if m != nil { - return m.ExternalId - } - return "" -} - -// IncrementProtoEntity -type IncrementProtoEntity struct { - IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart" json:"id_first_part,omitempty"` - IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart" json:"id_second_part,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` -} - -func (m *IncrementProtoEntity) Reset() { *m = IncrementProtoEntity{} } -func (m *IncrementProtoEntity) String() string { return proto.CompactTextString(m) } -func (*IncrementProtoEntity) ProtoMessage() {} -func (*IncrementProtoEntity) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } - -func (m *IncrementProtoEntity) GetIdFirstPart() string { - if m != nil { - return m.IdFirstPart - } - return "" -} - -func (m *IncrementProtoEntity) GetIdSecondPart() string { - if m != nil { - return m.IdSecondPart - } - return "" -} - -func (m *IncrementProtoEntity) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func init() { - proto.RegisterType((*ProtoEntity)(nil), "schema.ProtoEntity") - proto.RegisterType((*ProtoEntityId)(nil), "schema.ProtoEntityId") - proto.RegisterType((*ProtoEntityList)(nil), "schema.ProtoEntityList") - proto.RegisterType((*IssueProtoEntity)(nil), "schema.IssueProtoEntity") - proto.RegisterType((*IncrementProtoEntity)(nil), "schema.IncrementProtoEntity") -} - -func init() { proto.RegisterFile("proto_schema.proto", fileDescriptor1) } - -var fileDescriptor1 = []byte{ - // 251 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x92, 0x31, 0x4b, 0x04, 0x31, - 0x10, 0x85, 0x89, 0x77, 0x7b, 0xe0, 0xac, 0xa7, 0x12, 0xaf, 0x48, 0xe7, 0x12, 0x2c, 0xd6, 0xe6, - 0x0a, 0x6d, 0x6d, 0x15, 0x16, 0x2c, 0x8e, 0xb5, 0xb2, 0x0a, 0x71, 0x33, 0xe2, 0xc0, 0x6d, 0xf6, - 0x48, 0xe6, 0x44, 0x7f, 0x86, 0x7f, 0xc1, 0x5f, 0x2a, 0x97, 0x28, 0x6c, 0x67, 0x73, 0x5c, 0x97, - 0xf7, 0xf2, 0xcd, 0xf0, 0x78, 0x0c, 0xc8, 0x4d, 0x18, 0x78, 0x30, 0xb1, 0x7b, 0xc3, 0xde, 0x2e, - 0x93, 0x90, 0xb3, 0xac, 0xf4, 0xb7, 0x80, 0x72, 0xb5, 0x73, 0xee, 0x3d, 0x13, 0x7f, 0x4a, 0x0d, - 0x73, 0x72, 0xe6, 0x95, 0x42, 0x64, 0xb3, 0xb1, 0x81, 0x95, 0xa8, 0x44, 0x7d, 0xdc, 0x96, 0xe4, - 0x1e, 0x76, 0xde, 0xca, 0x06, 0x96, 0x57, 0x70, 0x4a, 0xce, 0x44, 0xec, 0x06, 0xef, 0x32, 0x74, - 0x94, 0xa0, 0x13, 0x72, 0x4f, 0xc9, 0x4c, 0x94, 0x84, 0xa9, 0xb7, 0x3d, 0xaa, 0x49, 0xfa, 0x4b, - 0x6f, 0xb9, 0x80, 0xe2, 0xdd, 0xae, 0xb7, 0xa8, 0xa6, 0x95, 0xa8, 0x8b, 0x36, 0x0b, 0x79, 0x09, - 0x25, 0x7e, 0x30, 0x06, 0x6f, 0xd7, 0x86, 0x9c, 0x2a, 0xd2, 0x00, 0xfc, 0x59, 0x8d, 0xd3, 0xcf, - 0x30, 0x1f, 0x65, 0x6c, 0xdc, 0xfe, 0x52, 0xea, 0x3b, 0x38, 0x1b, 0xad, 0x7e, 0xa4, 0xc8, 0xf2, - 0x1a, 0x0a, 0x62, 0xec, 0xa3, 0x12, 0xd5, 0xa4, 0x2e, 0x6f, 0x2e, 0x96, 0xbf, 0xc5, 0x8d, 0xb8, - 0x36, 0x13, 0xfa, 0x4b, 0xc0, 0x79, 0x13, 0xe3, 0x16, 0x0f, 0x57, 0xe1, 0xbf, 0x65, 0x31, 0x2c, - 0x1a, 0xdf, 0x05, 0xec, 0xd1, 0xf3, 0xc1, 0x62, 0xbd, 0xcc, 0xd2, 0x59, 0xdd, 0xfe, 0x04, 0x00, - 0x00, 0xff, 0xff, 0x0a, 0xda, 0xc5, 0x5b, 0x6c, 0x02, 0x00, 0x00, -} diff --git a/state/mapping/testdata/schema/proto_schema.proto b/state/mapping/testdata/schema/proto_schema.proto deleted file mode 100644 index 8e39cd7c..00000000 --- a/state/mapping/testdata/schema/proto_schema.proto +++ /dev/null @@ -1,37 +0,0 @@ -syntax = "proto3"; -package schema; - -// ProtoEntity -message ProtoEntity { - string id_first_part = 1; - string id_second_part = 2; - string name = 3; - int32 value = 4; - string external_id = 5; -} - -// ProtoEntityId -message ProtoEntityId { - string id_first_part = 1; - string id_second_part = 2; -} - -// ProtoEntityList -message ProtoEntityList { - repeated ProtoEntity items = 1; -} - -// IssueProtoEntity -message IssueProtoEntity { - string id_first_part = 1; - string id_second_part = 2; - string name = 3; - string external_id = 5; -} - -// IncrementProtoEntity -message IncrementProtoEntity { - string id_first_part = 1; - string id_second_part = 2; - string name = 3; -} diff --git a/state/mapping/testdata/schema/slice_id.pb.go b/state/mapping/testdata/schema/slice_id.pb.go deleted file mode 100644 index df2443ff..00000000 --- a/state/mapping/testdata/schema/slice_id.pb.go +++ /dev/null @@ -1,58 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: slice_id.proto - -package schema - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -type EntityWithSliceId struct { - Id []string `protobuf:"bytes,1,rep,name=Id" json:"Id,omitempty"` - SomeDate *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=some_date,json=someDate" json:"some_date,omitempty"` -} - -func (m *EntityWithSliceId) Reset() { *m = EntityWithSliceId{} } -func (m *EntityWithSliceId) String() string { return proto.CompactTextString(m) } -func (*EntityWithSliceId) ProtoMessage() {} -func (*EntityWithSliceId) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } - -func (m *EntityWithSliceId) GetId() []string { - if m != nil { - return m.Id - } - return nil -} - -func (m *EntityWithSliceId) GetSomeDate() *google_protobuf.Timestamp { - if m != nil { - return m.SomeDate - } - return nil -} - -func init() { - proto.RegisterType((*EntityWithSliceId)(nil), "schema.EntityWithSliceId") -} - -func init() { proto.RegisterFile("slice_id.proto", fileDescriptor2) } - -var fileDescriptor2 = []byte{ - // 153 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2b, 0xce, 0xc9, 0x4c, - 0x4e, 0x8d, 0xcf, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, 0x4e, 0xce, 0x48, - 0xcd, 0x4d, 0x94, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x07, 0x8b, 0x26, 0x95, 0xa6, - 0xe9, 0x97, 0x64, 0xe6, 0xa6, 0x16, 0x97, 0x24, 0xe6, 0x16, 0x40, 0x14, 0x2a, 0xc5, 0x70, 0x09, - 0xba, 0xe6, 0x95, 0x64, 0x96, 0x54, 0x86, 0x67, 0x96, 0x64, 0x04, 0x83, 0x0c, 0xf1, 0x4c, 0x11, - 0xe2, 0xe3, 0x62, 0xf2, 0x4c, 0x91, 0x60, 0x54, 0x60, 0xd6, 0xe0, 0x0c, 0x62, 0xf2, 0x4c, 0x11, - 0x32, 0xe7, 0xe2, 0x2c, 0xce, 0xcf, 0x4d, 0x8d, 0x4f, 0x49, 0x2c, 0x49, 0x95, 0x60, 0x52, 0x60, - 0xd4, 0xe0, 0x36, 0x92, 0xd2, 0x83, 0x98, 0xac, 0x07, 0x33, 0x59, 0x2f, 0x04, 0x66, 0x72, 0x10, - 0x07, 0x48, 0xb1, 0x4b, 0x62, 0x49, 0x6a, 0x12, 0x1b, 0x58, 0xd6, 0x18, 0x10, 0x00, 0x00, 0xff, - 0xff, 0xb2, 0xe9, 0x5e, 0xfb, 0x9f, 0x00, 0x00, 0x00, -} diff --git a/state/mapping/testdata/schema/with_complex_id.pb.go b/state/mapping/testdata/schema/with_complex_id.pb.go new file mode 100644 index 00000000..b2e37854 --- /dev/null +++ b/state/mapping/testdata/schema/with_complex_id.pb.go @@ -0,0 +1,141 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: with_complex_id.proto + +package schema + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type EntityWithComplexId struct { + Id *EntityComplexId `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` + SomeDate *timestamp.Timestamp `protobuf:"bytes,2,opt,name=some_date,json=someDate,proto3" json:"some_date,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityWithComplexId) Reset() { *m = EntityWithComplexId{} } +func (m *EntityWithComplexId) String() string { return proto.CompactTextString(m) } +func (*EntityWithComplexId) ProtoMessage() {} +func (*EntityWithComplexId) Descriptor() ([]byte, []int) { + return fileDescriptor_473b24ceaa56f1b8, []int{0} +} + +func (m *EntityWithComplexId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityWithComplexId.Unmarshal(m, b) +} +func (m *EntityWithComplexId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityWithComplexId.Marshal(b, m, deterministic) +} +func (m *EntityWithComplexId) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityWithComplexId.Merge(m, src) +} +func (m *EntityWithComplexId) XXX_Size() int { + return xxx_messageInfo_EntityWithComplexId.Size(m) +} +func (m *EntityWithComplexId) XXX_DiscardUnknown() { + xxx_messageInfo_EntityWithComplexId.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityWithComplexId proto.InternalMessageInfo + +func (m *EntityWithComplexId) GetId() *EntityComplexId { + if m != nil { + return m.Id + } + return nil +} + +func (m *EntityWithComplexId) GetSomeDate() *timestamp.Timestamp { + if m != nil { + return m.SomeDate + } + return nil +} + +// EntityComplexId +type EntityComplexId struct { + IdPart1 string `protobuf:"bytes,1,opt,name=idPart1,proto3" json:"idPart1,omitempty"` + IdPart2 string `protobuf:"bytes,2,opt,name=idPart2,proto3" json:"idPart2,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityComplexId) Reset() { *m = EntityComplexId{} } +func (m *EntityComplexId) String() string { return proto.CompactTextString(m) } +func (*EntityComplexId) ProtoMessage() {} +func (*EntityComplexId) Descriptor() ([]byte, []int) { + return fileDescriptor_473b24ceaa56f1b8, []int{1} +} + +func (m *EntityComplexId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityComplexId.Unmarshal(m, b) +} +func (m *EntityComplexId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityComplexId.Marshal(b, m, deterministic) +} +func (m *EntityComplexId) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityComplexId.Merge(m, src) +} +func (m *EntityComplexId) XXX_Size() int { + return xxx_messageInfo_EntityComplexId.Size(m) +} +func (m *EntityComplexId) XXX_DiscardUnknown() { + xxx_messageInfo_EntityComplexId.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityComplexId proto.InternalMessageInfo + +func (m *EntityComplexId) GetIdPart1() string { + if m != nil { + return m.IdPart1 + } + return "" +} + +func (m *EntityComplexId) GetIdPart2() string { + if m != nil { + return m.IdPart2 + } + return "" +} + +func init() { + proto.RegisterType((*EntityWithComplexId)(nil), "schema.EntityWithComplexId") + proto.RegisterType((*EntityComplexId)(nil), "schema.EntityComplexId") +} + +func init() { proto.RegisterFile("with_complex_id.proto", fileDescriptor_473b24ceaa56f1b8) } + +var fileDescriptor_473b24ceaa56f1b8 = []byte{ + // 197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x8d, 0xc1, 0x0b, 0x82, 0x30, + 0x14, 0x87, 0xd1, 0x83, 0xe5, 0x3a, 0x04, 0x8b, 0x48, 0xbc, 0x14, 0x5e, 0xea, 0x34, 0xc9, 0x0e, + 0xfd, 0x01, 0xe5, 0xc1, 0x5b, 0x48, 0xd0, 0x51, 0xa6, 0x5b, 0x3a, 0x70, 0x4d, 0xf4, 0x85, 0xf5, + 0xdf, 0x47, 0x1b, 0x1a, 0x74, 0x7c, 0xef, 0xf7, 0xf1, 0x7d, 0x68, 0xd9, 0x0b, 0xa8, 0xb2, 0x42, + 0xc9, 0xa6, 0xe6, 0xaf, 0x4c, 0x30, 0xd2, 0xb4, 0x0a, 0x14, 0x76, 0xba, 0xa2, 0xe2, 0x92, 0xfa, + 0xeb, 0x52, 0xa9, 0xb2, 0xe6, 0xa1, 0xfe, 0xe6, 0xcf, 0x7b, 0x08, 0x42, 0xf2, 0x0e, 0xa8, 0x6c, + 0x0c, 0x18, 0xf4, 0x68, 0x11, 0x3f, 0x40, 0xc0, 0xfb, 0x26, 0xa0, 0x3a, 0x19, 0x4d, 0xc2, 0xf0, + 0x16, 0xd9, 0x09, 0xf3, 0xac, 0x8d, 0xb5, 0x9b, 0x45, 0x2b, 0x62, 0x64, 0xc4, 0x80, 0x23, 0x94, + 0xda, 0x09, 0xc3, 0x47, 0xe4, 0x76, 0x4a, 0xf2, 0x8c, 0x51, 0xe0, 0x9e, 0xad, 0x79, 0x9f, 0x98, + 0x28, 0x19, 0xa2, 0xe4, 0x3a, 0x44, 0xd3, 0xe9, 0x17, 0x3e, 0x53, 0xe0, 0x41, 0x8c, 0xe6, 0x7f, + 0x3e, 0xec, 0xa1, 0x89, 0x60, 0x17, 0xda, 0xc2, 0x5e, 0x97, 0xdd, 0x74, 0x38, 0x7f, 0x4b, 0xa4, + 0x1b, 0xe3, 0x12, 0xe5, 0x8e, 0x8e, 0x1c, 0x3e, 0x01, 0x00, 0x00, 0xff, 0xff, 0x28, 0x46, 0xcc, + 0x35, 0x08, 0x01, 0x00, 0x00, +} diff --git a/state/mapping/testdata/schema/complex_id.proto b/state/mapping/testdata/schema/with_complex_id.proto similarity index 100% rename from state/mapping/testdata/schema/complex_id.proto rename to state/mapping/testdata/schema/with_complex_id.proto diff --git a/state/mapping/testdata/schema/with_composite_id.pb.go b/state/mapping/testdata/schema/with_composite_id.pb.go new file mode 100644 index 00000000..77b02a77 --- /dev/null +++ b/state/mapping/testdata/schema/with_composite_id.pb.go @@ -0,0 +1,330 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: with_composite_id.proto + +package schema + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// EntityWithCompositeId +type EntityWithCompositeId struct { + IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart,proto3" json:"id_first_part,omitempty"` + IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart,proto3" json:"id_second_part,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Value int32 `protobuf:"varint,4,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityWithCompositeId) Reset() { *m = EntityWithCompositeId{} } +func (m *EntityWithCompositeId) String() string { return proto.CompactTextString(m) } +func (*EntityWithCompositeId) ProtoMessage() {} +func (*EntityWithCompositeId) Descriptor() ([]byte, []int) { + return fileDescriptor_01b53010639f360d, []int{0} +} + +func (m *EntityWithCompositeId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityWithCompositeId.Unmarshal(m, b) +} +func (m *EntityWithCompositeId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityWithCompositeId.Marshal(b, m, deterministic) +} +func (m *EntityWithCompositeId) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityWithCompositeId.Merge(m, src) +} +func (m *EntityWithCompositeId) XXX_Size() int { + return xxx_messageInfo_EntityWithCompositeId.Size(m) +} +func (m *EntityWithCompositeId) XXX_DiscardUnknown() { + xxx_messageInfo_EntityWithCompositeId.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityWithCompositeId proto.InternalMessageInfo + +func (m *EntityWithCompositeId) GetIdFirstPart() string { + if m != nil { + return m.IdFirstPart + } + return "" +} + +func (m *EntityWithCompositeId) GetIdSecondPart() string { + if m != nil { + return m.IdSecondPart + } + return "" +} + +func (m *EntityWithCompositeId) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *EntityWithCompositeId) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +// EntityCompositeId - container for composite primary key +type EntityCompositeId struct { + IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart,proto3" json:"id_first_part,omitempty"` + IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart,proto3" json:"id_second_part,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityCompositeId) Reset() { *m = EntityCompositeId{} } +func (m *EntityCompositeId) String() string { return proto.CompactTextString(m) } +func (*EntityCompositeId) ProtoMessage() {} +func (*EntityCompositeId) Descriptor() ([]byte, []int) { + return fileDescriptor_01b53010639f360d, []int{1} +} + +func (m *EntityCompositeId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityCompositeId.Unmarshal(m, b) +} +func (m *EntityCompositeId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityCompositeId.Marshal(b, m, deterministic) +} +func (m *EntityCompositeId) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityCompositeId.Merge(m, src) +} +func (m *EntityCompositeId) XXX_Size() int { + return xxx_messageInfo_EntityCompositeId.Size(m) +} +func (m *EntityCompositeId) XXX_DiscardUnknown() { + xxx_messageInfo_EntityCompositeId.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityCompositeId proto.InternalMessageInfo + +func (m *EntityCompositeId) GetIdFirstPart() string { + if m != nil { + return m.IdFirstPart + } + return "" +} + +func (m *EntityCompositeId) GetIdSecondPart() string { + if m != nil { + return m.IdSecondPart + } + return "" +} + +// EntityWithCompositeIdList +type EntityWithCompositeIdList struct { + Items []*EntityWithCompositeId `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityWithCompositeIdList) Reset() { *m = EntityWithCompositeIdList{} } +func (m *EntityWithCompositeIdList) String() string { return proto.CompactTextString(m) } +func (*EntityWithCompositeIdList) ProtoMessage() {} +func (*EntityWithCompositeIdList) Descriptor() ([]byte, []int) { + return fileDescriptor_01b53010639f360d, []int{2} +} + +func (m *EntityWithCompositeIdList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityWithCompositeIdList.Unmarshal(m, b) +} +func (m *EntityWithCompositeIdList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityWithCompositeIdList.Marshal(b, m, deterministic) +} +func (m *EntityWithCompositeIdList) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityWithCompositeIdList.Merge(m, src) +} +func (m *EntityWithCompositeIdList) XXX_Size() int { + return xxx_messageInfo_EntityWithCompositeIdList.Size(m) +} +func (m *EntityWithCompositeIdList) XXX_DiscardUnknown() { + xxx_messageInfo_EntityWithCompositeIdList.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityWithCompositeIdList proto.InternalMessageInfo + +func (m *EntityWithCompositeIdList) GetItems() []*EntityWithCompositeId { + if m != nil { + return m.Items + } + return nil +} + +// CreateEntityWithCompositeId +type CreateEntityWithCompositeId struct { + IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart,proto3" json:"id_first_part,omitempty"` + IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart,proto3" json:"id_second_part,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Value int32 `protobuf:"varint,4,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateEntityWithCompositeId) Reset() { *m = CreateEntityWithCompositeId{} } +func (m *CreateEntityWithCompositeId) String() string { return proto.CompactTextString(m) } +func (*CreateEntityWithCompositeId) ProtoMessage() {} +func (*CreateEntityWithCompositeId) Descriptor() ([]byte, []int) { + return fileDescriptor_01b53010639f360d, []int{3} +} + +func (m *CreateEntityWithCompositeId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateEntityWithCompositeId.Unmarshal(m, b) +} +func (m *CreateEntityWithCompositeId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateEntityWithCompositeId.Marshal(b, m, deterministic) +} +func (m *CreateEntityWithCompositeId) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateEntityWithCompositeId.Merge(m, src) +} +func (m *CreateEntityWithCompositeId) XXX_Size() int { + return xxx_messageInfo_CreateEntityWithCompositeId.Size(m) +} +func (m *CreateEntityWithCompositeId) XXX_DiscardUnknown() { + xxx_messageInfo_CreateEntityWithCompositeId.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateEntityWithCompositeId proto.InternalMessageInfo + +func (m *CreateEntityWithCompositeId) GetIdFirstPart() string { + if m != nil { + return m.IdFirstPart + } + return "" +} + +func (m *CreateEntityWithCompositeId) GetIdSecondPart() string { + if m != nil { + return m.IdSecondPart + } + return "" +} + +func (m *CreateEntityWithCompositeId) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *CreateEntityWithCompositeId) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +// UpdateEntityWithCompositeId +type UpdateEntityWithCompositeId struct { + IdFirstPart string `protobuf:"bytes,1,opt,name=id_first_part,json=idFirstPart,proto3" json:"id_first_part,omitempty"` + IdSecondPart string `protobuf:"bytes,2,opt,name=id_second_part,json=idSecondPart,proto3" json:"id_second_part,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Value int32 `protobuf:"varint,4,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpdateEntityWithCompositeId) Reset() { *m = UpdateEntityWithCompositeId{} } +func (m *UpdateEntityWithCompositeId) String() string { return proto.CompactTextString(m) } +func (*UpdateEntityWithCompositeId) ProtoMessage() {} +func (*UpdateEntityWithCompositeId) Descriptor() ([]byte, []int) { + return fileDescriptor_01b53010639f360d, []int{4} +} + +func (m *UpdateEntityWithCompositeId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UpdateEntityWithCompositeId.Unmarshal(m, b) +} +func (m *UpdateEntityWithCompositeId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UpdateEntityWithCompositeId.Marshal(b, m, deterministic) +} +func (m *UpdateEntityWithCompositeId) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateEntityWithCompositeId.Merge(m, src) +} +func (m *UpdateEntityWithCompositeId) XXX_Size() int { + return xxx_messageInfo_UpdateEntityWithCompositeId.Size(m) +} +func (m *UpdateEntityWithCompositeId) XXX_DiscardUnknown() { + xxx_messageInfo_UpdateEntityWithCompositeId.DiscardUnknown(m) +} + +var xxx_messageInfo_UpdateEntityWithCompositeId proto.InternalMessageInfo + +func (m *UpdateEntityWithCompositeId) GetIdFirstPart() string { + if m != nil { + return m.IdFirstPart + } + return "" +} + +func (m *UpdateEntityWithCompositeId) GetIdSecondPart() string { + if m != nil { + return m.IdSecondPart + } + return "" +} + +func (m *UpdateEntityWithCompositeId) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *UpdateEntityWithCompositeId) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +func init() { + proto.RegisterType((*EntityWithCompositeId)(nil), "schema.EntityWithCompositeId") + proto.RegisterType((*EntityCompositeId)(nil), "schema.EntityCompositeId") + proto.RegisterType((*EntityWithCompositeIdList)(nil), "schema.EntityWithCompositeIdList") + proto.RegisterType((*CreateEntityWithCompositeId)(nil), "schema.CreateEntityWithCompositeId") + proto.RegisterType((*UpdateEntityWithCompositeId)(nil), "schema.UpdateEntityWithCompositeId") +} + +func init() { proto.RegisterFile("with_composite_id.proto", fileDescriptor_01b53010639f360d) } + +var fileDescriptor_01b53010639f360d = []byte{ + // 240 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x92, 0xc1, 0x4a, 0xc4, 0x30, + 0x10, 0x86, 0x89, 0xbb, 0x5d, 0x70, 0x56, 0x05, 0x83, 0x62, 0x45, 0x84, 0x12, 0x3c, 0xf4, 0xd4, + 0x83, 0xfb, 0x08, 0x8b, 0x82, 0xe0, 0x61, 0xa9, 0x88, 0x27, 0x09, 0xb1, 0x19, 0xe9, 0x80, 0x6d, + 0x42, 0x32, 0x2a, 0x3e, 0x83, 0x27, 0xdf, 0x58, 0x36, 0xc1, 0xdb, 0x5e, 0x85, 0xde, 0x92, 0x3f, + 0x5f, 0xe0, 0x9b, 0x9f, 0x81, 0xb3, 0x4f, 0xe2, 0x5e, 0x77, 0x6e, 0xf0, 0x2e, 0x12, 0xa3, 0x26, + 0xdb, 0xf8, 0xe0, 0xd8, 0xc9, 0x45, 0xec, 0x7a, 0x1c, 0x8c, 0xfa, 0x16, 0x70, 0x7a, 0x33, 0x32, + 0xf1, 0xd7, 0x13, 0x71, 0xbf, 0xfe, 0x03, 0xef, 0xac, 0x54, 0x70, 0x48, 0x56, 0xbf, 0x52, 0x88, + 0xac, 0xbd, 0x09, 0x5c, 0x8a, 0x4a, 0xd4, 0xfb, 0xed, 0x92, 0xec, 0xed, 0x36, 0xdb, 0x98, 0xc0, + 0xf2, 0x0a, 0x8e, 0xc8, 0xea, 0x88, 0x9d, 0x1b, 0x6d, 0x86, 0xf6, 0x12, 0x74, 0x40, 0xf6, 0x21, + 0x85, 0x89, 0x92, 0x30, 0x1f, 0xcd, 0x80, 0xe5, 0x2c, 0xbd, 0xa5, 0xb3, 0x3c, 0x81, 0xe2, 0xc3, + 0xbc, 0xbd, 0x63, 0x39, 0xaf, 0x44, 0x5d, 0xb4, 0xf9, 0xa2, 0x9e, 0xe1, 0x38, 0xcb, 0xfc, 0x8b, + 0x88, 0xda, 0xc0, 0xf9, 0xce, 0x59, 0xef, 0x29, 0xb2, 0x5c, 0x41, 0x41, 0x8c, 0x43, 0x2c, 0x45, + 0x35, 0xab, 0x97, 0xd7, 0x97, 0x4d, 0x6e, 0xa8, 0xd9, 0xf9, 0xa3, 0xcd, 0xac, 0xfa, 0x11, 0x70, + 0xb1, 0x0e, 0x68, 0x18, 0xa7, 0x53, 0xe2, 0xd6, 0xe9, 0xd1, 0xdb, 0x29, 0x39, 0xbd, 0x2c, 0xd2, + 0xd6, 0xad, 0x7e, 0x03, 0x00, 0x00, 0xff, 0xff, 0x81, 0x58, 0xe8, 0xed, 0x90, 0x02, 0x00, 0x00, +} diff --git a/state/mapping/testdata/schema/with_composite_id.proto b/state/mapping/testdata/schema/with_composite_id.proto new file mode 100644 index 00000000..662ebb6a --- /dev/null +++ b/state/mapping/testdata/schema/with_composite_id.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; +package schema; + +// EntityWithCompositeId +message EntityWithCompositeId { + string id_first_part = 1; // part of composite primary key + string id_second_part = 2; // part of composite primary key + + string name = 3; + int32 value = 4; +} + +// EntityCompositeId - container for composite primary key +message EntityCompositeId { + string id_first_part = 1; + string id_second_part = 2; +} + +// EntityWithCompositeIdList +message EntityWithCompositeIdList { + repeated EntityWithCompositeId items = 1; +} + +// CreateEntityWithCompositeId +message CreateEntityWithCompositeId { + string id_first_part = 1; + string id_second_part = 2; + string name = 3; + int32 value = 4; +} + +// UpdateEntityWithCompositeId +message UpdateEntityWithCompositeId { + string id_first_part = 1; + string id_second_part = 2; + string name = 3; + int32 value = 4; +} diff --git a/state/mapping/testdata/schema/with_indexes.pb.go b/state/mapping/testdata/schema/with_indexes.pb.go new file mode 100644 index 00000000..a0d90a2e --- /dev/null +++ b/state/mapping/testdata/schema/with_indexes.pb.go @@ -0,0 +1,314 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: with_indexes.proto + +package schema + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// EntityWithIndexes +type EntityWithIndexes struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // one external id + ExternalId string `protobuf:"bytes,2,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"` + // required multiple external ids (minimum 1) + RequiredExternalIds []string `protobuf:"bytes,3,rep,name=required_external_ids,json=requiredExternalIds,proto3" json:"required_external_ids,omitempty"` + // optional multiple external ids (minimum 0) + OptionalExternalIds []string `protobuf:"bytes,4,rep,name=optional_external_ids,json=optionalExternalIds,proto3" json:"optional_external_ids,omitempty"` + Value int32 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityWithIndexes) Reset() { *m = EntityWithIndexes{} } +func (m *EntityWithIndexes) String() string { return proto.CompactTextString(m) } +func (*EntityWithIndexes) ProtoMessage() {} +func (*EntityWithIndexes) Descriptor() ([]byte, []int) { + return fileDescriptor_fd22c1b92282e067, []int{0} +} + +func (m *EntityWithIndexes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityWithIndexes.Unmarshal(m, b) +} +func (m *EntityWithIndexes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityWithIndexes.Marshal(b, m, deterministic) +} +func (m *EntityWithIndexes) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityWithIndexes.Merge(m, src) +} +func (m *EntityWithIndexes) XXX_Size() int { + return xxx_messageInfo_EntityWithIndexes.Size(m) +} +func (m *EntityWithIndexes) XXX_DiscardUnknown() { + xxx_messageInfo_EntityWithIndexes.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityWithIndexes proto.InternalMessageInfo + +func (m *EntityWithIndexes) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *EntityWithIndexes) GetExternalId() string { + if m != nil { + return m.ExternalId + } + return "" +} + +func (m *EntityWithIndexes) GetRequiredExternalIds() []string { + if m != nil { + return m.RequiredExternalIds + } + return nil +} + +func (m *EntityWithIndexes) GetOptionalExternalIds() []string { + if m != nil { + return m.OptionalExternalIds + } + return nil +} + +func (m *EntityWithIndexes) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +// EntityWithIndexesList +type EntityWithIndexesList struct { + Items []*EntityWithIndexes `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityWithIndexesList) Reset() { *m = EntityWithIndexesList{} } +func (m *EntityWithIndexesList) String() string { return proto.CompactTextString(m) } +func (*EntityWithIndexesList) ProtoMessage() {} +func (*EntityWithIndexesList) Descriptor() ([]byte, []int) { + return fileDescriptor_fd22c1b92282e067, []int{1} +} + +func (m *EntityWithIndexesList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityWithIndexesList.Unmarshal(m, b) +} +func (m *EntityWithIndexesList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityWithIndexesList.Marshal(b, m, deterministic) +} +func (m *EntityWithIndexesList) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityWithIndexesList.Merge(m, src) +} +func (m *EntityWithIndexesList) XXX_Size() int { + return xxx_messageInfo_EntityWithIndexesList.Size(m) +} +func (m *EntityWithIndexesList) XXX_DiscardUnknown() { + xxx_messageInfo_EntityWithIndexesList.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityWithIndexesList proto.InternalMessageInfo + +func (m *EntityWithIndexesList) GetItems() []*EntityWithIndexes { + if m != nil { + return m.Items + } + return nil +} + +// CreateEntityWithIndexes +type CreateEntityWithIndexes struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // one external id + ExternalId string `protobuf:"bytes,2,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"` + // required multiple external ids (minimum 1) + RequiredExternalIds []string `protobuf:"bytes,3,rep,name=required_external_ids,json=requiredExternalIds,proto3" json:"required_external_ids,omitempty"` + // optional multiple external ids (minimum 0) + OptionalExternalIds []string `protobuf:"bytes,4,rep,name=optional_external_ids,json=optionalExternalIds,proto3" json:"optional_external_ids,omitempty"` + Value int32 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateEntityWithIndexes) Reset() { *m = CreateEntityWithIndexes{} } +func (m *CreateEntityWithIndexes) String() string { return proto.CompactTextString(m) } +func (*CreateEntityWithIndexes) ProtoMessage() {} +func (*CreateEntityWithIndexes) Descriptor() ([]byte, []int) { + return fileDescriptor_fd22c1b92282e067, []int{2} +} + +func (m *CreateEntityWithIndexes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateEntityWithIndexes.Unmarshal(m, b) +} +func (m *CreateEntityWithIndexes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateEntityWithIndexes.Marshal(b, m, deterministic) +} +func (m *CreateEntityWithIndexes) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateEntityWithIndexes.Merge(m, src) +} +func (m *CreateEntityWithIndexes) XXX_Size() int { + return xxx_messageInfo_CreateEntityWithIndexes.Size(m) +} +func (m *CreateEntityWithIndexes) XXX_DiscardUnknown() { + xxx_messageInfo_CreateEntityWithIndexes.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateEntityWithIndexes proto.InternalMessageInfo + +func (m *CreateEntityWithIndexes) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *CreateEntityWithIndexes) GetExternalId() string { + if m != nil { + return m.ExternalId + } + return "" +} + +func (m *CreateEntityWithIndexes) GetRequiredExternalIds() []string { + if m != nil { + return m.RequiredExternalIds + } + return nil +} + +func (m *CreateEntityWithIndexes) GetOptionalExternalIds() []string { + if m != nil { + return m.OptionalExternalIds + } + return nil +} + +func (m *CreateEntityWithIndexes) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +// UpdateEntityEntityWithIndexes +type UpdateEntityWithIndexes struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // one external id + ExternalId string `protobuf:"bytes,2,opt,name=external_id,json=externalId,proto3" json:"external_id,omitempty"` + // required multiple external ids (minimum 1) + RequiredExternalIds []string `protobuf:"bytes,3,rep,name=required_external_ids,json=requiredExternalIds,proto3" json:"required_external_ids,omitempty"` + // optional multiple external ids (minimum 0) + OptionalExternalIds []string `protobuf:"bytes,4,rep,name=optional_external_ids,json=optionalExternalIds,proto3" json:"optional_external_ids,omitempty"` + Value int32 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpdateEntityWithIndexes) Reset() { *m = UpdateEntityWithIndexes{} } +func (m *UpdateEntityWithIndexes) String() string { return proto.CompactTextString(m) } +func (*UpdateEntityWithIndexes) ProtoMessage() {} +func (*UpdateEntityWithIndexes) Descriptor() ([]byte, []int) { + return fileDescriptor_fd22c1b92282e067, []int{3} +} + +func (m *UpdateEntityWithIndexes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UpdateEntityWithIndexes.Unmarshal(m, b) +} +func (m *UpdateEntityWithIndexes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UpdateEntityWithIndexes.Marshal(b, m, deterministic) +} +func (m *UpdateEntityWithIndexes) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateEntityWithIndexes.Merge(m, src) +} +func (m *UpdateEntityWithIndexes) XXX_Size() int { + return xxx_messageInfo_UpdateEntityWithIndexes.Size(m) +} +func (m *UpdateEntityWithIndexes) XXX_DiscardUnknown() { + xxx_messageInfo_UpdateEntityWithIndexes.DiscardUnknown(m) +} + +var xxx_messageInfo_UpdateEntityWithIndexes proto.InternalMessageInfo + +func (m *UpdateEntityWithIndexes) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *UpdateEntityWithIndexes) GetExternalId() string { + if m != nil { + return m.ExternalId + } + return "" +} + +func (m *UpdateEntityWithIndexes) GetRequiredExternalIds() []string { + if m != nil { + return m.RequiredExternalIds + } + return nil +} + +func (m *UpdateEntityWithIndexes) GetOptionalExternalIds() []string { + if m != nil { + return m.OptionalExternalIds + } + return nil +} + +func (m *UpdateEntityWithIndexes) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +func init() { + proto.RegisterType((*EntityWithIndexes)(nil), "schema.EntityWithIndexes") + proto.RegisterType((*EntityWithIndexesList)(nil), "schema.EntityWithIndexesList") + proto.RegisterType((*CreateEntityWithIndexes)(nil), "schema.CreateEntityWithIndexes") + proto.RegisterType((*UpdateEntityWithIndexes)(nil), "schema.UpdateEntityWithIndexes") +} + +func init() { proto.RegisterFile("with_indexes.proto", fileDescriptor_fd22c1b92282e067) } + +var fileDescriptor_fd22c1b92282e067 = []byte{ + // 238 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x92, 0xc1, 0x4a, 0xc3, 0x30, + 0x18, 0xc7, 0x49, 0x6b, 0x07, 0xfb, 0x06, 0x82, 0xd1, 0x61, 0x3c, 0x59, 0x7a, 0xca, 0xa9, 0xc2, + 0x7c, 0x04, 0x19, 0x38, 0xf0, 0x14, 0x10, 0x8f, 0x25, 0x9a, 0x0f, 0xfa, 0xc1, 0xd6, 0xd4, 0xe4, + 0x9b, 0xce, 0xd7, 0xf3, 0xe4, 0x63, 0x49, 0x17, 0x2a, 0x93, 0x3d, 0x81, 0x1e, 0x93, 0xff, 0xef, + 0x77, 0xf8, 0x85, 0x80, 0x7c, 0x27, 0x6e, 0x1b, 0xea, 0x1c, 0xee, 0x30, 0xd6, 0x7d, 0xf0, 0xec, + 0xe5, 0x24, 0xbe, 0xb4, 0xb8, 0xb1, 0xd5, 0xa7, 0x80, 0xb3, 0x65, 0xc7, 0xc4, 0x1f, 0x4f, 0xc4, + 0xed, 0x2a, 0x31, 0xf2, 0x14, 0x32, 0x72, 0x4a, 0x94, 0x42, 0x4f, 0x4d, 0x46, 0x4e, 0x5e, 0xc3, + 0x0c, 0x77, 0x8c, 0xa1, 0xb3, 0xeb, 0x86, 0x9c, 0xca, 0xf6, 0x03, 0x8c, 0x57, 0x2b, 0x27, 0x17, + 0x30, 0x0f, 0xf8, 0xba, 0xa5, 0x80, 0xae, 0x39, 0x20, 0xa3, 0xca, 0xcb, 0x5c, 0x4f, 0xcd, 0xf9, + 0x38, 0x2e, 0x7f, 0x94, 0x38, 0x38, 0xbe, 0x67, 0xf2, 0x03, 0xfa, 0xcb, 0x39, 0x49, 0xce, 0x38, + 0x1e, 0x3a, 0x17, 0x50, 0xbc, 0xd9, 0xf5, 0x16, 0x55, 0x51, 0x0a, 0x5d, 0x98, 0x74, 0xa8, 0xee, + 0x61, 0x7e, 0xd4, 0xf0, 0x40, 0x91, 0xe5, 0x0d, 0x14, 0xc4, 0xb8, 0x89, 0x4a, 0x94, 0xb9, 0x9e, + 0x2d, 0xae, 0xea, 0x54, 0x5d, 0x1f, 0xd1, 0x26, 0x71, 0xd5, 0x97, 0x80, 0xcb, 0xbb, 0x80, 0x96, + 0xf1, 0xcf, 0x3f, 0xca, 0x90, 0xf2, 0xd8, 0xbb, 0x7f, 0x90, 0xf2, 0x3c, 0xd9, 0xff, 0xd9, 0xdb, + 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4a, 0x94, 0x9b, 0x51, 0xc9, 0x02, 0x00, 0x00, +} diff --git a/state/mapping/testdata/schema/with_indexes.proto b/state/mapping/testdata/schema/with_indexes.proto new file mode 100644 index 00000000..cb088c9f --- /dev/null +++ b/state/mapping/testdata/schema/with_indexes.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; +package schema; + +// EntityWithIndexes +message EntityWithIndexes { + string id = 1; + // one external id + string external_id = 2; + + // required multiple external ids (minimum 1) + repeated string required_external_ids = 3; + // optional multiple external ids (minimum 0) + repeated string optional_external_ids = 4; + + int32 value = 5; +} + +// EntityWithIndexesList +message EntityWithIndexesList { + repeated EntityWithIndexes items = 1; +} + +// CreateEntityWithIndexes +message CreateEntityWithIndexes { + string id = 1; + // one external id + string external_id = 2; + + // required multiple external ids (minimum 1) + repeated string required_external_ids = 3; + // optional multiple external ids (minimum 0) + repeated string optional_external_ids = 4; + + int32 value = 5; +} + +// UpdateEntityEntityWithIndexes +message UpdateEntityWithIndexes { + string id = 1; + // one external id + string external_id = 2; + + // required multiple external ids (minimum 1) + repeated string required_external_ids = 3; + // optional multiple external ids (minimum 0) + repeated string optional_external_ids = 4; + + int32 value = 5; +} \ No newline at end of file diff --git a/state/mapping/testdata/schema/with_slice_id.pb.go b/state/mapping/testdata/schema/with_slice_id.pb.go new file mode 100644 index 00000000..6d9d05aa --- /dev/null +++ b/state/mapping/testdata/schema/with_slice_id.pb.go @@ -0,0 +1,89 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: with_slice_id.proto + +package schema + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type EntityWithSliceId struct { + Id []string `protobuf:"bytes,1,rep,name=Id,proto3" json:"Id,omitempty"` + SomeDate *timestamp.Timestamp `protobuf:"bytes,2,opt,name=some_date,json=someDate,proto3" json:"some_date,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntityWithSliceId) Reset() { *m = EntityWithSliceId{} } +func (m *EntityWithSliceId) String() string { return proto.CompactTextString(m) } +func (*EntityWithSliceId) ProtoMessage() {} +func (*EntityWithSliceId) Descriptor() ([]byte, []int) { + return fileDescriptor_9c66da54a6d52f44, []int{0} +} + +func (m *EntityWithSliceId) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntityWithSliceId.Unmarshal(m, b) +} +func (m *EntityWithSliceId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntityWithSliceId.Marshal(b, m, deterministic) +} +func (m *EntityWithSliceId) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntityWithSliceId.Merge(m, src) +} +func (m *EntityWithSliceId) XXX_Size() int { + return xxx_messageInfo_EntityWithSliceId.Size(m) +} +func (m *EntityWithSliceId) XXX_DiscardUnknown() { + xxx_messageInfo_EntityWithSliceId.DiscardUnknown(m) +} + +var xxx_messageInfo_EntityWithSliceId proto.InternalMessageInfo + +func (m *EntityWithSliceId) GetId() []string { + if m != nil { + return m.Id + } + return nil +} + +func (m *EntityWithSliceId) GetSomeDate() *timestamp.Timestamp { + if m != nil { + return m.SomeDate + } + return nil +} + +func init() { + proto.RegisterType((*EntityWithSliceId)(nil), "schema.EntityWithSliceId") +} + +func init() { proto.RegisterFile("with_slice_id.proto", fileDescriptor_9c66da54a6d52f44) } + +var fileDescriptor_9c66da54a6d52f44 = []byte{ + // 158 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0xcf, 0x2c, 0xc9, + 0x88, 0x2f, 0xce, 0xc9, 0x4c, 0x4e, 0x8d, 0xcf, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, + 0x62, 0x2b, 0x4e, 0xce, 0x48, 0xcd, 0x4d, 0x94, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, + 0x07, 0x8b, 0x26, 0x95, 0xa6, 0xe9, 0x97, 0x64, 0xe6, 0xa6, 0x16, 0x97, 0x24, 0xe6, 0x16, 0x40, + 0x14, 0x2a, 0xc5, 0x70, 0x09, 0xba, 0xe6, 0x95, 0x64, 0x96, 0x54, 0x86, 0x67, 0x96, 0x64, 0x04, + 0x83, 0x0c, 0xf1, 0x4c, 0x11, 0xe2, 0xe3, 0x62, 0xf2, 0x4c, 0x91, 0x60, 0x54, 0x60, 0xd6, 0xe0, + 0x0c, 0x62, 0xf2, 0x4c, 0x11, 0x32, 0xe7, 0xe2, 0x2c, 0xce, 0xcf, 0x4d, 0x8d, 0x4f, 0x49, 0x2c, + 0x49, 0x95, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x36, 0x92, 0xd2, 0x83, 0x98, 0xac, 0x07, 0x33, 0x59, + 0x2f, 0x04, 0x66, 0x72, 0x10, 0x07, 0x48, 0xb1, 0x4b, 0x62, 0x49, 0x6a, 0x12, 0x1b, 0x58, 0xd6, + 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xac, 0x7a, 0x81, 0xa4, 0x00, 0x00, 0x00, +} diff --git a/state/mapping/testdata/schema/slice_id.proto b/state/mapping/testdata/schema/with_slice_id.proto similarity index 100% rename from state/mapping/testdata/schema/slice_id.proto rename to state/mapping/testdata/schema/with_slice_id.proto diff --git a/state/mapping/testdata/testdata.go b/state/mapping/testdata/testdata.go index 8afc8cec..a2ebe31d 100644 --- a/state/mapping/testdata/testdata.go +++ b/state/mapping/testdata/testdata.go @@ -3,34 +3,31 @@ package testdata import "github.com/s7techlab/cckit/state/mapping/testdata/schema" var ( - ProtoIssueMocks = []schema.IssueProtoEntity{{ + CreateEntityWithCompositeId = []*schema.CreateEntityWithCompositeId{{ IdFirstPart: "A", IdSecondPart: "1", Name: "Lorem", - ExternalId: "EXT1", + Value: 1, }, { IdFirstPart: "B", IdSecondPart: "1", Name: "Ipsum", - ExternalId: "EXT2", + Value: 2, }, { IdFirstPart: "B", IdSecondPart: "2", Name: "Dolor", - ExternalId: "EXT3", + Value: 3, }} - ProtoIssueMockExistingExternal = schema.IssueProtoEntity{ - IdFirstPart: "Z", - IdSecondPart: "1", - Name: "Lorem", - ExternalId: "EXT1", - } - - ProtoIssueMockExistingPrimary = schema.IssueProtoEntity{ - IdFirstPart: "A", - IdSecondPart: "1", - Name: "Lorem", - ExternalId: "EXT100", - } + CreateEntityWithIndexes = []*schema.CreateEntityWithIndexes{{ + Id: `aaa`, + ExternalId: `aaa_aaa`, + Value: 1, + }, { + Id: `bbb`, + ExternalId: `bbb_bbb`, + OptionalExternalIds: []string{`bbb_opt1`, `bbb_opt2`}, + Value: 1, + }} ) diff --git a/state/state.go b/state/state.go index 79ad3963..5b139eef 100644 --- a/state/state.go +++ b/state/state.go @@ -136,6 +136,10 @@ func (k Key) Append(key Key) Key { return append(k, key...) } +func (k Key) String() string { + return strings.Join(k, ` | `) +} + type Impl struct { stub shim.ChaincodeStubInterface logger *shim.ChaincodeLogger @@ -211,7 +215,7 @@ func (s *Impl) Get(entry interface{}, config ...interface{}) (interface{}, error if len(config) >= 2 { return config[1], nil } - return nil, errors.Wrap(KeyError(key), ErrKeyNotFound.Error()) + return nil, errors.Errorf(`%s: %s`, ErrKeyNotFound, key.Origin) } // config[0] - target type @@ -365,7 +369,7 @@ func (s *Impl) Insert(entry interface{}, values ...interface{}) error { return err } else if exists { key, _ := s.Key(entry) - return errors.Wrap(KeyError(key), ErrKeyAlreadyExists.Error()) + return errors.Errorf(`%s: %s`, ErrKeyAlreadyExists, key.Origin) } key, value, err := s.argKeyValue(entry, values) @@ -400,12 +404,6 @@ func (s *Impl) UseStatePutTransformer(tb ToBytesTransformer) State { return s } -// KeyError error with key -func KeyError(key *TransformedKey) error { - // show origin key - return errors.New(strings.Join(key.Origin, ` | `)) -} - type stringKeyer struct { str string keyer KeyerFunc @@ -438,7 +436,7 @@ func (s *Impl) GetPrivate(collection string, entry interface{}, config ...interf if len(config) >= 2 { return config[1], nil } - return nil, errors.Wrap(KeyError(key), ErrKeyNotFound.Error()) + return nil, errors.Errorf(`%s: %s`, ErrKeyNotFound, key.Origin.String()) } // config[0] - target type @@ -543,8 +541,8 @@ func (s *Impl) InsertPrivate(collection string, entry interface{}, values ...int if exists, err := s.ExistsPrivate(collection, entry); err != nil { return err } else if exists { - strKey, _ := s.Key(entry) - return errors.Wrap(KeyError(strKey), ErrKeyAlreadyExists.Error()) + key, _ := s.Key(entry) + return errors.Errorf(`%s: %s`, ErrKeyAlreadyExists, key.Origin) } key, value, err := s.argKeyValue(entry, values)