Skip to content

Commit

Permalink
Fix component sync.
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianStehle committed Nov 16, 2021
1 parent 61dc1ef commit eae2b77
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 83 deletions.
4 changes: 2 additions & 2 deletions cli/Squidex.CLI/Squidex.CLI/Commands/App_Backup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task Create(CreateArguments arguments)
while (!tcs.Token.IsCancellationRequested)
{
var backups = await session.Backups.GetBackupsAsync(session.App, tcs.Token);
var backup = backups.Items.FirstOrDefault(x => x.Started >= backupStarted);
var backup = backups.Items.Find(x => x.Started >= backupStarted);

if (backup?.Stopped != null)
{
Expand Down Expand Up @@ -97,7 +97,7 @@ public async Task Create(CreateArguments arguments)
}

[Validator(typeof(Validator))]
public sealed class CreateArguments: AppArguments
public sealed class CreateArguments : AppArguments
{
[Operand(Name = "file", Description = "The target file.")]
public string File { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ public void StepStart(string message)
{
if (message.Length > MaxActionLength - 3)
{
message = message.Substring(0, MaxActionLength - 3);
var length = MaxActionLength - 3;

message = message[..length];
}

message += "...";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ await log.DoSafeAsync($"Client '{client.Id}' deleting", async () =>

foreach (var (clientId, _) in model.Clients)
{
var existing = current.Items.FirstOrDefault(x => x.Id == clientId);
var existing = current.Items.Find(x => x.Id == clientId);

if (existing != null)
{
Expand All @@ -160,7 +160,7 @@ await log.DoSafeAsync($"Client '{clientId}' creating", async () =>

foreach (var (clientId, value) in model.Clients)
{
var existing = current.Items.FirstOrDefault(x => x.Id == clientId);
var existing = current.Items.Find(x => x.Id == clientId);

if (existing == null || value.JsonEquals(existing))
{
Expand Down Expand Up @@ -198,7 +198,7 @@ await log.DoSafeAsync($"Language '{language.Iso2Code}' deleting", async () =>

foreach (var (isoCode, _) in model.Languages)
{
var existing = current.Items.FirstOrDefault(x => x.Iso2Code == isoCode);
var existing = current.Items.Find(x => x.Iso2Code == isoCode);

if (existing != null)
{
Expand All @@ -215,7 +215,7 @@ await log.DoSafeAsync($"Language '{isoCode}' creating", async () =>

foreach (var (isoCode, value) in model.Languages)
{
var existing = current.Items.FirstOrDefault(x => x.Iso2Code == isoCode);
var existing = current.Items.Find(x => x.Iso2Code == isoCode);

if (existing == null || value.JsonEquals(existing))
{
Expand Down Expand Up @@ -256,7 +256,7 @@ await log.DoSafeAsync($"Role '{role.Name}' deleting", async () =>

foreach (var (roleName, _) in model.Roles)
{
var existing = current.Items.FirstOrDefault(x => x.Name == roleName);
var existing = current.Items.Find(x => x.Name == roleName);

if (existing != null)
{
Expand All @@ -273,7 +273,7 @@ await log.DoSafeAsync($"Role '{roleName}' creating", async () =>

foreach (var (roleName, value) in model.Roles)
{
var existing = current.Items.FirstOrDefault(x => x.Name == roleName);
var existing = current.Items.Find(x => x.Name == roleName);

if (existing == null || value.JsonEquals(existing))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public Task CleanupAsync(IFileSystem fs)
public async Task ExportAsync(ISyncService sync, SyncOptions options, ISession session)
{
var schemas = await session.Schemas.GetSchemasAsync(session.App);
var schemaMap = schemas.Items.ToDictionary(x => x.Id, x => x.Name);

var context = QueryContext.Default.Unpublished().IgnoreFallback();

Expand All @@ -65,6 +66,8 @@ Task SaveAsync()

await client.GetAllAsync(async content =>
{
content.MapComponents(schemaMap);

contents.Add(content.ToModel(schema.Name));

if (contents.Count > 50)
Expand All @@ -90,14 +93,20 @@ public async Task ImportAsync(ISyncService sync, SyncOptions options, ISession s
.Select(x => (x, sync.Read<ContentsModel>(x, log)));

var schemas = await session.Schemas.GetSchemasAsync(session.App);
var schemaMap = schemas.Items.ToDictionary(x => x.Name, x => x.Id);

foreach (var (file, model) in models)
{
if (model?.Contents?.Count > 0)
{
model.Clear(options.Languages);

var client = session.Contents(model.Contents.First().Schema);
foreach (var content in model.Contents)
{
content.MapComponents(schemaMap);
}

var client = session.Contents(model.Contents[0].Schema);

var request = new BulkUpdate
{
Expand All @@ -115,7 +124,7 @@ public async Task ImportAsync(ISyncService sync, SyncOptions options, ISession s

foreach (var content in model.Contents)
{
var result = results.FirstOrDefault(x => x.JobIndex == contentIndex);
var result = results.Find(x => x.JobIndex == contentIndex);

log.StepStart($"Upserting #{contentIndex}");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
Expand All @@ -20,7 +21,7 @@ public static BulkUpdateJob ToJob(this ContentModel model, SchemasDto schemas)
var id = model.Id;

#pragma warning disable CS0618 // Type or member is obsolete
var singleton = schemas.Items.FirstOrDefault(x => x.Name == model.Schema && x.IsSingleton);
var singleton = schemas.Items.Find(x => x.Name == model.Schema && x.IsSingleton);
#pragma warning restore CS0618 // Type or member is obsolete
if (singleton != null)
{
Expand Down Expand Up @@ -48,6 +49,52 @@ public static ContentModel ToModel(this DynamicContent content, string schema)
};
}

public static void MapComponents(this DynamicContent content, Dictionary<string, string> map)
{
MapComponents(content.Data, map);
}

public static void MapComponents(this ContentModel content, Dictionary<string, string> map)
{
MapComponents(content.Data, map);
}

private static void MapComponents(this DynamicData data, Dictionary<string, string> map)
{
static void Map(JToken token, Dictionary<string, string> map)
{
if (token is JObject obj)
{
foreach (var value in obj.Values())
{
Map(value, map);
}

if (!obj.TryGetValue(Component.Discriminator, StringComparison.Ordinal, out var schemaId))
{
return;
}

if (schemaId.Type == JTokenType.String && map.TryGetValue(schemaId.Value<string>(), out var target))
{
obj[Component.Discriminator] = target;
}
}
else if (token is JArray array)
{
foreach (var value in array)
{
Map(value, map);
}
}
}

foreach (var field in data.Values)
{
Map(field, map);
}
}

public static void Clear(this ContentsModel model, string[] languages)
{
if (languages?.Length > 0 && model.Contents?.Count > 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================

using System.Collections.Generic;
using Squidex.ClientLibrary.Management;

#pragma warning disable CS0618 // Type or member is obsolete
Expand All @@ -26,5 +27,65 @@ public static CreateSchemaDto ToRequest(this SchemaCreateModel model)

return new CreateSchemaDto { Name = model.Name, IsSingleton = isSingleton, Type = type };
}

public static void MapReferences(this SynchronizeSchemaDto schema, Dictionary<string, string> map)
{
if (schema.Fields != null)
{
foreach (var field in schema.Fields)
{
MapReferences(field, map);
}
}
}

public static void MapReferences(this UpsertSchemaFieldDto field, Dictionary<string, string> map)
{
MapReferences(field.Properties, map);

if (field.Nested != null)
{
foreach (var nested in field.Nested)
{
MapReferences(nested.Properties, map);
}
}
}

private static void MapReferences(FieldPropertiesDto properties, Dictionary<string, string> map)
{
if (properties is ReferencesFieldPropertiesDto references)
{
references.SchemaIds = MapReferences(references.SchemaIds, map);
}
else if (properties is ComponentFieldPropertiesDto component)
{
component.SchemaIds = MapReferences(component.SchemaIds, map);
}
else if (properties is ComponentsFieldPropertiesDto components)
{
components.SchemaIds = MapReferences(components.SchemaIds, map);
}
}

private static List<string> MapReferences(List<string> ids, Dictionary<string, string> map)
{
if (ids == null || ids.Count == 0)
{
return ids;
}

var result = new List<string>();

foreach (var id in ids)
{
if (map.TryGetValue(id, out var target))
{
result.Add(target);
}
}

return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Squidex.CLI.Commands.Implementation.Sync.Schemas
{
public sealed class SchemeModel : SchemaCreateModel
public sealed class SchemaModel : SchemaCreateModel
{
public SynchronizeSchemaDto Schema { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ await log.DoSafeAsync($"Exporting '{schema.Name}'", async () =>
{
var details = await session.Schemas.GetSchemaAsync(session.App, schema.Name);

var model = new SchemeModel
var model = new SchemaModel
{
Name = schema.Name,
Schema = sync.Convert<SynchronizeSchemaDto>(details),
SchemaType = details.Type,
IsSingleton = details.IsSingleton
};

MapReferences(model.Schema, schemaMap);
model.Schema.MapReferences(schemaMap);

await sync.WriteWithSchema(new FilePath($"schemas", $"{schema.Name}.json"), model, Ref);
});
Expand Down Expand Up @@ -117,12 +117,12 @@ await log.DoSafeAsync($"Schema {model.Name} creating", async () =>

var models =
GetSchemaFiles(sync.FileSystem)
.Select(x => sync.Read<SchemeModel>(x, log))
.Select(x => sync.Read<SchemaModel>(x, log))
.ToList();

foreach (var model in models)
{
MapReferences(model.Schema, schemaMap);
model.Schema.MapReferences(schemaMap);

var version = schemasByName[model.Name].Version;

Expand Down Expand Up @@ -158,9 +158,9 @@ private static IEnumerable<IFile> GetSchemaFiles(IFileSystem fs)

public async Task GenerateSchemaAsync(ISyncService sync)
{
await sync.WriteJsonSchemaAsync<SchemeModel>(new FilePath("schema.json"));
await sync.WriteJsonSchemaAsync<SchemaModel>(new FilePath("schema.json"));

var sample = new SchemeModel
var sample = new SchemaModel
{
Name = "my-schema",
Schema = new SynchronizeSchemaDto
Expand All @@ -187,65 +187,5 @@ public async Task GenerateSchemaAsync(ISyncService sync)

await sync.WriteWithSchema(new FilePath("schemas", "__schema.json"), sample, Ref);
}

private static void MapReferences(SynchronizeSchemaDto schema, Dictionary<string, string> map)
{
if (schema.Fields != null)
{
foreach (var field in schema.Fields)
{
MapReferences(field, map);
}
}
}

private static void MapReferences(UpsertSchemaFieldDto field, Dictionary<string, string> map)
{
MapReferences(field.Properties, map);

if (field.Nested != null)
{
foreach (var nested in field.Nested)
{
MapReferences(nested.Properties, map);
}
}
}

private static void MapReferences(FieldPropertiesDto properties, Dictionary<string, string> map)
{
if (properties is ReferencesFieldPropertiesDto references)
{
references.SchemaIds = MapReferences(references.SchemaIds, map);
}
else if (properties is ComponentFieldPropertiesDto component)
{
component.SchemaIds = MapReferences(component.SchemaIds, map);
}
else if (properties is ComponentsFieldPropertiesDto components)
{
components.SchemaIds = MapReferences(components.SchemaIds, map);
}
}

private static List<string> MapReferences(List<string> ids, Dictionary<string, string> map)
{
if (ids == null || ids.Count == 0)
{
return ids;
}

var result = new List<string>();

foreach (var id in ids)
{
if (map.TryGetValue(id, out var target))
{
result.Add(target);
}
}

return result;
}
}
}
Loading

0 comments on commit eae2b77

Please sign in to comment.