Browse Source

Allocation improvements. (#1009)

* Allocation improvements.

* Fix usings.
pull/1010/head
Sebastian Stehle 3 years ago
committed by GitHub
parent
commit
bc971331d1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 53
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationMutations.cs
  2. 21
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationQueries.cs
  3. 14
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ComponentGraphType.cs
  4. 28
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentGraphType.cs
  5. 14
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataFlatGraphType.cs
  6. 28
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataGraphType.cs
  7. 14
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataInputGraphType.cs
  8. 14
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedGraphType.cs
  9. 7
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedInputGraphType.cs
  10. 23
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/FieldTypeWithSchemaId.cs
  11. 15
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/FieldTypeWithSourceName.cs
  12. 38
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/SharedExtensions.cs
  13. 10
      backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs

53
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationMutations.cs

@ -8,6 +8,7 @@
using GraphQL.Types;
using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents;
using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Primitives;
using Squidex.Domain.Apps.Entities.Schemas;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types;
@ -34,69 +35,79 @@ internal sealed class ApplicationMutations : ObjectGraphType
var nonNullContentType = new NonNullGraphType(contentType);
AddField(new FieldType
// Calculate the named if once to avoid allocations.
var schemaid = schemaInfo.Schema.NamedId();
AddField(new FieldTypeWithSchemaNamedId
{
Name = $"create{schemaInfo.TypeName}Content",
Arguments = ContentActions.Create.Arguments(inputType),
ResolvedType = contentType,
Resolver = ContentActions.Create.Resolver,
Description = $"Creates an {schemaInfo.DisplayName} content."
}).WithSchemaNamedId(schemaInfo);
Description = $"Creates an {schemaInfo.DisplayName} content.",
SchemaId = schemaInfo.Schema.NamedId()
});
AddField(new FieldType
AddField(new FieldTypeWithSchemaNamedId
{
Name = $"update{schemaInfo.TypeName}Content",
Arguments = ContentActions.Update.Arguments(inputType),
ResolvedType = contentType,
Resolver = ContentActions.Update.Resolver,
Description = $"Update an {schemaInfo.DisplayName} content by id."
}).WithSchemaNamedId(schemaInfo);
Description = $"Update an {schemaInfo.DisplayName} content by id.",
SchemaId = schemaInfo.Schema.NamedId()
});
AddField(new FieldType
AddField(new FieldTypeWithSchemaNamedId
{
Name = $"upsert{schemaInfo.TypeName}Content",
Arguments = ContentActions.Upsert.Arguments(inputType),
ResolvedType = contentType,
Resolver = ContentActions.Upsert.Resolver,
Description = $"Upsert an {schemaInfo.DisplayName} content by id."
}).WithSchemaNamedId(schemaInfo);
Description = $"Upsert an {schemaInfo.DisplayName} content by id.",
SchemaId = schemaInfo.Schema.NamedId()
});
AddField(new FieldType
AddField(new FieldTypeWithSchemaNamedId
{
Name = $"patch{schemaInfo.TypeName}Content",
Arguments = ContentActions.Patch.Arguments(inputType),
ResolvedType = contentType,
Resolver = ContentActions.Patch.Resolver,
Description = $"Patch an {schemaInfo.DisplayName} content by id."
}).WithSchemaNamedId(schemaInfo);
Description = $"Patch an {schemaInfo.DisplayName} content by id.",
SchemaId = schemaInfo.Schema.NamedId()
});
AddField(new FieldType
AddField(new FieldTypeWithSchemaNamedId
{
Name = $"change{schemaInfo.TypeName}Content",
Arguments = ContentActions.ChangeStatus.Arguments,
ResolvedType = contentType,
Resolver = ContentActions.ChangeStatus.Resolver,
Description = $"Change a {schemaInfo.DisplayName} content."
}).WithSchemaNamedId(schemaInfo);
Description = $"Change a {schemaInfo.DisplayName} content.",
SchemaId = schemaInfo.Schema.NamedId()
});
AddField(new FieldType
AddField(new FieldTypeWithSchemaNamedId
{
Name = $"delete{schemaInfo.TypeName}Content",
Arguments = ContentActions.Delete.Arguments,
ResolvedType = EntitySavedGraphType.NonNull,
Resolver = ContentActions.Delete.Resolver,
Description = $"Delete an {schemaInfo.DisplayName} content."
}).WithSchemaNamedId(schemaInfo);
Description = $"Delete an {schemaInfo.DisplayName} content.",
SchemaId = schemaInfo.Schema.NamedId()
});
AddField(new FieldType
AddField(new FieldTypeWithSchemaNamedId
{
Name = $"publish{schemaInfo.TypeName}Content",
Arguments = ContentActions.ChangeStatus.Arguments,
ResolvedType = contentType,
Resolver = ContentActions.ChangeStatus.Resolver,
Description = $"Publish a {schemaInfo.DisplayName} content.",
DeprecationReason = $"Use 'change{schemaInfo.TypeName}Content' instead"
}).WithSchemaNamedId(schemaInfo);
DeprecationReason = $"Use 'change{schemaInfo.TypeName}Content' instead",
SchemaId = schemaInfo.Schema.NamedId()
});
}
Description = "The app mutations.";

