From d7add894419543667e60569bfeb439e8e797a4d1 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 23 May 2020 19:25:34 -0400 Subject: drop MongoDB code MongoDB support unnecessarily complicated the code and there's no need to run distributed servers in the foreseeable future. This keeps the abstract storage interface so we can wrap a distributed cache in the future. --- src/SMAPI.Web/Framework/Caching/Cached.cs | 37 ++++ src/SMAPI.Web/Framework/Caching/Mods/CachedMod.cs | 107 ---------- .../Framework/Caching/Mods/IModCacheRepository.cs | 5 +- .../Caching/Mods/ModCacheMemoryRepository.cs | 30 +-- .../Caching/Mods/ModCacheMongoRepository.cs | 105 ---------- .../Caching/UtcDateTimeOffsetSerializer.cs | 40 ---- .../Framework/Caching/Wiki/CachedWikiMetadata.cs | 43 ---- .../Framework/Caching/Wiki/CachedWikiMod.cs | 230 --------------------- .../Framework/Caching/Wiki/IWikiCacheRepository.cs | 9 +- .../Caching/Wiki/WikiCacheMemoryRepository.cs | 25 ++- .../Caching/Wiki/WikiCacheMongoRepository.cs | 73 ------- .../Framework/Caching/Wiki/WikiMetadata.cs | 31 +++ 12 files changed, 96 insertions(+), 639 deletions(-) create mode 100644 src/SMAPI.Web/Framework/Caching/Cached.cs delete mode 100644 src/SMAPI.Web/Framework/Caching/Mods/CachedMod.cs delete mode 100644 src/SMAPI.Web/Framework/Caching/Mods/ModCacheMongoRepository.cs delete mode 100644 src/SMAPI.Web/Framework/Caching/UtcDateTimeOffsetSerializer.cs delete mode 100644 src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMetadata.cs delete mode 100644 src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMod.cs delete mode 100644 src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMongoRepository.cs create mode 100644 src/SMAPI.Web/Framework/Caching/Wiki/WikiMetadata.cs (limited to 'src/SMAPI.Web/Framework/Caching') diff --git a/src/SMAPI.Web/Framework/Caching/Cached.cs b/src/SMAPI.Web/Framework/Caching/Cached.cs new file mode 100644 index 00000000..52041a16 --- /dev/null +++ b/src/SMAPI.Web/Framework/Caching/Cached.cs @@ -0,0 +1,37 @@ +using System; + +namespace StardewModdingAPI.Web.Framework.Caching +{ + /// A cache entry. + /// The cached value type. + internal class Cached + { + /********* + ** Accessors + *********/ + /// The cached data. + public T Data { get; set; } + + /// When the data was last updated. + public DateTimeOffset LastUpdated { get; set; } + + /// When the data was last requested through the mod API. + public DateTimeOffset LastRequested { get; set; } + + + /********* + ** Public methods + *********/ + /// Construct an empty instance. + public Cached() { } + + /// Construct an instance. + /// The cached data. + public Cached(T data) + { + this.Data = data; + this.LastUpdated = DateTimeOffset.UtcNow; + this.LastRequested = DateTimeOffset.UtcNow; + } + } +} diff --git a/src/SMAPI.Web/Framework/Caching/Mods/CachedMod.cs b/src/SMAPI.Web/Framework/Caching/Mods/CachedMod.cs deleted file mode 100644 index 96eca847..00000000 --- a/src/SMAPI.Web/Framework/Caching/Mods/CachedMod.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using StardewModdingAPI.Toolkit.Framework.UpdateData; -using StardewModdingAPI.Web.Framework.ModRepositories; - -namespace StardewModdingAPI.Web.Framework.Caching.Mods -{ - /// The model for cached mod data. - internal class CachedMod - { - /********* - ** Accessors - *********/ - /**** - ** Tracking - ****/ - /// The internal MongoDB ID. - [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Named per MongoDB conventions.")] - [BsonIgnoreIfDefault] - public ObjectId _id { get; set; } - - /// When the data was last updated. - public DateTimeOffset LastUpdated { get; set; } - - /// When the data was last requested through the web API. - public DateTimeOffset LastRequested { get; set; } - - /**** - ** Metadata - ****/ - /// The mod site on which the mod is found. - public ModRepositoryKey Site { get; set; } - - /// The mod's unique ID within the . - public string ID { get; set; } - - /// The mod availability status on the remote site. - public RemoteModStatus FetchStatus { get; set; } - - /// The error message providing more info for the , if applicable. - public string FetchError { get; set; } - - - /**** - ** Mod info - ****/ - /// The mod's display name. - public string Name { get; set; } - - /// The mod's latest version. - public string MainVersion { get; set; } - - /// The mod's latest optional or prerelease version, if newer than . - public string PreviewVersion { get; set; } - - /// The URL for the mod page. - public string Url { get; set; } - - /// The license URL, if available. - public string LicenseUrl { get; set; } - - /// The license name, if available. - public string LicenseName { get; set; } - - - /********* - ** Accessors - *********/ - /// Construct an instance. - public CachedMod() { } - - /// Construct an instance. - /// The mod site on which the mod is found. - /// The mod's unique ID within the . - /// The mod data. - public CachedMod(ModRepositoryKey site, string id, ModInfoModel mod) - { - // tracking - this.LastUpdated = DateTimeOffset.UtcNow; - this.LastRequested = DateTimeOffset.UtcNow; - - // metadata - this.Site = site; - this.ID = id; - this.FetchStatus = mod.Status; - this.FetchError = mod.Error; - - // mod info - this.Name = mod.Name; - this.MainVersion = mod.Version; - this.PreviewVersion = mod.PreviewVersion; - this.Url = mod.Url; - this.LicenseUrl = mod.LicenseUrl; - this.LicenseName = mod.LicenseName; - } - - /// Get the API model for the cached data. - public ModInfoModel GetModel() - { - return new ModInfoModel(name: this.Name, version: this.MainVersion, url: this.Url, previewVersion: this.PreviewVersion) - .SetLicense(this.LicenseUrl, this.LicenseName) - .SetError(this.FetchStatus, this.FetchError); - } - } -} diff --git a/src/SMAPI.Web/Framework/Caching/Mods/IModCacheRepository.cs b/src/SMAPI.Web/Framework/Caching/Mods/IModCacheRepository.cs index 08749f3b..004202f9 100644 --- a/src/SMAPI.Web/Framework/Caching/Mods/IModCacheRepository.cs +++ b/src/SMAPI.Web/Framework/Caching/Mods/IModCacheRepository.cs @@ -15,14 +15,13 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods /// The mod's unique ID within the . /// The fetched mod. /// Whether to update the mod's 'last requested' date. - bool TryGetMod(ModRepositoryKey site, string id, out CachedMod mod, bool markRequested = true); + bool TryGetMod(ModRepositoryKey site, string id, out Cached mod, bool markRequested = true); /// Save data fetched for a mod. /// The mod site on which the mod is found. /// The mod's unique ID within the . /// The mod data. - /// The stored mod record. - void SaveMod(ModRepositoryKey site, string id, ModInfoModel mod, out CachedMod cachedMod); + void SaveMod(ModRepositoryKey site, string id, ModInfoModel mod); /// Delete data for mods which haven't been requested within a given time limit. /// The minimum age for which to remove mods. diff --git a/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs b/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs index 9c5a217e..62461116 100644 --- a/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs +++ b/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs @@ -13,7 +13,7 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods ** Fields *********/ /// The cached mod data indexed by {site key}:{ID}. - private readonly IDictionary Mods = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + private readonly IDictionary> Mods = new Dictionary>(StringComparer.InvariantCultureIgnoreCase); /********* @@ -24,19 +24,20 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods /// The mod's unique ID within the . /// The fetched mod. /// Whether to update the mod's 'last requested' date. - public bool TryGetMod(ModRepositoryKey site, string id, out CachedMod mod, bool markRequested = true) + public bool TryGetMod(ModRepositoryKey site, string id, out Cached mod, bool markRequested = true) { // get mod - if (!this.Mods.TryGetValue(this.GetKey(site, id), out mod)) + if (!this.Mods.TryGetValue(this.GetKey(site, id), out var cachedMod)) + { + mod = null; return false; + } // bump 'last requested' if (markRequested) - { - mod.LastRequested = DateTimeOffset.UtcNow; - mod = this.SaveMod(mod); - } + cachedMod.LastRequested = DateTimeOffset.UtcNow; + mod = cachedMod; return true; } @@ -44,11 +45,10 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods /// The mod site on which the mod is found. /// The mod's unique ID within the . /// The mod data. - /// The stored mod record. - public void SaveMod(ModRepositoryKey site, string id, ModInfoModel mod, out CachedMod cachedMod) + public void SaveMod(ModRepositoryKey site, string id, ModInfoModel mod) { string key = this.GetKey(site, id); - cachedMod = this.SaveMod(new CachedMod(site, id, mod)); + this.Mods[key] = new Cached(mod); } /// Delete data for mods which haven't been requested within a given time limit. @@ -66,14 +66,6 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods this.Mods.Remove(key); } - /// Save data fetched for a mod. - /// The mod data. - public CachedMod SaveMod(CachedMod mod) - { - string key = this.GetKey(mod.Site, mod.ID); - return this.Mods[key] = mod; - } - /********* ** Private methods @@ -81,7 +73,7 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods /// Get a cache key. /// The mod site. /// The mod ID. - public string GetKey(ModRepositoryKey site, string id) + private string GetKey(ModRepositoryKey site, string id) { return $"{site}:{id.Trim()}".ToLower(); } diff --git a/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMongoRepository.cs b/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMongoRepository.cs deleted file mode 100644 index f105baab..00000000 --- a/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMongoRepository.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using MongoDB.Driver; -using StardewModdingAPI.Toolkit.Framework.UpdateData; -using StardewModdingAPI.Web.Framework.ModRepositories; - -namespace StardewModdingAPI.Web.Framework.Caching.Mods -{ - /// Manages cached mod data in MongoDB. - internal class ModCacheMongoRepository : BaseCacheRepository, IModCacheRepository - { - /********* - ** Fields - *********/ - /// The collection for cached mod data. - private readonly IMongoCollection Mods; - - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The authenticated MongoDB database. - public ModCacheMongoRepository(IMongoDatabase database) - { - // get collections - this.Mods = database.GetCollection("mods"); - - // add indexes if needed - this.Mods.Indexes.CreateOne(new CreateIndexModel(Builders.IndexKeys.Ascending(p => p.ID).Ascending(p => p.Site))); - } - - - /********* - ** Public methods - *********/ - /// Get the cached mod data. - /// The mod site to search. - /// The mod's unique ID within the . - /// The fetched mod. - /// Whether to update the mod's 'last requested' date. - public bool TryGetMod(ModRepositoryKey site, string id, out CachedMod mod, bool markRequested = true) - { - // get mod - id = this.NormalizeId(id); - mod = this.Mods.Find(entry => entry.ID == id && entry.Site == site).FirstOrDefault(); - if (mod == null) - return false; - - // bump 'last requested' - if (markRequested) - { - mod.LastRequested = DateTimeOffset.UtcNow; - mod = this.SaveMod(mod); - } - - return true; - } - - /// Save data fetched for a mod. - /// The mod site on which the mod is found. - /// The mod's unique ID within the . - /// The mod data. - /// The stored mod record. - public void SaveMod(ModRepositoryKey site, string id, ModInfoModel mod, out CachedMod cachedMod) - { - id = this.NormalizeId(id); - - cachedMod = this.SaveMod(new CachedMod(site, id, mod)); - } - - /// Delete data for mods which haven't been requested within a given time limit. - /// The minimum age for which to remove mods. - public void RemoveStaleMods(TimeSpan age) - { - DateTimeOffset minDate = DateTimeOffset.UtcNow.Subtract(age); - this.Mods.DeleteMany(p => p.LastRequested < minDate); - } - - /// Save data fetched for a mod. - /// The mod data. - public CachedMod SaveMod(CachedMod mod) - { - string id = this.NormalizeId(mod.ID); - - this.Mods.ReplaceOne( - entry => entry.ID == id && entry.Site == mod.Site, - mod, - new ReplaceOptions { IsUpsert = true } - ); - - return mod; - } - - - /********* - ** Private methods - *********/ - /// Normalize a mod ID for case-insensitive search. - /// The mod ID. - public string NormalizeId(string id) - { - return id.Trim().ToLower(); - } - } -} diff --git a/src/SMAPI.Web/Framework/Caching/UtcDateTimeOffsetSerializer.cs b/src/SMAPI.Web/Framework/Caching/UtcDateTimeOffsetSerializer.cs deleted file mode 100644 index 6a103e37..00000000 --- a/src/SMAPI.Web/Framework/Caching/UtcDateTimeOffsetSerializer.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using MongoDB.Bson; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; - -namespace StardewModdingAPI.Web.Framework.Caching -{ - /// Serializes to a UTC date field instead of the default array. - public class UtcDateTimeOffsetSerializer : StructSerializerBase - { - /********* - ** Fields - *********/ - /// The underlying date serializer. - private static readonly DateTimeSerializer DateTimeSerializer = new DateTimeSerializer(DateTimeKind.Utc, BsonType.DateTime); - - - /********* - ** Public methods - *********/ - /// Deserializes a value. - /// The deserialization context. - /// The deserialization args. - /// A deserialized value. - public override DateTimeOffset Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) - { - DateTime date = UtcDateTimeOffsetSerializer.DateTimeSerializer.Deserialize(context, args); - return new DateTimeOffset(date, TimeSpan.Zero); - } - - /// Serializes a value. - /// The serialization context. - /// The serialization args. - /// The object. - public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTimeOffset value) - { - UtcDateTimeOffsetSerializer.DateTimeSerializer.Serialize(context, args, value.UtcDateTime); - } - } -} diff --git a/src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMetadata.cs b/src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMetadata.cs deleted file mode 100644 index 6a560eb4..00000000 --- a/src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMetadata.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using MongoDB.Bson; - -namespace StardewModdingAPI.Web.Framework.Caching.Wiki -{ - /// The model for cached wiki metadata. - internal class CachedWikiMetadata - { - /********* - ** Accessors - *********/ - /// The internal MongoDB ID. - [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Named per MongoDB conventions.")] - public ObjectId _id { get; set; } - - /// When the data was last updated. - public DateTimeOffset LastUpdated { get; set; } - - /// The current stable Stardew Valley version. - public string StableVersion { get; set; } - - /// The current beta Stardew Valley version. - public string BetaVersion { get; set; } - - - /********* - ** Public methods - *********/ - /// Construct an instance. - public CachedWikiMetadata() { } - - /// Construct an instance. - /// The current stable Stardew Valley version. - /// The current beta Stardew Valley version. - public CachedWikiMetadata(string stableVersion, string betaVersion) - { - this.StableVersion = stableVersion; - this.BetaVersion = betaVersion; - this.LastUpdated = DateTimeOffset.UtcNow; - } - } -} diff --git a/src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMod.cs b/src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMod.cs deleted file mode 100644 index 7e7c99bc..00000000 --- a/src/SMAPI.Web/Framework/Caching/Wiki/CachedWikiMod.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Bson.Serialization.Options; -using StardewModdingAPI.Toolkit; -using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; - -namespace StardewModdingAPI.Web.Framework.Caching.Wiki -{ - /// The model for cached wiki mods. - internal class CachedWikiMod - { - /********* - ** Accessors - *********/ - /**** - ** Tracking - ****/ - /// The internal MongoDB ID. - [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Named per MongoDB conventions.")] - public ObjectId _id { get; set; } - - /// When the data was last updated. - public DateTimeOffset LastUpdated { get; set; } - - /**** - ** Mod info - ****/ - /// The mod's unique ID. If the mod has alternate/old IDs, they're listed in latest to newest order. - public string[] ID { get; set; } - - /// The mod's display name. If the mod has multiple names, the first one is the most canonical name. - public string[] Name { get; set; } - - /// The mod's author name. If the author has multiple names, the first one is the most canonical name. - public string[] Author { get; set; } - - /// The mod ID on Nexus. - public int? NexusID { get; set; } - - /// The mod ID in the Chucklefish mod repo. - public int? ChucklefishID { get; set; } - - /// The mod ID in the CurseForge mod repo. - public int? CurseForgeID { get; set; } - - /// The mod key in the CurseForge mod repo (used in mod page URLs). - public string CurseForgeKey { get; set; } - - /// The mod ID in the ModDrop mod repo. - public int? ModDropID { get; set; } - - /// The GitHub repository in the form 'owner/repo'. - public string GitHubRepo { get; set; } - - /// The URL to a non-GitHub source repo. - public string CustomSourceUrl { get; set; } - - /// The custom mod page URL (if applicable). - public string CustomUrl { get; set; } - - /// The name of the mod which loads this content pack, if applicable. - public string ContentPackFor { get; set; } - - /// The human-readable warnings for players about this mod. - public string[] Warnings { get; set; } - - /// The URL of the pull request which submits changes for an unofficial update to the author, if any. - public string PullRequestUrl { get; set; } - - /// Special notes intended for developers who maintain unofficial updates or submit pull requests. - public string DevNote { get; set; } - - /// The link anchor for the mod entry in the wiki compatibility list. - public string Anchor { get; set; } - - /**** - ** Stable compatibility - ****/ - /// The compatibility status. - public WikiCompatibilityStatus MainStatus { get; set; } - - /// The human-readable summary of the compatibility status or workaround, without HTML formatting. - public string MainSummary { get; set; } - - /// The game or SMAPI version which broke this mod (if applicable). - public string MainBrokeIn { get; set; } - - /// The version of the latest unofficial update, if applicable. - public string MainUnofficialVersion { get; set; } - - /// The URL to the latest unofficial update, if applicable. - public string MainUnofficialUrl { get; set; } - - /**** - ** Beta compatibility - ****/ - /// The compatibility status. - public WikiCompatibilityStatus? BetaStatus { get; set; } - - /// The human-readable summary of the compatibility status or workaround, without HTML formatting. - public string BetaSummary { get; set; } - - /// The game or SMAPI version which broke this mod (if applicable). - public string BetaBrokeIn { get; set; } - - /// The version of the latest unofficial update, if applicable. - public string BetaUnofficialVersion { get; set; } - - /// The URL to the latest unofficial update, if applicable. - public string BetaUnofficialUrl { get; set; } - - /**** - ** Version maps - ****/ - /// Maps local versions to a semantic version for update checks. - [BsonDictionaryOptions(Representation = DictionaryRepresentation.ArrayOfArrays)] - public IDictionary MapLocalVersions { get; set; } - - /// Maps remote versions to a semantic version for update checks. - [BsonDictionaryOptions(Representation = DictionaryRepresentation.ArrayOfArrays)] - public IDictionary MapRemoteVersions { get; set; } - - - /********* - ** Accessors - *********/ - /// Construct an instance. - public CachedWikiMod() { } - - /// Construct an instance. - /// The mod data. - public CachedWikiMod(WikiModEntry mod) - { - // tracking - this.LastUpdated = DateTimeOffset.UtcNow; - - // mod info - this.ID = mod.ID; - this.Name = mod.Name; - this.Author = mod.Author; - this.NexusID = mod.NexusID; - this.ChucklefishID = mod.ChucklefishID; - this.CurseForgeID = mod.CurseForgeID; - this.CurseForgeKey = mod.CurseForgeKey; - this.ModDropID = mod.ModDropID; - this.GitHubRepo = mod.GitHubRepo; - this.CustomSourceUrl = mod.CustomSourceUrl; - this.CustomUrl = mod.CustomUrl; - this.ContentPackFor = mod.ContentPackFor; - this.PullRequestUrl = mod.PullRequestUrl; - this.Warnings = mod.Warnings; - this.DevNote = mod.DevNote; - this.Anchor = mod.Anchor; - - // stable compatibility - this.MainStatus = mod.Compatibility.Status; - this.MainSummary = mod.Compatibility.Summary; - this.MainBrokeIn = mod.Compatibility.BrokeIn; - this.MainUnofficialVersion = mod.Compatibility.UnofficialVersion?.ToString(); - this.MainUnofficialUrl = mod.Compatibility.UnofficialUrl; - - // beta compatibility - this.BetaStatus = mod.BetaCompatibility?.Status; - this.BetaSummary = mod.BetaCompatibility?.Summary; - this.BetaBrokeIn = mod.BetaCompatibility?.BrokeIn; - this.BetaUnofficialVersion = mod.BetaCompatibility?.UnofficialVersion?.ToString(); - this.BetaUnofficialUrl = mod.BetaCompatibility?.UnofficialUrl; - - // version maps - this.MapLocalVersions = mod.MapLocalVersions; - this.MapRemoteVersions = mod.MapRemoteVersions; - } - - /// Reconstruct the original model. - public WikiModEntry GetModel() - { - var mod = new WikiModEntry - { - ID = this.ID, - Name = this.Name, - Author = this.Author, - NexusID = this.NexusID, - ChucklefishID = this.ChucklefishID, - CurseForgeID = this.CurseForgeID, - CurseForgeKey = this.CurseForgeKey, - ModDropID = this.ModDropID, - GitHubRepo = this.GitHubRepo, - CustomSourceUrl = this.CustomSourceUrl, - CustomUrl = this.CustomUrl, - ContentPackFor = this.ContentPackFor, - Warnings = this.Warnings, - PullRequestUrl = this.PullRequestUrl, - DevNote = this.DevNote, - Anchor = this.Anchor, - - // stable compatibility - Compatibility = new WikiCompatibilityInfo - { - Status = this.MainStatus, - Summary = this.MainSummary, - BrokeIn = this.MainBrokeIn, - UnofficialVersion = this.MainUnofficialVersion != null ? new SemanticVersion(this.MainUnofficialVersion) : null, - UnofficialUrl = this.MainUnofficialUrl - }, - - // version maps - MapLocalVersions = this.MapLocalVersions, - MapRemoteVersions = this.MapRemoteVersions - }; - - // beta compatibility - if (this.BetaStatus != null) - { - mod.BetaCompatibility = new WikiCompatibilityInfo - { - Status = this.BetaStatus.Value, - Summary = this.BetaSummary, - BrokeIn = this.BetaBrokeIn, - UnofficialVersion = this.BetaUnofficialVersion != null ? new SemanticVersion(this.BetaUnofficialVersion) : null, - UnofficialUrl = this.BetaUnofficialUrl - }; - } - - return mod; - } - } -} diff --git a/src/SMAPI.Web/Framework/Caching/Wiki/IWikiCacheRepository.cs b/src/SMAPI.Web/Framework/Caching/Wiki/IWikiCacheRepository.cs index 02097f52..2ab7ea5a 100644 --- a/src/SMAPI.Web/Framework/Caching/Wiki/IWikiCacheRepository.cs +++ b/src/SMAPI.Web/Framework/Caching/Wiki/IWikiCacheRepository.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq.Expressions; using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; namespace StardewModdingAPI.Web.Framework.Caching.Wiki @@ -13,18 +12,16 @@ namespace StardewModdingAPI.Web.Framework.Caching.Wiki *********/ /// Get the cached wiki metadata. /// The fetched metadata. - bool TryGetWikiMetadata(out CachedWikiMetadata metadata); + bool TryGetWikiMetadata(out Cached metadata); /// Get the cached wiki mods. /// A filter to apply, if any. - IEnumerable GetWikiMods(Expression> filter = null); + IEnumerable> GetWikiMods(Func filter = null); /// Save data fetched from the wiki compatibility list. /// The current stable Stardew Valley version. /// The current beta Stardew Valley version. /// The mod data. - /// The stored metadata record. - /// The stored mod records. - void SaveWikiData(string stableVersion, string betaVersion, IEnumerable mods, out CachedWikiMetadata cachedMetadata, out CachedWikiMod[] cachedMods); + void SaveWikiData(string stableVersion, string betaVersion, IEnumerable mods); } } diff --git a/src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMemoryRepository.cs b/src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMemoryRepository.cs index 4621f5e3..064a7c3c 100644 --- a/src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMemoryRepository.cs +++ b/src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMemoryRepository.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; namespace StardewModdingAPI.Web.Framework.Caching.Wiki @@ -13,10 +12,10 @@ namespace StardewModdingAPI.Web.Framework.Caching.Wiki ** Fields *********/ /// The saved wiki metadata. - private CachedWikiMetadata Metadata; + private Cached Metadata; /// The cached wiki data. - private CachedWikiMod[] Mods = new CachedWikiMod[0]; + private Cached[] Mods = new Cached[0]; /********* @@ -24,7 +23,7 @@ namespace StardewModdingAPI.Web.Framework.Caching.Wiki *********/ /// Get the cached wiki metadata. /// The fetched metadata. - public bool TryGetWikiMetadata(out CachedWikiMetadata metadata) + public bool TryGetWikiMetadata(out Cached metadata) { metadata = this.Metadata; return metadata != null; @@ -32,23 +31,23 @@ namespace StardewModdingAPI.Web.Framework.Caching.Wiki /// Get the cached wiki mods. /// A filter to apply, if any. - public IEnumerable GetWikiMods(Expression> filter = null) + public IEnumerable> GetWikiMods(Func filter = null) { - return filter != null - ? this.Mods.Where(filter.Compile()) - : this.Mods.ToArray(); + foreach (var mod in this.Mods) + { + if (filter == null || filter(mod.Data)) + yield return mod; + } } /// Save data fetched from the wiki compatibility list. /// The current stable Stardew Valley version. /// The current beta Stardew Valley version. /// The mod data. - /// The stored metadata record. - /// The stored mod records. - public void SaveWikiData(string stableVersion, string betaVersion, IEnumerable mods, out CachedWikiMetadata cachedMetadata, out CachedWikiMod[] cachedMods) + public void SaveWikiData(string stableVersion, string betaVersion, IEnumerable mods) { - this.Metadata = cachedMetadata = new CachedWikiMetadata(stableVersion, betaVersion); - this.Mods = cachedMods = mods.Select(mod => new CachedWikiMod(mod)).ToArray(); + this.Metadata = new Cached(new WikiMetadata(stableVersion, betaVersion)); + this.Mods = mods.Select(mod => new Cached(mod)).ToArray(); } } } diff --git a/src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMongoRepository.cs b/src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMongoRepository.cs deleted file mode 100644 index 07e7c721..00000000 --- a/src/SMAPI.Web/Framework/Caching/Wiki/WikiCacheMongoRepository.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using MongoDB.Driver; -using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; - -namespace StardewModdingAPI.Web.Framework.Caching.Wiki -{ - /// Manages cached wiki data in MongoDB. - internal class WikiCacheMongoRepository : BaseCacheRepository, IWikiCacheRepository - { - /********* - ** Fields - *********/ - /// The collection for wiki metadata. - private readonly IMongoCollection Metadata; - - /// The collection for wiki mod data. - private readonly IMongoCollection Mods; - - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The authenticated MongoDB database. - public WikiCacheMongoRepository(IMongoDatabase database) - { - // get collections - this.Metadata = database.GetCollection("wiki-metadata"); - this.Mods = database.GetCollection("wiki-mods"); - - // add indexes if needed - this.Mods.Indexes.CreateOne(new CreateIndexModel(Builders.IndexKeys.Ascending(p => p.ID))); - } - - /// Get the cached wiki metadata. - /// The fetched metadata. - public bool TryGetWikiMetadata(out CachedWikiMetadata metadata) - { - metadata = this.Metadata.Find("{}").FirstOrDefault(); - return metadata != null; - } - - /// Get the cached wiki mods. - /// A filter to apply, if any. - public IEnumerable GetWikiMods(Expression> filter = null) - { - return filter != null - ? this.Mods.Find(filter).ToList() - : this.Mods.Find("{}").ToList(); - } - - /// Save data fetched from the wiki compatibility list. - /// The current stable Stardew Valley version. - /// The current beta Stardew Valley version. - /// The mod data. - /// The stored metadata record. - /// The stored mod records. - public void SaveWikiData(string stableVersion, string betaVersion, IEnumerable mods, out CachedWikiMetadata cachedMetadata, out CachedWikiMod[] cachedMods) - { - cachedMetadata = new CachedWikiMetadata(stableVersion, betaVersion); - cachedMods = mods.Select(mod => new CachedWikiMod(mod)).ToArray(); - - this.Mods.DeleteMany("{}"); - this.Mods.InsertMany(cachedMods); - - this.Metadata.DeleteMany("{}"); - this.Metadata.InsertOne(cachedMetadata); - } - } -} diff --git a/src/SMAPI.Web/Framework/Caching/Wiki/WikiMetadata.cs b/src/SMAPI.Web/Framework/Caching/Wiki/WikiMetadata.cs new file mode 100644 index 00000000..c04de4a5 --- /dev/null +++ b/src/SMAPI.Web/Framework/Caching/Wiki/WikiMetadata.cs @@ -0,0 +1,31 @@ +namespace StardewModdingAPI.Web.Framework.Caching.Wiki +{ + /// The model for cached wiki metadata. + internal class WikiMetadata + { + /********* + ** Accessors + *********/ + /// The current stable Stardew Valley version. + public string StableVersion { get; set; } + + /// The current beta Stardew Valley version. + public string BetaVersion { get; set; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + public WikiMetadata() { } + + /// Construct an instance. + /// The current stable Stardew Valley version. + /// The current beta Stardew Valley version. + public WikiMetadata(string stableVersion, string betaVersion) + { + this.StableVersion = stableVersion; + this.BetaVersion = betaVersion; + } + } +} -- cgit