From 2919fbea16d5992e9297b7ef770bd2b7f55fe91b Mon Sep 17 00:00:00 2001 From: Thomas Hounsell Date: Wed, 9 Sep 2015 23:48:29 +0100 Subject: [PATCH] A fuckload of Mongo Starting to take shape with some nice perf gains. --- BuildFeed/Controllers/frontController.cs | 569 ++++++++-------- BuildFeed/Models/Build.cs | 619 ++++++++++-------- BuildFeed/Views/front/editBuild.cshtml | 2 +- BuildFeed/Views/front/viewBuild.cshtml | 2 +- BuildFeed/Views/front/viewGroup.cshtml | 8 +- BuildFeed/Views/front/viewLab.cshtml | 2 +- BuildFeed/Views/front/viewSource.cshtml | 2 +- BuildFeed/Views/front/viewVersion.cshtml | 2 +- BuildFeed/Views/front/viewYear.cshtml | 2 +- BuildFeed/Web.config | 5 +- BuildFeed/content/style.css | 12 +- RedisMongoMigration/Build.cs | 29 + RedisMongoMigration/Mongo/Build.cs | 110 ++++ RedisMongoMigration/Program.cs | 41 +- RedisMongoMigration/Redis/Build.cs | 72 +- .../RedisMongoMigration.csproj | 15 + RedisMongoMigration/packages.config | 3 + 17 files changed, 850 insertions(+), 645 deletions(-) create mode 100644 RedisMongoMigration/Build.cs create mode 100644 RedisMongoMigration/Mongo/Build.cs diff --git a/BuildFeed/Controllers/frontController.cs b/BuildFeed/Controllers/frontController.cs index 1cb3d40..0c734de 100644 --- a/BuildFeed/Controllers/frontController.cs +++ b/BuildFeed/Controllers/frontController.cs @@ -11,311 +11,290 @@ namespace BuildFeed.Controllers { - public class frontController : Controller - { - public const int PAGE_SIZE = 96; + public class frontController : Controller + { + public const int PAGE_SIZE = 96; - [Route("", Order = 1)] + [Route("", Order = 1)] #if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] #endif - public ActionResult index() { return indexPage(1); } + public ActionResult index() { return indexPage(1); } - [Route("page-{page:int:min(2)}/", Order = 0)] + [Route("page-{page:int:min(2)}/", Order = 0)] #if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] + [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] #endif - public ActionResult indexPage(int page) - { - var buildGroups = (from b in new Build().Select() - group b by new BuildGroup - { - Major = b.MajorVersion, - Minor = b.MinorVersion, - Build = b.Number, - Revision = b.Revision - } - into bg - orderby bg.Key.Major descending, - bg.Key.Minor descending, - bg.Key.Build descending, - bg.Key.Revision descending - select new FrontBuildGroup - { - Key = bg.Key, - LastBuild = bg.Max(m => m.BuildTime), - BuildCount = bg.Count() - }).ToArray(); + public ActionResult indexPage(int page) + { + Build bModel = new Build(); + var buildGroups = bModel.SelectBuildGroups(PAGE_SIZE, (page - 1) * PAGE_SIZE); - ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(buildGroups.Length) / Convert.ToDouble(PAGE_SIZE)); + ViewBag.PageNumber = page; + ViewBag.PageCount = Math.Ceiling( + Convert.ToDouble(bModel.SelectBuildGroupsCount()) / + Convert.ToDouble(PAGE_SIZE)); - if (ViewBag.PageNumber > ViewBag.PageCount) + if (ViewBag.PageCount != 0 && ViewBag.PageNumber > ViewBag.PageCount) + { + return new HttpNotFoundResult(); + } + + return View("index", buildGroups); + } + + [Route("group/{major}.{minor}.{number}.{revision}/")] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] +#endif + public ActionResult viewGroup(byte major, byte minor, ushort number, ushort? revision = null) + { + Build bModel = new Build(); + var builds = bModel.SelectSingleBuildGroup(new BuildGroup() + { + Major = major, + Minor = minor, + Build = number, + Revision = revision + }); + + return builds.Item2.Count() == 1 ? + RedirectToAction("viewBuild", new { id = builds.Item2.Single().Id }) as ActionResult : + View(builds); + } + + [Route("build/{id}/", Name = "Build")] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] +#endif + public ActionResult viewBuild(Guid id) + { + BuildModel b = new Build().SelectById(id); + return View(b); + } + + [Route("twitter/{id}/")] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none")] + [CustomContentType(ContentType = "image/png", Order = 2)] +#endif + public ActionResult twitterCard(Guid id) + { + BuildModel b = new Build().SelectById(id); + + using (Bitmap bm = new Bitmap(560, 300)) + { + using (Graphics gr = Graphics.FromImage(bm)) { - return new HttpNotFoundResult(); + GraphicsPath gp = new GraphicsPath(); + gr.CompositingMode = CompositingMode.SourceOver; + gr.CompositingQuality = CompositingQuality.HighQuality; + gr.InterpolationMode = InterpolationMode.HighQualityBicubic; + gr.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; + gr.SmoothingMode = SmoothingMode.HighQuality; + gr.PixelOffsetMode = PixelOffsetMode.HighQuality; + + gr.FillRectangle(new SolidBrush(Color.FromArgb(0x27, 0x2b, 0x30)), 0, 0, 560, 300); + gp.AddString("BUILDFEED", new FontFamily("Segoe UI"), (int)FontStyle.Bold, 16, new Point(20, 20), StringFormat.GenericTypographic); + gp.AddString($"Windows NT {b.MajorVersion}.{b.MinorVersion} build", new FontFamily("Segoe UI"), 0, 24, new Point(20, 40), StringFormat.GenericTypographic); + gp.AddString(b.Number.ToString(), new FontFamily("Segoe UI Light"), 0, 180, new Point(12, 20), StringFormat.GenericTypographic); + gp.AddString($"{b.Lab}", new FontFamily("Segoe UI"), 0, 40, new Point(16, 220), StringFormat.GenericTypographic); + gr.FillPath(Brushes.White, gp); + + Response.ContentType = "image/png"; + bm.Save(Response.OutputStream, ImageFormat.Png); + } + } + + return new EmptyResult(); + } + + [Route("lab/{lab}/", Order = 1, Name = "Lab Root")] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] +#endif + public ActionResult viewLab(string lab) { return viewLabPage(lab, 1); } + + [Route("lab/{lab}/page-{page:int:min(2)}/", Order = 0)] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] +#endif + public ActionResult viewLabPage(string lab, int page) + { + ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey + { + Type = MetaType.Lab, + Value = lab + }); + ViewBag.ItemId = lab; + + var builds = new Build().SelectLabInBuildOrder(lab, (page - 1) * PAGE_SIZE, PAGE_SIZE); + + ViewBag.PageNumber = page; + ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Count) / Convert.ToDouble(PAGE_SIZE)); + + if (ViewBag.PageNumber > ViewBag.PageCount) + { + return new HttpNotFoundResult(); + } + + return View("viewLab", builds); + } + + [Route("source/{source}/", Order = 1, Name = "Source Root")] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] +#endif + public ActionResult viewSource(TypeOfSource source) { return viewSourcePage(source, 1); } + + [Route("source/{source}/page-{page:int:min(2)}/", Order = 0)] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] +#endif + public ActionResult viewSourcePage(TypeOfSource source, int page) + { + ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey + { + Type = MetaType.Source, + Value = source.ToString() + }); + ViewBag.ItemId = DisplayHelpers.GetDisplayTextForEnum(source); + + var builds = new Build().SelectInBuildOrder().Where(b => b.SourceType == source).ToArray(); + + ViewBag.PageNumber = page; + ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Length) / Convert.ToDouble(PAGE_SIZE)); + + if (ViewBag.PageNumber > ViewBag.PageCount) + { + return new HttpNotFoundResult(); + } + + return View("viewSource", builds.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); + } + + [Route("year/{year}/", Order = 1, Name = "Year Root")] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] +#endif + public ActionResult viewYear(int year) { return viewYearPage(year, 1); } + + [Route("year/{year}/page-{page:int:min(2)}/", Order = 0)] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] +#endif + public ActionResult viewYearPage(int year, int page) + { + ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey + { + Type = MetaType.Year, + Value = year.ToString() + }); + ViewBag.ItemId = year.ToString(); + + var builds = new Build().SelectInBuildOrder().Where(b => b.BuildTime.HasValue && b.BuildTime.Value.Year == year).ToArray(); + + ViewBag.PageNumber = page; + ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Length) / Convert.ToDouble(PAGE_SIZE)); + + if (ViewBag.PageNumber > ViewBag.PageCount) + { + return new HttpNotFoundResult(); + } + + return View("viewYear", builds.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); + } + + [Route("version/{major}.{minor}/", Order = 1, Name = "Version Root")] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] +#endif + public ActionResult viewVersion(int major, int minor) { return viewVersionPage(major, minor, 1); } + + [Route("version/{major}.{minor}/page-{page:int:min(2)}/", Order = 0)] +#if !DEBUG + [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] +#endif + public ActionResult viewVersionPage(int major, int minor, int page) + { + string valueString = $"{major}.{minor}"; + ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey + { + Type = MetaType.Version, + Value = valueString + }); + ViewBag.ItemId = valueString; + + var builds = new Build().SelectInBuildOrder().Where(b => b.MajorVersion == major && b.MinorVersion == minor).ToArray(); + + ViewBag.PageNumber = page; + ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Length) / Convert.ToDouble(PAGE_SIZE)); + + if (ViewBag.PageNumber > ViewBag.PageCount) + { + return new HttpNotFoundResult(); + } + + return View("viewVersion", builds.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); + } + + [Route("add/"), Authorize] + public ActionResult addBuild() { return View("editBuild"); } + + [Route("add/"), Authorize, HttpPost] + public ActionResult addBuild(BuildModel build) + { + if (ModelState.IsValid) + { + try + { + build.Added = DateTime.Now; + build.Modified = DateTime.Now; + new Build().Insert(build); + } + catch + { + return View("editBuild", build); + } + return RedirectToAction("viewBuild", new + { + id = build.Id + }); + } + return View("editBuild", build); + } + + [Route("edit/{id}/"), Authorize] + public ActionResult editBuild(Guid id) + { + BuildModel b = new Build().SelectById(id); + return View(b); + } + + [Route("edit/{id}/"), Authorize, HttpPost] + public ActionResult editBuild(long id, BuildModel build) + { + if (ModelState.IsValid) + { + try + { + new Build().Update(build); + } + catch + { + return View(build); } - return View("index", buildGroups.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); - } + return RedirectToAction("viewBuild", new { id = build.Id }); + } + return View(build); + } - [Route("group/{major}.{minor}.{number}.{revision}/")] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] -#endif - public ActionResult viewGroup(byte major, byte minor, ushort number, ushort? revision = null) - { - var builds = (from b in new Build().Select() - group b by new BuildGroup - { - Major = b.MajorVersion, - Minor = b.MinorVersion, - Build = b.Number, - Revision = b.Revision - } - into bg - where bg.Key.Major == major - where bg.Key.Minor == minor - where bg.Key.Build == number - where bg.Key.Revision == revision - select bg).Single(); - - return builds.Count() == 1 ? - RedirectToAction("viewBuild", new {id = builds.Single().Id}) as ActionResult : - View(builds); - } - - [Route("build/{id}/", Name = "Build")] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] -#endif - public ActionResult viewBuild(Guid id) - { - BuildModel b = new Build().SelectById(id); - return View(b); - } - - [Route("twitter/{id}/")] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none")] - [CustomContentType(ContentType = "image/png", Order = 2)] -#endif - public ActionResult twitterCard(Guid id) - { - BuildModel b = new Build().SelectById(id); - - using (Bitmap bm = new Bitmap(560, 300)) - { - using (Graphics gr = Graphics.FromImage(bm)) - { - GraphicsPath gp = new GraphicsPath(); - gr.CompositingMode = CompositingMode.SourceOver; - gr.CompositingQuality = CompositingQuality.HighQuality; - gr.InterpolationMode = InterpolationMode.HighQualityBicubic; - gr.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; - gr.SmoothingMode = SmoothingMode.HighQuality; - gr.PixelOffsetMode = PixelOffsetMode.HighQuality; - - gr.FillRectangle(new SolidBrush(Color.FromArgb(0x27, 0x2b, 0x30)), 0, 0, 560, 300); - gp.AddString("BUILDFEED", new FontFamily("Segoe UI"), (int) FontStyle.Bold, 16, new Point(20, 20), StringFormat.GenericTypographic); - gp.AddString($"Windows NT {b.MajorVersion}.{b.MinorVersion} build", new FontFamily("Segoe UI"), 0, 24, new Point(20, 40), StringFormat.GenericTypographic); - gp.AddString(b.Number.ToString(), new FontFamily("Segoe UI Light"), 0, 180, new Point(12, 20), StringFormat.GenericTypographic); - gp.AddString($"{b.Lab}", new FontFamily("Segoe UI"), 0, 40, new Point(16, 220), StringFormat.GenericTypographic); - gr.FillPath(Brushes.White, gp); - - Response.ContentType = "image/png"; - bm.Save(Response.OutputStream, ImageFormat.Png); - } - } - - return new EmptyResult(); - } - - [Route("lab/{lab}/", Order = 1, Name = "Lab Root")] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] -#endif - public ActionResult viewLab(string lab) { return viewLabPage(lab, 1); } - - [Route("lab/{lab}/page-{page:int:min(2)}/", Order = 0)] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] -#endif - public ActionResult viewLabPage(string lab, int page) - { - ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey - { - Type = MetaType.Lab, - Value = lab - }); - ViewBag.ItemId = lab; - - var builds = new Build().SelectInBuildOrder().Where(b => b.Lab != null && (b.Lab.ToLower() == lab.ToLower())).ToArray(); - - ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Length) / Convert.ToDouble(PAGE_SIZE)); - - if (ViewBag.PageNumber > ViewBag.PageCount) - { - return new HttpNotFoundResult(); - } - - return View("viewLab", builds.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); - } - - [Route("source/{source}/", Order = 1, Name = "Source Root")] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] -#endif - public ActionResult viewSource(TypeOfSource source) { return viewSourcePage(source, 1); } - - [Route("source/{source}/page-{page:int:min(2)}/", Order = 0)] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] -#endif - public ActionResult viewSourcePage(TypeOfSource source, int page) - { - ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey - { - Type = MetaType.Source, - Value = source.ToString() - }); - ViewBag.ItemId = DisplayHelpers.GetDisplayTextForEnum(source); - - var builds = new Build().SelectInBuildOrder().Where(b => b.SourceType == source).ToArray(); - - ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Length) / Convert.ToDouble(PAGE_SIZE)); - - if (ViewBag.PageNumber > ViewBag.PageCount) - { - return new HttpNotFoundResult(); - } - - return View("viewSource", builds.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); - } - - [Route("year/{year}/", Order = 1, Name = "Year Root")] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] -#endif - public ActionResult viewYear(int year) { return viewYearPage(year, 1); } - - [Route("year/{year}/page-{page:int:min(2)}/", Order = 0)] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "page", VaryByCustom = "userName")] -#endif - public ActionResult viewYearPage(int year, int page) - { - ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey - { - Type = MetaType.Year, - Value = year.ToString() - }); - ViewBag.ItemId = year.ToString(); - - var builds = new Build().SelectInBuildOrder().Where(b => b.BuildTime.HasValue && b.BuildTime.Value.Year == year).ToArray(); - - ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Length) / Convert.ToDouble(PAGE_SIZE)); - - if (ViewBag.PageNumber > ViewBag.PageCount) - { - return new HttpNotFoundResult(); - } - - return View("viewYear", builds.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); - } - - [Route("version/{major}.{minor}/", Order = 1, Name = "Version Root")] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] -#endif - public ActionResult viewVersion(int major, int minor) { return viewVersionPage(major, minor, 1); } - - [Route("version/{major}.{minor}/page-{page:int:min(2)}/", Order = 0)] -#if !DEBUG - [OutputCache(Duration = 600, VaryByParam = "none", VaryByCustom = "userName")] -#endif - public ActionResult viewVersionPage(int major, int minor, int page) - { - string valueString = $"{major}.{minor}"; - ViewBag.MetaItem = new MetaItem().SelectById(new MetaItemKey - { - Type = MetaType.Version, - Value = valueString - }); - ViewBag.ItemId = valueString; - - var builds = new Build().SelectInBuildOrder().Where(b => b.MajorVersion == major && b.MinorVersion == minor).ToArray(); - - ViewBag.PageNumber = page; - ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(builds.Length) / Convert.ToDouble(PAGE_SIZE)); - - if (ViewBag.PageNumber > ViewBag.PageCount) - { - return new HttpNotFoundResult(); - } - - return View("viewVersion", builds.Skip((page - 1) * PAGE_SIZE).Take(PAGE_SIZE)); - } - - [Route("add/"), Authorize] - public ActionResult addBuild() { return View("editBuild"); } - - [Route("add/"), Authorize, HttpPost] - public ActionResult addBuild(BuildModel build) - { - if (ModelState.IsValid) - { - try - { - build.Added = DateTime.Now; - build.Modified = DateTime.Now; - new Build().Insert(build); - } - catch - { - return View("editBuild", build); - } - return RedirectToAction("viewBuild", new - { - id = build.Id - }); - } - return View("editBuild", build); - } - - [Route("edit/{id}/"), Authorize] - public ActionResult editBuild(Guid id) - { - BuildModel b = new Build().SelectById(id); - return View(b); - } - - [Route("edit/{id}/"), Authorize, HttpPost] - public ActionResult editBuild(long id, BuildModel build) - { - if (ModelState.IsValid) - { - try - { - new Build().Update(build); - } - catch - { - return View(build); - } - - return RedirectToAction("viewBuild", new { id = build.Id }); - } - return View(build); - } - - [Route("delete/{id}/"), Authorize(Roles = "Administrators")] - public ActionResult deleteBuild(Guid id) - { - new Build().DeleteById(id); - return RedirectToAction("index"); - } - } + [Route("delete/{id}/"), Authorize(Roles = "Administrators")] + public ActionResult deleteBuild(Guid id) + { + new Build().DeleteById(id); + return RedirectToAction("index"); + } + } } \ No newline at end of file diff --git a/BuildFeed/Models/Build.cs b/BuildFeed/Models/Build.cs index 3cf9692..d0fb648 100644 --- a/BuildFeed/Models/Build.cs +++ b/BuildFeed/Models/Build.cs @@ -1,333 +1,414 @@ -using System; +using BuildFeed.Local; +using BuildFeed.Models.ViewModel.Front; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver; +using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; - -using Required = System.ComponentModel.DataAnnotations.RequiredAttribute; using System.Web.Mvc; -using BuildFeed.Local; -using MongoDB.Driver; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; +using Required = System.ComponentModel.DataAnnotations.RequiredAttribute; namespace BuildFeed.Models { - [DataObject] - public class BuildModel - { - [Key, BsonId] - public Guid Id { get; set; } + [DataObject] + public class BuildModel + { + [Key, BsonId] + public Guid Id { get; set; } - public long? LegacyId { get; set; } + public long? LegacyId { get; set; } - [@Required] - [Display(ResourceType = typeof(Model), Name = "MajorVersion")] - public byte MajorVersion { get; set; } + [@Required] + [Display(ResourceType = typeof(Model), Name = "MajorVersion")] + public byte MajorVersion { get; set; } - [@Required] - [Display(ResourceType = typeof(Model), Name = "MinorVersion")] - public byte MinorVersion { get; set; } + [@Required] + [Display(ResourceType = typeof(Model), Name = "MinorVersion")] + public byte MinorVersion { get; set; } - [@Required] - [Display(ResourceType = typeof(Model), Name = "Number")] - public ushort Number { get; set; } + [@Required] + [Display(ResourceType = typeof(Model), Name = "Number")] + public ushort Number { get; set; } - [Display(ResourceType = typeof(Model), Name = "Revision")] - [DisplayFormat(ConvertEmptyStringToNull = true)] - public ushort? Revision { get; set; } + [Display(ResourceType = typeof(Model), Name = "Revision")] + [DisplayFormat(ConvertEmptyStringToNull = true)] + public ushort? Revision { get; set; } - [Display(ResourceType = typeof(Model), Name = "Lab")] - public string Lab { get; set; } + [Display(ResourceType = typeof(Model), Name = "Lab")] + public string Lab { get; set; } - [Display(ResourceType = typeof(Model), Name = "BuildTime")] - [DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true, DataFormatString = "{0:yyMMdd-HHmm}")] - public DateTime? BuildTime { get; set; } + [Display(ResourceType = typeof(Model), Name = "BuildTime")] + [DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true, DataFormatString = "{0:yyMMdd-HHmm}")] + public DateTime? BuildTime { get; set; } - [@Required] - [Display(ResourceType = typeof(Model), Name = "Added")] - public DateTime Added { get; set; } + [@Required] + [Display(ResourceType = typeof(Model), Name = "Added")] + public DateTime Added { get; set; } - [@Required] - [Display(ResourceType = typeof(Model), Name = "Modified")] - public DateTime Modified { get; set; } + [@Required] + [Display(ResourceType = typeof(Model), Name = "Modified")] + public DateTime Modified { get; set; } - [@Required] - [Display(ResourceType = typeof(Model), Name = "SourceType")] - [EnumDataType(typeof(TypeOfSource))] - public TypeOfSource SourceType { get; set; } + [@Required] + [Display(ResourceType = typeof(Model), Name = "SourceType")] + [EnumDataType(typeof(TypeOfSource))] + public TypeOfSource SourceType { get; set; } - [Display(ResourceType = typeof(Model), Name = "SourceDetails")] - [AllowHtml] - public string SourceDetails { get; set; } + [Display(ResourceType = typeof(Model), Name = "SourceDetails")] + [AllowHtml] + public string SourceDetails { get; set; } - [Display(ResourceType = typeof(Model), Name = "LeakDate")] - [DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] - public DateTime? LeakDate { get; set; } + [Display(ResourceType = typeof(Model), Name = "LeakDate")] + [DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")] + public DateTime? LeakDate { get; set; } - [Display(ResourceType = typeof(Model), Name = "FlightLevel")] - [EnumDataType(typeof(LevelOfFlight))] - public LevelOfFlight FlightLevel { get; set; } + [Display(ResourceType = typeof(Model), Name = "FlightLevel")] + [EnumDataType(typeof(LevelOfFlight))] + public LevelOfFlight FlightLevel { get; set; } - public bool IsLeaked - { - get + public bool IsLeaked + { + get + { + switch (SourceType) { - switch (SourceType) - { - case TypeOfSource.PublicRelease: - case TypeOfSource.InternalLeak: - case TypeOfSource.UpdateGDR: - case TypeOfSource.UpdateLDR: - return true; - default: - return false; - } + case TypeOfSource.PublicRelease: + case TypeOfSource.InternalLeak: + case TypeOfSource.UpdateGDR: + case TypeOfSource.UpdateLDR: + return true; + default: + return false; } - } + } + } - public string FullBuildString - { - get + public string FullBuildString + { + get + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("{0}.{1}.{2}", MajorVersion, MinorVersion, Number); + + if (Revision.HasValue) { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("{0}.{1}.{2}", MajorVersion, MinorVersion, Number); - - if (Revision.HasValue) - { - sb.AppendFormat(".{0}", Revision); - } - - if (!string.IsNullOrWhiteSpace(Lab)) - { - sb.AppendFormat(".{0}", Lab); - } - - if (BuildTime.HasValue) - { - sb.AppendFormat(".{0:yyMMdd-HHmm}", BuildTime); - } - - return sb.ToString(); + sb.AppendFormat(".{0}", Revision); } - } - } - public class Build - { - private const string _buildCollectionName = "builds"; - - private MongoClient _dbClient; - private IMongoCollection _buildCollection; - - public Build() - { - _dbClient = new MongoClient(new MongoClientSettings() + if (!string.IsNullOrWhiteSpace(Lab)) { - Server = new MongoServerAddress(MongoConfig.Host, MongoConfig.Port) - }); + sb.AppendFormat(".{0}", Lab); + } - _buildCollection = _dbClient.GetDatabase(MongoConfig.Database).GetCollection(_buildCollectionName); - } + if (BuildTime.HasValue) + { + sb.AppendFormat(".{0:yyMMdd-HHmm}", BuildTime); + } - [DataObjectMethod(DataObjectMethodType.Select, true)] - public IEnumerable Select() - { - var task = _buildCollection.Find(new BsonDocument()).ToListAsync(); - task.Wait(); - return task.Result; - } + return sb.ToString(); + } + } + } - [DataObjectMethod(DataObjectMethodType.Select, false)] - public BuildModel SelectById(Guid id) - { - var task = _buildCollection.Find(f => f.Id == id).SingleOrDefaultAsync(); - task.Wait(); - return task.Result; - } + public class Build + { + private const string _buildCollectionName = "builds"; - [DataObjectMethod(DataObjectMethodType.Select, false)] - public BuildModel SelectByLegacyId(long id) - { - var task = _buildCollection.Find(f => f.LegacyId == id).SingleOrDefaultAsync(); - task.Wait(); - return task.Result; - } + private MongoClient _dbClient; + private IMongoCollection _buildCollection; - [DataObjectMethod(DataObjectMethodType.Select, false)] - public IEnumerable SelectInBuildOrder() - { - var task = _buildCollection.Find(new BsonDocument()) - .SortByDescending(b => b.BuildTime) - .ThenByDescending(b => b.MajorVersion) - .ThenByDescending(b => b.MinorVersion) - .ThenByDescending(b => b.Number) - .ThenByDescending(b => b.Revision) - .ToListAsync(); - task.Wait(); - return task.Result; - } + public Build() + { + _dbClient = new MongoClient(new MongoClientSettings() + { + Server = new MongoServerAddress(MongoConfig.Host, MongoConfig.Port) + }); - [DataObjectMethod(DataObjectMethodType.Select, false)] - public IEnumerable SelectInVersionOrder() - { - var task = _buildCollection.Find(new BsonDocument()) - .SortByDescending(b => b.MajorVersion) - .ThenByDescending(b => b.MinorVersion) - .ThenByDescending(b => b.Number) - .ThenByDescending(b => b.Revision) - .ThenByDescending(b => b.BuildTime) - .ToListAsync(); - task.Wait(); - return task.Result; - } + _buildCollection = _dbClient.GetDatabase(MongoConfig.Database).GetCollection(_buildCollectionName); + } - [DataObjectMethod(DataObjectMethodType.Select, false)] - public IEnumerable SelectBuildVersions() - { - var task = _buildCollection.DistinctAsync(b => new BuildVersion() { Major = b.MajorVersion, Minor = b.MinorVersion }, b => true); - task.Wait(); - var outTask = task.Result.ToListAsync(); - outTask.Wait(); - return outTask.Result - .OrderByDescending(y => y.Major) - .ThenByDescending(y => y.Minor); - } + [DataObjectMethod(DataObjectMethodType.Select, true)] + public List Select() + { + var task = _buildCollection.Find(new BsonDocument()).ToListAsync(); + task.Wait(); + return task.Result; + } - [DataObjectMethod(DataObjectMethodType.Select, false)] - public IEnumerable SelectBuildYears() - { - var task = _buildCollection.DistinctAsync(b => b.BuildTime.Value.Year, b => b.BuildTime.HasValue); - task.Wait(); - var outTask = task.Result.ToListAsync(); - outTask.Wait(); - return outTask.Result.OrderBy(b => b); - } + [DataObjectMethod(DataObjectMethodType.Select, false)] + public List SelectBuildGroups(int limit, int skip) + { + var pipeline = _buildCollection.Aggregate() + .Group(b => new BuildGroup() + { + Major = b.MajorVersion, + Minor = b.MinorVersion, + Build = b.Number, + Revision = b.Revision + }, + bg => new FrontBuildGroup() + { + Key = bg.Key, + BuildCount = bg.Count(), + LastBuild = bg.Max(b => b.BuildTime) + }) + .SortByDescending(b => b.Key.Major) + .ThenByDescending(b => b.Key.Minor) + .ThenByDescending(b => b.Key.Build) + .ThenByDescending(b => b.Key.Revision) + .Skip(skip) + .Limit(limit); - [DataObjectMethod(DataObjectMethodType.Select, false)] - public IEnumerable SelectBuildLabs() - { - var task = _buildCollection.DistinctAsync(b => b.Lab.ToLower(), b => !string.IsNullOrWhiteSpace(b.Lab)); - task.Wait(); - var outTask = task.Result.ToListAsync(); - outTask.Wait(); - return outTask.Result.OrderBy(b => b); - } + var task = pipeline.ToListAsync(); + task.Wait(); - [DataObjectMethod(DataObjectMethodType.Select, false)] - public IEnumerable SelectBuildLabs(byte major, byte minor) - { - var task = _buildCollection.DistinctAsync(b => b.Lab.ToLower(), b => !string.IsNullOrWhiteSpace(b.Lab) && b.MajorVersion == major && b.MinorVersion == minor); - task.Wait(); - var outTask = task.Result.ToListAsync(); - outTask.Wait(); - return outTask.Result.OrderBy(b => b); - } + return task.Result; + } - [DataObjectMethod(DataObjectMethodType.Insert, true)] - public void Insert(BuildModel item) - { - item.Id = Guid.NewGuid(); - var task = _buildCollection.InsertOneAsync(item); - task.Wait(); - } + [DataObjectMethod(DataObjectMethodType.Select, true)] + public int SelectBuildGroupsCount() + { + var pipeline = _buildCollection.Aggregate() + .Group(b => new BuildGroup() + { + Major = b.MajorVersion, + Minor = b.MinorVersion, + Build = b.Number, + Revision = b.Revision + }, + bg => new BsonDocument()); - [DataObjectMethod(DataObjectMethodType.Update, true)] - public void Update(BuildModel item) - { - BuildModel old = SelectById(item.Id); - item.Added = old.Added; - item.Modified = DateTime.Now; + var task = pipeline.ToListAsync(); + task.Wait(); - var task = _buildCollection.ReplaceOneAsync(f => f.Id == item.Id, item); - task.Wait(); - } + return task.Result.Count(); + } - [DataObjectMethod(DataObjectMethodType.Insert, false)] - public void InsertAll(IEnumerable items) - { - var task = _buildCollection.InsertManyAsync(items); - task.Wait(); - } + [DataObjectMethod(DataObjectMethodType.Select, false)] + public Tuple> SelectSingleBuildGroup(BuildGroup bGroup) + { + var pipeline = _buildCollection.Aggregate() + .Match(b => b.MajorVersion == bGroup.Major) + .Match(b => b.MinorVersion == bGroup.Minor) + .Match(b => b.Number == bGroup.Build) + .Match(b => b.Revision == bGroup.Revision) + .SortByDescending(b => b.BuildTime); - [DataObjectMethod(DataObjectMethodType.Delete, true)] - public void DeleteById(Guid id) - { - var task = _buildCollection.DeleteOneAsync(f => f.Id == id); - task.Wait(); - } - } + var task = pipeline.ToListAsync(); + task.Wait(); - public enum TypeOfSource - { - [Display(ResourceType = typeof(Model), Name = "PublicRelease")] - PublicRelease, + return new Tuple>(bGroup, task.Result); + } - [Display(ResourceType = typeof(Model), Name = "InternalLeak")] - InternalLeak, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public BuildModel SelectById(Guid id) + { + var task = _buildCollection.Find(f => f.Id == id).SingleOrDefaultAsync(); + task.Wait(); + return task.Result; + } - [Display(ResourceType = typeof(Model), Name = "UpdateGDR")] - UpdateGDR, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public BuildModel SelectByLegacyId(long id) + { + var task = _buildCollection.Find(f => f.LegacyId == id).SingleOrDefaultAsync(); + task.Wait(); + return task.Result; + } - [Display(ResourceType = typeof(Model), Name = "UpdateLDR")] - UpdateLDR, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public IEnumerable SelectInBuildOrder() + { + var task = _buildCollection.Find(new BsonDocument()) + .SortByDescending(b => b.BuildTime) + .ThenByDescending(b => b.MajorVersion) + .ThenByDescending(b => b.MinorVersion) + .ThenByDescending(b => b.Number) + .ThenByDescending(b => b.Revision) + .ToListAsync(); + task.Wait(); + return task.Result; + } - [Display(ResourceType = typeof(Model), Name = "AppPackage")] - AppPackage, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public List SelectLabInBuildOrder(string lab, int skip, int limit) + { + var task = _buildCollection.Find(b => b.Lab != null && (b.Lab.ToLower() == lab.ToLower())) + .SortByDescending(b => b.BuildTime) + .ThenByDescending(b => b.MajorVersion) + .ThenByDescending(b => b.MinorVersion) + .ThenByDescending(b => b.Number) + .ThenByDescending(b => b.Revision) + .Skip(skip) + .Limit(limit) + .ToListAsync(); + task.Wait(); + return task.Result; + } - [Display(ResourceType = typeof(Model), Name = "BuildTools")] - BuildTools, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public IEnumerable SelectInVersionOrder() + { + var task = _buildCollection.Find(new BsonDocument()) + .SortByDescending(b => b.MajorVersion) + .ThenByDescending(b => b.MinorVersion) + .ThenByDescending(b => b.Number) + .ThenByDescending(b => b.Revision) + .ThenByDescending(b => b.BuildTime) + .ToListAsync(); + task.Wait(); + return task.Result; + } - [Display(ResourceType = typeof(Model), Name = "Documentation")] - Documentation, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public IEnumerable SelectBuildVersions() + { + var task = _buildCollection.DistinctAsync(b => new BuildVersion() { Major = b.MajorVersion, Minor = b.MinorVersion }, b => true); + task.Wait(); + var outTask = task.Result.ToListAsync(); + outTask.Wait(); + return outTask.Result + .OrderByDescending(y => y.Major) + .ThenByDescending(y => y.Minor); + } - [Display(ResourceType = typeof(Model), Name = "Logging")] - Logging, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public IEnumerable SelectBuildYears() + { + var task = _buildCollection.DistinctAsync(b => b.BuildTime.Value.Year, b => b.BuildTime.HasValue); + task.Wait(); + var outTask = task.Result.ToListAsync(); + outTask.Wait(); + return outTask.Result.OrderBy(b => b); + } - [Display(ResourceType = typeof(Model), Name = "PrivateLeak")] - PrivateLeak - } + [DataObjectMethod(DataObjectMethodType.Select, false)] + public IEnumerable SelectBuildLabs() + { + var task = _buildCollection.DistinctAsync(b => b.Lab.ToLower(), b => !string.IsNullOrWhiteSpace(b.Lab)); + task.Wait(); + var outTask = task.Result.ToListAsync(); + outTask.Wait(); + return outTask.Result.OrderBy(b => b); + } - public enum LevelOfFlight - { - [Display(ResourceType = typeof(Model), Name = "FlightNone")] - None = 0, + [DataObjectMethod(DataObjectMethodType.Select, false)] + public IEnumerable SelectBuildLabs(byte major, byte minor) + { + var task = _buildCollection.DistinctAsync(b => b.Lab.ToLower(), b => !string.IsNullOrWhiteSpace(b.Lab) && b.MajorVersion == major && b.MinorVersion == minor); + task.Wait(); + var outTask = task.Result.ToListAsync(); + outTask.Wait(); + return outTask.Result.OrderBy(b => b); + } - [Display(ResourceType = typeof(Model), Name = "FlightLow")] - Low = 1, + [DataObjectMethod(DataObjectMethodType.Insert, true)] + public void Insert(BuildModel item) + { + item.Id = Guid.NewGuid(); + var task = _buildCollection.InsertOneAsync(item); + task.Wait(); + } - [Display(ResourceType = typeof(Model), Name = "FlightMedium")] - Medium = 2, + [DataObjectMethod(DataObjectMethodType.Insert, false)] + public void InsertAll(IEnumerable items) + { + var task = _buildCollection.InsertManyAsync(items); + task.Wait(); + } - [Display(ResourceType = typeof(Model), Name = "FlightHigh")] - High = 3 - } + [DataObjectMethod(DataObjectMethodType.Update, true)] + public void Update(BuildModel item) + { + BuildModel old = SelectById(item.Id); + item.Added = old.Added; + item.Modified = DateTime.Now; - public struct BuildVersion - { - public byte Major { get; set; } - public byte Minor { get; set; } + var task = _buildCollection.ReplaceOneAsync(f => f.Id == item.Id, item); + task.Wait(); + } - public override string ToString() - { - return $"{Major}.{Minor}"; - } - } + [DataObjectMethod(DataObjectMethodType.Delete, true)] + public void DeleteById(Guid id) + { + var task = _buildCollection.DeleteOneAsync(f => f.Id == id); + task.Wait(); + } + } - public struct BuildGroup - { - public byte Major { get; set; } - public byte Minor { get; set; } - public ushort Build { get; set; } - public ushort? Revision { get; set; } + public enum TypeOfSource + { + [Display(ResourceType = typeof(Model), Name = "PublicRelease")] + PublicRelease, - public override string ToString() - { - return Revision.HasValue ? - $"{Major}.{Minor}.{Build}.{Revision.Value}" : - $"{Major}.{Minor}.{Build}"; - } - } + [Display(ResourceType = typeof(Model), Name = "InternalLeak")] + InternalLeak, + + [Display(ResourceType = typeof(Model), Name = "UpdateGDR")] + UpdateGDR, + + [Display(ResourceType = typeof(Model), Name = "UpdateLDR")] + UpdateLDR, + + [Display(ResourceType = typeof(Model), Name = "AppPackage")] + AppPackage, + + [Display(ResourceType = typeof(Model), Name = "BuildTools")] + BuildTools, + + [Display(ResourceType = typeof(Model), Name = "Documentation")] + Documentation, + + [Display(ResourceType = typeof(Model), Name = "Logging")] + Logging, + + [Display(ResourceType = typeof(Model), Name = "PrivateLeak")] + PrivateLeak + } + + public enum LevelOfFlight + { + [Display(ResourceType = typeof(Model), Name = "FlightNone")] + None = 0, + + [Display(ResourceType = typeof(Model), Name = "FlightLow")] + Low = 1, + + [Display(ResourceType = typeof(Model), Name = "FlightMedium")] + Medium = 2, + + [Display(ResourceType = typeof(Model), Name = "FlightHigh")] + High = 3 + } + + public struct BuildVersion + { + public byte Major { get; set; } + public byte Minor { get; set; } + + public override string ToString() + { + return $"{Major}.{Minor}"; + } + } + + public class BuildGroup + { + public byte Major { get; set; } + public byte Minor { get; set; } + public ushort Build { get; set; } + public ushort? Revision { get; set; } + + public override string ToString() + { + return Revision.HasValue ? + $"{Major}.{Minor}.{Build}.{Revision.Value}" : + $"{Major}.{Minor}.{Build}"; + } + } } \ No newline at end of file diff --git a/BuildFeed/Views/front/editBuild.cshtml b/BuildFeed/Views/front/editBuild.cshtml index 38e7ab1..4fac9e1 100644 --- a/BuildFeed/Views/front/editBuild.cshtml +++ b/BuildFeed/Views/front/editBuild.cshtml @@ -1,4 +1,4 @@ -@model BuildFeed.Models.Build +@model BuildFeed.Models.BuildModel @{ ViewBag.Title = (string)(ViewContext.RouteData.Values["action"]) == "addBuild" ? string.Format("{0} | {1}", BuildFeed.Local.Front.AddABuild, BuildFeed.Local.Common.SiteName) : string.Format("{0} {1} | {2}", BuildFeed.Local.Front.EditBuild, Model.FullBuildString, BuildFeed.Local.Common.SiteName); Html.EnableClientValidation(); diff --git a/BuildFeed/Views/front/viewBuild.cshtml b/BuildFeed/Views/front/viewBuild.cshtml index 53a1cb9..46dae50 100644 --- a/BuildFeed/Views/front/viewBuild.cshtml +++ b/BuildFeed/Views/front/viewBuild.cshtml @@ -1,4 +1,4 @@ -@model BuildFeed.Models.Build +@model BuildFeed.Models.BuildModel @{ ViewBag.Title = Model.FullBuildString + " | BuildFeed"; diff --git a/BuildFeed/Views/front/viewGroup.cshtml b/BuildFeed/Views/front/viewGroup.cshtml index 5593404..316830a 100644 --- a/BuildFeed/Views/front/viewGroup.cshtml +++ b/BuildFeed/Views/front/viewGroup.cshtml @@ -1,13 +1,13 @@ -@model IGrouping +@model Tuple> @using Humanizer; @{ - ViewBag.Title = string.Format("{0} | {1}", Model.Key.ToString(), BuildFeed.Local.Common.SiteName); + ViewBag.Title = string.Format("{0} | {1}", Model.Item1.ToString(), BuildFeed.Local.Common.SiteName); } -

@Model.Key.ToString()

+

@Model.Item1.ToString()

- @foreach (var build in Model.OrderBy(b => b.BuildTime)) + @foreach (var build in Model.Item2) {

@build.Lab

diff --git a/BuildFeed/Views/front/viewLab.cshtml b/BuildFeed/Views/front/viewLab.cshtml index ba8b7a1..66e4095 100644 --- a/BuildFeed/Views/front/viewLab.cshtml +++ b/BuildFeed/Views/front/viewLab.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @using Humanizer; @{ ViewBag.Title = string.Format("{0} {1}{2} | {3}", BuildFeed.Local.Front.BuildsFrom, ViewBag.ItemId, ViewBag.PageNumber == 1 ? "" : string.Format(BuildFeed.Local.Common.PageTitleSegment, ViewBag.PageNumber), BuildFeed.Local.Common.SiteName); diff --git a/BuildFeed/Views/front/viewSource.cshtml b/BuildFeed/Views/front/viewSource.cshtml index 6028416..2d4664a 100644 --- a/BuildFeed/Views/front/viewSource.cshtml +++ b/BuildFeed/Views/front/viewSource.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @using Humanizer; @{ ViewBag.Title = string.Format("{0}{1} | {2}", ViewBag.ItemId, ViewBag.PageNumber == 1 ? "" : string.Format(BuildFeed.Local.Common.PageTitleSegment, ViewBag.PageNumber), @BuildFeed.Local.Common.SiteName); diff --git a/BuildFeed/Views/front/viewVersion.cshtml b/BuildFeed/Views/front/viewVersion.cshtml index c64a3c3..05bfcb2 100644 --- a/BuildFeed/Views/front/viewVersion.cshtml +++ b/BuildFeed/Views/front/viewVersion.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @using Humanizer; @{ ViewBag.Title = string.Format("{0} {1}{2} | {3}", BuildFeed.Local.Common.ProductName, ViewBag.ItemId, ViewBag.PageNumber == 1 ? "" : string.Format(BuildFeed.Local.Common.PageTitleSegment, ViewBag.PageNumber), BuildFeed.Local.Common.SiteName); diff --git a/BuildFeed/Views/front/viewYear.cshtml b/BuildFeed/Views/front/viewYear.cshtml index 95a4b90..6c5f49e 100644 --- a/BuildFeed/Views/front/viewYear.cshtml +++ b/BuildFeed/Views/front/viewYear.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @using Humanizer; @{ ViewBag.Title = string.Format("{0} {1}{2} | {3}", BuildFeed.Local.Front.BuildsFrom, ViewBag.ItemId, ViewBag.PageNumber == 1 ? "" : string.Format(BuildFeed.Local.Common.PageTitleSegment, ViewBag.PageNumber), BuildFeed.Local.Common.SiteName); diff --git a/BuildFeed/Web.config b/BuildFeed/Web.config index 5343bb4..832607c 100644 --- a/BuildFeed/Web.config +++ b/BuildFeed/Web.config @@ -10,11 +10,8 @@ - - - - + diff --git a/BuildFeed/content/style.css b/BuildFeed/content/style.css index 318c8c2..31539da 100644 --- a/BuildFeed/content/style.css +++ b/BuildFeed/content/style.css @@ -125,7 +125,17 @@ label, .control-label, .help-block, .checkbox, .radio white-space: nowrap; } -#search-results .list-group-item-heading h4 + #search-results .list-group-item-heading h4 { font-size: 16px; } + +#haackroutedebugger +{ + color: #000; +} + + #haackroutedebugger h1, #haackroutedebugger h2, #haackroutedebugger h3 + { + text-shadow: none; + } diff --git a/RedisMongoMigration/Build.cs b/RedisMongoMigration/Build.cs new file mode 100644 index 0000000..8babc32 --- /dev/null +++ b/RedisMongoMigration/Build.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RedisMongoMigration +{ + public enum TypeOfSource + { + PublicRelease, + InternalLeak, + UpdateGDR, + UpdateLDR, + AppPackage, + BuildTools, + Documentation, + Logging, + PrivateLeak + } + + public enum LevelOfFlight + { + None = 0, + Low = 1, + Medium = 2, + High = 3 + } +} diff --git a/RedisMongoMigration/Mongo/Build.cs b/RedisMongoMigration/Mongo/Build.cs new file mode 100644 index 0000000..7df3ba4 --- /dev/null +++ b/RedisMongoMigration/Mongo/Build.cs @@ -0,0 +1,110 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver; +using System; +using System.Collections.Generic; +using System.Text; + +namespace RedisMongoMigration.Mongo +{ + public class BuildModel + { + [BsonId] + public Guid Id { get; set; } + public long? LegacyId { get; set; } + public byte MajorVersion { get; set; } + public byte MinorVersion { get; set; } + public ushort Number { get; set; } + public ushort? Revision { get; set; } + public string Lab { get; set; } + public DateTime? BuildTime { get; set; } + + public DateTime Added { get; set; } + public DateTime Modified { get; set; } + public TypeOfSource SourceType { get; set; } + public string SourceDetails { get; set; } + public DateTime? LeakDate { get; set; } + public LevelOfFlight FlightLevel { get; set; } + + public bool IsLeaked + { + get + { + switch (SourceType) + { + case TypeOfSource.PublicRelease: + case TypeOfSource.InternalLeak: + case TypeOfSource.UpdateGDR: + case TypeOfSource.UpdateLDR: + return true; + default: + return false; + } + } + } + + public string FullBuildString + { + get + { + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("{0}.{1}.{2}", MajorVersion, MinorVersion, Number); + + if (Revision.HasValue) + { + sb.AppendFormat(".{0}", Revision); + } + + if (!string.IsNullOrWhiteSpace(Lab)) + { + sb.AppendFormat(".{0}", Lab); + } + + if (BuildTime.HasValue) + { + sb.AppendFormat(".{0:yyMMdd-HHmm}", BuildTime); + } + + return sb.ToString(); + } + } + } + + public class Build + { + private const string _buildCollectionName = "builds"; + + private MongoClient _dbClient; + private IMongoCollection _buildCollection; + + public Build() + { + _dbClient = new MongoClient(new MongoClientSettings() + { + Server = new MongoServerAddress("localhost", 27017) + }); + + _buildCollection = _dbClient.GetDatabase("BuildFeed").GetCollection(_buildCollectionName); + } + + public List Select() + { + var task = _buildCollection.Find(new BsonDocument()).ToListAsync(); + task.Wait(); + return task.Result; + } + + public void Insert(BuildModel item) + { + item.Id = Guid.NewGuid(); + var task = _buildCollection.InsertOneAsync(item); + task.Wait(); + } + + public void InsertAll(IEnumerable items) + { + var task = _buildCollection.InsertManyAsync(items); + task.Wait(); + } + } +} diff --git a/RedisMongoMigration/Program.cs b/RedisMongoMigration/Program.cs index 920d29d..4116e55 100644 --- a/RedisMongoMigration/Program.cs +++ b/RedisMongoMigration/Program.cs @@ -4,12 +4,41 @@ using System.Text; using System.Threading.Tasks; +using MBuildModel = RedisMongoMigration.Mongo.BuildModel; +using MBuild = RedisMongoMigration.Mongo.Build; +using RBuild = RedisMongoMigration.Redis.Build; + namespace RedisMongoMigration { - class Program - { - static void Main(string[] args) - { - } - } + class Program + { + static void Main(string[] args) + { + var builds = RBuild.Select(); + var newBuilds = from b in builds + select new MBuildModel() + { + Id = Guid.NewGuid(), + LegacyId = b.Id, + + MajorVersion = b.MajorVersion, + MinorVersion = b.MinorVersion, + Number = b.Number, + Revision = b.Revision, + Lab = b.Lab, + BuildTime = b.BuildTime, + + Added = b.Added, + Modified = b.Modified, + SourceType = b.SourceType, + SourceDetails = b.SourceDetails, + LeakDate = b.LeakDate, + FlightLevel = b.FlightLevel + }; + MBuild m = new MBuild(); + m.InsertAll(newBuilds); + Console.WriteLine("Builds: Complete"); + Console.ReadKey(); + } + } } diff --git a/RedisMongoMigration/Redis/Build.cs b/RedisMongoMigration/Redis/Build.cs index 843535b..f076bf2 100644 --- a/RedisMongoMigration/Redis/Build.cs +++ b/RedisMongoMigration/Redis/Build.cs @@ -1,6 +1,8 @@ using NServiceKit.DataAnnotations; using NServiceKit.DesignPatterns.Model; +using NServiceKit.Redis; using System; +using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Text; @@ -14,30 +16,18 @@ public class Build : IHasId [AutoIncrement] [Index] public long Id { get; set; } - public byte MajorVersion { get; set; } - public byte MinorVersion { get; set; } - public ushort Number { get; set; } - public ushort? Revision { get; set; } - public string Lab { get; set; } - public DateTime? BuildTime { get; set; } - public DateTime Added { get; set; } - public DateTime Modified { get; set; } - public TypeOfSource SourceType { get; set; } - public string SourceDetails { get; set; } - public DateTime? LeakDate { get; set; } - public LevelOfFlight FlightLevel { get; set; } public bool IsLeaked @@ -80,53 +70,15 @@ public string FullBuildString return sb.ToString(); } - } - } + } - public enum TypeOfSource - { - PublicRelease, - InternalLeak, - UpdateGDR, - UpdateLDR, - AppPackage, - BuildTools, - Documentation, - Logging, - PrivateLeak - } - - public enum LevelOfFlight - { - None = 0, - Low = 1, - Medium = 2, - High = 3 - } - - public struct BuildVersion - { - public byte Major { get; set; } - public byte Minor { get; set; } - - public override string ToString() - { - return $"{Major}.{Minor}"; - } - } - - public struct BuildGroup - { - public byte Major { get; set; } - public byte Minor { get; set; } - public ushort Build { get; set; } - public ushort? Revision { get; set; } - - public override string ToString() - { - return Revision.HasValue ? - $"{Major}.{Minor}.{Build}.{Revision.Value}" : - $"{Major}.{Minor}.{Build}"; - } - } + public static IEnumerable Select() + { + using (RedisClient rClient = new RedisClient("localhost", 6379, db: 1)) + { + var client = rClient.As(); + return client.GetAll(); + } + } + } } diff --git a/RedisMongoMigration/RedisMongoMigration.csproj b/RedisMongoMigration/RedisMongoMigration.csproj index 329b7a1..a5e389c 100644 --- a/RedisMongoMigration/RedisMongoMigration.csproj +++ b/RedisMongoMigration/RedisMongoMigration.csproj @@ -33,6 +33,18 @@ 4 + + ..\packages\MongoDB.Bson.2.0.1\lib\net45\MongoDB.Bson.dll + True + + + ..\packages\MongoDB.Driver.2.0.1\lib\net45\MongoDB.Driver.dll + True + + + ..\packages\MongoDB.Driver.Core.2.0.1\lib\net45\MongoDB.Driver.Core.dll + True + ..\packages\NServiceKit.Common.1.0.31\lib\net35\NServiceKit.Common.dll True @@ -60,6 +72,8 @@ + + @@ -71,6 +85,7 @@ +