21
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationQueries.cs

@ -37,26 +37,28 @@ internal sealed class ApplicationQueries : ObjectGraphType
private void AddContentFind(SchemaInfo schemaInfo, IGraphType contentType)
{
AddField(new FieldType
AddField(new FieldTypeWithSchemaId
{
Name = $"find{schemaInfo.TypeName}Content",
Arguments = ContentActions.Find.Arguments,
ResolvedType = contentType,
Resolver = ContentActions.Find.Resolver,
Description = $"Find an {schemaInfo.DisplayName} content by id."
}).WithSchemaId(schemaInfo);
Description = $"Find an {schemaInfo.DisplayName} content by id.",
SchemaId = schemaInfo.Schema.Id
});
}
private void AddContentQueries(Builder builder, SchemaInfo schemaInfo, IGraphType contentType)
{
AddField(new FieldType
AddField(new FieldTypeWithSchemaId
{
Name = $"query{schemaInfo.TypeName}Contents",
Arguments = ContentActions.QueryOrReferencing.Arguments,
ResolvedType = new ListGraphType(new NonNullGraphType(contentType)),
Resolver = ContentActions.QueryOrReferencing.Query,
Description = $"Query {schemaInfo.DisplayName} content items."
}).WithSchemaId(schemaInfo);
Description = $"Query {schemaInfo.DisplayName} content items.",
SchemaId = schemaInfo.Schema.Id
});
var contentResultTyp = builder.GetContentResultType(schemaInfo);
@ -65,14 +67,15 @@ internal sealed class ApplicationQueries : ObjectGraphType
return;
}
AddField(new FieldType
AddField(new FieldTypeWithSchemaId
{
Name = $"query{schemaInfo.TypeName}ContentsWithTotal",
Arguments = ContentActions.QueryOrReferencing.Arguments,
ResolvedType = contentResultTyp,
Resolver = ContentActions.QueryOrReferencing.QueryWithTotal,
Description = $"Query {schemaInfo.DisplayName} content items with total count."
}).WithSchemaId(schemaInfo);
Description = $"Query {schemaInfo.DisplayName} content items with total count.",
SchemaId = schemaInfo.Schema.Id
});
}
private void AddContentQuery(Builder builder)

14
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ComponentGraphType.cs

@ -33,28 +33,30 @@ internal sealed class ComponentGraphType : ObjectGraphType<JsonObject>
{
if (fieldInfo.Field.IsComponentLike())
{
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = fieldInfo.FieldNameDynamic,
Arguments = ContentActions.Json.Arguments,
ResolvedType = Scalars.Json,
Resolver = FieldVisitor.JsonPath,
Description = fieldInfo.Field.RawProperties.Hints
}).WithSourceName(fieldInfo);
Description = fieldInfo.Field.RawProperties.Hints,
SourceName = fieldInfo.Field.Name
});
}
var (resolvedType, resolver, args) = builder.GetGraphType(fieldInfo);
if (resolvedType != null && resolver != null)
{
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = fieldInfo.FieldName,
Arguments = args,
ResolvedType = resolvedType,
Resolver = resolver,
Description = fieldInfo.Field.RawProperties.Hints
}).WithSourceName(fieldInfo);
Description = fieldInfo.Field.RawProperties.Hints,
SourceName = fieldInfo.Field.Name
});
}
}

