Prefer Interfaces in return values from data model

core
BuildFeed Bot 2018-10-28 22:15:30 +00:00
parent 4687f43040
commit d6b008d9d4
No known key found for this signature in database
GPG Key ID: 3757685ADD91E0A1
14 changed files with 58 additions and 75 deletions

View File

@ -1,10 +1,11 @@
using System; using System;
using System.Collections.Generic;
namespace BuildFeed.Model.Api namespace BuildFeed.Model.Api
{ {
public class NewBuildPost public class NewBuildPost
{ {
public NewBuild[] NewBuilds { get; set; } public IReadOnlyCollection<NewBuild> NewBuilds { get; set; }
public string Password { get; set; } public string Password { get; set; }
public string Username { get; set; } public string Username { get; set; }
} }

View File

@ -11,12 +11,12 @@ namespace BuildFeed.Model
{ {
public partial class BuildRepository public partial class BuildRepository
{ {
public Task<ProjectFamily[]> SelectAllFamilies(int limit = -1, int skip = 0) => Task.Run(() => public Task<IReadOnlyCollection<ProjectFamily>> SelectAllFamilies(int limit = -1, int skip = 0) => Task.Run(() =>
{ {
Array values = Enum.GetValues(typeof(ProjectFamily)); Array values = Enum.GetValues(typeof(ProjectFamily));
if (values.Length == 0) if (values.Length == 0)
{ {
return Array.Empty<ProjectFamily>(); return (IReadOnlyCollection<ProjectFamily>)Array.Empty<ProjectFamily>();
} }
var valuesWithoutNone = new ProjectFamily[values.Length - 1]; var valuesWithoutNone = new ProjectFamily[values.Length - 1];
@ -28,12 +28,12 @@ namespace BuildFeed.Model
valuesWithoutNone[i] = (ProjectFamily)values.GetValue(j); valuesWithoutNone[i] = (ProjectFamily)values.GetValue(j);
} }
return valuesWithoutNone; return (IReadOnlyCollection<ProjectFamily>)valuesWithoutNone;
}); });
public Task<long> SelectAllFamiliesCount() => Task.Run(() => Enum.GetValues(typeof(ProjectFamily)).LongLength); public Task<long> SelectAllFamiliesCount() => Task.Run(() => Enum.GetValues(typeof(ProjectFamily)).LongLength);
public async Task<List<Build>> SelectFamily(ProjectFamily family, int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<Build>> SelectFamily(ProjectFamily family, int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Find(new BsonDocument(nameof(Build.Family), family)) var query = _buildCollection.Find(new BsonDocument(nameof(Build.Family), family))
.Sort(sortByOrder) .Sort(sortByOrder)
@ -50,7 +50,7 @@ namespace BuildFeed.Model
public async Task<long> SelectFamilyCount(ProjectFamily family) public async Task<long> SelectFamilyCount(ProjectFamily family)
=> await _buildCollection.CountDocumentsAsync(new BsonDocument(nameof(Build.Family), family)); => await _buildCollection.CountDocumentsAsync(new BsonDocument(nameof(Build.Family), family));
public async Task<List<FamilyOverview>> SelectFamilyOverviews() public async Task<IReadOnlyCollection<FamilyOverview>> SelectFamilyOverviews()
{ {
var families = _buildCollection.Aggregate() var families = _buildCollection.Aggregate()
.Sort(sortByOrder) .Sort(sortByOrder)

View File

@ -9,7 +9,7 @@ namespace BuildFeed.Model
{ {
public partial class BuildRepository public partial class BuildRepository
{ {
public async Task<FrontBuildGroup[]> SelectAllGroups(int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<FrontBuildGroup>> SelectAllGroups(int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Aggregate() var query = _buildCollection.Aggregate()
.Group(new BsonDocument .Group(new BsonDocument
@ -74,7 +74,7 @@ namespace BuildFeed.Model
return grouping.Count; return grouping.Count;
} }
public async Task<List<Build>> SelectGroup(BuildGroup group, int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<Build>> SelectGroup(BuildGroup group, int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Find(new BsonDocument var query = _buildCollection.Find(new BsonDocument
{ {

View File

@ -9,7 +9,7 @@ namespace BuildFeed.Model
{ {
public partial class BuildRepository public partial class BuildRepository
{ {
public async Task<string[]> SelectAllLabs(int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<string>> SelectAllLabs(int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Aggregate() var query = _buildCollection.Aggregate()
.Group(new BsonDocument("_id", $"${nameof(Build.Lab)}")) .Group(new BsonDocument("_id", $"${nameof(Build.Lab)}"))
@ -28,7 +28,7 @@ namespace BuildFeed.Model
select g["_id"].AsString).ToArray(); select g["_id"].AsString).ToArray();
} }
public async Task<string[]> SelectLabsForVersion(int major, int minor) public async Task<IReadOnlyCollection<string>> SelectLabsForVersion(int major, int minor)
{ {
var query = _buildCollection.Aggregate() var query = _buildCollection.Aggregate()
.Match(new BsonDocument .Match(new BsonDocument
@ -46,7 +46,7 @@ namespace BuildFeed.Model
select g["_id"].AsString).ToArray(); select g["_id"].AsString).ToArray();
} }
public async Task<List<string>> SearchLabs(string search) public async Task<IReadOnlyCollection<string>> SearchLabs(string search)
{ {
var result = await _buildCollection.Aggregate() var result = await _buildCollection.Aggregate()
.Match(b => b.Lab != null) .Match(b => b.Lab != null)
@ -72,7 +72,7 @@ namespace BuildFeed.Model
return grouping.Count; return grouping.Count;
} }
public async Task<List<Build>> SelectLab(string lab, int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<Build>> SelectLab(string lab, int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Find(new BsonDocument(nameof(Build.LabUrl), lab)) var query = _buildCollection.Find(new BsonDocument(nameof(Build.LabUrl), lab))
.Sort(sortByCompileDate) .Sort(sortByCompileDate)

View File

@ -8,12 +8,12 @@ namespace BuildFeed.Model
{ {
public partial class BuildRepository public partial class BuildRepository
{ {
public Task<TypeOfSource[]> SelectAllSources(int limit = -1, int skip = 0) public Task<IReadOnlyCollection<TypeOfSource>> SelectAllSources(int limit = -1, int skip = 0)
=> Task.Run(() => Enum.GetValues(typeof(TypeOfSource)) as TypeOfSource[]); => Task.Run(() => Enum.GetValues(typeof(TypeOfSource)) as IReadOnlyCollection<TypeOfSource>);
public Task<long> SelectAllSourcesCount() => Task.Run(() => Enum.GetValues(typeof(TypeOfSource)).LongLength); public Task<long> SelectAllSourcesCount() => Task.Run(() => Enum.GetValues(typeof(TypeOfSource)).LongLength);
public async Task<List<Build>> SelectSource(TypeOfSource source, int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<Build>> SelectSource(TypeOfSource source, int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Find(new BsonDocument(nameof(Build.SourceType), source)) var query = _buildCollection.Find(new BsonDocument(nameof(Build.SourceType), source))
.Sort(sortByOrder) .Sort(sortByOrder)

View File

@ -8,7 +8,7 @@ namespace BuildFeed.Model
{ {
public partial class BuildRepository public partial class BuildRepository
{ {
public async Task<BuildVersion[]> SelectAllVersions(int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<BuildVersion>> SelectAllVersions(int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Aggregate() var query = _buildCollection.Aggregate()
.Group(new BsonDocument("_id", .Group(new BsonDocument("_id",
@ -52,7 +52,7 @@ namespace BuildFeed.Model
return query.Count; return query.Count;
} }
public async Task<List<Build>> SelectVersion(uint major, uint minor, int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<Build>> SelectVersion(uint major, uint minor, int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Find(new BsonDocument var query = _buildCollection.Find(new BsonDocument
{ {

View File

@ -9,7 +9,7 @@ namespace BuildFeed.Model
{ {
public partial class BuildRepository public partial class BuildRepository
{ {
public async Task<int[]> SelectAllYears(int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<int>> SelectAllYears(int limit = -1, int skip = 0)
{ {
var query = var query =
_buildCollection.Aggregate() _buildCollection.Aggregate()
@ -40,7 +40,7 @@ namespace BuildFeed.Model
return query.Count; return query.Count;
} }
public async Task<List<Build>> SelectYear(int year, int limit = -1, int skip = 0) public async Task<IReadOnlyCollection<Build>> SelectYear(int year, int limit = -1, int skip = 0)
{ {
var query = var query =
_buildCollection.Find(Builders<Build>.Filter.And(Builders<Build>.Filter.Gte(b => b.BuildTime, _buildCollection.Find(Builders<Build>.Filter.And(Builders<Build>.Filter.Gte(b => b.BuildTime,

View File

@ -11,7 +11,7 @@ namespace BuildFeed.Model
{ {
public partial class BuildRepository public partial class BuildRepository
{ {
public const int CURRENT_LONG_TERM = (int)ProjectFamily.Redstone; public const int CURRENT_LONG_TERM = (int)ProjectFamily.Redstone5;
public const int CURRENT_RELEASE = (int)ProjectFamily.Redstone5; public const int CURRENT_RELEASE = (int)ProjectFamily.Redstone5;
public const int CURRENT_XBOX = (int)ProjectFamily.Redstone5; public const int CURRENT_XBOX = (int)ProjectFamily.Redstone5;
@ -50,7 +50,9 @@ namespace BuildFeed.Model
_buildCollection = buildDatabase.GetCollection<Build>(BUILD_COLLECTION_NAME); _buildCollection = buildDatabase.GetCollection<Build>(BUILD_COLLECTION_NAME);
} }
public async Task SetupIndexes() public async void SetupIndexes() => await SetupIndexesAsync();
private async Task SetupIndexesAsync()
{ {
var indexes = await (await _buildCollection.Indexes.ListAsync()).ToListAsync(); var indexes = await (await _buildCollection.Indexes.ListAsync()).ToListAsync();
@ -133,20 +135,16 @@ namespace BuildFeed.Model
} }
} }
[DataObjectMethod(DataObjectMethodType.Select, true)] public async Task<IReadOnlyCollection<Build>> Select() => await _buildCollection.Find(new BsonDocument()).ToListAsync();
public async Task<List<Build>> Select() => await _buildCollection.Find(new BsonDocument()).ToListAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<Build> SelectById(Guid id) public async Task<Build> SelectById(Guid id)
=> await _buildCollection.Find(Builders<Build>.Filter.Eq(b => b.Id, id)).SingleOrDefaultAsync(); => await _buildCollection.Find(Builders<Build>.Filter.Eq(b => b.Id, id)).SingleOrDefaultAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<Build> SelectByLegacyId(long id) => await _buildCollection public async Task<Build> SelectByLegacyId(long id) => await _buildCollection
.Find(Builders<Build>.Filter.Eq(b => b.LegacyId, id)) .Find(Builders<Build>.Filter.Eq(b => b.LegacyId, id))
.SingleOrDefaultAsync(); .SingleOrDefaultAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)] public async Task<IReadOnlyCollection<Build>> SelectBuildsByOrder(int limit = -1, int skip = 0)
public async Task<List<Build>> SelectBuildsByOrder(int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Find(new BsonDocument()).Sort(sortByOrder).Skip(skip); var query = _buildCollection.Find(new BsonDocument()).Sort(sortByOrder).Skip(skip);
@ -158,8 +156,7 @@ namespace BuildFeed.Model
return await query.ToListAsync(); return await query.ToListAsync();
} }
[DataObjectMethod(DataObjectMethodType.Select, false)] public async Task<IReadOnlyDictionary<ProjectFamily, FrontPage>> SelectFrontPage()
public async Task<Dictionary<ProjectFamily, FrontPage>> SelectFrontPage()
{ {
var families = new Dictionary<ProjectFamily, FrontPage>(); var families = new Dictionary<ProjectFamily, FrontPage>();
@ -299,8 +296,7 @@ namespace BuildFeed.Model
return families; return families;
} }
[DataObjectMethod(DataObjectMethodType.Select, false)] public async Task<IReadOnlyCollection<Build>> SelectBuildsByStringSearch(string term, int limit = -1)
public async Task<List<Build>> SelectBuildsByStringSearch(string term, int limit = -1)
{ {
var query = _buildCollection.Aggregate() var query = _buildCollection.Aggregate()
.Match(b => b.FullBuildString != null) .Match(b => b.FullBuildString != null)
@ -315,15 +311,13 @@ namespace BuildFeed.Model
return await query.ToListAsync(); return await query.ToListAsync();
} }
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<Build> SelectBuildByFullBuildString(string build) => await _buildCollection public async Task<Build> SelectBuildByFullBuildString(string build) => await _buildCollection
.Find(Builders<Build>.Filter.Eq(b => b.FullBuildString, build)) .Find(Builders<Build>.Filter.Eq(b => b.FullBuildString, build))
.SingleOrDefaultAsync(); .SingleOrDefaultAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)] private async Task<IReadOnlyCollection<Build>> SelectBuildsBySortOption(BsonDocument sort, int limit, int skip)
public async Task<List<Build>> SelectBuildsByCompileDate(int limit = -1, int skip = 0)
{ {
var query = _buildCollection.Find(new BsonDocument()).Sort(sortByCompileDate).Skip(skip); var query = _buildCollection.Find(new BsonDocument()).Sort(sort).Skip(skip);
if (limit > 0) if (limit > 0)
{ {
@ -333,33 +327,15 @@ namespace BuildFeed.Model
return await query.ToListAsync(); return await query.ToListAsync();
} }
[DataObjectMethod(DataObjectMethodType.Select, false)] public Task<IReadOnlyCollection<Build>> SelectBuildsByCompileDate(int limit = -1, int skip = 0)
public async Task<List<Build>> SelectBuildsByAddedDate(int limit = -1, int skip = 0) => SelectBuildsBySortOption(sortByCompileDate, limit, skip);
{
var query = _buildCollection.Find(new BsonDocument()).Sort(sortByAddedDate).Skip(skip);
if (limit > 0) public Task<IReadOnlyCollection<Build>> SelectBuildsByAddedDate(int limit = -1, int skip = 0)
{ => SelectBuildsBySortOption(sortByAddedDate, limit, skip);
query = query.Limit(limit);
}
return await query.ToListAsync(); public Task<IReadOnlyCollection<Build>> SelectBuildsByLeakedDate(int limit = -1, int skip = 0)
} => SelectBuildsBySortOption(sortByLeakedDate, limit, skip);
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<Build>> SelectBuildsByLeakedDate(int limit = -1, int skip = 0)
{
var query = _buildCollection.Find(new BsonDocument()).Sort(sortByLeakedDate).Skip(skip);
if (limit > 0)
{
query = query.Limit(limit);
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Insert, true)]
public async Task Insert(Build item) public async Task Insert(Build item)
{ {
item.Id = Guid.NewGuid(); item.Id = Guid.NewGuid();
@ -368,7 +344,6 @@ namespace BuildFeed.Model
await _buildCollection.InsertOneAsync(item); await _buildCollection.InsertOneAsync(item);
} }
[DataObjectMethod(DataObjectMethodType.Insert, false)]
public async Task InsertAll(IEnumerable<Build> items) public async Task InsertAll(IEnumerable<Build> items)
{ {
var generatedItems = new List<Build>(); var generatedItems = new List<Build>();
@ -383,7 +358,6 @@ namespace BuildFeed.Model
await _buildCollection.InsertManyAsync(generatedItems); await _buildCollection.InsertManyAsync(generatedItems);
} }
[DataObjectMethod(DataObjectMethodType.Update, true)]
public async Task Update(Build item) public async Task Update(Build item)
{ {
Build old = await SelectById(item.Id); Build old = await SelectById(item.Id);
@ -404,7 +378,6 @@ namespace BuildFeed.Model
} }
} }
[DataObjectMethod(DataObjectMethodType.Delete, true)]
public async Task DeleteById(Guid id) public async Task DeleteById(Guid id)
{ {
await _buildCollection.DeleteOneAsync(Builders<Build>.Filter.Eq(b => b.Id, id)); await _buildCollection.DeleteOneAsync(Builders<Build>.Filter.Eq(b => b.Id, id));

View File

@ -32,9 +32,7 @@
public void SetupIndexes() public void SetupIndexes()
{ {
var b = new BuildRepository(this); var b = new BuildRepository(this);
#pragma warning disable 4014
b.SetupIndexes(); b.SetupIndexes();
#pragma warning restore 4014
} }
} }
} }

View File

@ -6,15 +6,15 @@ namespace BuildFeed.Model.View
{ {
public class SitemapData public class SitemapData
{ {
public Dictionary<string, SitemapPagedAction[]> Actions { get; set; } public IReadOnlyDictionary<string, IReadOnlyCollection<SitemapPagedAction>> Actions { get; set; }
public SitemapDataBuildGroup[] Builds { get; set; } public IReadOnlyCollection<SitemapDataBuildGroup> Builds { get; set; }
public string[] Labs { get; set; } public IReadOnlyCollection<string> Labs { get; set; }
} }
public class SitemapDataBuildGroup public class SitemapDataBuildGroup
{ {
public SitemapDataBuild[] Builds { get; set; } public IReadOnlyCollection<SitemapDataBuild> Builds { get; set; }
public BuildGroup Id { get; set; } public BuildGroup Id { get; set; }
} }

View File

@ -0,0 +1,8 @@
namespace BuildFeed
{
public struct Pagination
{
public int PageNumber;
public int PageCount;
}
}

View File

@ -53,11 +53,14 @@ namespace BuildFeed.Controllers
{ {
var buildGroups = await _bModel.SelectAllGroups(PAGE_SIZE, (page - 1) * PAGE_SIZE); var buildGroups = await _bModel.SelectAllGroups(PAGE_SIZE, (page - 1) * PAGE_SIZE);
ViewBag.PageNumber = page; var pages = new Pagination
ViewBag.PageCount = {
Math.Ceiling(Convert.ToDouble(await _bModel.SelectAllGroupsCount()) / Convert.ToDouble(PAGE_SIZE)); PageNumber = page,
PageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(await _bModel.SelectAllGroupsCount()) / Convert.ToDouble(PAGE_SIZE)))
};
HttpContext.Features.Set(pages);
if (ViewBag.PageNumber > ViewBag.PageCount) if (pages.PageNumber > pages.PageCount)
{ {
return NotFound(); return NotFound();
} }
@ -85,7 +88,7 @@ namespace BuildFeed.Controllers
{ {
id = builds.Single().Id id = builds.Single().Id
}) as ActionResult }) as ActionResult
: View(new Tuple<BuildGroup, List<Build>>(bg, builds)); : View(new Tuple<BuildGroup, IReadOnlyCollection<Build>>(bg, builds));
} }
[Route("build/{id:guid}/", Name = "Build")] [Route("build/{id:guid}/", Name = "Build")]

View File

@ -1,5 +1,5 @@
@using Microsoft.AspNetCore.Html @using Microsoft.AspNetCore.Html
@model Dictionary<ProjectFamily, FrontPage> @model IReadOnlyDictionary<ProjectFamily, FrontPage>
@{ @{
ViewBag.Title = string.Format(VariantTerms.Front_HomeH1, InvariantTerms.SiteName); ViewBag.Title = string.Format(VariantTerms.Front_HomeH1, InvariantTerms.SiteName);

View File

@ -1,5 +1,5 @@
@using Humanizer @using Humanizer
@model Tuple<BuildGroup, List<Build>> @model Tuple<BuildGroup, IReadOnlyCollection<Build>>
@{ @{
ViewBag.Title = $"{Model.Item1} | {InvariantTerms.SiteName}"; ViewBag.Title = $"{Model.Item1} | {InvariantTerms.SiteName}";
} }