From eda43d34a6c6d1220c0ea2532a20beb4478563a7 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Tue, 8 Oct 2024 14:38:45 -0400 Subject: [PATCH] WIP - Prevent mutations from secondary side of relation --- client/collection_description.go | 4 ++++ client/definitions.go | 2 +- client/document.go | 5 +++++ client/errors.go | 6 ++++++ internal/request/graphql/schema/generate.go | 4 ++++ .../field_kinds/one_to_one/with_simple_test.go | 13 ++++--------- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/client/collection_description.go b/client/collection_description.go index d86a252644..236d819b3a 100644 --- a/client/collection_description.go +++ b/client/collection_description.go @@ -150,6 +150,10 @@ func (col CollectionDescription) GetFieldByRelation( otherCollectionName string, otherFieldName string, ) (CollectionFieldDescription, bool) { + if relationName == "" { + return CollectionFieldDescription{}, false + } + for _, field := range col.Fields { if field.RelationName.Value() == relationName && !(col.Name.Value() == otherCollectionName && otherFieldName == field.Name) && diff --git a/client/definitions.go b/client/definitions.go index 269a703ac9..3aeec2485d 100644 --- a/client/definitions.go +++ b/client/definitions.go @@ -166,7 +166,7 @@ func NewFieldDefinition(local CollectionFieldDescription, global SchemaFieldDesc Kind: kind, RelationName: local.RelationName.Value(), Typ: global.Typ, - IsPrimaryRelation: kind.IsObject() && !kind.IsArray(), + IsPrimaryRelation: local.RelationName.HasValue() && !kind.IsArray(), DefaultValue: local.DefaultValue, } } diff --git a/client/document.go b/client/document.go index cc15d45673..c6144bdb70 100644 --- a/client/document.go +++ b/client/document.go @@ -692,6 +692,11 @@ func (doc *Document) Set(field string, value any) error { if !exists { return NewErrFieldNotExist(field) } + + if fd.RelationName != "" && !fd.IsPrimaryRelation { + return NewErrCannotSetRelationFromSecondarySide(field) + } + if fd.Kind.IsObject() && !fd.Kind.IsArray() { if !strings.HasSuffix(field, request.RelatedObjectID) { field = field + request.RelatedObjectID diff --git a/client/errors.go b/client/errors.go index 81ebf2e3f5..b21c0805d0 100644 --- a/client/errors.go +++ b/client/errors.go @@ -34,6 +34,7 @@ const ( errCanNotTurnNormalValueIntoArray string = "can not turn normal value into array" errCanNotMakeNormalNilFromFieldKind string = "can not make normal nil from field kind" errFailedToParseKind string = "failed to parse kind" + errCannotSetRelationFromSecondarySide string = "cannot set relation from secondary side" ) // Errors returnable from this package. @@ -61,6 +62,7 @@ var ( ErrCanNotMakeNormalNilFromFieldKind = errors.New(errCanNotMakeNormalNilFromFieldKind) ErrCollectionNotFound = errors.New(errCollectionNotFound) ErrFailedToParseKind = errors.New(errFailedToParseKind) + ErrCannotSetRelationFromSecondarySide = errors.New(errCannotSetRelationFromSecondarySide) ) // NewErrFieldNotExist returns an error indicating that the given field does not exist. @@ -190,3 +192,7 @@ func ReviveError(message string) error { return fmt.Errorf("%s", message) } } + +func NewErrCannotSetRelationFromSecondarySide(name string) error { + return errors.New(errCannotSetRelationFromSecondarySide, errors.NewKV("Name", name)) +} diff --git a/internal/request/graphql/schema/generate.go b/internal/request/graphql/schema/generate.go index f326a8232a..db6e993026 100644 --- a/internal/request/graphql/schema/generate.go +++ b/internal/request/graphql/schema/generate.go @@ -566,6 +566,10 @@ func (g *Generator) buildMutationInputTypes(collections []client.CollectionDefin continue } + if field.RelationName != "" && !field.IsPrimaryRelation { + continue + } + var ttype gql.Type if field.Kind.IsObject() { if field.Kind.IsArray() { diff --git a/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go b/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go index b2b3859d2d..79dfee1847 100644 --- a/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go +++ b/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go @@ -260,7 +260,6 @@ func TestMutationUpdateOneToOne_RelationIDToLinkFromPrimarySide(t *testing.T) { } func TestMutationUpdateOneToOne_RelationIDToLinkFromSecondarySide(t *testing.T) { - author1ID := "bae-53eff350-ad8e-532c-b72d-f95c4f47909c" author2ID := "bae-c058cfd4-259f-5b08-975d-106f13a143d5" test := testUtils.TestCase{ @@ -280,13 +279,9 @@ func TestMutationUpdateOneToOne_RelationIDToLinkFromSecondarySide(t *testing.T) }, testUtils.CreateDoc{ CollectionID: 0, - Doc: fmt.Sprintf( - `{ - "name": "Painted House", - "author_id": "%s" - }`, - author1ID, - ), + Doc: `{ + "name": "Painted House" + }`, }, testUtils.UpdateDoc{ CollectionID: 0, @@ -297,7 +292,7 @@ func TestMutationUpdateOneToOne_RelationIDToLinkFromSecondarySide(t *testing.T) }`, author2ID, ), - ExpectedError: "target document is already linked to another document.", + ExpectedError: "cannot set relation from secondary side", }, }, }