Browse Source

Single endpoint for assets.

pull/214/head
Sebastian Stehle 8 years ago
parent
commit
b941d0b0e0
  1. 77
      src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs
  2. 10
      src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository.cs
  3. 26
      src/Squidex.Domain.Apps.Entities/AppProvider.cs
  4. 5
      src/Squidex.Domain.Apps.Entities/Assets/Repositories/IAssetRepository.cs
  5. 2
      src/Squidex.Domain.Apps.Entities/Schemas/Repositories/ISchemaRepository.cs
  6. 17
      src/Squidex.Infrastructure/IResultList.cs
  7. 31
      src/Squidex.Infrastructure/ResultList.cs
  8. 9
      src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs
  9. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTests.cs

77
src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs

@ -44,40 +44,43 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
.Descending(x => x.State.LastModified));
}
public async Task<(AssetState Value, long Version)> ReadAsync(Guid key)
public async Task<IResultList<IAssetEntity>> QueryAsync(Guid appId, HashSet<string> mimeTypes = null, HashSet<Guid> ids = null, string query = null, int take = 10, int skip = 0)
{
var existing =
await Collection.Find(x => x.Id == key)
.FirstOrDefaultAsync();
var filters = new List<FilterDefinition<MongoAssetEntity>>
{
Filter.Eq(x => x.State.AppId, appId),
Filter.Eq(x => x.State.IsDeleted, false)
};
if (existing != null)
if (ids != null && ids.Count > 0)
{
return (existing.State, existing.Version);
filters.Add(Filter.In(x => x.Id, ids));
}
return (null, EtagVersion.NotFound);
}
public async Task<IReadOnlyList<IAssetEntity>> QueryAsync(Guid appId, HashSet<string> mimeTypes = null, HashSet<Guid> ids = null, string query = null, int take = 10, int skip = 0)
{
var filter = CreateFilter(appId, mimeTypes, ids, query);
if (mimeTypes != null && mimeTypes.Count > 0)
{
filters.Add(Filter.In(x => x.State.MimeType, mimeTypes));
}
var assetEntities =
await Collection.Find(filter).Skip(skip).Limit(take).SortByDescending(x => x.State.LastModified)
.ToListAsync();
if (!string.IsNullOrWhiteSpace(query))
{
filters.Add(Filter.Regex(x => x.State.FileName, new BsonRegularExpression(query, "i")));
}
return assetEntities.Select(x => x.State).ToList();
}
var filter = Filter.And(filters);
public async Task<long> CountAsync(Guid appId, HashSet<string> mimeTypes = null, HashSet<Guid> ids = null, string query = null)
{
var filter = CreateFilter(appId, mimeTypes, ids, query);
var find = Collection.Find(filter);
var assetsCount =
await Collection.Find(filter)
var assetEntities =
Collection.Find(filter).Skip(skip).Limit(take).SortByDescending(x => x.State.LastModified)
.ToListAsync();
var assetCount =
Collection.Find(filter)
.CountAsync();
return assetsCount;
await Task.WhenAll(assetEntities, assetCount);
return ResultList.Create<IAssetEntity>(assetEntities.Result.Select(x => x.State), assetCount.Result);
}
public async Task<IAssetEntity> FindAssetAsync(Guid id)
@ -87,32 +90,18 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
return state;
}
private static FilterDefinition<MongoAssetEntity> CreateFilter(Guid appId, ICollection<string> mimeTypes, ICollection<Guid> ids, string query)
public async Task<(AssetState Value, long Version)> ReadAsync(Guid key)
{
var filters = new List<FilterDefinition<MongoAssetEntity>>
{
Filter.Eq(x => x.State.AppId, appId),
Filter.Eq(x => x.State.IsDeleted, false)
};
if (ids != null && ids.Count > 0)
{
filters.Add(Filter.In(x => x.Id, ids));
}
if (mimeTypes != null && mimeTypes.Count > 0)
{
filters.Add(Filter.In(x => x.State.MimeType, mimeTypes));
}
var existing =
await Collection.Find(x => x.Id == key)
.FirstOrDefaultAsync();
if (!string.IsNullOrWhiteSpace(query))
if (existing != null)
{
filters.Add(Filter.Regex(x => x.State.FileName, new BsonRegularExpression(query, "i")));
return (existing.State, existing.Version);
}
var filter = Filter.And(filters);
return filter;
return (null, EtagVersion.NotFound);
}
public async Task WriteAsync(Guid key, AssetState value, long oldVersion, long newVersion)

10
src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemaRepository.cs

@ -51,13 +51,13 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas
return (null, EtagVersion.NotFound);
}
public async Task<Guid> FindSchemaIdAsync(Guid appId, string name)
public async Task<IReadOnlyList<Guid>> QuerySchemaIdsAsync(Guid appId, string name)
{
var schemaEntity =
await Collection.Find(x => x.AppId == appId && x.Name == name).Only(x => x.Id)
.FirstOrDefaultAsync();
var schemaEntities =
await Collection.Find(x => x.AppId == appId && x.Name == name).Only(x => x.Id).SortByDescending(x => x.Version)
.ToListAsync();
return schemaEntity != null ? Guid.Parse(schemaEntity["_id"].AsString) : Guid.Empty;
return schemaEntities.Select(x => Guid.Parse(x["_id"].AsString)).ToList();
}
public async Task<IReadOnlyList<Guid>> QuerySchemaIdsAsync(Guid appId)

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

