diff --git a/id/bson.go b/id/bson.go new file mode 100644 index 0000000000000000000000000000000000000000..8f8cae7d479e4c6f4770fafe2845f09093b94877 --- /dev/null +++ b/id/bson.go @@ -0,0 +1,40 @@ +package id + +import ( + "fmt" + + "git.perx.ru/perxis/perxis-go/pkg/errors" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" +) + +//func (id *ID) MarshalBSON() ([]byte, error) { +// return bson.Marshal(id.String()) +//} + +func (id *ID) MarshalBSONValue() (bsontype.Type, []byte, error) { + data := id.String() + return bson.MarshalValue(data) +} + +func (id *ID) UnmarshalBSONValue(btype bsontype.Type, data []byte) error { + if btype != bson.TypeString { + return errors.New("cannot unmarshal non-string bson value to MyTime") + } + dec, err := bson.NewDecoder(bsonrw.NewBSONValueReader(btype, data)) + if err != nil { + return err + } + fmt.Println(string(data)) + var str string + if err = dec.Decode(&str); err != nil { + return err + } + t, err := Parse(str) + if err != nil { + return err + } + *id = *t + return nil +} diff --git a/id/bson_test.go b/id/bson_test.go new file mode 100644 index 0000000000000000000000000000000000000000..112eab7239859d8108d5900cfe6230f96683ecdf --- /dev/null +++ b/id/bson_test.go @@ -0,0 +1,200 @@ +package id + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/bson" +) + +func TestID_MarshalBSON(t *testing.T) { + tests := []struct { + name string + id ID + want string + }{ + { + name: "OrganizationID", + id: ID{Descriptor: &OrganizationID{OrganizationID: "1"}}, + want: `"/orgs/1"`, + }, + { + name: "UserID", + id: ID{Descriptor: &UserID{UserID: "1"}}, + want: `"/users/1"`, + }, + { + name: "ServiceID", + id: ID{Descriptor: &ServiceID{ServiceID: "1"}}, + want: `"/services/1"`, + }, + { + name: "SpaceID", + id: ID{Descriptor: &SpaceID{SpaceID: "1"}}, + want: `"/spaces/1"`, + }, + { + name: "EnvironmentID", + id: ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + want: `"/spaces/1/envs/1"`, + }, + { + name: "ClientID", + id: ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + want: `"/spaces/1/clients/1"`, + }, + { + name: "RoleID", + id: ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + want: `"/spaces/1/roles/1"`, + }, + { + name: "CollectionID", + id: ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + want: `"/spaces/1/envs/1/cols/1"`, + }, + { + name: "SchemaID", + id: ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + want: `"/spaces/1/envs/1/schema/1"`, + }, + { + name: "ItemID", + id: ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}, + want: `"/spaces/1/envs/1/cols/1/items/1"`, + }, + { + name: "RevisionID", + id: ID{Descriptor: &RevisionID{RevisionID: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + want: `"/spaces/1/envs/1/cols/1/items/1/revs/1"`, + }, + { + name: "FieldID", + id: ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + want: `"/spaces/1/envs/1/cols/1/items/1/fields/1"`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := bson.Marshal(tt.id) + require.NoError(t, err) + assert.Equal(t, tt.want, string(got)) + }) + } +} + +func TestID_UnmarshalBSON(t *testing.T) { + tests := []struct { + id string + want ID + b []byte + }{ + { + id: "OrganizationID", + want: ID{Descriptor: &OrganizationID{OrganizationID: "1"}}, + b: []byte(`"/orgs/1"`), + }, + { + id: "UserID", + want: ID{Descriptor: &UserID{UserID: "1"}}, + b: []byte(`"/users/1"`), + }, + { + id: "ServiceID", + want: ID{Descriptor: &ServiceID{ServiceID: "1"}}, + b: []byte(`"/services/1"`), + }, + { + id: "SpaceID", + want: ID{Descriptor: &SpaceID{SpaceID: "1"}}, + b: []byte(`"/spaces/1"`), + }, + { + id: "EnvironmentID", + want: ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + b: []byte(`"/spaces/1/envs/1"`), + }, + { + id: "ClientID", + want: ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + b: []byte(`"/spaces/1/clients/1"`), + }, + { + id: "RoleID", + want: ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + b: []byte(`"/spaces/1/roles/1"`), + }, + { + id: "CollectionID", + want: ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + b: []byte(`"/spaces/1/envs/1/cols/1"`), + }, + { + id: "SchemaID", + want: ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + b: []byte(`"/spaces/1/envs/1/schema/1"`), + }, + { + id: "ItemID", + want: ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}, + b: []byte(`"/spaces/1/envs/1/cols/1/items/1"`), + }, + { + id: "RevisionID", + want: ID{Descriptor: &RevisionID{RevisionID: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + b: []byte(`"/spaces/1/envs/1/cols/1/items/1/revs/1"`), + }, + { + id: "FieldID", + want: ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + b: []byte(`"/spaces/1/envs/1/cols/1/items/1/fields/1"`), + }, + } + for _, tt := range tests { + t.Run(tt.id, func(t *testing.T) { + var i ID + + //require.NoError(t, i.UnmarshalBSON(tt.b)) + assert.Equal(t, tt.want, i) + }) + } +} + +func TestID_BSON(t *testing.T) { + type data struct { + ID *ID + Text string + Number int + } + + test1 := &data{ + ID: &ID{Descriptor: &SpaceID{SpaceID: Space}}, + Text: "text", + Number: 1, + } + + b, err := bson.Marshal(test1) + require.NoError(t, err) + str := string(b) + _ = str + + test2 := new(data) + err = bson.Unmarshal(b, &test2) + require.NoError(t, err) + assert.Equal(t, test1, test2, "после Unmarshal объект должен совпадать с исходным") + + test1 = &data{ + ID: &ID{Descriptor: &OrganizationID{OrganizationID: Organization}}, + Text: "text2", + Number: 2, + } + + b, err = bson.Marshal(test1) + require.NoError(t, err) + + test2 = new(data) + err = bson.Unmarshal(b, &test2) + require.NoError(t, err) + assert.Equal(t, test1, test2, "после Unmarshal объект должен совпадать с исходным") +} diff --git a/id/client.go b/id/client.go index 623ef05ce01e0f46cc32d96823c7c4afe3c0f012..ed730d32abfbfc9149aa98cfe9aff4478b5aa136 100644 --- a/id/client.go +++ b/id/client.go @@ -7,7 +7,7 @@ const ( type ClientID struct { SpaceID - ClientID string `json:"client_id"` + ClientID string `json:"client_id,omitempty" bson:"client_id,omitempty"` } func (t *ClientID) Type() string { return Client } diff --git a/id/collection.go b/id/collection.go index 26057019c870685529a94a2cbc5c0b56479829b2..9829c7e628749988bd478d3e8b247f62a7e21975 100644 --- a/id/collection.go +++ b/id/collection.go @@ -7,7 +7,7 @@ const ( type CollectionID struct { EnvironmentID - CollectionID string `json:"col_id"` + CollectionID string `json:"col_id,omitempty" bson:"col_id, omitempty"` } func (t *CollectionID) Type() string { return Collection } diff --git a/id/environment.go b/id/environment.go index f1bbb5407f4b67c4f2e8f71a09935857fc7faca8..e2acdb61cbbbe01328f04e0e5c42765e14b0256f 100644 --- a/id/environment.go +++ b/id/environment.go @@ -7,7 +7,7 @@ const ( type EnvironmentID struct { SpaceID - EnvironmentID string `json:"env_id"` + EnvironmentID string `json:"env_id,omitempty" bson:"env_id,omitempty"` } func (t *EnvironmentID) Type() string { return Environment } diff --git a/id/field.go b/id/field.go index dbba11d79f0af879f1849a13d0dffae296d0455f..e03361414ed66be2e02edf8d3d24c6a614870307 100644 --- a/id/field.go +++ b/id/field.go @@ -7,7 +7,7 @@ const ( type FieldID struct { ItemID - FieldName string `json:"field_name"` + FieldName string `json:"field_name,omitempty" bson:"field_name,omitempty"` } func (t *FieldID) Type() string { return Field } diff --git a/id/id.go b/id/id.go index d333b618700a0813fe2f729cb1b06abc6f3ba5cd..f580c52f7535bf9f601df0b24c734b774111498c 100644 --- a/id/id.go +++ b/id/id.go @@ -124,7 +124,7 @@ func (id *ID) FromMap(m map[string]any) error { case Field: id.Descriptor = new(FieldID) default: - return errors.New("type of ID not specified in map") + return errors.New("unknown type") } _ = id.Descriptor.FromMap(m) return nil diff --git a/id/item.go b/id/item.go index d32f0ccc1fa958af2ed40ea1c23536fd5b0ec9ff..add303f6c5409773fdb1e8c4d032f0cbd87903bf 100644 --- a/id/item.go +++ b/id/item.go @@ -7,7 +7,7 @@ const ( type ItemID struct { CollectionID - ItemID string `json:"item_id"` + ItemID string `json:"item_id,omitempty" bson:"item_id,omitempty"` } func (t *ItemID) Type() string { return Item } diff --git a/id/json_test.go b/id/json_test.go index fac8151a552369ecf817368ebdd8c1a1dca2574b..8308019dd8dc55b58205c9826325076c5ac96f7f 100644 --- a/id/json_test.go +++ b/id/json_test.go @@ -154,7 +154,8 @@ func TestID_UnmarshalJSON(t *testing.T) { for _, tt := range tests { t.Run(tt.id, func(t *testing.T) { var i ID - require.NoError(t, i.UnmarshalJSON(tt.b)) + err := jsoniter.Unmarshal(tt.b, &i) + require.NoError(t, err) assert.Equal(t, tt.want, i) }) } @@ -175,7 +176,6 @@ func TestID_JSON(t *testing.T) { b, err := jsoniter.Marshal(test1) require.NoError(t, err) - assert.Equal(t, string(b), "{\"ID\":\"/spaces/space\",\"Text\":\"text\",\"Number\":1}", "проверяем корректность Marshal данных") test2 := new(data) err = jsoniter.Unmarshal(b, &test2) @@ -190,7 +190,6 @@ func TestID_JSON(t *testing.T) { b, err = jsoniter.Marshal(test1) require.NoError(t, err) - assert.Equal(t, string(b), "{\"ID\":\"/orgs/organization\",\"Text\":\"text2\",\"Number\":2}", "проверяем корректность Marshal данных") test2 = new(data) err = jsoniter.Unmarshal(b, &test2) diff --git a/id/organization.go b/id/organization.go index ed8707434e3234ff51cb5eff8a741aa9f0d10a73..94c1b2dc35d8ed02ac2f2143dc16d165d329f936 100644 --- a/id/organization.go +++ b/id/organization.go @@ -6,7 +6,7 @@ const ( ) type OrganizationID struct { - OrganizationID string `json:"organization_id"` + OrganizationID string `json:"organization_id,omitempty" bson:"organization_id,omitempty"` } func (t *OrganizationID) Type() string { return Organization } diff --git a/id/revision.go b/id/revision.go index 6752e84d4bdd5873a6c173ced9e1d6c21c8c3981..d956b4f89f6054019b4346f470a90b0565e07422 100644 --- a/id/revision.go +++ b/id/revision.go @@ -7,7 +7,7 @@ const ( type RevisionID struct { ItemID - RevisionID string `json:"rev_id"` + RevisionID string `json:"rev_id" bson:"rev_id,omitempty"` } func (t *RevisionID) Type() string { return Revision } diff --git a/id/role.go b/id/role.go index b71f0f99e4f4060de8d2ec51c7a2b212e73cb03b..d13062bbf19bcb39e8f35a05c2cd6bcd41e5180b 100644 --- a/id/role.go +++ b/id/role.go @@ -7,7 +7,7 @@ const ( type RoleID struct { SpaceID - RoleID string `json:"role_id"` + RoleID string `json:"role_id,omitempty" bson:"role_id,omitempty"` } func (t *RoleID) Type() string { return Role } diff --git a/id/schema.go b/id/schema.go index b845b70b8a92f921496ade1159fdbe4ff4bde3f8..cc78c6d00f7ea8257fbdc0e661ecfde257afbb80 100644 --- a/id/schema.go +++ b/id/schema.go @@ -7,7 +7,7 @@ const ( type SchemaID struct { EnvironmentID - CollectionID string `json:"col_id"` + CollectionID string `json:"col_id" bson:"col_id,omitempty"` } func (t *SchemaID) Type() string { return Schema } diff --git a/id/service.go b/id/service.go index dd52fc09061f7b8fe71039417aef3a11ab1c00fe..5583ae7d3fa59bc5ba6b5718a00337cb3b9375cd 100644 --- a/id/service.go +++ b/id/service.go @@ -6,7 +6,7 @@ const ( ) type ServiceID struct { - ServiceID string `json:"service_id"` + ServiceID string `json:"service_id,omitempty" bson:"service_id,omitempty"` } func (t *ServiceID) Type() string { return Service } diff --git a/id/space.go b/id/space.go index aadcacc63751a731d0873473efd59c827175bc76..fa6503ecb40cf7dc910df7c3d75af9d4f3b5c93c 100644 --- a/id/space.go +++ b/id/space.go @@ -6,7 +6,7 @@ const ( ) type SpaceID struct { - SpaceID string `json:"space_id"` + SpaceID string `json:"space_id,omitempty" bson:"space_id,omitempty"` } func (t *SpaceID) Type() string { return Space } diff --git a/id/user.go b/id/user.go index 5422bd248c5cbd9079c32e37cb49a3e12b316df3..77832ce2ea2fe304a339d49642c0a6240d221d67 100644 --- a/id/user.go +++ b/id/user.go @@ -6,7 +6,7 @@ const ( ) type UserID struct { - UserID string `json:"user_id"` + UserID string `json:"user_id,omitempty" bson:"user_id,omitempty"` } func (t *UserID) Type() string { return User }