28
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentGraphType.cs

@ -95,14 +95,15 @@ internal sealed class ContentGraphType : ObjectGraphType<IEnrichedContentEntity>
{
var contentType = builder.GetContentType(referencingSchemaInfo);
AddField(new FieldType
AddField(new FieldTypeWithSchemaId
{
Name = $"referencing{referencingSchemaInfo.TypeName}Contents",
Arguments = ContentActions.QueryOrReferencing.Arguments,
ResolvedType = new ListGraphType(new NonNullGraphType(contentType)),
Resolver = ContentActions.QueryOrReferencing.Referencing,
Description = $"Query {referencingSchemaInfo.DisplayName} content items."
}).WithSchemaId(referencingSchemaInfo);
Description = $"Query {referencingSchemaInfo.DisplayName} content items.",
SchemaId = referencingSchemaInfo.Schema.Id
});
var contentResultTyp = builder.GetContentResultType(referencingSchemaInfo);
@ -111,28 +112,30 @@ internal sealed class ContentGraphType : ObjectGraphType<IEnrichedContentEntity>
return;
}
AddField(new FieldType
AddField(new FieldTypeWithSchemaId
{
Name = $"referencing{referencingSchemaInfo.TypeName}ContentsWithTotal",
Arguments = ContentActions.QueryOrReferencing.Arguments,
ResolvedType = contentResultTyp,
Resolver = ContentActions.QueryOrReferencing.ReferencingWithTotal,
Description = $"Query {referencingSchemaInfo.DisplayName} content items with total count."
}).WithSchemaId(referencingSchemaInfo);
Description = $"Query {referencingSchemaInfo.DisplayName} content items with total count.",
SchemaId = referencingSchemaInfo.Schema.Id
});
}
private void AddReferencesQueries(Builder builder, SchemaInfo referencesSchemaInfo)
{
var contentType = builder.GetContentType(referencesSchemaInfo);
AddField(new FieldType
AddField(new FieldTypeWithSchemaId
{
Name = $"references{referencesSchemaInfo.TypeName}Contents",
Arguments = ContentActions.QueryOrReferencing.Arguments,
ResolvedType = new ListGraphType(new NonNullGraphType(contentType)),
Resolver = ContentActions.QueryOrReferencing.References,
Description = $"Query {referencesSchemaInfo.DisplayName} content items."
}).WithSchemaId(referencesSchemaInfo);
Description = $"Query {referencesSchemaInfo.DisplayName} content items.",
SchemaId = referencesSchemaInfo.Schema.Id
});
var contentResultTyp = builder.GetContentResultType(referencesSchemaInfo);
@ -141,14 +144,15 @@ internal sealed class ContentGraphType : ObjectGraphType<IEnrichedContentEntity>
return;
}
AddField(new FieldType
AddField(new FieldTypeWithSchemaId
{
Name = $"references{referencesSchemaInfo.TypeName}ContentsWithTotal",
Arguments = ContentActions.QueryOrReferencing.Arguments,
ResolvedType = contentResultTyp,
Resolver = ContentActions.QueryOrReferencing.ReferencesWithTotal,
Description = $"Query {referencesSchemaInfo.DisplayName} content items with total count."
}).WithSchemaId(referencesSchemaInfo);
Description = $"Query {referencesSchemaInfo.DisplayName} content items with total count.",
SchemaId = referencesSchemaInfo.Schema.Id
});
}
private static bool IsReference(SchemaInfo from, SchemaInfo to)

14
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataFlatGraphType.cs

@ -22,28 +22,30 @@ internal sealed class DataFlatGraphType : ObjectGraphType<FlatContentData>
{
if (fieldInfo.Field.IsComponentLike())
{
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = fieldInfo.FieldNameDynamic,
Arguments = ContentActions.Json.Arguments,
ResolvedType = Scalars.Json,
Resolver = FieldVisitor.JsonPath,
Description = fieldInfo.Field.RawProperties.Hints
}).WithSourceName(fieldInfo);
Description = fieldInfo.Field.RawProperties.Hints,
SourceName = fieldInfo.Field.Name
});
}
var (resolvedType, resolver, args) = builder.GetGraphType(fieldInfo);
if (resolver != null)
{
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = fieldInfo.FieldName,
Arguments = args,
ResolvedType = resolvedType,
Resolver = resolver,
Description = fieldInfo.Field.RawProperties.Hints
}).WithSourceName(fieldInfo);
Description = fieldInfo.Field.RawProperties.Hints,
SourceName = fieldInfo.Field.Name
});
}
}

