public async Task <IResultList <IAssetEntity> > QueryAsync(Guid appId, HashSet <Guid> ids) { using (Profiler.TraceMethod <MongoAssetRepository>("QueryAsyncByIds")) { var find = Collection.Find(x => ids.Contains(x.Id)).SortByDescending(x => x.LastModified); var assetItems = find.ToListAsync(); var assetCount = find.CountDocumentsAsync(); await Task.WhenAll(assetItems, assetCount); return(ResultList.Create(assetCount.Result, assetItems.Result.OfType <IAssetEntity>())); } }
public async Task Should_load_assets_with_query_and_resolve_tags() { A.CallTo(() => assetRepository.QueryAsync(appId, A <Query> .Ignored)) .Returns(ResultList.Create(8, CreateAsset(Guid.NewGuid(), "id1", "id2"), CreateAsset(Guid.NewGuid(), "id2", "id3"))); var result = await sut.QueryAsync(context, Q.Empty); Assert.Equal(8, result.Total); Assert.Equal(2, result.Count); Assert.Equal(HashSet.Of("name1", "name2"), result[0].Tags); Assert.Equal(HashSet.Of("name2", "name3"), result[1].Tags); }
public async Task QueryAll_should_not_return_contents_if_user_has_no_permission() { var ctx = CreateContext(isFrontend: false, allowSchema: false); var ids = Enumerable.Range(0, 5).Select(x => DomainId.NewGuid()).ToList(); var q = Q.Empty.WithIds(ids); A.CallTo(() => contentRepository.QueryAsync(ctx.App, A <List <ISchemaEntity> > .That.Matches(x => x.Count == 0), q, SearchScope.All)) .Returns(ResultList.Create(0, ids.Select(CreateContent))); var result = await sut.QueryAsync(ctx, q); Assert.Empty(result); }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, List <ISchemaEntity> schemas, Q q) { Guard.NotNull(app, nameof(app)); Guard.NotNull(q, nameof(q)); try { var query = q.Query.AdjustToModel(null); List <DomainId>?fullTextIds = null; if (!string.IsNullOrWhiteSpace(query.FullText)) { throw new NotSupportedException(); } var filter = CreateFilter(app.Id, schemas.Select(x => x.Id), fullTextIds, query, q.Reference); var contentEntities = await FindContentsAsync(query, filter); var contentTotal = (long)contentEntities.Count; if (contentEntities.Count > 0) { if (contentTotal >= q.Query.Take || q.Query.Skip > 0) { contentTotal = await Collection.Find(filter).CountDocumentsAsync(); } var contentSchemas = schemas.ToDictionary(x => x.Id); foreach (var entity in contentEntities) { entity.ParseData(contentSchemas[entity.IndexedSchemaId].SchemaDef, DataConverter); } } return(ResultList.Create <IContentEntity>(contentTotal, contentEntities)); } catch (MongoCommandException ex) when(ex.Code == 96) { throw new DomainException(T.Get("common.resultTooLarge")); } catch (MongoQueryException ex) when(ex.Message.Contains("17406")) { throw new DomainException(T.Get("common.resultTooLarge")); } }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, HashSet <Guid> ids, Status[] status, bool useDraft) { var find = Collection.Find(FilterFactory.IdsBySchema(schema.Id, ids, status)); var contentItems = find.WithoutDraft(useDraft).ToListAsync(); var contentCount = find.CountDocumentsAsync(); await Task.WhenAll(contentItems, contentCount); foreach (var entity in contentItems.Result) { entity.ParseData(schema.SchemaDef, serializer); } return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result)); }
public async Task <IResultList <IRuleEventEntity> > QueryByAppAsync(DomainId appId, DomainId?ruleId = null, int skip = 0, int take = 20) { var filter = Filter.Eq(x => x.AppId, appId); if (ruleId.HasValue && ruleId.Value != DomainId.Empty) { filter = Filter.And(filter, Filter.Eq(x => x.RuleId, ruleId.Value)); } var taskForItems = Collection.Find(filter).Skip(skip).Limit(take).SortByDescending(x => x.Created).ToListAsync(); var taskForCount = Collection.Find(filter).CountDocumentsAsync(); var(items, total) = await AsyncHelper.WhenAll(taskForItems, taskForCount); return(ResultList.Create(total, items)); }
public async Task Should_query_contents_with_matching_permissions() { var requestContext = CreateContext(allowSchema: false); var ids = Enumerable.Range(0, 5).Select(x => DomainId.NewGuid()).ToList(); var q = Q.Empty.WithIds(ids); A.CallTo(() => contentRepository.QueryAsync(requestContext.App, A <List <ISchemaEntity> > .That.Matches(x => x.Count == 0), q, SearchScope.All)) .Returns(ResultList.Create(0, ids.Select(CreateContent))); var result = await sut.QueryAsync(requestContext, q); Assert.Empty(result); }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, HashSet <Guid> ids) { var find = Collection.Find(x => ids.Contains(x.Id) && x.IsLatest); var contentItems = find.ToListAsync(); var contentCount = find.CountAsync(); await Task.WhenAll(contentItems, contentCount); foreach (var entity in contentItems.Result) { entity.ParseData(schema.SchemaDef); } return(ResultList.Create <IContentEntity>(contentItems.Result, contentCount.Result)); }
public async Task <IResultList <IRuleEventEntity> > QueryByAppAsync(Guid appId, Guid?ruleId = null, int skip = 0, int take = 20) { var filter = Filter.Eq(x => x.AppId, appId); if (ruleId.HasValue) { filter = Filter.And(filter, Filter.Eq(x => x.RuleId, ruleId)); } var taskForItems = Collection.Find(filter).Skip(skip).Limit(take).SortByDescending(x => x.Created).ToListAsync(); var taskForCount = Collection.Find(filter).CountDocumentsAsync(); await Task.WhenAll(taskForItems, taskForCount); return(ResultList.Create(taskForCount.Result, taskForItems.Result)); }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, Q q, SearchScope scope) { Guard.NotNull(app, nameof(app)); Guard.NotNull(schema, nameof(schema)); Guard.NotNull(q, nameof(q)); try { var query = q.Query.AdjustToModel(schema.SchemaDef); List <DomainId>?fullTextIds = null; if (!string.IsNullOrWhiteSpace(query.FullText)) { var searchFilter = SearchFilter.ShouldHaveSchemas(schema.Id); fullTextIds = await indexer.SearchAsync(query.FullText, app, searchFilter, scope); if (fullTextIds?.Count == 0) { return(ResultList.CreateFrom <IContentEntity>(0)); } } var filter = CreateFilter(schema.AppId.Id, Enumerable.Repeat(schema.Id, 1), fullTextIds, query, q.Reference); var contentCount = Collection.Find(filter).CountDocumentsAsync(); var contentItems = FindContentsAsync(query, filter); var(items, total) = await AsyncHelper.WhenAll(contentItems, contentCount); foreach (var entity in items) { entity.ParseData(schema.SchemaDef, DataConverter); } return(ResultList.Create <IContentEntity>(total, items)); } catch (MongoCommandException ex) when(ex.Code == 96) { throw new DomainException(T.Get("common.resultTooLarge")); } catch (MongoQueryException ex) when(ex.Message.Contains("17406")) { throw new DomainException(T.Get("common.resultTooLarge")); } }
public async Task <IResultList <IContentEntity> > DoAsync(IAppEntity app, ISchemaEntity schema, ClrQuery query, SearchScope scope) { Guard.NotNull(app, nameof(app)); Guard.NotNull(schema, nameof(schema)); Guard.NotNull(query, nameof(query)); try { query = query.AdjustToModel(schema.SchemaDef); List <Guid>?fullTextIds = null; if (!string.IsNullOrWhiteSpace(query.FullText)) { var searchFilter = SearchFilter.ShouldHaveSchemas(schema.Id); fullTextIds = await indexer.SearchAsync(query.FullText, app, searchFilter, scope); if (fullTextIds?.Count == 0) { return(ResultList.CreateFrom <IContentEntity>(0)); } } var filter = CreateFilter(schema.Id, fullTextIds, query); var contentCount = Collection.Find(filter).CountDocumentsAsync(); var contentItems = FindContentsAsync(query, filter); await Task.WhenAll(contentItems, contentCount); foreach (var entity in contentItems.Result) { entity.ParseData(schema.SchemaDef, converter); } return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result)); } catch (MongoCommandException ex) when(ex.Code == 96) { throw new DomainException("Result set is too large to be retrieved. Use $take parameter to reduce the number of items."); } catch (MongoQueryException ex) when(ex.Message.Contains("17406")) { throw new DomainException("Result set is too large to be retrieved. Use $take parameter to reduce the number of items."); } }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, ODataUriParser odataQuery, Status[] status = null, bool useDraft = false) { try { var propertyCalculator = FindExtensions.CreatePropertyCalculator(schema.SchemaDef, useDraft); var filter = FindExtensions.BuildQuery(odataQuery, schema.Id, status, propertyCalculator); var contentCount = Collection.Find(filter).CountDocumentsAsync(); var contentItems = Collection.Find(filter) .ContentTake(odataQuery) .ContentSkip(odataQuery) .ContentSort(odataQuery, propertyCalculator) .Not(x => x.DataText) .ToListAsync(); await Task.WhenAll(contentItems, contentCount); foreach (var entity in contentItems.Result) { entity.ParseData(schema.SchemaDef); } return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result)); } catch (NotSupportedException) { throw new ValidationException("This odata operation is not supported."); } catch (NotImplementedException) { throw new ValidationException("This odata operation is not supported."); } catch (MongoQueryException ex) { if (ex.Message.Contains("17406")) { throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items."); } else { throw; } } }
public async Task QueryAll_should_return_contents(int isFrontend, int unpublished, SearchScope scope) { var ctx = CreateContext(isFrontend: isFrontend == 1, allowSchema: true) .WithUnpublished(unpublished == 1); var ids = Enumerable.Range(0, 5).Select(x => DomainId.NewGuid()).ToList(); var q = Q.Empty.WithIds(ids); A.CallTo(() => contentRepository.QueryAsync(ctx.App, A <List <ISchemaEntity> > .That.Matches(x => x.Count == 1), q, scope)) .Returns(ResultList.Create(5, ids.Select(CreateContent))); var result = await sut.QueryAsync(ctx, q); Assert.Equal(ids, result.Select(x => x.Id).ToList()); }
public async Task <IResultList <IUser> > QueryAsync(IEnumerable <string> ids) { Guard.NotNull(ids, nameof(ids)); ids = ids.Where(userFactory.IsId); if (!ids.Any()) { return(ResultList.CreateFrom <IUser>(0)); } var users = userManager.Users.Where(x => ids.Contains(x.Id)).ToList(); var resolved = await ResolveAsync(users); return(ResultList.Create(users.Count, resolved)); }
public async Task <IResultList <IEnrichedAssetEntity> > QueryAsync(Context context, DomainId?parentId, Q q) { Guard.NotNull(context, nameof(context)); Guard.NotNull(q, nameof(q)); q = await queryParser.ParseQueryAsync(context, q); var assets = await assetRepository.QueryAsync(context.App.Id, parentId, q); if (q.Ids != null && q.Ids.Count > 0) { assets = assets.SortSet(x => x.Id, q.Ids); } var enriched = await assetEnricher.EnrichAsync(assets, context); return(ResultList.Create(assets.Total, enriched)); }
public async Task <IResultList <IContentEntity> > QueryAsync(DomainId appId, List <ISchemaEntity> schemas, Q q, CancellationToken ct) { Guard.NotNull(q, nameof(q)); if (q.ScheduledFrom == null || q.ScheduledTo == null) { return(ResultList.CreateFrom <IContentEntity>(0)); } var filter = CreateFilter(appId, schemas.Select(x => x.Id), q.ScheduledFrom.Value, q.ScheduledTo.Value); var contentEntities = await Collection.Find(filter).Limit(100).ToListAsync(ct); var contentTotal = (long)contentEntities.Count; return(ResultList.Create(contentTotal, contentEntities)); }
public async Task <IResultList <UserNotification> > QueryAsync(string appId, string userId, UserNotificationQuery query, CancellationToken ct) { var filters = new List <FilterDefinition <UserNotification> > { Filter.Eq(x => x.AppId, appId), Filter.Eq(x => x.UserId, userId) }; if (query.After != default) { filters.Add(Filter.Gte(x => x.Updated, query.After)); } switch (query.Scope) { case UserNotificationQueryScope.Deleted: { filters.Add(Filter.Eq(x => x.IsDeleted, true)); break; } case UserNotificationQueryScope.NonDeleted: { filters.Add( Filter.Or( Filter.Exists(x => x.IsDeleted, false), Filter.Eq(x => x.IsDeleted, false))); break; } } var filter = Filter.And(filters); var resultItems = await Collection.Find(filter).SortByDescending(x => x.Created).ToListAsync(query, ct); var resultTotal = (long)resultItems.Count; if (query.ShouldQueryTotal(resultItems)) { resultTotal = await Collection.Find(filter).CountDocumentsAsync(ct); } return(ResultList.Create(resultTotal, resultItems)); }
public async Task <IResultList <IAssetEntity> > QueryAsync(Guid appId, string query = null) { using (Profiler.TraceMethod <MongoAssetRepository>("QueryAsyncByQuery")) { try { var odataQuery = EdmAssetModel.Edm.ParseQuery(query); var filter = FindExtensions.BuildQuery(odataQuery, appId, tagService); var contentCount = Collection.Find(filter).CountDocumentsAsync(); var contentItems = Collection.Find(filter) .AssetTake(odataQuery) .AssetSkip(odataQuery) .AssetSort(odataQuery) .ToListAsync(); await Task.WhenAll(contentItems, contentCount); return(ResultList.Create <IAssetEntity>(contentCount.Result, contentItems.Result)); } catch (NotSupportedException) { throw new ValidationException("This odata operation is not supported."); } catch (NotImplementedException) { throw new ValidationException("This odata operation is not supported."); } catch (MongoQueryException ex) { if (ex.Message.Contains("17406")) { throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items."); } else { throw; } } } }
public async Task <IResultList <Media> > QueryAsync(string appId, MediaQuery query, CancellationToken ct = default) { using (Telemetry.Activities.StartActivity("MongoDbMediaRepository/QueryAsync")) { var filter = BuildFilter(appId, query); var resultItems = await Collection.Find(filter).ToListAsync(query, ct); var resultTotal = (long)resultItems.Count; if (query.ShouldQueryTotal(resultItems)) { resultTotal = await Collection.Find(filter).CountDocumentsAsync(ct); } return(ResultList.Create(resultTotal, resultItems.Select(x => x.ToMedia()))); } }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, HashSet <Guid> ids, Status[] status = null) { var find = status != null && status.Length > 0 ? Collection.Find(x => x.IndexedSchemaId == schema.Id && ids.Contains(x.Id) && x.IsDeleted != true && status.Contains(x.Status)) : Collection.Find(x => x.IndexedSchemaId == schema.Id && ids.Contains(x.Id)); var contentItems = find.Not(x => x.DataText).ToListAsync(); var contentCount = find.CountDocumentsAsync(); await Task.WhenAll(contentItems, contentCount); foreach (var entity in contentItems.Result) { entity.ParseData(schema.SchemaDef, Serializer); } return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result)); }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, bool inDraft, Query query, bool includeDraft = true) { Guard.NotNull(app, nameof(app)); Guard.NotNull(schema, nameof(schema)); Guard.NotNull(status, nameof(status)); Guard.NotNull(query, nameof(query)); using (Profiler.TraceMethod <MongoContentRepository>("QueryAsyncByQuery")) { var fullTextIds = await indexer.SearchAsync(query.FullText, app, schema.Id, inDraft?Scope.Draft : Scope.Published); if (fullTextIds?.Count == 0) { return(ResultList.Create <IContentEntity>(0)); } return(await contents.QueryAsync(schema, query, fullTextIds, status, inDraft, includeDraft)); } }
public async Task <IResultList <IRuleEventEntity> > QueryByAppAsync(DomainId appId, DomainId?ruleId = null, int skip = 0, int take = 20) { var filter = Filter.Eq(x => x.AppId, appId); if (ruleId.HasValue && ruleId.Value != DomainId.Empty) { filter = Filter.And(filter, Filter.Eq(x => x.RuleId, ruleId.Value)); } var ruleEventEntities = await Collection.Find(filter).Skip(skip).Limit(take).SortByDescending(x => x.Created).ToListAsync(); var ruleEventTotal = (long)ruleEventEntities.Count; if (ruleEventTotal >= take || skip > 0) { ruleEventTotal = await Collection.Find(filter).CountDocumentsAsync(); } return(ResultList.Create(ruleEventTotal, ruleEventEntities)); }
public async Task Should_load_assets_from_ids_and_resolve_tags() { var id1 = Guid.NewGuid(); var id2 = Guid.NewGuid(); var ids = HashSet.Of(id1, id2); A.CallTo(() => assetRepository.QueryAsync(appId, A <HashSet <Guid> > .That.IsSameSequenceAs(ids))) .Returns(ResultList.Create(8, CreateAsset(id1, "id1", "id2", "id3"), CreateAsset(id2))); var result = await sut.QueryAsync(context, Q.Empty.WithIds(ids)); Assert.Equal(8, result.Total); Assert.Equal(2, result.Count); Assert.Equal(HashSet.Of("name1", "name2", "name3"), result[0].Tags); Assert.Empty(result[1].Tags); }
public async Task <IResultList <IEnrichedAssetEntity> > QueryAsync(Context context, Guid?parentId, Q query) { Guard.NotNull(context, nameof(context)); Guard.NotNull(query, nameof(query)); IResultList <IAssetEntity> assets; if (query.Ids != null && query.Ids.Count > 0) { assets = await QueryByIdsAsync(context, query); } else { assets = await QueryByQueryAsync(context, parentId, query); } var enriched = await assetEnricher.EnrichAsync(assets, context); return(ResultList.Create(assets.Total, enriched)); }
public async Task <IResultList <IAssetEntity> > QueryAsync(DomainId appId, DomainId?parentId, Q q) { using (Profiler.TraceMethod <MongoAssetRepository>("QueryAsyncByQuery")) { try { if (q.Ids != null && q.Ids.Count > 0) { var assetEntities = await Collection.Find(BuildFilter(appId, q.Ids.ToHashSet())).SortByDescending(x => x.LastModified) .QueryLimit(q.Query) .QuerySkip(q.Query) .ToListAsync(); return(ResultList.Create(assetEntities.Count, assetEntities.OfType <IAssetEntity>())); } else { var query = q.Query.AdjustToModel(); var filter = query.BuildFilter(appId, parentId); var assetCount = Collection.Find(filter).CountDocumentsAsync(); var assetItems = Collection.Find(filter) .QueryLimit(query) .QuerySkip(query) .QuerySort(query) .ToListAsync(); var(items, total) = await AsyncHelper.WhenAll(assetItems, assetCount); return(ResultList.Create <IAssetEntity>(total, items)); } } catch (MongoQueryException ex) when(ex.Message.Contains("17406")) { throw new DomainException(T.Get("common.resultTooLarge")); } } }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, Q q) { Guard.NotNull(app, nameof(app)); Guard.NotNull(schema, nameof(schema)); Guard.NotNull(q, nameof(q)); try { var query = q.Query.AdjustToModel(app.Id, schema.SchemaDef); var filter = CreateFilter(schema.AppId.Id, Enumerable.Repeat(schema.Id, 1), query, q.Reference); var contentEntities = await FindContentsAsync(query, filter); var contentTotal = (long)contentEntities.Count; if (contentEntities.Count > 0) { if (contentTotal >= q.Query.Take || q.Query.Skip > 0) { contentTotal = await Collection.Find(filter).CountDocumentsAsync(); } foreach (var entity in contentEntities) { entity.ParseData(schema.SchemaDef, DataConverter); } } return(ResultList.Create <IContentEntity>(contentTotal, contentEntities)); } catch (MongoCommandException ex) when(ex.Code == 96) { throw new DomainException(T.Get("common.resultTooLarge")); } catch (MongoQueryException ex) when(ex.Message.Contains("17406")) { throw new DomainException(T.Get("common.resultTooLarge")); } }
public async Task <IResultList <LogEntry> > QueryAsync(string appId, LogQuery query, CancellationToken ct = default) { using (var activity = Telemetry.Activities.StartActivity("MongoDbLogRepository/DeleteAsync")) { var filter = BuildFilter(appId, query); var resultItems = await Collection.Find(filter).SortByDescending(x => x.Entry.LastSeen).ToListAsync(query, ct); var resultTotal = (long)resultItems.Count; if (query.ShouldQueryTotal(resultItems)) { resultTotal = await Collection.Find(filter).CountDocumentsAsync(ct); } activity?.SetTag("numResults", resultItems.Count); activity?.SetTag("numTotal", resultTotal); return(ResultList.Create(resultTotal, resultItems.Select(x => x.ToEntry()))); } }
public async Task <IResultList <ChannelTemplate <T> > > QueryAsync(string appId, ChannelTemplateQuery query, CancellationToken ct = default) { using (var activity = Telemetry.Activities.StartActivity("MongoDbChannelTemplateRepository/QueryAsync")) { var filter = BuildFilter(appId, query); var resultItems = await Collection.Find(filter).ToListAsync(query, ct); var resultTotal = (long)resultItems.Count; if (query.ShouldQueryTotal(resultItems)) { resultTotal = await Collection.Find(filter).CountDocumentsAsync(ct); } activity?.SetTag("numResults", resultItems.Count); activity?.SetTag("numTotal", resultTotal); return(ResultList.Create(resultTotal, resultItems.Select(x => x.ToChannelTemplate()))); } }
public async Task <IResultList <IContentEntity> > QueryAsync(IAppEntity app, ISchemaEntity schema, Query query, Status[] status = null, bool useDraft = false) { try { query = query.AdjustToModel(schema.SchemaDef, useDraft); var filter = query.ToFilter(schema.Id, status); var contentCount = Collection.Find(filter).CountDocumentsAsync(); var contentItems = Collection.Find(filter) .ContentTake(query) .ContentSkip(query) .ContentSort(query) .Not(x => x.DataText) .ToListAsync(); await Task.WhenAll(contentItems, contentCount); foreach (var entity in contentItems.Result) { entity.ParseData(schema.SchemaDef, Serializer); } return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result)); } catch (MongoQueryException ex) { if (ex.Message.Contains("17406")) { throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items."); } else { throw; } } }
public async Task <IResultList <IContentEntity> > QueryAsync(ISchemaEntity schema, ClrQuery query, List <Guid>?ids, Status[]?status, bool inDraft, bool includeDraft = true) { try { query = query.AdjustToModel(schema.SchemaDef, inDraft); var filter = query.ToFilter(schema.Id, ids, status); var contentCount = Collection.Find(filter).CountDocumentsAsync(); var contentItems = Collection.Find(filter) .WithoutDraft(includeDraft) .ContentTake(query) .ContentSkip(query) .ContentSort(query) .ToListAsync(); await Task.WhenAll(contentItems, contentCount); foreach (var entity in contentItems.Result) { entity.ParseData(schema.SchemaDef, serializer); } return(ResultList.Create <IContentEntity>(contentCount.Result, contentItems.Result)); } catch (MongoQueryException ex) { if (ex.Message.Contains("17406")) { throw new DomainException("Result set is too large to be retrieved. Use $top parameter to reduce the number of items."); } else { throw; } } }