示例#1
0
        private static IEnumerable <SchemaEvent> SyncFields <T>(
            FieldCollection <T> source,
            FieldCollection <T> target,
            IJsonSerializer serializer,
            Func <long> idGenerator,
            NamedId <long> parentId, SchemaSynchronizationOptions options) where T : class, IField
        {
            FieldEvent E(FieldEvent @event)
            {
                @event.ParentFieldId = parentId;

                return(@event);
            }

            var sourceIds   = new List <NamedId <long> >(source.Ordered.Select(x => x.NamedId()));
            var sourceNames = sourceIds.Select(x => x.Name).ToList();

            if (!options.NoFieldDeletion)
            {
                foreach (var sourceField in source.Ordered)
                {
                    if (!target.ByName.TryGetValue(sourceField.Name, out _))
                    {
                        var id = sourceField.NamedId();

                        sourceIds.Remove(id);
                        sourceNames.Remove(id.Name);

                        yield return(E(new FieldDeleted {
                            FieldId = id
                        }));
                    }
                }
            }

            foreach (var targetField in target.Ordered)
            {
                NamedId <long> id = null;

                var canCreateField = true;

                if (source.ByName.TryGetValue(targetField.Name, out var sourceField))
                {
                    canCreateField = false;

                    id = sourceField.NamedId();

                    if (CanUpdate(sourceField, targetField))
                    {
                        if (!sourceField.RawProperties.EqualsJson(targetField.RawProperties, serializer))
                        {
                            yield return(E(new FieldUpdated {
                                FieldId = id, Properties = targetField.RawProperties
                            }));
                        }
                    }
                    else if (!sourceField.IsLocked && !options.NoFieldRecreation)
                    {
                        canCreateField = true;

                        sourceIds.Remove(id);
                        sourceNames.Remove(id.Name);

                        yield return(E(new FieldDeleted {
                            FieldId = id
                        }));
                    }
                }

                if (canCreateField)
                {
                    var partitioning = (string)null;

                    if (targetField is IRootField rootField)
                    {
                        partitioning = rootField.Partitioning.Key;
                    }

                    id = NamedId.Of(idGenerator(), targetField.Name);

                    yield return(new FieldAdded
                    {
                        Name = targetField.Name,
                        ParentFieldId = parentId,
                        Partitioning = partitioning,
                        Properties = targetField.RawProperties,
                        FieldId = id
                    });

                    sourceIds.Add(id);
                    sourceNames.Add(id.Name);
                }

                if (id != null && (sourceField == null || CanUpdate(sourceField, targetField)))
                {
                    if (!targetField.IsLocked.BoolEquals(sourceField?.IsLocked))
                    {
                        yield return(E(new FieldLocked {
                            FieldId = id
                        }));
                    }

                    if (!targetField.IsHidden.BoolEquals(sourceField?.IsHidden))
                    {
                        yield return(targetField.IsHidden ?
                                     E(new FieldHidden {
                            FieldId = id
                        }) :
                                     E(new FieldShown {
                            FieldId = id
                        }));
                    }

                    if (!targetField.IsDisabled.BoolEquals(sourceField?.IsDisabled))
                    {
                        yield return(targetField.IsDisabled ?
                                     E(new FieldDisabled {
                            FieldId = id
                        }) :
                                     E(new FieldEnabled {
                            FieldId = id
                        }));
                    }

                    if ((sourceField == null || sourceField is IArrayField) && targetField is IArrayField targetArrayField)
                    {
                        var fields = ((IArrayField)sourceField)?.FieldCollection ?? FieldCollection <NestedField> .Empty;

                        var events = SyncFields(fields, targetArrayField.FieldCollection, serializer, idGenerator, id, options);

                        foreach (var @event in events)
                        {
                            yield return(@event);
                        }
                    }
                }
            }

            if (sourceNames.Count > 1)
            {
                var targetNames = target.Ordered.Select(x => x.Name);

                if (sourceNames.Intersect(targetNames).Count() == target.Ordered.Count && !sourceNames.SequenceEqual(targetNames))
                {
                    yield return(new SchemaFieldsReordered {
                        FieldIds = sourceIds.Select(x => x.Id).ToList(), ParentFieldId = parentId
                    });
                }
            }
        }