28
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataGraphType.cs

@ -33,24 +33,26 @@ internal sealed class DataGraphType : ObjectGraphType<ContentData>
foreach (var partitionKey in partitioning.AllKeys)
{
fieldGraphType.AddField(new FieldType
fieldGraphType.AddField(new FieldTypeWithSourceName
{
Name = partitionKey.EscapePartition(),
Arguments = ContentActions.Json.Arguments,
ResolvedType = Scalars.Json,
Resolver = FieldVisitor.JsonPath,
Description = fieldInfo.Field.RawProperties.Hints
}).WithSourceName(partitionKey);
Description = fieldInfo.Field.RawProperties.Hints,
SourceName = partitionKey
});
}
fieldGraphType.Description = $"The dynamic structure of the {fieldInfo.DisplayName} field of the {schemaInfo.DisplayName} content type.";
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = fieldInfo.FieldNameDynamic,
ResolvedType = fieldGraphType,
Resolver = ContentResolvers.Field
}).WithSourceName(fieldInfo);
Resolver = ContentResolvers.Field,
SourceName = fieldInfo.Field.Name
});
}
var (resolvedType, resolver, args) = builder.GetGraphType(fieldInfo);
@ -65,24 +67,26 @@ internal sealed class DataGraphType : ObjectGraphType<ContentData>
foreach (var partitionKey in partitioning.AllKeys)
{
fieldGraphType.AddField(new FieldType
fieldGraphType.AddField(new FieldTypeWithSourceName
{
Name = partitionKey.EscapePartition(),
Arguments = args,
ResolvedType = resolvedType,
Resolver = resolver,
Description = fieldInfo.Field.RawProperties.Hints
}).WithSourceName(partitionKey);
Description = fieldInfo.Field.RawProperties.Hints,
SourceName = partitionKey
});
}
fieldGraphType.Description = $"The structure of the {fieldInfo.DisplayName} field of the {schemaInfo.DisplayName} content type.";
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = fieldInfo.FieldName,
ResolvedType = fieldGraphType,
Resolver = ContentResolvers.Field
}).WithSourceName(fieldInfo);
Resolver = ContentResolvers.Field,
SourceName = fieldInfo.Field.Name,
});
}
}

14
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataInputGraphType.cs

@ -40,23 +40,25 @@ internal sealed class DataInputGraphType : InputObjectGraphType
foreach (var partitionKey in partitioning.AllKeys)
{
fieldGraphType.AddField(new FieldType
fieldGraphType.AddField(new FieldTypeWithSourceName
{
Name = partitionKey.EscapePartition(),
ResolvedType = resolvedType,
Resolver = null,
Description = fieldInfo.Field.RawProperties.Hints
}).WithSourceName(partitionKey);
Description = fieldInfo.Field.RawProperties.Hints,
SourceName = partitionKey
});
}
fieldGraphType.Description = $"The structure of the {fieldInfo.DisplayName} field of the {schemaInfo.DisplayName} content input type.";
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = fieldInfo.FieldName,
ResolvedType = fieldGraphType,
Resolver = null
}).WithSourceName(fieldInfo);
Resolver = null,
SourceName = fieldInfo.Field.Name,
});
}
Description = $"The structure of the {schemaInfo.DisplayName} data input type.";

14
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedGraphType.cs

@ -22,28 +22,30 @@ internal sealed class NestedGraphType : ObjectGraphType<JsonObject>
{
if (nestedFieldInfo.Field.IsComponentLike())
{
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = nestedFieldInfo.FieldNameDynamic,
Arguments = ContentActions.Json.Arguments,
ResolvedType = Scalars.Json,
Resolver = FieldVisitor.JsonPath,
Description = nestedFieldInfo.Field.RawProperties.Hints
}).WithSourceName(nestedFieldInfo);
Description = nestedFieldInfo.Field.RawProperties.Hints,
SourceName = nestedFieldInfo.Field.Name
});
}
var (resolvedType, resolver, args) = builder.GetGraphType(nestedFieldInfo);
if (resolvedType != null && resolver != null)
{
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = nestedFieldInfo.FieldName,
Arguments = args,
ResolvedType = resolvedType,
Resolver = resolver,
Description = nestedFieldInfo.Field.RawProperties.Hints
}).WithSourceName(nestedFieldInfo);
Description = nestedFieldInfo.Field.RawProperties.Hints,
SourceName = nestedFieldInfo.Field.Name
});
}
}

