-
Notifications
You must be signed in to change notification settings - Fork 277
Multiple-create: Schema generation #1902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ayush3797
merged 87 commits into
dev/NestedMutations
from
dev/agarwalayush/schemaGeneration
Mar 21, 2024
Merged
Multiple-create: Schema generation #1902
ayush3797
merged 87 commits into
dev/NestedMutations
from
dev/agarwalayush/schemaGeneration
Mar 21, 2024
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…hether entity is linking or not
seantleonard
reviewed
Mar 7, 2024
Aniruddh25
approved these changes
Mar 11, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Please get this in. No more changes other than any simple stylistic or obviously wrong assumptions.
/azp run |
Azure Pipelines successfully started running 2 pipeline(s). |
seantleonard
approved these changes
Mar 14, 2024
severussundar
approved these changes
Mar 19, 2024
2 tasks
/azp run |
Azure Pipelines successfully started running 2 pipeline(s). |
severussundar
added a commit
that referenced
this pull request
Mar 26, 2024
…ue (#2116) ## Why make this change? - Closes #1951 - PR #1983, #2103 add CLI options to enable or disable multiple mutation/multiple create operation through CLI. With the changes introduced in the mentioned PRs, the configuration properties successfully gets written to the config file. Also, during deserialization, the properties are read and the `MultipleMutationOptions`, `MultipleCreateOptions`, `GraphQLRuntimeOptions` objects are created accordingly. - The above-mentioned PRs do not introduce any change in DAB engine behavior depending on the configuration property values. - This PR introduces changes to read these fields and enable/disable multiple create operation depending on whether the feature is enabled/disabled through the config file. This is achieved by introducing behavior changes in the schema generation. ## What is this change? - This PR builds on top of a) Schema generation PR #1902 b) Rename nested-create to multiple create PR #2103 - When multiple create operation is disabled, > i) Fields belonging to the related entities are not created in the input object type are not created. > ii) Many type multiple create mutation nodes (ex: `createbooks`, `createpeople_multiple` ) are not created. > iii) ReferencingField directive is not applied on relationship fields, so they continue to remain required fields for the create mutation operation. > iv) Entities for linking objects are not created as they are relevant only in the context of multiple create operations. ## How was this tested? - [x] Unit Tests and Integration Tests - [x] Manual Tests **Note:** At the moment, multiple create operation is disabled in the config file generated for integration tests. This is because of the plan to merge in the Schema generation, AuthZ/N branches separately to the main branch. With just these 2 PRs, a multiple create operation will fail, hence, the disabling multiple create operation. At the moment, tests that perform validations specific to multiple create feature enable it by i) updating the runtime object (or) ii) creating a custom config in which the operation is enabled. ## Sample Request(s) ### When Multiple Create operation is enabled - MsSQL #### Related entity fields are created in the input object type  #### Multiple type create operation is created in addition to point create operation  #### Querying related entities continue to work successfully  ### When Multiple Create operation is disabled - MsSQL #### Only fields belonging to the given entity are created in the input object type  #### Multiple type create operation is not created ### When Multiple Create operation is enabled - Other relational database types #### Only fields belonging to the given entity are created in the input object type  #### Multiple type create operation is not created --------- Co-authored-by: Ayush Agarwal <[email protected]>
1 task
severussundar
added a commit
that referenced
this pull request
Mar 29, 2024
## Why make this change? - All code changes for **Multiple Create** feature was being merged into `dev/NestedMutations` branch. - This PR attempts to merge all these changes to the `main` branch in preparation for the `0.12.* rc1` release ## What is this change? - Right now, `dev/NestedMutations` branch contains the code changes for the following components of Multiple Create feature - Schema Generation - #1902 - AuthZ - #1943 - Feature flag - CLI changes #1983 - Feature flag - Re-naming changes #2103 - Feature flag - Engine changes #2116 - Each specified PR was reviewed before merging into `dev/NestedMutations` branch. - This PR aims to merge all the changes into `main` branch ## How was this tested? - [x] Unit, Integration and Manual tests were performed on each PR before merging into `dev/NestedMutations` --------- Co-authored-by: Shyam Sundar J <[email protected]> Co-authored-by: Sean Leonard <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
enhancement
New feature or request
mssql
an issue thats specific to mssql
Multiple mutations
Fixes/enhancements related to nested mutations.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Why make this change?
Currently, for a create mutation (or any graphql mutation essentially), we can only do insertion/mutation in one table and not in another table which is related to this table via some relationship (either defined in config or in the database). This PR aims to:
createMultiple
mutations which will allow multiple nested insertions starting from the top-level entity.Note: All changes made in this PR are specific to MsSql. Nothing changes for the other database flavors.
Quick glossary:
What is this change?
We no more ignore relationship fields while generating the input types for a create mutation: Till date, we were only considering the column fields in an object (of type
ObjectTypeDefinitionNode
) to generate the input type (of typeInputObjectTypeDefinitionNode
) for a table entity. But to support nested insertion, we would now also iterate over relationship fields to generate the input type for a create/createMultiple mutation.Addition of linking entities at the backend: To support nested insertions in tables which have a relationship with cardinality N:N, the user can provide a linking table with the source defined in
linking.object
field which we need the user to provide. We need to generate an object type (of typeObjectTypeDefinitionNode
) for this linking entity. This object type is later be used to generate the input object type for the linked tables.Additional details about linking entities:
-> A boolean property
IsLinkingEntity
is added with a default value offalse
to theEntity
record. This ensures that we are backwards compatible, and all the entities provided in the config are not considered as linking entities. For all the linking entities, this boolean property will be set totrue
.-> For a linking entity, the GraphQL and REST endpoints are disabled (set to
false
) by default. This ensures that we don't accidentally expose the linking entity to the user.-> MsSqlMetadataProvider.EntityToDatabaseObject contains database objects for Entities in config + Linking Entities. After we get all the deserialized entities, we will create entities to represent linking tables. The database objects for all the entities in config will be generated by a call to SqlMetadataProvider.GenerateDatabaseObjectForEntities() method which in turn sequentially goes over all the entities in the config and call the method SqlMetadataProvider.PopulateDatabaseObjectForEntity() which actually populates the database object for an entity.
-> The method SqlMetadataProvider.AddForeignKeysForRelationships() is renamed to SqlMetadataProvider.ProcessRelationships(). The method now in addition to adding FKs to metadata, also creates linking entities for M:N relationships. This is done via a call to method SqlMetadataProvider.PopulateMetadataForLinkingObject().
-> The method PopulateMetadataForLinkingObject() is a virtual method which has an overridden implementation only for MsSql. Thus, linking entities are generated only for MsSql.
ReferencingFieldDirectiveType: is a new directive type being added. The presence of this directive for a column field implies that the column is a referencing key to some column in another entity exposed in the config. With nested insertions support, the values for such fields can come via insertion in the referenced table. And hence while generating the input object for a
create
/createMultiple
mutation, we mark such a field as not required.Name of the create multiple mutation: is generated via a call to the newly added helper method
CreateMutationBuilder.GetInsertMultipleMutationName(singularName, pluralName)
which takes in the singular/plural names of the entity. If singularName == pluralName, the createMultiple mutation will be generated with the name:create{singularName}_Multiple
else, it will be generated with the namecreate{pluralName}
. The pluralName for an entity is fetched using another newly added helper methodGraphQLNaming.GetDefinedPluralName(entityName, configEntity)
For create multiple mutations, the input argument name will be
items
which is stored in a constant stringMutationBuilder.ARRAY_INPUT_ARGUMENT_NAME
.Object types (of type
ObjectTypeDefinitionNode
) for linking entities will be generated using a methodGraphQLSchemaCreator.GenerateObjectDefinitionsForLinkingEntities(linkingEntityNames, entities)
.sourceTargetLinkingNode: The object type for linking entity is later used to generate object type for a
sourceTargetLinkingNode
which will contain:-> Fields present in the linking table (but not used to relate source/target)
-> All the fields from the target entity.
This is done using a call to the newly added method
GraphQLSchemaCreator.GenerateSourceTargetLinkingObjectDefinitions()
.Renamed method
GraphQLSchemaCreator.FromDatabaseObject()
toGraphQLSchemaCreator.GenerateObjectTypeDefinitionForDatabaseObject()
to better convey what the method is doing.To make code more streamlined and bug-free the method SchemaConverter.FromDatabaseObject() is broken down into smaller chunks which handle smaller and easy to read/comprehend responsibilities. Passing of existing test cases confirm the refactor.
Added a method
GraphQLUtils.GenerateLinkingEntityName(sourceEntityName, targetEntityName)
which concatenates the names of the source and target entities with a delimiter (ENTITY_NAME_DELIMITER = "$"
) between the names and prefixes the concatenated string with:LINKING_ENTITY_PREFIX = "LinkingEntity"
string.Added a method
GraphQLUtils.GetSourceAndTargetEntityNameFromLinkingEntityName(string linkingEntityName)
which returns the the names of the source and target entities from the linking entity name.Split the
CreateMutationBuilder.GenerateCreateInputType()
method which was used to create input types for Relational (Pg/My/Ms/Dw Sql) and non-relational dbs (Cosmos_NoSql) into two new methods:CreateMutationBuilder.GenerateCreateInputTypeForRelationalDb()
andCreateMutationBuilder.GenerateCreateInputTypeForNonRelationalDb()
.Split the
CreateMutationBuilder.GetComplexInputType()
method which was used to build input types for Relational (Pg/My/Ms/Dw Sql) and non-relational dbs (Cosmos_NoSql) into two new methods:CreateMutationBuilder.GenerateComplexInputTypeForRelationalDb()
andCreateMutationBuilder.GenerateComplexInputTypeForNonRelationalDb()
.Validations Required:
sourceTargetLinkingNode
for a source, target pair of tables (refer above for what all fields would be present in this object type). The name of the field (either a relationship field or a column field) in the target entity might conflict with the name of the column field in the linking table. Hence, we need a validation in place to ensure that if there is a conflict, we catch it during startup (currently this check is done during schema generation) and throw an appropriate exception with an actionable message.-> Either via nested insertion , or
-> By the user
we should throw an exception accordingly. This will maintain backwards compatibility. UNLESS THIS VALIDATION IS IN, WE ARE NOT BACKWARDS COMPATIBLE.
How was this tested?
NestedMutationBuilderTests.cs
class.Sample Request(s)