示例#2
0
        private static IEnumerable <ParentFieldEvent> SyncFields <T>(
            FieldCollection <T> source,
            FieldCollection <T> target,
            Func <long> idGenerator,
            Func <T, T, bool> canUpdate,
            SchemaSynchronizationOptions options) where T : class, IField
        {
            var sourceIds = source.Ordered.Select(x => x.NamedId()).ToList();

            if (!options.NoFieldDeletion)
            {
                foreach (var sourceField in source.Ordered)
                {
                    if (!target.ByName.TryGetValue(sourceField.Name, out _))
                    {
                        var id = sourceField.NamedId();

                        sourceIds.Remove(id);

                        yield return(new FieldDeleted {
                            FieldId = id
                        });
                    }
                }
            }

            foreach (var targetField in target.Ordered)
            {
                NamedId <long>?id = null;

                var canCreateField = true;

                if (source.ByName.TryGetValue(targetField.Name, out var sourceField))
                {
                    canCreateField = false;

                    id = sourceField.NamedId();

                    if (canUpdate(sourceField, targetField))
                    {
                        if (!sourceField.RawProperties.Equals(targetField.RawProperties as object))
                        {
                            yield return(new FieldUpdated {
                                FieldId = id, Properties = targetField.RawProperties
                            });
                        }
                    }
                    else if (!sourceField.IsLocked && !options.NoFieldRecreation)
                    {
                        canCreateField = true;

                        sourceIds.Remove(id);

                        yield return(new FieldDeleted {
                            FieldId = id
                        });
                    }
                }

                if (canCreateField)
                {
                    var partitioning = (string?)null;

                    if (targetField is IRootField rootField)
                    {
                        partitioning = rootField.Partitioning.Key;
                    }

                    id = NamedId.Of(idGenerator(), targetField.Name);

                    yield return(new FieldAdded
                    {
                        Name = targetField.Name,
                        Partitioning = partitioning,
                        Properties = targetField.RawProperties,
                        FieldId = id
                    });

                    sourceIds.Add(id);
                }

                if (id != null && (sourceField == null || CanUpdate(sourceField, targetField)))
                {
                    if (!targetField.IsLocked.BoolEquals(sourceField?.IsLocked))
                    {
                        yield return(new FieldLocked {
                            FieldId = id
                        });
                    }

                    if (!targetField.IsHidden.BoolEquals(sourceField?.IsHidden))
                    {
                        yield return(targetField.IsHidden ?
                                     new FieldHidden {
                            FieldId = id
                        } :
                                     new FieldShown {
                            FieldId = id
                        });
                    }

                    if (!targetField.IsDisabled.BoolEquals(sourceField?.IsDisabled))
                    {
                        yield return(targetField.IsDisabled ?
                                     new FieldDisabled {
                            FieldId = id
                        } :
                                     new FieldEnabled {
                            FieldId = id
                        });
                    }

                    if ((sourceField == null || sourceField is IArrayField) && targetField is IArrayField targetArrayField)
                    {
                        var fields = (sourceField as IArrayField)?.FieldCollection ?? FieldCollection <NestedField> .Empty;

                        var events = SyncFields(fields, targetArrayField.FieldCollection, idGenerator, CanUpdate, options);

                        foreach (var @event in events)
                        {
                            @event.ParentFieldId = id;

                            yield return(@event);
                        }
                    }
                }
            }

            if (sourceIds.Count > 1)
            {
                var sourceNames = sourceIds.Select(x => x.Name).ToHashSet();
                var targetNames = target.Ordered.Select(x => x.Name).ToHashSet();

                if (sourceNames.SetEquals(targetNames) && !sourceNames.SequenceEqual(targetNames))
                {
                    var fieldIds = targetNames.Select(x => sourceIds.Find(y => y.Name == x) !.Id).ToArray();

                    yield return(new SchemaFieldsReordered {
                        FieldIds = fieldIds
                    });
                }
            }
        }
示例#3
0
        public static IEnumerable <IEvent> Synchronize(this Schema source, Schema target, IJsonSerializer serializer, Func <long> idGenerator, SchemaSynchronizationOptions options = null)
        {
            Guard.NotNull(source, nameof(source));
            Guard.NotNull(serializer, nameof(serializer));
            Guard.NotNull(idGenerator, nameof(idGenerator));

            if (target == null)
            {
                yield return(new SchemaDeleted());
            }
            else
            {
                options = options ?? new SchemaSynchronizationOptions();

                SchemaEvent E(SchemaEvent @event)
                {
                    return(@event);
                }

                if (!source.Properties.EqualsJson(target.Properties, serializer))
                {
                    yield return(E(new SchemaUpdated {
                        Properties = target.Properties
                    }));
                }

                if (!source.Category.StringEquals(target.Category))
                {
                    yield return(E(new SchemaCategoryChanged {
                        Name = target.Category
                    }));
                }

                if (!source.Scripts.EqualsJson(target.Scripts, serializer))
                {
                    yield return(E(new SchemaScriptsConfigured {
                        Scripts = target.Scripts
                    }));
                }

                if (!source.PreviewUrls.EqualsDictionary(target.PreviewUrls))
                {
                    yield return(E(new SchemaPreviewUrlsConfigured {
                        PreviewUrls = target.PreviewUrls.ToDictionary(x => x.Key, x => x.Value)
                    }));
                }

                if (source.IsPublished != target.IsPublished)
                {
                    yield return(target.IsPublished ?
                                 E(new SchemaPublished()) :
                                 E(new SchemaUnpublished()));
                }

                var events = SyncFields(source.FieldCollection, target.FieldCollection, serializer, idGenerator, null, options);

                foreach (var @event in events)
                {
                    yield return(E(@event));
                }
            }
        }