mirror of https://github.com/Squidex/squidex.git
20 changed files with 467 additions and 408 deletions
@ -0,0 +1,67 @@ |
|||
// ==========================================================================
|
|||
// MongoAppRepository_SnapshotStore.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using MongoDB.Driver; |
|||
using Squidex.Domain.Apps.Entities.Apps.State; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.States; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.MongoDb.Apps |
|||
{ |
|||
public sealed partial class MongoAppRepository : ISnapshotStore<AppState, Guid> |
|||
{ |
|||
public async Task<(AppState Value, long Version)> ReadAsync(Guid key) |
|||
{ |
|||
var existing = |
|||
await Collection.Find(x => x.Id == key) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existing != null) |
|||
{ |
|||
return (existing.State, existing.Version); |
|||
} |
|||
|
|||
return (null, EtagVersion.NotFound); |
|||
} |
|||
|
|||
public async Task WriteAsync(Guid key, AppState value, long oldVersion, long newVersion) |
|||
{ |
|||
try |
|||
{ |
|||
await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, |
|||
Update |
|||
.Set(x => x.UserIds, value.Contributors.Keys.ToArray()) |
|||
.Set(x => x.Name, value.Name) |
|||
.Set(x => x.State, value) |
|||
.Set(x => x.Version, newVersion), |
|||
Upsert); |
|||
} |
|||
catch (MongoWriteException ex) |
|||
{ |
|||
if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) |
|||
{ |
|||
var existingVersion = |
|||
await Collection.Find(x => x.Id == key) |
|||
.Project<MongoAppEntity>(Projection.Exclude(x => x.Id)).FirstOrDefaultAsync(); |
|||
|
|||
if (existingVersion != null) |
|||
{ |
|||
throw new InconsistentStateException(existingVersion.Version, oldVersion, ex); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
// ==========================================================================
|
|||
// MongoAssetRepository_SnapshotStore.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using MongoDB.Driver; |
|||
using Squidex.Domain.Apps.Entities.Assets.State; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.MongoDb; |
|||
using Squidex.Infrastructure.States; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets |
|||
{ |
|||
public sealed partial class MongoAssetRepository : ISnapshotStore<AssetState, Guid> |
|||
{ |
|||
public async Task<(AssetState Value, long Version)> ReadAsync(Guid key) |
|||
{ |
|||
var existing = |
|||
await Collection.Find(x => x.Id == key) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existing != null) |
|||
{ |
|||
return (existing.State, existing.Version); |
|||
} |
|||
|
|||
return (null, EtagVersion.NotFound); |
|||
} |
|||
|
|||
public async Task WriteAsync(Guid key, AssetState value, long oldVersion, long newVersion) |
|||
{ |
|||
try |
|||
{ |
|||
await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, |
|||
Update |
|||
.Set(x => x.State, value) |
|||
.Set(x => x.Version, newVersion), |
|||
Upsert); |
|||
} |
|||
catch (MongoWriteException ex) |
|||
{ |
|||
if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) |
|||
{ |
|||
var existingVersion = |
|||
await Collection.Find(x => x.Id == key).Only(x => x.Id, x => x.Version) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existingVersion != null) |
|||
{ |
|||
throw new InconsistentStateException(existingVersion["Version"].AsInt64, oldVersion, ex); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,98 @@ |
|||
// ==========================================================================
|
|||
// MongoContentRepository_SnapshotStore.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using MongoDB.Driver; |
|||
using Squidex.Domain.Apps.Core.ConvertContent; |
|||
using Squidex.Domain.Apps.Entities.Contents.State; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.MongoDb; |
|||
using Squidex.Infrastructure.Reflection; |
|||
using Squidex.Infrastructure.States; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.MongoDb.Contents |
|||
{ |
|||
public partial class MongoContentRepository : ISnapshotStore<ContentState, Guid> |
|||
{ |
|||
public async Task<(ContentState Value, long Version)> ReadAsync(Guid key) |
|||
{ |
|||
var contentEntity = |
|||
await Collection.Find(x => x.Id == key).SortByDescending(x => x.Version) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (contentEntity != null) |
|||
{ |
|||
var schema = await appProvider.GetSchemaAsync(contentEntity.AppId, contentEntity.SchemaId, true); |
|||
|
|||
if (schema == null) |
|||
{ |
|||
throw new InvalidOperationException($"Cannot find schema {contentEntity.SchemaId}"); |
|||
} |
|||
|
|||
contentEntity?.ParseData(schema.SchemaDef); |
|||
|
|||
return (SimpleMapper.Map(contentEntity, new ContentState()), contentEntity.Version); |
|||
} |
|||
|
|||
return (null, EtagVersion.NotFound); |
|||
} |
|||
|
|||
public async Task WriteAsync(Guid key, ContentState value, long oldVersion, long newVersion) |
|||
{ |
|||
var documentId = $"{key}_{newVersion}"; |
|||
|
|||
if (value.SchemaId == Guid.Empty) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var schema = await appProvider.GetSchemaAsync(value.AppId, value.SchemaId, true); |
|||
|
|||
if (schema == null) |
|||
{ |
|||
throw new InvalidOperationException($"Cannot find schema {value.SchemaId}"); |
|||
} |
|||
|
|||
var idData = value.Data?.ToIdModel(schema.SchemaDef, true); |
|||
|
|||
var document = SimpleMapper.Map(value, new MongoContentEntity |
|||
{ |
|||
DocumentId = documentId, |
|||
DataText = idData?.ToFullText(), |
|||
DataByIds = idData, |
|||
IsLatest = !value.IsDeleted, |
|||
ReferencedIds = idData?.ToReferencedIds(schema.SchemaDef), |
|||
}); |
|||
|
|||
try |
|||
{ |
|||
await Collection.InsertOneAsync(document); |
|||
await Collection.UpdateManyAsync(x => x.Id == value.Id && x.Version < value.Version, Update.Set(x => x.IsLatest, false)); |
|||
} |
|||
catch (MongoWriteException ex) |
|||
{ |
|||
if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) |
|||
{ |
|||
var existingVersion = |
|||
await Collection.Find(x => x.Id == value.Id && x.IsLatest).Only(x => x.Id, x => x.Version) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existingVersion != null) |
|||
{ |
|||
throw new InconsistentStateException(existingVersion["vs"].AsInt64, oldVersion, ex); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
// ==========================================================================
|
|||
// MongoRuleRepository_SnapshotStore.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using MongoDB.Driver; |
|||
using Squidex.Domain.Apps.Entities.Rules.State; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.MongoDb; |
|||
using Squidex.Infrastructure.States; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.MongoDb.Rules |
|||
{ |
|||
public sealed partial class MongoRuleRepository : ISnapshotStore<RuleState, Guid> |
|||
{ |
|||
public async Task<(RuleState Value, long Version)> ReadAsync(Guid key) |
|||
{ |
|||
var existing = |
|||
await Collection.Find(x => x.Id == key) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existing != null) |
|||
{ |
|||
return (existing.State, existing.Version); |
|||
} |
|||
|
|||
return (null, EtagVersion.NotFound); |
|||
} |
|||
|
|||
public async Task WriteAsync(Guid key, RuleState value, long oldVersion, long newVersion) |
|||
{ |
|||
try |
|||
{ |
|||
await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, |
|||
Update |
|||
.Set(x => x.State, value) |
|||
.Set(x => x.AppId, value.AppId) |
|||
.Set(x => x.IsDeleted, value.IsDeleted) |
|||
.Set(x => x.Version, newVersion), |
|||
Upsert); |
|||
} |
|||
catch (MongoWriteException ex) |
|||
{ |
|||
if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) |
|||
{ |
|||
var existingVersion = |
|||
await Collection.Find(x => x.Id == key).Only(x => x.Id, x => x.Version) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existingVersion != null) |
|||
{ |
|||
throw new InconsistentStateException(existingVersion["Version"].AsInt64, oldVersion, ex); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
// ==========================================================================
|
|||
// MongoSchemaRepository_SnapshotStore.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using MongoDB.Driver; |
|||
using Squidex.Domain.Apps.Entities.Schemas.State; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.MongoDb; |
|||
using Squidex.Infrastructure.States; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas |
|||
{ |
|||
public sealed partial class MongoSchemaRepository : ISnapshotStore<SchemaState, Guid> |
|||
{ |
|||
public async Task<(SchemaState Value, long Version)> ReadAsync(Guid key) |
|||
{ |
|||
var existing = |
|||
await Collection.Find(x => x.Id == key) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existing != null) |
|||
{ |
|||
return (existing.State, existing.Version); |
|||
} |
|||
|
|||
return (null, EtagVersion.NotFound); |
|||
} |
|||
|
|||
public async Task WriteAsync(Guid key, SchemaState value, long oldVersion, long newVersion) |
|||
{ |
|||
try |
|||
{ |
|||
await Collection.UpdateOneAsync(x => x.Id == key && x.Version == oldVersion, |
|||
Update |
|||
.Set(x => x.State, value) |
|||
.Set(x => x.AppId, value.AppId) |
|||
.Set(x => x.Name, value.Name) |
|||
.Set(x => x.Version, newVersion), |
|||
Upsert); |
|||
} |
|||
catch (MongoWriteException ex) |
|||
{ |
|||
if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) |
|||
{ |
|||
var existingVersion = |
|||
await Collection.Find(x => x.Id == key).Only(x => x.Version) |
|||
.FirstOrDefaultAsync(); |
|||
|
|||
if (existingVersion != null) |
|||
{ |
|||
throw new InconsistentStateException(existingVersion["Version"].AsInt64, oldVersion, ex); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue