// ========================================================================== // MongoContentRepository.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.OData.UriParser; using MongoDB.Bson; using MongoDB.Driver; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Read.Apps; using Squidex.Domain.Apps.Read.Contents; using Squidex.Domain.Apps.Read.Contents.Repositories; using Squidex.Domain.Apps.Read.MongoDb.Contents.Visitors; using Squidex.Domain.Apps.Read.Schemas; using Squidex.Domain.Apps.Read.Schemas.Services; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Domain.Apps.Read.MongoDb.Contents { public partial class MongoContentRepository : IContentRepository, IEventConsumer { private const string Prefix = "Projections_Content_"; private readonly IMongoDatabase database; private readonly ISchemaProvider schemas; protected static FilterDefinitionBuilder Filter { get { return Builders.Filter; } } protected static UpdateDefinitionBuilder Update { get { return Builders.Update; } } protected static ProjectionDefinitionBuilder Projection { get { return Builders.Projection; } } protected static IndexKeysDefinitionBuilder Index { get { return Builders.IndexKeys; } } public MongoContentRepository(IMongoDatabase database, ISchemaProvider schemas) { Guard.NotNull(database, nameof(database)); Guard.NotNull(schemas, nameof(schemas)); this.database = database; this.schemas = schemas; } public async Task> QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, ODataUriParser odataQuery) { var collection = GetCollection(app.Id); IFindFluent cursor; try { cursor = collection .Find(odataQuery, schema.Id, schema.SchemaDef, status) .Take(odataQuery) .Skip(odataQuery) .Sort(odataQuery, schema.SchemaDef); } catch (NotSupportedException) { throw new ValidationException("This odata operation is not supported."); } catch (NotImplementedException) { throw new ValidationException("This odata operation is not supported."); } var contentEntities = await cursor.ToListAsync(); foreach (var entity in contentEntities) { entity.ParseData(schema.SchemaDef); } return contentEntities; } public Task CountAsync(IAppEntity app, ISchemaEntity schema, Status[] status, ODataUriParser odataQuery) { var collection = GetCollection(app.Id); IFindFluent cursor; try { cursor = collection.Find(odataQuery, schema.Id, schema.SchemaDef, status); } catch (NotSupportedException) { throw new ValidationException("This odata operation is not supported."); } catch (NotImplementedException) { throw new ValidationException("This odata operation is not supported."); } return cursor.CountAsync(); } public async Task CountAsync(IAppEntity app, ISchemaEntity schema, Status[] status, HashSet ids) { var collection = GetCollection(app.Id); var contentsCount = await collection.Find(x => ids.Contains(x.Id)) .CountAsync(); return contentsCount; } public async Task> QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, HashSet ids) { var collection = GetCollection(app.Id); var contentEntities = await collection.Find(x => ids.Contains(x.Id)) .ToListAsync(); foreach (var entity in contentEntities) { entity.ParseData(schema.SchemaDef); } return contentEntities.OfType().ToList(); } public async Task> QueryNotFoundAsync(Guid appId, Guid schemaId, IList contentIds) { var collection = GetCollection(appId); var contentEntities = await collection.Find(x => contentIds.Contains(x.Id) && x.AppId == appId).Project(Projection.Include(x => x.Id)) .ToListAsync(); return contentIds.Except(contentEntities.Select(x => Guid.Parse(x["_id"].AsString))).ToList(); } public async Task FindContentAsync(IAppEntity app, ISchemaEntity schema, Guid id) { var collection = GetCollection(app.Id); var contentEntity = await collection.Find(x => x.Id == id) .FirstOrDefaultAsync(); contentEntity?.ParseData(schema.SchemaDef); return contentEntity; } private async Task ForSchemaAsync(Guid appId, Guid schemaId, Func, ISchemaEntity, Task> action) { var collection = GetCollection(appId); var schema = await schemas.FindSchemaByIdAsync(schemaId, true); if (schema == null) { return; } await action(collection, schema); } } }