7
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedInputGraphType.cs

@ -27,13 +27,14 @@ internal sealed class NestedInputGraphType : InputObjectGraphType
continue;
}
AddField(new FieldType
AddField(new FieldTypeWithSourceName
{
Name = nestedFieldInfo.FieldName,
ResolvedType = resolvedType,
Resolver = null,
Description = nestedFieldInfo.Field.RawProperties.Hints
}).WithSourceName(nestedFieldInfo);
Description = nestedFieldInfo.Field.RawProperties.Hints,
SourceName = nestedFieldInfo.Field.Name,
});
}
Description = $"The structure of the {fieldInfo.DisplayName} nested schema.";

23
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/FieldTypeWithSchemaId.cs

@ -0,0 +1,23 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using GraphQL.Types;
using Squidex.Infrastructure;
#pragma warning disable MA0048 // File name must match type name
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types;
internal sealed class FieldTypeWithSchemaId : FieldType
{
required public DomainId SchemaId { get; set; }
}
internal sealed class FieldTypeWithSchemaNamedId : FieldType
{
required public NamedId<DomainId> SchemaId { get; set; }
}

15
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/FieldTypeWithSourceName.cs

@ -0,0 +1,15 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using GraphQL.Types;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types;
internal sealed class FieldTypeWithSourceName : FieldType
{
required public string SourceName { get; set; }
}

38
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/SharedExtensions.cs

@ -78,7 +78,6 @@ public static class SharedExtensions
try
{
NameValidator.ValidateDefault(name!, type);
return true;
}
catch
@ -87,39 +86,34 @@ public static class SharedExtensions
}
}
internal static FieldType WithSourceName(this FieldType field, string value)
{
return field.WithMetadata(nameof(SourceName), value);
}
internal static FieldType WithSourceName(this FieldType field, FieldInfo value)
{
return field.WithMetadata(nameof(SourceName), value.Field.Name);
}
internal static string SourceName(this FieldType field)
{
return field.GetMetadata<string>(nameof(SourceName))!;
}
if (field is FieldTypeWithSourceName typed)
{
return typed.SourceName;
}
internal static FieldType WithSchemaId(this FieldType field, SchemaInfo value)
{
return field.WithMetadata(nameof(SchemaId), value.Schema.Id);
throw new InvalidOperationException("Invalid field type");
}
internal static DomainId SchemaId(this FieldType field)
{
return field.GetMetadata<DomainId>(nameof(SchemaId))!;
}
if (field is FieldTypeWithSchemaId typed)
{
return typed.SchemaId;
}
internal static FieldType WithSchemaNamedId(this FieldType field, SchemaInfo value)
{
return field.WithMetadata(nameof(SchemaNamedId), value.Schema.NamedId());
throw new InvalidOperationException("Invalid field type");
}
internal static NamedId<DomainId> SchemaNamedId(this FieldType field)
{
return field.GetMetadata<NamedId<DomainId>>(nameof(SchemaNamedId))!;
if (field is FieldTypeWithSchemaNamedId typed)
{
return typed.SchemaId;
}
throw new InvalidOperationException("Invalid field type");
}
public static IGraphType? InnerType(this IGraphType type)

10
backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs

@ -6,6 +6,8 @@
// ==========================================================================
using System.Text.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NJsonSchema;
using NJsonSchema.Generation;
using NJsonSchema.Generation.TypeMappers;
@ -64,7 +66,13 @@ public static class OpenApiServices
services.AddSingleton(c =>
{
var settings = new OpenApiDocumentGeneratorSettings();
var settings = new OpenApiDocumentGeneratorSettings
{
SerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
}
};
ConfigureSchemaSettings(settings, c.GetRequiredService<TypeRegistry>(), true);

Loading…
Cancel
Save