diff --git a/backend/src/Squidex.Domain.Apps.Entities/DomainObjectState.cs b/backend/src/Squidex.Domain.Apps.Entities/DomainObjectState.cs index 3578b072a..83c55edbf 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/DomainObjectState.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/DomainObjectState.cs @@ -69,13 +69,15 @@ namespace Squidex.Domain.Apps.Entities clone.Id = headers.AggregateId(); } + var timestamp = headers.Timestamp(); + if (clone.CreatedBy == null) { - clone.Created = headers.Timestamp(); + clone.Created = timestamp; clone.CreatedBy = payload.Actor; } - clone.LastModified = headers.Timestamp(); + clone.LastModified = timestamp; clone.LastModifiedBy = payload.Actor; return (clone as T)!; diff --git a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/StreamPosition.cs b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/StreamPosition.cs index dcfb32884..81e9e8fd8 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/StreamPosition.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/StreamPosition.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System.Text; using MongoDB.Bson; namespace Squidex.Infrastructure.EventSourcing @@ -34,15 +35,17 @@ namespace Squidex.Infrastructure.EventSourcing public static implicit operator string(StreamPosition position) { - var parts = new object[] - { - position.Timestamp.Timestamp, - position.Timestamp.Increment, - position.CommitOffset, - position.CommitSize - }; + var sb = new StringBuilder(); + + sb.Append(position.Timestamp.Timestamp); + sb.Append(","); + sb.Append(position.Timestamp.Increment); + sb.Append(","); + sb.Append(position.CommitOffset); + sb.Append(","); + sb.Append(position.CommitSize); - return string.Join("-", parts); + return sb.ToString(); } public static implicit operator StreamPosition(string? position) diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonHelper.cs b/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonHelper.cs index 578683590..dc6c45fb4 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonHelper.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/BsonHelper.cs @@ -9,13 +9,26 @@ namespace Squidex.Infrastructure.MongoDb { public static class BsonHelper { + private const string TypeBson = "§type"; + private const string TypeJson = "$json"; + public static string UnescapeBson(this string value) { + if (value == TypeBson) + { + return TypeJson; + } + return ReplaceFirstCharacter(value, '§', '$'); } public static string EscapeJson(this string value) { + if (value == TypeJson) + { + return TypeBson; + } + return ReplaceFirstCharacter(value, '$', '§'); } diff --git a/backend/src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs b/backend/src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs index e5014a77d..aa45e976c 100644 --- a/backend/src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs +++ b/backend/src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs @@ -29,9 +29,9 @@ namespace Squidex.Infrastructure.Json.Newtonsoft return result; } - private static bool ParseString(string value, out string result) + private static bool ParseString(ReadOnlySpan value, out string result) { - result = value; + result = new string(value); return true; } diff --git a/backend/src/Squidex.Infrastructure/Language.cs b/backend/src/Squidex.Infrastructure/Language.cs index f4497c89a..1b5dd27a2 100644 --- a/backend/src/Squidex.Infrastructure/Language.cs +++ b/backend/src/Squidex.Infrastructure/Language.cs @@ -56,14 +56,14 @@ namespace Squidex.Infrastructure public static bool IsValidLanguage(string iso2Code) { - Guard.NotNullOrEmpty(iso2Code); + Guard.NotNull(iso2Code); return AllLanguagesField.ContainsKey(iso2Code); } public static bool TryGetLanguage(string iso2Code, [MaybeNullWhen(false)] out Language language) { - Guard.NotNullOrEmpty(iso2Code); + Guard.NotNull(iso2Code); return AllLanguagesField.TryGetValue(iso2Code, out language!); } diff --git a/backend/src/Squidex.Infrastructure/NamedId{T}.cs b/backend/src/Squidex.Infrastructure/NamedId{T}.cs index f32893219..5ab243df4 100644 --- a/backend/src/Squidex.Infrastructure/NamedId{T}.cs +++ b/backend/src/Squidex.Infrastructure/NamedId{T}.cs @@ -12,7 +12,7 @@ using System.Diagnostics.CodeAnalysis; namespace Squidex.Infrastructure { - public delegate bool Parser(string input, out T result); + public delegate bool Parser(ReadOnlySpan input, out T result); [Equals(DoNotAddEqualityOperators = true)] public sealed class NamedId where T : notnull @@ -42,11 +42,13 @@ namespace Squidex.Infrastructure { if (value != null) { + var span = value.AsSpan(); + if (typeof(T) == typeof(Guid)) { if (value.Length > GuidLength + 1 && value[GuidLength] == ',') { - if (parser(value.Substring(0, GuidLength), out var id)) + if (parser(span.Slice(0, GuidLength), out var id)) { result = new NamedId(id, value.Substring(GuidLength + 1)); @@ -60,7 +62,7 @@ namespace Squidex.Infrastructure if (index > 0 && index < value.Length - 1) { - if (parser(value.Substring(0, index), out var id)) + if (parser(span.Slice(0, index), out var id)) { result = new NamedId(id, value.Substring(index + 1));