Skip to content
Snippets Groups Projects
Commit 08aaf1e5 authored by ko_oler's avatar ko_oler
Browse files

Merge branch 'feature/PRXS-951-Log' into feature/PRXS-1896-LogSDKUpd

parents 11274d85 9fa57aa9
No related branches found
No related tags found
No related merge requests found
package id
import (
"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) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(id.String())
}
func (id *ID) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
if btype != bson.TypeString {
return errors.New("cannot unmarshal non-string bson value to ID")
}
dec, err := bson.NewDecoder(bsonrw.NewBSONValueReader(btype, data))
if err != nil {
return err
}
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
}
package id
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/bson"
)
func TestID_MarshalUnmarshalBSON(t *testing.T) {
tests := []struct {
name string
id *ID
}{
{
name: "OrganizationID",
id: &ID{Descriptor: &OrganizationID{OrganizationID: "1"}},
},
{
name: "UserID",
id: &ID{Descriptor: &UserID{UserID: "1"}},
},
{
name: "ServiceID",
id: &ID{Descriptor: &ServiceID{ServiceID: "1"}},
},
{
name: "SpaceID",
id: &ID{Descriptor: &SpaceID{SpaceID: "1"}},
},
{
name: "EnvironmentID",
id: &ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
},
{
name: "ClientID",
id: &ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
},
{
name: "RoleID",
id: &ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
},
{
name: "CollectionID",
id: &ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
},
{
name: "SchemaID",
id: &ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
},
{
name: "ItemID",
id: &ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "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"}}}}}},
},
{
name: "FieldID",
id: &ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}},
},
{
name: "SystemID",
id: &ID{Descriptor: &SystemID{}},
},
}
type test struct {
Text string
ID *ID
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &test{Text: tt.name, ID: tt.id}
b, err := bson.Marshal(s)
require.NoError(t, err)
var v *test
require.NoError(t, bson.Unmarshal(b, &v))
assert.Equal(t, s, v, "после Unmarshal объект должен быть идентичен исходному")
})
}
}
func TestID_ExampleBSON(t *testing.T) {
type data struct {
ID *ID
Text string
Number int
}
test := &data{
ID: &ID{Descriptor: &SpaceID{SpaceID: Space}},
Text: "text",
Number: 1,
}
b, err := bson.Marshal(test)
require.NoError(t, err)
buf := new(data)
err = bson.Unmarshal(b, &buf)
require.NoError(t, err)
assert.Equal(t, test, buf, "после Unmarshal объект должен совпадать с исходным")
}
package id
const (
Client = "client"
ClientsPrefix = "clients"
)
type ClientID struct {
SpaceID
ClientID string `json:"client_id,omitempty" bson:"client_id,omitempty"`
}
func (t *ClientID) Type() string { return Client }
func (t *ClientID) String() string {
return Join(t.SpaceID.String(), ClientsPrefix, t.ClientID)
}
func (t *ClientID) ToMap() map[string]any {
m := t.SpaceID.ToMap()
m["client_id"] = t.ClientID
m["type"] = Client
return m
}
func (t *ClientID) FromMap(m map[string]any) error {
if err := t.SpaceID.FromMap(m); err != nil {
return err
}
t.ClientID = m["client_id"].(string)
return nil
}
func (t *ClientID) Validate() error {
if t.ClientID == "" {
return ErrInvalidID
}
return t.SpaceID.Validate()
}
func parseClientID(parts []string) (*ClientID, error) {
if len(parts) != 4 || parts[2] != ClientsPrefix {
return nil, ErrInvalidID
}
spaceID, err := parseSpaceID(parts[:2])
if err != nil {
return nil, err
}
var id ClientID
id.SpaceID = *spaceID
id.ClientID = parts[3]
return &id, nil
}
func NewClientID(spaceID, id string) *ID {
return &ID{Descriptor: &ClientID{SpaceID: SpaceID{SpaceID: spaceID}, ClientID: id}}
}
package id
const (
Collection = "collection"
CollectionsPrefix = "cols"
)
type CollectionID struct {
EnvironmentID
CollectionID string `json:"col_id,omitempty" bson:"col_id, omitempty"`
}
func (t *CollectionID) Type() string { return Collection }
func (t *CollectionID) String() string {
return Join(t.EnvironmentID.String(), CollectionsPrefix, t.CollectionID)
}
func (t *CollectionID) ToMap() map[string]any {
m := t.EnvironmentID.ToMap()
m["col_id"] = t.CollectionID
m["type"] = Collection
return m
}
func (t *CollectionID) FromMap(m map[string]any) error {
if err := t.EnvironmentID.FromMap(m); err != nil {
return err
}
t.CollectionID = m["col_id"].(string)
return nil
}
func (t *CollectionID) Validate() error {
if t.CollectionID == "" {
return ErrInvalidID
}
return t.EnvironmentID.Validate()
}
func parseCollectionID(parts []string) (*CollectionID, error) {
if len(parts) != 6 || parts[4] != CollectionsPrefix {
return nil, ErrInvalidID
}
envID, err := parseEnvironmentID(parts[:4])
if err != nil {
return nil, err
}
var id CollectionID
id.CollectionID = parts[5]
id.EnvironmentID = *envID
return &id, nil
}
func NewCollectionID(spaceID, envID, id string) *ID {
return &ID{Descriptor: &CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: id}}
}
package id
const (
Environment = "environment"
EnvironmentsPrefix = "envs"
)
type EnvironmentID struct {
SpaceID
EnvironmentID string `json:"env_id,omitempty" bson:"env_id,omitempty"`
}
func (t *EnvironmentID) Type() string { return Environment }
func (t *EnvironmentID) String() string {
return Join(t.SpaceID.String(), EnvironmentsPrefix, t.EnvironmentID)
}
func (t *EnvironmentID) ToMap() map[string]any {
m := t.SpaceID.ToMap()
m["env_id"] = t.EnvironmentID
m["type"] = Environment
return m
}
func (t *EnvironmentID) FromMap(m map[string]any) error {
if err := t.SpaceID.FromMap(m); err != nil {
return err
}
t.EnvironmentID = m["env_id"].(string)
return nil
}
func (t *EnvironmentID) Validate() error {
if t.EnvironmentID == "" {
return ErrInvalidID
}
return t.SpaceID.Validate()
}
func parseEnvironmentID(parts []string) (*EnvironmentID, error) {
if len(parts) != 4 || parts[2] != EnvironmentsPrefix {
return nil, ErrInvalidID
}
spaceID, err := parseSpaceID(parts[:2])
if err != nil {
return nil, err
}
var id EnvironmentID
id.EnvironmentID = parts[3]
id.SpaceID = *spaceID
return &id, nil
}
func NewEnvironmentID(spaceID, id string) *ID {
return &ID{Descriptor: &EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: id}}
}
package id
const (
Field = "field"
FieldsPrefix = "fields"
)
type FieldID struct {
ItemID
FieldName string `json:"field_name,omitempty" bson:"field_name,omitempty"`
}
func (t *FieldID) Type() string { return Field }
func (t *FieldID) String() string {
return Join(t.ItemID.String(), FieldsPrefix, t.FieldName)
}
func (t *FieldID) ToMap() map[string]any {
m := t.ItemID.ToMap()
m["field_name"] = t.FieldName
m["type"] = Field
return m
}
func (t *FieldID) FromMap(m map[string]any) error {
if err := t.ItemID.FromMap(m); err != nil {
return err
}
t.FieldName = m["field_name"].(string)
return nil
}
func (t *FieldID) Validate() error {
if t.FieldName == "" {
return ErrInvalidID
}
return t.ItemID.Validate()
}
func parseFieldID(parts []string) (*FieldID, error) {
if len(parts) != 10 || parts[8] != FieldsPrefix {
return nil, ErrInvalidID
}
itemID, err := parseItemID(parts[:8])
if err != nil {
return nil, err
}
var id FieldID
id.ItemID = *itemID
id.FieldName = parts[9]
return &id, nil
}
func NewFieldID(spaceID, envID, collID, itemID, id string) *ID {
return &ID{Descriptor: &FieldID{ItemID: ItemID{CollectionID: CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: collID}, ItemID: itemID}, FieldName: id}}
}
id/id.go 0 → 100644
package id
import (
"strings"
"git.perx.ru/perxis/perxis-go/pkg/errors"
)
const Separator = '/'
var (
ErrInvalidID = errors.New("invalid id")
)
type Descriptor interface {
String() string
Type() string
ToMap() map[string]any
FromMap(map[string]any) error
Validate() error
}
type ID struct {
Descriptor
}
func Parse(s string) (*ID, error) {
parts := Split(s)
if id, _ := parseServiceID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseUserID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseOrganizationID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseSpaceID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseEnvironmentID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseClientID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseRoleID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseCollectionID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseSchemaID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseItemID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseRevisionID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseFieldID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
if id, _ := parseSystemID(parts); id != nil {
return &ID{Descriptor: id}, nil
}
return nil, ErrInvalidID
}
func Split(id string) []string {
if id[0] != Separator {
return nil
}
return strings.Split(id[1:], string(Separator))
}
func Join(parts ...string) string {
s := strings.Join(parts, string(Separator))
if s[0] != Separator {
s = string(Separator) + s
}
return s
}
func FromMap(m map[string]any) (*ID, error) {
if m == nil {
return nil, errors.New("nil map")
}
v := new(ID)
switch m["type"] {
case Organization:
v.Descriptor = new(OrganizationID)
case Service:
v.Descriptor = new(ServiceID)
case User:
v.Descriptor = new(UserID)
case Space:
v.Descriptor = new(SpaceID)
case Environment:
v.Descriptor = new(EnvironmentID)
case Client:
v.Descriptor = new(ClientID)
case Role:
v.Descriptor = new(RoleID)
case Collection:
v.Descriptor = new(CollectionID)
case Schema:
v.Descriptor = new(SchemaID)
case Item:
v.Descriptor = new(ItemID)
case Revision:
v.Descriptor = new(RevisionID)
case Field:
v.Descriptor = new(FieldID)
case System:
v.Descriptor = new(SystemID)
default:
return nil, errors.New("unknown type")
}
if err := v.Descriptor.FromMap(m); err != nil {
return nil, err
}
return v, nil
}
package id
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_ParseID(t *testing.T) {
tests := []struct {
name string
id string
result *ID
wantError bool
}{
{
name: "ServiceID",
id: "/services/<service_id>",
result: &ID{Descriptor: &ServiceID{ServiceID: "<service_id>"}},
},
{
name: "UserID",
id: "/users/<user_id>",
result: &ID{Descriptor: &UserID{UserID: "<user_id>"}},
},
{
name: "OrganizationID",
id: "/orgs/<org_id>",
result: &ID{Descriptor: &OrganizationID{OrganizationID: "<org_id>"}},
},
{
name: "SpaceID",
id: "/spaces/<space_id>",
result: &ID{Descriptor: &SpaceID{SpaceID: "<space_id>"}},
},
{
name: "ClientID",
id: "/spaces/<space_id>/clients/<client_id>",
result: &ID{Descriptor: &ClientID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
ClientID: "<client_id>",
}},
},
{
name: "RoleID",
id: "/spaces/<space_id>/roles/<role_id>",
result: &ID{Descriptor: &RoleID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
RoleID: "<role_id>",
}},
},
{
name: "EnvironmentID",
id: "/spaces/<space_id>/envs/<env_id>",
result: &ID{Descriptor: &EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
}},
},
{
name: "CollectionID",
id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>",
result: &ID{Descriptor: &CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
}},
},
{
name: "SchemaID",
id: "/spaces/<space_id>/envs/<env_id>/schema/<collection_id>",
result: &ID{Descriptor: &SchemaID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
}},
},
{
name: "ItemID",
id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>",
result: &ID{Descriptor: &ItemID{
CollectionID: CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
},
ItemID: "<item_id>",
}},
},
{
name: "RevisionID",
id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/revs/<rev_id>",
result: &ID{Descriptor: &RevisionID{
ItemID: ItemID{
CollectionID: CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
},
ItemID: "<item_id>",
},
RevisionID: "<rev_id>",
}},
},
{
name: "FieldID",
id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/fields/<field_name>",
result: &ID{Descriptor: &FieldID{
ItemID: ItemID{
CollectionID: CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
},
ItemID: "<item_id>",
},
FieldName: "<field_name>",
}},
},
{
name: "SystemID",
id: "/system",
result: &ID{Descriptor: &SystemID{}},
},
{
name: "With error #1: no backslash in the beginning of id",
id: "spaces/<space_id>",
result: nil,
wantError: true,
},
{
name: "With error #2: backslash in the end of id",
id: "/spaces/<space_id>/",
result: nil,
wantError: true,
},
{
name: "With error #3: typo in 'spaces'",
id: "/space/<space_id>",
result: nil,
wantError: true,
},
{
name: "With error #4: no space_id in id",
id: "/spaces",
result: nil,
wantError: true,
},
{
name: "With error #5: multiple backslashes in the end of id",
id: "/spaces/<space_id>///",
result: nil,
wantError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
id, err := Parse(tt.id)
if tt.wantError {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.result, id)
require.Equal(t, tt.id, id.String(), "проверяем корректность работы метода String, полученное ID должно совпадать с исходным")
})
}
}
func Test_Map(t *testing.T) {
tests := []struct {
name string
id *ID
}{
{
name: "ServiceID",
id: &ID{Descriptor: &ServiceID{ServiceID: "<service_id>"}},
},
{
name: "UserID",
id: &ID{Descriptor: &UserID{UserID: "<user_id>"}},
},
{
name: "OrganizationID",
id: &ID{Descriptor: &OrganizationID{OrganizationID: "<org_id>"}},
},
{
name: "SpaceID",
id: &ID{Descriptor: &SpaceID{SpaceID: "<space_id>"}},
},
{
name: "ClientID",
id: &ID{Descriptor: &ClientID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
ClientID: "<client_id>",
}},
},
{
name: "RoleID",
id: &ID{Descriptor: &RoleID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
RoleID: "<role_id>",
}},
},
{
name: "EnvironmentID",
id: &ID{Descriptor: &EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
}},
},
{
name: "CollectionID",
id: &ID{Descriptor: &CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
}},
},
{
name: "Schema ID",
id: &ID{Descriptor: &SchemaID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
}},
},
{
name: "ItemID",
id: &ID{Descriptor: &ItemID{
CollectionID: CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
},
ItemID: "<item_id>",
}},
},
{
name: "RevisionID",
id: &ID{Descriptor: &RevisionID{
ItemID: ItemID{
CollectionID: CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
},
ItemID: "<item_id>",
},
RevisionID: "<rev_id>",
}},
},
{
name: "FieldID",
id: &ID{Descriptor: &FieldID{
ItemID: ItemID{
CollectionID: CollectionID{
EnvironmentID: EnvironmentID{
SpaceID: SpaceID{SpaceID: "<space_id>"},
EnvironmentID: "<env_id>",
},
CollectionID: "<collection_id>",
},
ItemID: "<item_id>",
},
FieldName: "<field_name>",
}},
},
{
name: "SystemID",
id: &ID{Descriptor: &SystemID{}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v, err := FromMap(tt.id.ToMap())
require.NoError(t, err)
assert.Equal(t, tt.id, v, "проверка FromMap для типа ID, должен быть равен исходному значению")
assert.Equal(t, v.ToMap(), tt.id.ToMap())
})
}
}
package id
const (
Item = "item"
ItemsPrefix = "items"
)
type ItemID struct {
CollectionID
ItemID string `json:"item_id,omitempty" bson:"item_id,omitempty"`
}
func (t *ItemID) Type() string { return Item }
func (t *ItemID) String() string {
return Join(t.CollectionID.String(), ItemsPrefix, t.ItemID)
}
func (t *ItemID) ToMap() map[string]any {
m := t.CollectionID.ToMap()
m["item_id"] = t.ItemID
m["type"] = Item
return m
}
func (t *ItemID) FromMap(m map[string]any) error {
if err := t.CollectionID.FromMap(m); err != nil {
return err
}
t.ItemID = m["item_id"].(string)
return nil
}
func (t *ItemID) Validate() error {
if t.ItemID == "" {
return ErrInvalidID
}
return t.CollectionID.Validate()
}
func parseItemID(parts []string) (*ItemID, error) {
if len(parts) != 8 || parts[6] != ItemsPrefix {
return nil, ErrInvalidID
}
collID, err := parseCollectionID(parts[:6])
if err != nil {
return nil, err
}
var id ItemID
id.CollectionID = *collID
id.ItemID = parts[7]
return &id, nil
}
func NewItemID(spaceID, envID, collID, id string) *ID {
return &ID{Descriptor: &ItemID{CollectionID: CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: collID}, ItemID: id}}
}
package id
import (
jsoniter "github.com/json-iterator/go"
)
func (id *ID) MarshalJSON() ([]byte, error) {
return jsoniter.Marshal(id.String())
}
func (id *ID) UnmarshalJSON(b []byte) error {
var s string
var err error
if err = jsoniter.Unmarshal(b, &s); err != nil {
return err
}
t, err := Parse(s)
if err != nil {
return err
}
*id = *t
return nil
}
package id
import (
"testing"
jsoniter "github.com/json-iterator/go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestID_MarshalUnmarshalJSON(t *testing.T) {
tests := []struct {
name string
id *ID
}{
{
name: "OrganizationID",
id: &ID{Descriptor: &OrganizationID{OrganizationID: "1"}},
},
{
name: "UserID",
id: &ID{Descriptor: &UserID{UserID: "1"}},
},
{
name: "ServiceID",
id: &ID{Descriptor: &ServiceID{ServiceID: "1"}},
},
{
name: "SpaceID",
id: &ID{Descriptor: &SpaceID{SpaceID: "1"}},
},
{
name: "EnvironmentID",
id: &ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
},
{
name: "ClientID",
id: &ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
},
{
name: "RoleID",
id: &ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
},
{
name: "CollectionID",
id: &ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
},
{
name: "SchemaID",
id: &ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
},
{
name: "ItemID",
id: &ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "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"}}}}}},
},
{
name: "FieldID",
id: &ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}},
},
{
name: "SystemID",
id: &ID{Descriptor: &SystemID{}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b, err := jsoniter.Marshal(&tt.id)
require.NoError(t, err)
var i ID
require.NoError(t, jsoniter.Unmarshal(b, &i))
assert.Equal(t, tt.id, &i, "после Unmarshal объект должен быть идентичен исходному")
})
}
}
func TestID_ExampleJSON(t *testing.T) {
type data struct {
ID *ID
Text string
Number int
}
test := &data{
ID: &ID{Descriptor: &SpaceID{SpaceID: Space}},
Text: "text",
Number: 1,
}
b, err := jsoniter.Marshal(test)
require.NoError(t, err)
buf := new(data)
err = jsoniter.Unmarshal(b, &buf)
require.NoError(t, err)
assert.Equal(t, test, buf, "после Unmarshal объект должен совпадать с исходным")
}
package id
const (
Organization = "organization"
OrganizationsPrefix = "orgs"
)
type OrganizationID struct {
OrganizationID string `json:"organization_id,omitempty" bson:"organization_id,omitempty"`
}
func (t *OrganizationID) Type() string { return Organization }
func (t *OrganizationID) String() string {
return Join(OrganizationsPrefix, t.OrganizationID)
}
func (t *OrganizationID) ToMap() map[string]any {
return map[string]any{
"organization_id": t.OrganizationID,
"type": Organization,
}
}
func (t *OrganizationID) FromMap(m map[string]any) error {
t.OrganizationID = m["organization_id"].(string)
return nil
}
func (t *OrganizationID) Validate() error {
if t.OrganizationID == "" {
return ErrInvalidID
}
return nil
}
func parseOrganizationID(parts []string) (*OrganizationID, error) {
var id OrganizationID
if len(parts) != 2 || parts[0] != OrganizationsPrefix {
return nil, ErrInvalidID
}
id.OrganizationID = parts[1]
return &id, nil
}
func NewOrganizationID(id string) *ID {
return &ID{Descriptor: &OrganizationID{OrganizationID: id}}
}
package id
const (
Revision = "revision"
RevisionsPrefix = "revs"
)
type RevisionID struct {
ItemID
RevisionID string `json:"rev_id" bson:"rev_id,omitempty"`
}
func (t *RevisionID) Type() string { return Revision }
func (t *RevisionID) String() string {
return Join(t.ItemID.String(), RevisionsPrefix, t.RevisionID)
}
func (t *RevisionID) ToMap() map[string]any {
m := t.ItemID.ToMap()
m["rev_id"] = t.RevisionID
m["type"] = Revision
return m
}
func (t *RevisionID) FromMap(m map[string]any) error {
if err := t.ItemID.FromMap(m); err != nil {
return err
}
t.RevisionID = m["rev_id"].(string)
return nil
}
func (t *RevisionID) Validate() error {
if t.RevisionID == "" {
return ErrInvalidID
}
return t.ItemID.Validate()
}
func parseRevisionID(parts []string) (*RevisionID, error) {
if len(parts) != 10 || parts[8] != RevisionsPrefix {
return nil, ErrInvalidID
}
itemID, err := parseItemID(parts[:8])
if err != nil {
return nil, err
}
var id RevisionID
id.ItemID = *itemID
id.RevisionID = parts[9]
return &id, nil
}
func NewRevisionID(spaceID, envID, collID, itemID, id string) *ID {
return &ID{Descriptor: &RevisionID{ItemID: ItemID{CollectionID: CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: collID}, ItemID: itemID}, RevisionID: id}}
}
package id
const (
Role = "role"
RolesPrefix = "roles"
)
type RoleID struct {
SpaceID
RoleID string `json:"role_id,omitempty" bson:"role_id,omitempty"`
}
func (t *RoleID) Type() string { return Role }
func (t *RoleID) String() string {
return Join(t.SpaceID.String(), RolesPrefix, t.RoleID)
}
func (t *RoleID) ToMap() map[string]any {
m := t.SpaceID.ToMap()
m["role_id"] = t.RoleID
m["type"] = Role
return m
}
func (t *RoleID) FromMap(m map[string]any) error {
if err := t.SpaceID.FromMap(m); err != nil {
return err
}
t.RoleID = m["role_id"].(string)
return nil
}
func (t *RoleID) Validate() error {
if t.RoleID == "" {
return ErrInvalidID
}
return t.SpaceID.Validate()
}
func parseRoleID(parts []string) (*RoleID, error) {
if len(parts) != 4 || parts[2] != RolesPrefix {
return nil, ErrInvalidID
}
spaceID, err := parseSpaceID(parts[:2])
if err != nil {
return nil, err
}
var id RoleID
id.SpaceID = *spaceID
id.RoleID = parts[3]
return &id, nil
}
func NewRoleID(spaceID, id string) *ID {
return &ID{Descriptor: &RoleID{SpaceID: SpaceID{SpaceID: spaceID}, RoleID: id}}
}
package id
const (
Schema = "schema"
SchemaPrefix = "schema"
)
type SchemaID struct {
EnvironmentID
CollectionID string `json:"col_id" bson:"col_id,omitempty"`
}
func (t *SchemaID) Type() string { return Schema }
func (t *SchemaID) String() string {
return Join(t.EnvironmentID.String(), SchemaPrefix, t.CollectionID)
}
func (t *SchemaID) ToMap() map[string]any {
m := t.EnvironmentID.ToMap()
m["col_id"] = t.CollectionID
m["type"] = Schema
return m
}
func (t *SchemaID) FromMap(m map[string]any) error {
if err := t.EnvironmentID.FromMap(m); err != nil {
return err
}
t.CollectionID = m["col_id"].(string)
return nil
}
func (t *SchemaID) Validate() error {
if t.CollectionID == "" {
return ErrInvalidID
}
return t.EnvironmentID.Validate()
}
func parseSchemaID(parts []string) (*SchemaID, error) {
if len(parts) != 6 || parts[4] != SchemaPrefix {
return nil, ErrInvalidID
}
envID, err := parseEnvironmentID(parts[:4])
if err != nil {
return nil, err
}
var id SchemaID
id.EnvironmentID = *envID
id.CollectionID = parts[5]
return &id, nil
}
func NewSchemaID(spaceID, envID, id string) *ID {
return &ID{Descriptor: &SchemaID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: id}}
}
package id
const (
Service = "service"
ServicesPrefix = "services"
)
type ServiceID struct {
ServiceID string `json:"service_id,omitempty" bson:"service_id,omitempty"`
}
func (t *ServiceID) Type() string { return Service }
func (t *ServiceID) String() string {
return Join(ServicesPrefix, t.ServiceID)
}
func (t *ServiceID) ToMap() map[string]any {
return map[string]any{
"service_id": t.ServiceID,
"type": Service,
}
}
func (t *ServiceID) FromMap(m map[string]any) error {
t.ServiceID = m["service_id"].(string)
return nil
}
func (t *ServiceID) Validate() error {
if t.ServiceID == "" {
return ErrInvalidID
}
return nil
}
func parseServiceID(parts []string) (*ServiceID, error) {
var id ServiceID
if len(parts) != 2 || parts[0] != ServicesPrefix {
return nil, ErrInvalidID
}
id.ServiceID = parts[1]
return &id, nil
}
func NewServiceID(id string) *ID {
return &ID{Descriptor: &ServiceID{ServiceID: id}}
}
package id
const (
Space = "space"
SpacesPrefix = "spaces"
)
type SpaceID struct {
SpaceID string `json:"space_id,omitempty" bson:"space_id,omitempty"`
}
func (t *SpaceID) Type() string { return Space }
func (t *SpaceID) String() string {
return Join(SpacesPrefix, t.SpaceID)
}
func (t *SpaceID) ToMap() map[string]any {
return map[string]any{
"space_id": t.SpaceID,
"type": Space,
}
}
func (t *SpaceID) FromMap(m map[string]any) error {
t.SpaceID = m["space_id"].(string)
return nil
}
func (t *SpaceID) Validate() error {
if t.SpaceID == "" {
return ErrInvalidID
}
return nil
}
func parseSpaceID(parts []string) (*SpaceID, error) {
var id SpaceID
if len(parts) != 2 || parts[0] != SpacesPrefix {
return nil, ErrInvalidID
}
id.SpaceID = parts[1]
return &id, nil
}
func NewSpaceID(id string) *ID {
return &ID{Descriptor: &SpaceID{SpaceID: id}}
}
package id
const System = "system"
type SystemID struct{}
func (t *SystemID) Type() string { return Space }
func (t *SystemID) String() string { return string(Separator) + System }
func (t *SystemID) ToMap() map[string]any { return map[string]any{"type": System} }
func (t *SystemID) FromMap(m map[string]any) error { return nil }
func (t *SystemID) Validate() error { return nil }
func parseSystemID(parts []string) (*SystemID, error) {
var id SystemID
if len(parts) != 1 || parts[0] != System {
return nil, ErrInvalidID
}
return &id, nil
}
func NewSystemID() *ID {
return &ID{Descriptor: &SystemID{}}
}
package id
const (
User = "user"
UsersPrefix = "users"
)
type UserID struct {
UserID string `json:"user_id,omitempty" bson:"user_id,omitempty"`
}
func (t *UserID) Type() string { return User }
func (t *UserID) String() string {
return Join(UsersPrefix, t.UserID)
}
func (t *UserID) ToMap() map[string]any {
return map[string]any{
"user_id": t.UserID,
"type": User,
}
}
func (t *UserID) FromMap(m map[string]any) error {
t.UserID = m["user_id"].(string)
return nil
}
func (t *UserID) Validate() error {
if t.UserID == "" {
return ErrInvalidID
}
return nil
}
func parseUserID(parts []string) (*UserID, error) {
var id UserID
if len(parts) != 2 || parts[0] != UsersPrefix {
return nil, ErrInvalidID
}
id.UserID = parts[1]
return &id, nil
}
func NewUserID(id string) *ID {
return &ID{Descriptor: &UserID{UserID: id}}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment