Browse Source

Migration completed

pull/218/head
Sebastian Stehle 8 years ago
parent
commit
c095b3636e
  1. 3
      src/Squidex.Domain.Apps.Entities/Apps/AppDomainObject.cs
  2. 3
      src/Squidex.Domain.Apps.Entities/Assets/AssetDomainObject.cs
  3. 3
      src/Squidex.Domain.Apps.Entities/Contents/ContentDomainObject.cs
  4. 3
      src/Squidex.Domain.Apps.Entities/Rules/RuleDomainObject.cs
  5. 3
      src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs
  6. 26
      src/Squidex.Domain.Apps.Entities/SquidexDomainObjectBase.cs
  7. 28
      src/Squidex.Domain.Apps.Events/SquidexHeaderExtensions.cs
  8. 14
      src/Squidex.Domain.Apps.Events/SquidexHeaders.cs
  9. 4
      src/Squidex.Infrastructure.GetEventStore/EventSourcing/ProjectionClient.cs
  10. 13
      src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs
  11. 2
      src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs
  12. 2
      src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs
  13. 1
      src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs
  14. 4
      src/Squidex.Infrastructure/Commands/DomainObjectBase.cs
  15. 13
      src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs
  16. 13
      src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs
  17. 2
      src/Squidex.Infrastructure/Migrations/Migrator.cs
  18. 22
      src/Squidex.Infrastructure/NamedId.cs
  19. 6
      tools/Migrate_01/MigrationPath.cs
  20. 17
      tools/Migrate_01/Migrations/ConvertEventStore.cs

3
src/Squidex.Domain.Apps.Entities/Apps/AppDomainObject.cs

@ -13,13 +13,12 @@ using Squidex.Domain.Apps.Entities.Apps.State;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Apps;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Apps
{
public sealed class AppDomainObject : DomainObjectBase<AppState>
public sealed class AppDomainObject : SquidexDomainObjectBase<AppState>
{
private readonly InitialPatterns initialPatterns;

3
src/Squidex.Domain.Apps.Entities/Assets/AssetDomainObject.cs

@ -9,13 +9,12 @@ using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Domain.Apps.Entities.Assets.State;
using Squidex.Domain.Apps.Events.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Assets
{
public sealed class AssetDomainObject : DomainObjectBase<AssetState>
public sealed class AssetDomainObject : SquidexDomainObjectBase<AssetState>
{
public AssetDomainObject Create(CreateAsset command)
{

3
src/Squidex.Domain.Apps.Entities/Contents/ContentDomainObject.cs

@ -10,13 +10,12 @@ using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Contents.State;
using Squidex.Domain.Apps.Events.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Contents
{
public sealed class ContentDomainObject : DomainObjectBase<ContentState>
public sealed class ContentDomainObject : SquidexDomainObjectBase<ContentState>
{
public ContentDomainObject Create(CreateContent command)
{

3
src/Squidex.Domain.Apps.Entities/Rules/RuleDomainObject.cs

@ -9,13 +9,12 @@ using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Domain.Apps.Entities.Rules.State;
using Squidex.Domain.Apps.Events.Rules;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Rules
{
public sealed class RuleDomainObject : DomainObjectBase<RuleState>
public sealed class RuleDomainObject : SquidexDomainObjectBase<RuleState>
{
public void Create(CreateRule command)
{

3
src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs

@ -12,13 +12,12 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Domain.Apps.Entities.Schemas.State;
using Squidex.Domain.Apps.Events.Schemas;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Schemas
{
public sealed class SchemaDomainObject : DomainObjectBase<SchemaState>
public sealed class SchemaDomainObject : SquidexDomainObjectBase<SchemaState>
{
private readonly FieldRegistry registry;

26
src/Squidex.Domain.Apps.Entities/SquidexDomainObjectBase.cs

@ -0,0 +1,26 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Domain.Apps.Entities
{
public abstract class SquidexDomainObjectBase<T> : DomainObjectBase<T> where T : IDomainState, new()
{
public override void RaiseEvent(Envelope<IEvent> @event)
{
if (@event.Payload is AppEvent appEvent)
{
@event.SetAppId(appEvent.AppId.Id);
}
base.RaiseEvent(@event);
}
}
}

28
src/Squidex.Domain.Apps.Events/SquidexHeaderExtensions.cs

@ -0,0 +1,28 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Globalization;
using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Domain.Apps.Events
{
public static class SquidexHeaderExtensions
{
public static Guid AppId(this EnvelopeHeaders headers)
{
return headers[SquidexHeaders.AppId].ToGuid(CultureInfo.InvariantCulture);
}
public static Envelope<T> SetAppId<T>(this Envelope<T> envelope, Guid value) where T : class
{
envelope.Headers.Set(SquidexHeaders.AppId, value);
return envelope;
}
}
}

14
src/Squidex.Domain.Apps.Events/SquidexHeaders.cs

@ -0,0 +1,14 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Domain.Apps.Events
{
public static class SquidexHeaders
{
public static readonly string AppId = "AppId";
}
}

4
src/Squidex.Infrastructure.GetEventStore/EventSourcing/ProjectionClient.cs

@ -51,8 +51,8 @@ namespace Squidex.Infrastructure.EventSourcing
$@"fromAll()
.when({{
$any: function (s, e) {{
if (e.streamId.indexOf('{prefix}') === 0 && e.data.{property}) {{
linkTo('{name}-' + e.data.{property}, e);
if (e.streamId.indexOf('{prefix}') === 0 && e.metadata.{property}) {{
linkTo('{name}-' + e.metadata.{property}, e);
}}
}}
}});";

13
src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs

@ -7,7 +7,6 @@
using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json.Linq;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Infrastructure.EventSourcing
{
@ -15,7 +14,7 @@ namespace Squidex.Infrastructure.EventSourcing
{
[BsonElement]
[BsonRequired]
public JToken Payload { get; set; }
public string Payload { get; set; }
[BsonElement]
[BsonRequired]
@ -25,18 +24,14 @@ namespace Squidex.Infrastructure.EventSourcing
[BsonRequired]
public string Type { get; set; }
public MongoEvent()
public static MongoEvent FromEventData(EventData data)
{
}
public MongoEvent(EventData data)
{
SimpleMapper.Map(data, this);
return new MongoEvent { Type = data.Type, Metadata = data.Metadata, Payload = data.ToString() };
}
public EventData ToEventData()
{
return SimpleMapper.Map(this, new EventData());
return new EventData { Type = Type, Metadata = Metadata, Payload = JObject.Parse(Payload) };
}
}
}

2
src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs

@ -167,7 +167,7 @@ namespace Squidex.Infrastructure.EventSourcing
private static string CreateIndexPath(string property)
{
return $"Events.Payload.{property}";
return $"Events.Metadata.{property}";
}
}
}

2
src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs

@ -108,7 +108,7 @@ namespace Squidex.Infrastructure.EventSourcing
foreach (var e in events)
{
var mongoEvent = new MongoEvent(e);
var mongoEvent = MongoEvent.FromEventData(e);
commitEvents[i++] = mongoEvent;
}

1
src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs

@ -12,6 +12,7 @@ using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.MongoDb
{

4
src/Squidex.Infrastructure/Commands/DomainObjectBase.cs

@ -45,13 +45,13 @@ namespace Squidex.Infrastructure.Commands
RaiseEvent(Envelope.Create(@event));
}
public void RaiseEvent<TEvent>(Envelope<TEvent> @event) where TEvent : class, IEvent
public virtual void RaiseEvent(Envelope<IEvent> @event)
{
Guard.NotNull(@event, nameof(@event));
@event.SetAggregateId(id);
ApplyEvent(@event.To<IEvent>());
ApplyEvent(@event);
snapshot.Version++;

13
src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs

@ -25,19 +25,14 @@ namespace Squidex.Infrastructure.Json
throw new JsonException($"Expected String, but got {reader.TokenType}.");
}
var parts = reader.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
try
{
throw new JsonException("Named id must have more than 2 parts divided by commata.");
return NamedId<Guid>.Parse(reader.Value.ToString(), Guid.TryParse);
}
if (!Guid.TryParse(parts[0], out var id))
catch (ArgumentException ex)
{
throw new JsonException("Named id must be a valid guid.");
throw new JsonException(ex.Message);
}
return new NamedId<Guid>(id, string.Join(",", parts.Skip(1)));
}
}
}

13
src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs

@ -25,19 +25,14 @@ namespace Squidex.Infrastructure.Json
throw new JsonException($"Expected String, but got {reader.TokenType}.");
}
var parts = reader.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
try
{
throw new JsonException("Named id must have more than 2 parts divided by commata.");
return NamedId<long>.Parse(reader.Value.ToString(), long.TryParse);
}
if (!long.TryParse(parts[0], out var id))
catch (ArgumentException ex)
{
throw new JsonException("Named id must be a valid long.");
throw new JsonException(ex.Message);
}
return new NamedId<long>(id, string.Join(",", parts.Skip(1)));
}
}
}

2
src/Squidex.Infrastructure/Migrations/Migrator.cs

@ -17,7 +17,7 @@ namespace Squidex.Infrastructure.Migrations
private readonly IMigrationStatus migrationStatus;
private readonly IMigrationPath migrationPath;
public int LockWaitMs { get; set; } = 5000;
public int LockWaitMs { get; set; } = 500;
public Migrator(IMigrationStatus migrationStatus, IMigrationPath migrationPath, ISemanticLog log)
{

22
src/Squidex.Infrastructure/NamedId.cs

@ -6,9 +6,12 @@
// ==========================================================================
using System;
using System.Linq;
namespace Squidex.Infrastructure
{
public delegate bool Parser<T>(string input, out T result);
public sealed class NamedId<T> : IEquatable<NamedId<T>>
{
public T Id { get; }
@ -44,5 +47,24 @@ namespace Squidex.Infrastructure
{
return (Id.GetHashCode() * 397) ^ Name.GetHashCode();
}
public static NamedId<T> Parse(string value, Parser<T> parser)
{
Guard.NotNull(value, nameof(value));
var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
{
throw new ArgumentException("Named id must have more than 2 parts divided by commata.");
}
if (!parser(parts[0], out var id))
{
throw new ArgumentException("Named id must be a valid guid.");
}
return new NamedId<T>(id, string.Join(",", parts.Skip(1)));
}
}
}

6
tools/Migrate_01/MigrationPath.cs

@ -13,16 +13,16 @@ using Squidex.Infrastructure.Migrations;
namespace Migrate_01
{
public class MigrationMatrix
public sealed class MigrationPath : IMigrationPath
{
private readonly IServiceProvider serviceProvider;
public MigrationMatrix(IServiceProvider serviceProvider)
public MigrationPath(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public (int Version, IEnumerable<IMigration> Migrations) MigrationPath(int version)
public (int Version, IEnumerable<IMigration> Migrations) GetNext(int version)
{
switch (version)
{

17
tools/Migrate_01/Migrations/ConvertEventStore.cs

@ -5,11 +5,16 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Migrations;
using Squidex.Infrastructure.MongoDb;
namespace Migrate_01.Migrations
{
@ -34,10 +39,16 @@ namespace Migrate_01.Migrations
{
foreach (BsonDocument @event in commit["Events"].AsBsonArray)
{
@event.Remove("EventId");
var meta = JObject.Parse(@event["Metadata"].AsString);
var data = JObject.Parse(@event["Payload"].AsString);
@event["Payload"] = BsonDocument.Parse(@event["Payload"].AsString);
@event["Metadata"] = BsonDocument.Parse(@event["Metadata"].AsString);
if (data.TryGetValue("appId", out var appId))
{
meta[SquidexHeaders.AppId] = NamedId<Guid>.Parse(appId.ToString(), Guid.TryParse).Id;
}
@event.Remove("EventId");
@event["Metadata"] = meta.ToBson();
}
await collection.ReplaceOneAsync(filter.Eq("_id", commit["_id"].AsString), commit);

Loading…
Cancel
Save