@ -73,25 +73,22 @@ namespace Squidex.Domain.Apps.Entities
return IsNotFound(app) ? null : app.State;
}
public async Task<ISchemaEntity> GetSchemaAsync(Guid appId, string name, bool provideDeleted = false)
public async Task<ISchemaEntity> GetSchemaAsync(Guid appId, Guid id, bool provideDeleted = false)
{
var schemaId = await GetSchemaIdAsync(appId, name);
if (schemaId == Guid.Empty)
{
return null;
}
var schema = await stateFactory.GetSingleAsync<SchemaDomainObject>(schemaId);
var schema = await stateFactory.GetSingleAsync<SchemaDomainObject>(id);
return IsNotFound(provideDeleted, schema) ? null : schema.State;
}
public async Task<ISchemaEntity> GetSchemaAsync(Guid appId, Guid id, bool provideDeleted = false)
public async Task<ISchemaEntity> GetSchemaAsync(Guid appId, string name, bool provideDeleted = false)
{
var schema = await stateFactory.GetSingleAsync<SchemaDomainObject>(id);
var ids = await schemaRepository.QuerySchemaIdsAsync(appId);
return IsNotFound(provideDeleted, schema) ? null : schema.State;
var schemas =
await Task.WhenAll(
ids.Select(id => stateFactory.GetSingleAsync<SchemaDomainObject>(id)));
return schemas.OrderByDescending(x => x.State.LastModified).FirstOrDefault(s => IsNotFound(provideDeleted, s))?.State;
}
public async Task<List<ISchemaEntity>> GetSchemasAsync(Guid appId)
@ -132,11 +129,6 @@ namespace Squidex.Domain.Apps.Entities
return appRepository.FindAppIdByNameAsync(name);
}
private Task<Guid> GetSchemaIdAsync(Guid appId, string name)
{
return schemaRepository.FindSchemaIdAsync(appId, name);
}
private static bool IsNotFound(AppDomainObject app)
{
return app.Version < 0;

5
src/Squidex.Domain.Apps.Entities/Assets/Repositories/IAssetRepository.cs

@ -9,15 +9,14 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Assets.Repositories
{
public interface IAssetRepository
{
Task<IReadOnlyList<IAssetEntity>> QueryAsync(Guid appId, HashSet<string> mimeTypes = null, HashSet<Guid> ids = null, string query = null, int take = 10, int skip = 0);
Task<IResultList<IAssetEntity>> QueryAsync(Guid appId, HashSet<string> mimeTypes = null, HashSet<Guid> ids = null, string query = null, int take = 10, int skip = 0);
Task<IAssetEntity> FindAssetAsync(Guid id);
Task<long> CountAsync(Guid appId, HashSet<string> mimeTypes = null, HashSet<Guid> ids = null, string query = null);
}
}

2
src/Squidex.Domain.Apps.Entities/Schemas/Repositories/ISchemaRepository.cs

@ -14,7 +14,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Repositories
{
public interface ISchemaRepository
{
Task<Guid> FindSchemaIdAsync(Guid appId, string name);
Task<IReadOnlyList<Guid>> QuerySchemaIdsAsync(Guid appId, string name);
Task<IReadOnlyList<Guid>> QuerySchemaIdsAsync(Guid appId);
}

17
src/Squidex.Infrastructure/IResultList.cs

@ -0,0 +1,17 @@
// ==========================================================================
// IResultList.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
namespace Squidex.Infrastructure
{
public interface IResultList<T> : IReadOnlyList<T>
{
long Total { get; }
}
}

31
src/Squidex.Infrastructure/ResultList.cs

@ -0,0 +1,31 @@
// ==========================================================================
// ResultList.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
namespace Squidex.Infrastructure
{
public static class ResultList
{
private sealed class Impl<T> : List<T>, IResultList<T>
{
public long Total { get; }
public Impl(IEnumerable<T> items, long total)
: base(items)
{
Total = total;
}
}
public static IResultList<T> Create<T>(IEnumerable<T> items, long total)
{
return new Impl<T>(items, total);
}
}
}

9
src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs

@ -102,15 +102,12 @@ namespace Squidex.Areas.Api.Controllers.Assets
}
}
var taskForItems = assetRepository.QueryAsync(App.Id, mimeTypeList, idsList, query, take, skip);
var taskForCount = assetRepository.CountAsync(App.Id, mimeTypeList, idsList, query);
await Task.WhenAll(taskForItems, taskForCount);
var assets = await assetRepository.QueryAsync(App.Id, mimeTypeList, idsList, query, take, skip);
var response = new AssetsDto
{
Total = taskForCount.Result,
Items = taskForItems.Result.Select(x => SimpleMapper.Map(x, new AssetDto { FileType = x.FileName.FileType() })).ToArray()
Total = assets.Total,
Items = assets.Select(x => SimpleMapper.Map(x, new AssetDto { FileType = x.FileName.FileType() })).ToArray()
};
return Ok(response);

4
tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTests.cs

@ -137,7 +137,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
var assets = new List<IAssetEntity> { asset };
A.CallTo(() => assetRepository.QueryAsync(app.Id, null, null, "my-query", 30, 5))
.Returns(assets);
.Returns(ResultList.Create(assets, 0));
var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });
@ -546,7 +546,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
.Returns((schema, content));
A.CallTo(() => assetRepository.QueryAsync(app.Id, null, A<HashSet<Guid>>.That.Matches(x => x.Contains(assetRefId)), null, int.MaxValue, 0))
.Returns(refAssets);
.Returns(ResultList.Create(refAssets, 0));
var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query });

Loading…
Cancel
Save