123123
This commit is contained in:
@@ -13,11 +13,12 @@ namespace ZelWiki.Repository
|
||||
{
|
||||
public static class ConfigurationRepository
|
||||
{
|
||||
#region Upgrade Database.
|
||||
#region
|
||||
|
||||
public static string GetVersionStateVersion()
|
||||
{
|
||||
var entries = ManagedDataStorage.Config.ExecuteScalar<string>(@"Scripts\Initialization\GetVersionStateVersion.sql");
|
||||
var entries =
|
||||
ManagedDataStorage.Config.ExecuteScalar<string>(@"Scripts\Initialization\GetVersionStateVersion.sql");
|
||||
return entries ?? "0.0.0";
|
||||
}
|
||||
|
||||
@@ -25,11 +26,12 @@ namespace ZelWiki.Repository
|
||||
{
|
||||
var version = string.Join('.',
|
||||
(Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "0.0.0.0").Split('.').Take(3));
|
||||
ManagedDataStorage.Config.Execute(@"Scripts\Initialization\SetVersionStateVersion.sql", new { Version = version });
|
||||
ManagedDataStorage.Config.Execute(@"Scripts\Initialization\SetVersionStateVersion.sql",
|
||||
new { Version = version });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See @Initialization.Versions.md
|
||||
///
|
||||
/// </summary>
|
||||
public static void UpgradeDatabase()
|
||||
{
|
||||
@@ -45,43 +47,44 @@ namespace ZelWiki.Repository
|
||||
|
||||
if (currentPaddedVersion == storedPaddedVersion)
|
||||
{
|
||||
return; //The database version is already at the latest version.
|
||||
return;
|
||||
}
|
||||
|
||||
var updateScriptNames = Assembly.GetExecutingAssembly().GetManifestResourceNames()
|
||||
.Where(o => o.Contains("Repository.Scripts.Initialization.Versions", StringComparison.InvariantCultureIgnoreCase)).OrderBy(o => o);
|
||||
.Where(o => o.Contains("Repository.Scripts.Initialization.Versions",
|
||||
StringComparison.InvariantCultureIgnoreCase)).OrderBy(o => o);
|
||||
|
||||
string startVersionTag = ".Initialization.Versions.";
|
||||
string endVersionTag = ".^";
|
||||
var startVersionTag = ".Initialization.Versions.";
|
||||
var endVersionTag = ".^";
|
||||
|
||||
foreach (var updateScriptName in updateScriptNames)
|
||||
{
|
||||
int startIndex = updateScriptName.IndexOf(startVersionTag, StringComparison.InvariantCultureIgnoreCase);
|
||||
int startIndex =
|
||||
updateScriptName.IndexOf(startVersionTag, StringComparison.InvariantCultureIgnoreCase);
|
||||
if (startIndex >= 0)
|
||||
{
|
||||
startIndex += startVersionTag.Length;
|
||||
|
||||
int endIndex = updateScriptName.IndexOf(endVersionTag, startIndex, StringComparison.InvariantCultureIgnoreCase);
|
||||
var endIndex = updateScriptName.IndexOf(endVersionTag, startIndex,
|
||||
StringComparison.InvariantCultureIgnoreCase);
|
||||
if (endIndex > startIndex)
|
||||
{
|
||||
//The name of the script file without the namespaces, version numbers etc.
|
||||
var fullScriptName = updateScriptName.Substring(endIndex + endVersionTag.Length).Trim().Replace("_", "");
|
||||
var fullScriptName = updateScriptName.Substring(endIndex + endVersionTag.Length).Trim()
|
||||
.Replace("_", "");
|
||||
|
||||
int filesFolderVersion = Utility.PadVersionString(updateScriptName.Substring(startIndex, endIndex - startIndex).Trim().Replace("_", ""));
|
||||
int filesFolderVersion = Utility.PadVersionString(updateScriptName
|
||||
.Substring(startIndex, endIndex - startIndex).Trim().Replace("_", ""));
|
||||
if (filesFolderVersion > storedPaddedVersion)
|
||||
{
|
||||
//Get the script text.
|
||||
using var stream = assembly.GetManifestResourceStream(updateScriptName);
|
||||
using var reader = new StreamReader(stream.EnsureNotNull());
|
||||
var scriptText = reader.ReadToEnd();
|
||||
|
||||
//Get the script "metadata" from the file name.
|
||||
|
||||
var scriptNameParts = fullScriptName.Split('^');
|
||||
//string executionOrder = scriptNameParts[0];
|
||||
string databaseName = scriptNameParts[1];
|
||||
//string scriptName = scriptNameParts[2];
|
||||
var databaseName = scriptNameParts[1];
|
||||
|
||||
var databaseFactory = ManagedDataStorage.Collection.Single(o => o.Name == databaseName).Factory;
|
||||
var databaseFactory = ManagedDataStorage.Collection.Single(o => o.Name == databaseName)
|
||||
.Factory;
|
||||
|
||||
databaseFactory.Execute(scriptText);
|
||||
}
|
||||
@@ -95,13 +98,14 @@ namespace ZelWiki.Repository
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExceptionRepository.InsertException(ex, "Database upgrade failed.");
|
||||
ExceptionRepository.InsertException(ex, "数据库升级失败");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static ConfigurationEntries GetConfigurationEntryValuesByGroupName(string groupName, bool allowCache = true)
|
||||
public static ConfigurationEntries GetConfigurationEntryValuesByGroupName(string groupName,
|
||||
bool allowCache = true)
|
||||
{
|
||||
if (allowCache)
|
||||
{
|
||||
@@ -163,27 +167,25 @@ namespace ZelWiki.Repository
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if this is the first time the wiki has run. Returns true if it is the first time.
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsFirstRun()
|
||||
{
|
||||
bool isEncryptionValid = GetCryptoCheck();
|
||||
var isEncryptionValid = GetCryptoCheck();
|
||||
if (isEncryptionValid == false)
|
||||
{
|
||||
SetCryptoCheck();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an encrypted value from the database so we can determine if encryption is setup.
|
||||
/// If the value is missing then we are NOT setup.
|
||||
/// If the value is present but we cant decrypt it, then we are NOT setup.
|
||||
/// /// If the value is present and we can decrypt it, then we are setup and good to go!
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool GetCryptoCheck()
|
||||
{
|
||||
var value = ManagedDataStorage.Config.QueryFirstOrDefault<string>("GetCryptoCheck.sql") ?? string.Empty;
|
||||
@@ -203,9 +205,9 @@ namespace ZelWiki.Repository
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an encrypted value to the database so we can test at a later time to ensure that encryption is setup.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void SetCryptoCheck()
|
||||
{
|
||||
var param = new
|
||||
@@ -275,6 +277,7 @@ namespace ZelWiki.Repository
|
||||
ConfigurationGroupId = group.Key,
|
||||
});
|
||||
}
|
||||
|
||||
result.Add(nest);
|
||||
}
|
||||
|
||||
@@ -284,14 +287,16 @@ namespace ZelWiki.Repository
|
||||
public static List<ConfigurationFlat> GetFlatConfiguration()
|
||||
=> ManagedDataStorage.Config.Query<ConfigurationFlat>("GetFlatConfiguration.sql").ToList();
|
||||
|
||||
public static string? GetConfigurationEntryValuesByGroupNameAndEntryName(string groupName, string entryName, bool allowCache = true)
|
||||
public static string? GetConfigurationEntryValuesByGroupNameAndEntryName(string groupName, string entryName,
|
||||
bool allowCache = true)
|
||||
{
|
||||
if (allowCache)
|
||||
{
|
||||
var cacheKey = WikiCacheKeyFunction.Build(WikiCache.Category.Configuration, [groupName, entryName]);
|
||||
if (!WikiCache.TryGet<string>(cacheKey, out var result))
|
||||
{
|
||||
if ((result = GetConfigurationEntryValuesByGroupNameAndEntryName(groupName, entryName, false)) != null)
|
||||
if ((result = GetConfigurationEntryValuesByGroupNameAndEntryName(groupName, entryName, false)) !=
|
||||
null)
|
||||
{
|
||||
WikiCache.Put(cacheKey, result);
|
||||
}
|
||||
@@ -306,7 +311,9 @@ namespace ZelWiki.Repository
|
||||
EntryName = entryName
|
||||
};
|
||||
|
||||
var configEntry = ManagedDataStorage.Config.QuerySingle<ConfigurationEntry>("GetConfigurationEntryValuesByGroupNameAndEntryName.sql", param);
|
||||
var configEntry =
|
||||
ManagedDataStorage.Config.QuerySingle<ConfigurationEntry>(
|
||||
"GetConfigurationEntryValuesByGroupNameAndEntryName.sql", param);
|
||||
if (configEntry?.IsEncrypted == true)
|
||||
{
|
||||
try
|
||||
@@ -431,33 +438,31 @@ namespace ZelWiki.Repository
|
||||
|
||||
if (emoji.ImageData != null)
|
||||
{
|
||||
var scaledImageCacheKey = WikiCacheKey.Build(WikiCache.Category.Emoji, [emoji.Shortcut, "100"]);
|
||||
var scaledImageCacheKey =
|
||||
WikiCacheKey.Build(WikiCache.Category.Emoji, [emoji.Shortcut, "100"]);
|
||||
var decompressedImageBytes = Utility.Decompress(emoji.ImageData);
|
||||
var img = Image.Load(new MemoryStream(decompressedImageBytes));
|
||||
|
||||
int customScalePercent = 100;
|
||||
var customScalePercent = 100;
|
||||
|
||||
var (Width, Height) = Utility.ScaleToMaxOf(img.Width, img.Height, GlobalConfiguration.DefaultEmojiHeight);
|
||||
|
||||
//Adjust to any specified scaling.
|
||||
var (Width, Height) = Utility.ScaleToMaxOf(img.Width, img.Height,
|
||||
GlobalConfiguration.DefaultEmojiHeight);
|
||||
|
||||
Height = (int)(Height * (customScalePercent / 100.0));
|
||||
Width = (int)(Width * (customScalePercent / 100.0));
|
||||
|
||||
//Adjusting by a ratio (and especially after applying additional scaling) may have caused one
|
||||
// dimension to become very small (or even negative). So here we will check the height and width
|
||||
// to ensure they are both at least n pixels and adjust both dimensions.
|
||||
|
||||
if (Height < 16)
|
||||
{
|
||||
Height += 16 - Height;
|
||||
Width += 16 - Height;
|
||||
}
|
||||
|
||||
if (Width < 16)
|
||||
{
|
||||
Height += 16 - Width;
|
||||
Width += 16 - Width;
|
||||
}
|
||||
|
||||
//These are hard to generate, so just keep it forever.
|
||||
|
||||
var resized = Images.ResizeGifImage(decompressedImageBytes, Width, Height);
|
||||
var itemCache = new ImageCacheItem(resized, "image/gif");
|
||||
WikiCache.Put(scaledImageCacheKey, itemCache, new CacheItemPolicy());
|
||||
@@ -497,27 +502,34 @@ namespace ZelWiki.Repository
|
||||
|
||||
GlobalConfiguration.FixedMenuPosition = customizationConfig.Value("Fixed Header Menu Position", false);
|
||||
GlobalConfiguration.AllowSignup = membershipConfig.Value("Allow Signup", false);
|
||||
GlobalConfiguration.DefaultProfileRecentlyModifiedCount = performanceConfig.Value<int>("Default Profile Recently Modified Count");
|
||||
GlobalConfiguration.DefaultProfileRecentlyModifiedCount =
|
||||
performanceConfig.Value<int>("Default Profile Recently Modified Count");
|
||||
GlobalConfiguration.PreLoadAnimatedEmojis = performanceConfig.Value<bool>("Pre-Load Animated Emojis");
|
||||
GlobalConfiguration.SystemTheme = GetAllThemes().Single(o => o.Name == themeName);
|
||||
GlobalConfiguration.DefaultEmojiHeight = customizationConfig.Value<int>("Default Emoji Height");
|
||||
GlobalConfiguration.AllowGoogleAuthentication = membershipConfig.Value<bool>("Allow Google Authentication");
|
||||
GlobalConfiguration.DefaultTimeZone = customizationConfig?.Value<string>("Default TimeZone") ?? string.Empty;
|
||||
GlobalConfiguration.IncludeWikiDescriptionInMeta = functionalityConfig.Value<bool>("Include wiki Description in Meta");
|
||||
GlobalConfiguration.DefaultTimeZone =
|
||||
customizationConfig?.Value<string>("Default TimeZone") ?? string.Empty;
|
||||
GlobalConfiguration.IncludeWikiDescriptionInMeta =
|
||||
functionalityConfig.Value<bool>("Include wiki Description in Meta");
|
||||
GlobalConfiguration.IncludeWikiTagsInMeta = functionalityConfig.Value<bool>("Include wiki Tags in Meta");
|
||||
GlobalConfiguration.EnablePageComments = functionalityConfig.Value<bool>("Enable Page Comments");
|
||||
GlobalConfiguration.EnablePublicProfiles = functionalityConfig.Value<bool>("Enable Public Profiles");
|
||||
GlobalConfiguration.ShowCommentsOnPageFooter = functionalityConfig.Value<bool>("Show Comments on Page Footer");
|
||||
GlobalConfiguration.ShowLastModifiedOnPageFooter = functionalityConfig.Value<bool>("Show Last Modified on Page Footer");
|
||||
GlobalConfiguration.ShowCommentsOnPageFooter =
|
||||
functionalityConfig.Value<bool>("Show Comments on Page Footer");
|
||||
GlobalConfiguration.ShowLastModifiedOnPageFooter =
|
||||
functionalityConfig.Value<bool>("Show Last Modified on Page Footer");
|
||||
GlobalConfiguration.IncludeSearchOnNavbar = searchConfig.Value<bool>("Include Search on Navbar");
|
||||
GlobalConfiguration.HTMLHeader = htmlConfig?.Value<string>("Header") ?? string.Empty;
|
||||
GlobalConfiguration.HTMLFooter = htmlConfig?.Value<string>("Footer") ?? string.Empty;
|
||||
GlobalConfiguration.HTMLPreBody = htmlConfig?.Value<string>("Pre-Body") ?? string.Empty;
|
||||
GlobalConfiguration.HTMLPostBody = htmlConfig?.Value<string>("Post-Body") ?? string.Empty;
|
||||
GlobalConfiguration.BrandImageSmall = customizationConfig?.Value<string>("Brand Image (Small)") ?? string.Empty;
|
||||
GlobalConfiguration.BrandImageSmall =
|
||||
customizationConfig?.Value<string>("Brand Image (Small)") ?? string.Empty;
|
||||
GlobalConfiguration.FooterBlurb = customizationConfig?.Value<string>("FooterBlurb") ?? string.Empty;
|
||||
GlobalConfiguration.MaxAvatarFileSize = filesAndAttachmentsConfig.Value<int>("Max Avatar File Size");
|
||||
GlobalConfiguration.MaxAttachmentFileSize = filesAndAttachmentsConfig.Value<int>("Max Attachment File Size");
|
||||
GlobalConfiguration.MaxAttachmentFileSize =
|
||||
filesAndAttachmentsConfig.Value<int>("Max Attachment File Size");
|
||||
GlobalConfiguration.MaxEmojiFileSize = filesAndAttachmentsConfig.Value<int>("Max Emoji File Size");
|
||||
|
||||
GlobalConfiguration.MenuItems = GetAllMenuItems();
|
||||
@@ -525,4 +537,4 @@ namespace ZelWiki.Repository
|
||||
ReloadEmojis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
namespace ZelWiki.Repository
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores instances of ManagedDataStorageFactories that are used to store various parts of the data for the site.
|
||||
/// </summary>
|
||||
public static class ManagedDataStorage
|
||||
{
|
||||
private static (string Name, ManagedDataStorageFactory Factory)[]? _collection = null;
|
||||
|
||||
@@ -179,8 +179,6 @@ namespace ZelWiki.Repository
|
||||
var pageFileInfo = GetPageFileInfoByFileNavigation(o, item.PageId, item.FileNavigation);
|
||||
if (pageFileInfo == null)
|
||||
{
|
||||
//If the page file does not exist, then insert it.
|
||||
|
||||
var InsertPageFileParam = new
|
||||
{
|
||||
PageId = item.PageId,
|
||||
@@ -193,8 +191,7 @@ namespace ZelWiki.Repository
|
||||
};
|
||||
|
||||
o.Execute("InsertPageFile.sql", InsertPageFileParam);
|
||||
|
||||
//Get the id of the newly inserted page file.
|
||||
|
||||
pageFileInfo = GetPageFileInfoByFileNavigation(o, item.PageId, item.FileNavigation)
|
||||
?? throw new Exception("Failed find newly inserted page attachment.");
|
||||
|
||||
@@ -208,26 +205,19 @@ namespace ZelWiki.Repository
|
||||
var currentlyAttachedFile = GetPageCurrentRevisionAttachmentByFileNavigation(o, item.PageId, item.FileNavigation);
|
||||
if (currentlyAttachedFile != null)
|
||||
{
|
||||
//The PageFile exists and a revision of it is attached to this page revision.
|
||||
//Keep track of the file revision, and determine if the file has changed (via the file hash).
|
||||
|
||||
currentFileRevision = currentlyAttachedFile.Revision;
|
||||
hasFileChanged = currentlyAttachedFile.DataHash != newDataHash;
|
||||
}
|
||||
else
|
||||
{
|
||||
//The file either does not exist or is not attached to the current page revision.
|
||||
hasFileChanged = true;
|
||||
|
||||
//We determined earlier that the PageFile does exist, so keep track of the file revision.
|
||||
currentFileRevision = pageFileInfo.Revision;
|
||||
}
|
||||
|
||||
if (hasFileChanged)
|
||||
{
|
||||
currentFileRevision++;
|
||||
|
||||
//Get the current page revision so that we can associate the page file attachment with the current page revision.
|
||||
|
||||
int currentPageRevision = PageRepository.GetCurrentPageRevision(o, item.PageId);
|
||||
|
||||
var updatePageFileRevisionParam = new
|
||||
@@ -235,7 +225,6 @@ namespace ZelWiki.Repository
|
||||
PageFileId = pageFileInfo.PageFileId,
|
||||
FileRevision = currentFileRevision
|
||||
};
|
||||
//The file has changed (or is newly inserted), bump the file revision.
|
||||
o.Execute("UpdatePageFileRevision.sql", updatePageFileRevisionParam);
|
||||
|
||||
var insertPageFileRevisionParam = new
|
||||
@@ -250,7 +239,6 @@ namespace ZelWiki.Repository
|
||||
DataHash = newDataHash,
|
||||
};
|
||||
|
||||
//Insert the actual file data.
|
||||
o.Execute("InsertPageFileRevision.sql", insertPageFileRevisionParam);
|
||||
|
||||
var associatePageFileAttachmentWithPageRevisionParam = new
|
||||
@@ -259,10 +247,9 @@ namespace ZelWiki.Repository
|
||||
PageFileId = pageFileInfo.PageFileId,
|
||||
PageRevision = currentPageRevision,
|
||||
FileRevision = currentFileRevision,
|
||||
PreviousFileRevision = currentlyAttachedFile?.Revision //This is so we can disassociate the previous file revision.
|
||||
PreviousFileRevision = currentlyAttachedFile?.Revision
|
||||
};
|
||||
|
||||
//Associate the latest version of the file with the latest version of the page.
|
||||
o.Execute("AssociatePageFileAttachmentWithPageRevision.sql", associatePageFileAttachmentWithPageRevisionParam);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace ZelWiki.Repository
|
||||
return ManagedDataStorage.Pages.QuerySingleOrDefault<Page>("GetPageRevisionInfoById.sql", param);
|
||||
}
|
||||
|
||||
public static ProcessingInstructionCollection GetPageProcessingInstructionsByPageId(int pageId, bool allowCache = true)
|
||||
public static ProcessingInstructionCollection GetPageProcessingInstructionsByPageId(int pageId,
|
||||
bool allowCache = true)
|
||||
{
|
||||
if (allowCache)
|
||||
{
|
||||
@@ -41,7 +42,8 @@ namespace ZelWiki.Repository
|
||||
|
||||
return new ProcessingInstructionCollection()
|
||||
{
|
||||
Collection = ManagedDataStorage.Pages.Query<ProcessingInstruction>("GetPageProcessingInstructionsByPageId.sql", param).ToList()
|
||||
Collection = ManagedDataStorage.Pages
|
||||
.Query<ProcessingInstruction>("GetPageProcessingInstructionsByPageId.sql", param).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -68,7 +70,8 @@ namespace ZelWiki.Repository
|
||||
}
|
||||
|
||||
public static List<PageRevision> GetPageRevisionsInfoByNavigationPaged(
|
||||
string navigation, int pageNumber, string? orderBy = null, string? orderByDirection = null, int? pageSize = null)
|
||||
string navigation, int pageNumber, string? orderBy = null, string? orderByDirection = null,
|
||||
int? pageSize = null)
|
||||
{
|
||||
pageSize ??= ConfigurationRepository.Get<int>("Customization", "Pagination Size");
|
||||
|
||||
@@ -83,7 +86,8 @@ namespace ZelWiki.Repository
|
||||
{
|
||||
using var users_db = o.Attach("users.db", "users_db");
|
||||
|
||||
var query = RepositoryHelper.TransposeOrderby("GetPageRevisionsInfoByNavigationPaged.sql", orderBy, orderByDirection);
|
||||
var query = RepositoryHelper.TransposeOrderby("GetPageRevisionsInfoByNavigationPaged.sql", orderBy,
|
||||
orderByDirection);
|
||||
return o.Query<PageRevision>(query, param).ToList();
|
||||
});
|
||||
}
|
||||
@@ -96,7 +100,8 @@ namespace ZelWiki.Repository
|
||||
TopCount = topCount
|
||||
};
|
||||
|
||||
return ManagedDataStorage.Pages.Query<PageRevision>("GetTopRecentlyModifiedPagesInfoByUserId.sql", param).ToList();
|
||||
return ManagedDataStorage.Pages.Query<PageRevision>("GetTopRecentlyModifiedPagesInfoByUserId.sql", param)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static string? GetPageNavigationByPageId(int pageId)
|
||||
@@ -149,12 +154,13 @@ namespace ZelWiki.Repository
|
||||
});
|
||||
}
|
||||
|
||||
private static List<PageSearchToken> GetMeteredPageSearchTokens(List<string> searchTerms, bool allowFuzzyMatching, bool allowCache = true)
|
||||
private static List<PageSearchToken> GetMeteredPageSearchTokens(List<string> searchTerms,
|
||||
bool allowFuzzyMatching, bool allowCache = true)
|
||||
{
|
||||
if (allowCache)
|
||||
{
|
||||
//This caching is really just used for paging - so we don't have to do a token search for every click of next/previous.
|
||||
var cacheKey = WikiCacheKeyFunction.Build(WikiCache.Category.Search, [string.Join(',', searchTerms), allowFuzzyMatching]);
|
||||
var cacheKey = WikiCacheKeyFunction.Build(WikiCache.Category.Search,
|
||||
[string.Join(',', searchTerms), allowFuzzyMatching]);
|
||||
if (!WikiCache.TryGet<List<PageSearchToken>>(cacheKey, out var result))
|
||||
{
|
||||
result = GetMeteredPageSearchTokens(searchTerms, allowFuzzyMatching, false);
|
||||
@@ -167,11 +173,11 @@ namespace ZelWiki.Repository
|
||||
var minimumMatchScore = ConfigurationRepository.Get<float>("Search", "Minimum Match Score");
|
||||
|
||||
var searchTokens = (from o in searchTerms
|
||||
select new PageToken
|
||||
{
|
||||
Token = o,
|
||||
DoubleMetaphone = o.ToDoubleMetaphone()
|
||||
}).ToList();
|
||||
select new PageToken
|
||||
{
|
||||
Token = o,
|
||||
DoubleMetaphone = o.ToDoubleMetaphone()
|
||||
}).ToList();
|
||||
|
||||
if (allowFuzzyMatching == true)
|
||||
{
|
||||
@@ -181,15 +187,15 @@ namespace ZelWiki.Repository
|
||||
allTokens.AddRange(fuzzyTokens);
|
||||
|
||||
return allTokens
|
||||
.GroupBy(token => token.PageId)
|
||||
.Where(group => group.Sum(g => g.Score) >= minimumMatchScore) // Filtering groups
|
||||
.Select(group => new PageSearchToken
|
||||
{
|
||||
PageId = group.Key,
|
||||
Match = group.Max(g => g.Match),
|
||||
Weight = group.Max(g => g.Weight),
|
||||
Score = group.Max(g => g.Score)
|
||||
}).ToList();
|
||||
.GroupBy(token => token.PageId)
|
||||
.Where(group => group.Sum(g => g.Score) >= minimumMatchScore)
|
||||
.Select(group => new PageSearchToken
|
||||
{
|
||||
PageId = group.Key,
|
||||
Match = group.Max(g => g.Match),
|
||||
Weight = group.Max(g => g.Weight),
|
||||
Score = group.Max(g => g.Score)
|
||||
}).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -204,7 +210,7 @@ namespace ZelWiki.Repository
|
||||
return new List<Page>();
|
||||
}
|
||||
|
||||
bool allowFuzzyMatching = ConfigurationRepository.Get<bool>("Search", "Allow Fuzzy Matching");
|
||||
var allowFuzzyMatching = ConfigurationRepository.Get<bool>("Search", "Allow Fuzzy Matching");
|
||||
var meteredSearchTokens = GetMeteredPageSearchTokens(searchTerms, allowFuzzyMatching == true);
|
||||
if (meteredSearchTokens.Count == 0)
|
||||
{
|
||||
@@ -224,7 +230,8 @@ namespace ZelWiki.Repository
|
||||
});
|
||||
}
|
||||
|
||||
public static List<Page> PageSearchPaged(List<string> searchTerms, int pageNumber, int? pageSize = null, bool? allowFuzzyMatching = null)
|
||||
public static List<Page> PageSearchPaged(List<string> searchTerms, int pageNumber, int? pageSize = null,
|
||||
bool? allowFuzzyMatching = null)
|
||||
{
|
||||
if (searchTerms.Count == 0)
|
||||
{
|
||||
@@ -256,7 +263,8 @@ namespace ZelWiki.Repository
|
||||
});
|
||||
}
|
||||
|
||||
public static List<RelatedPage> GetSimilarPagesPaged(int pageId, int similarity, int pageNumber, int? pageSize = null)
|
||||
public static List<RelatedPage> GetSimilarPagesPaged(int pageId, int similarity, int pageNumber,
|
||||
int? pageSize = null)
|
||||
{
|
||||
pageSize ??= ConfigurationRepository.Get<int>("Customization", "Pagination Size");
|
||||
|
||||
@@ -364,7 +372,8 @@ namespace ZelWiki.Repository
|
||||
});
|
||||
}
|
||||
|
||||
public static List<NonexistentPage> GetMissingPagesPaged(int pageNumber, string? orderBy = null, string? orderByDirection = null)
|
||||
public static List<NonexistentPage> GetMissingPagesPaged(int pageNumber, string? orderBy = null,
|
||||
string? orderByDirection = null)
|
||||
{
|
||||
int pageSize = ConfigurationRepository.Get<int>("Customization", "Pagination Size");
|
||||
|
||||
@@ -478,17 +487,18 @@ namespace ZelWiki.Repository
|
||||
return ManagedDataStorage.Pages.Ephemeral(o =>
|
||||
{
|
||||
using var users_db = o.Attach("users.db", "users_db");
|
||||
var query = RepositoryHelper.TransposeOrderby("GetAllNamespacePagesPaged.sql", orderBy, orderByDirection);
|
||||
var query = RepositoryHelper.TransposeOrderby("GetAllNamespacePagesPaged.sql", orderBy,
|
||||
orderByDirection);
|
||||
return o.Query<Page>(query, param).ToList();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlike the search, this method returns all pages and allows them to be paired down using the search terms.
|
||||
/// Whereas the search requires a search term to get results. The matching here is also exact, no score based matching.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pageNumber"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="orderBy"></param>
|
||||
/// <param name="orderByDirection"></param>
|
||||
/// <param name="searchTerms"></param>
|
||||
/// <returns></returns>
|
||||
public static List<Page> GetAllPagesPaged(int pageNumber,
|
||||
@@ -512,7 +522,8 @@ namespace ZelWiki.Repository
|
||||
using var deletedpagerevisions_db = o.Attach("deletedpagerevisions.db", "deletedpagerevisions_db");
|
||||
using var tempTable = o.CreateTempTableFrom("TempPageIds", pageIds);
|
||||
|
||||
var query = RepositoryHelper.TransposeOrderby("GetAllPagesByPageIdPaged.sql", orderBy, orderByDirection);
|
||||
var query = RepositoryHelper.TransposeOrderby("GetAllPagesByPageIdPaged.sql", orderBy,
|
||||
orderByDirection);
|
||||
return o.Query<Page>(query, param).ToList();
|
||||
});
|
||||
}
|
||||
@@ -528,11 +539,11 @@ namespace ZelWiki.Repository
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlike the search, this method returns all pages and allows them to be paired down using the search terms.
|
||||
/// Whereas the search requires a search term to get results. The matching here is also exact, no score based matching.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pageNumber"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="orderBy"></param>
|
||||
/// <param name="orderByDirection"></param>
|
||||
/// <param name="searchTerms"></param>
|
||||
/// <returns></returns>
|
||||
public static List<Page> GetAllDeletedPagesPaged(int pageNumber, string? orderBy = null,
|
||||
@@ -554,7 +565,8 @@ namespace ZelWiki.Repository
|
||||
using var users_db = o.Attach("users.db", "users_db");
|
||||
using var tempTable = o.CreateTempTableFrom("TempPageIds", pageIds);
|
||||
|
||||
var query = RepositoryHelper.TransposeOrderby("GetAllDeletedPagesByPageIdPaged.sql", orderBy, orderByDirection);
|
||||
var query = RepositoryHelper.TransposeOrderby("GetAllDeletedPagesByPageIdPaged.sql", orderBy,
|
||||
orderByDirection);
|
||||
return o.Query<Page>(query, param).ToList();
|
||||
});
|
||||
}
|
||||
@@ -567,7 +579,8 @@ namespace ZelWiki.Repository
|
||||
});
|
||||
}
|
||||
|
||||
public static List<NamespaceStat> GetAllNamespacesPaged(int pageNumber, string? orderBy = null, string? orderByDirection = null)
|
||||
public static List<NamespaceStat> GetAllNamespacesPaged(int pageNumber, string? orderBy = null,
|
||||
string? orderByDirection = null)
|
||||
{
|
||||
int pageSize = ConfigurationRepository.Get<int>("Customization", "Pagination Size");
|
||||
|
||||
@@ -683,6 +696,7 @@ namespace ZelWiki.Repository
|
||||
WikiCache.Put(cacheKey, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -719,31 +733,27 @@ namespace ZelWiki.Repository
|
||||
|
||||
try
|
||||
{
|
||||
int currentPageRevision = 0;
|
||||
bool hasPageChanged = false;
|
||||
var currentPageRevision = 0;
|
||||
var hasPageChanged = false;
|
||||
|
||||
if (page.Id == 0)
|
||||
{
|
||||
//This is a new page, just insert it.
|
||||
page.Id = o.ExecuteScalar<int>("CreatePage.sql", pageUpsertParam);
|
||||
hasPageChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Get current page so we can determine if anything has changed.
|
||||
var currentRevisionInfo = GetLimitedPageInfoByIdAndRevision(page.Id)
|
||||
?? throw new Exception("The page could not be found.");
|
||||
?? throw new Exception("The page could not be found.");
|
||||
|
||||
currentPageRevision = currentRevisionInfo.Revision;
|
||||
|
||||
//Update the existing page.
|
||||
o.Execute("UpdatePage.sql", pageUpsertParam);
|
||||
|
||||
//Determine if anything has actually changed.
|
||||
hasPageChanged = currentRevisionInfo.Name != page.Name
|
||||
|| currentRevisionInfo.Namespace != page.Namespace
|
||||
|| currentRevisionInfo.Description != page.Description
|
||||
|| currentRevisionInfo.DataHash != newDataHash;
|
||||
|| currentRevisionInfo.Namespace != page.Namespace
|
||||
|| currentRevisionInfo.Description != page.Description
|
||||
|| currentRevisionInfo.DataHash != newDataHash;
|
||||
}
|
||||
|
||||
if (hasPageChanged)
|
||||
@@ -755,7 +765,6 @@ namespace ZelWiki.Repository
|
||||
PageId = page.Id,
|
||||
PageRevision = currentPageRevision
|
||||
};
|
||||
//The page content has actually changed (according to the checksum), so we will bump the page revision.
|
||||
o.Execute("UpdatePageRevisionNumber.sql", updatePageRevisionNumberParam);
|
||||
|
||||
var InsertPageRevisionParam = new
|
||||
@@ -770,7 +779,6 @@ namespace ZelWiki.Repository
|
||||
ModifiedByUserId = page.ModifiedByUserId,
|
||||
ModifiedDate = DateTime.UtcNow,
|
||||
};
|
||||
//Insert the new actual page revision entry (this is the data).
|
||||
o.Execute("InsertPageRevision.sql", InsertPageRevisionParam);
|
||||
|
||||
var reassociateAllPageAttachmentsParam = new
|
||||
@@ -778,7 +786,6 @@ namespace ZelWiki.Repository
|
||||
PageId = page.Id,
|
||||
PageRevision = currentPageRevision,
|
||||
};
|
||||
//Associate all page attachments with the latest revision.
|
||||
o.Execute("ReassociateAllPageAttachments.sql", reassociateAllPageAttachmentsParam);
|
||||
}
|
||||
|
||||
@@ -795,7 +802,7 @@ namespace ZelWiki.Repository
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the page info without the content.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="navigation"></param>
|
||||
/// <returns></returns>
|
||||
@@ -1001,7 +1008,8 @@ namespace ZelWiki.Repository
|
||||
{
|
||||
using var users_db = o.Attach("users.db", "users_db");
|
||||
|
||||
var query = RepositoryHelper.TransposeOrderby("GetDeletedPageRevisionsByIdPaged.sql", orderBy, orderByDirection);
|
||||
var query = RepositoryHelper.TransposeOrderby("GetDeletedPageRevisionsByIdPaged.sql", orderBy,
|
||||
orderByDirection);
|
||||
return o.Query<DeletedPageRevision>(query, param).ToList();
|
||||
});
|
||||
}
|
||||
@@ -1083,7 +1091,8 @@ namespace ZelWiki.Repository
|
||||
});
|
||||
}
|
||||
|
||||
public static Page? GetPageRevisionByNavigation(string givenNavigation, int? revision = null, bool allowCache = true)
|
||||
public static Page? GetPageRevisionByNavigation(string givenNavigation, int? revision = null,
|
||||
bool allowCache = true)
|
||||
{
|
||||
var navigation = new NamespaceNavigation(givenNavigation);
|
||||
|
||||
@@ -1172,4 +1181,4 @@ namespace ZelWiki.Repository
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,13 @@ namespace ZelWiki.Repository
|
||||
internal static class RepositoryHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Fills in a custom orderby on a given sql script.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
/// <param name="orderBy"></param>
|
||||
/// <param name="orderByDirection"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static string TransposeOrderby(string filename, string? orderBy, string? orderByDirection)
|
||||
{
|
||||
var script = ManagedDataStorageInstance.TranslateSqlScript(filename);
|
||||
@@ -19,47 +21,53 @@ namespace ZelWiki.Repository
|
||||
return script;
|
||||
}
|
||||
|
||||
string beginParentTag = "--CUSTOM_ORDER_BEGIN::";
|
||||
string endParentTag = "--::CUSTOM_ORDER_BEGIN";
|
||||
var beginParentTag = "--CUSTOM_ORDER_BEGIN::";
|
||||
var endParentTag = "--::CUSTOM_ORDER_BEGIN";
|
||||
|
||||
string beginConfigTag = "--CONFIG::";
|
||||
string endConfigTag = "--::CONFIG";
|
||||
var beginConfigTag = "--CONFIG::";
|
||||
var endConfigTag = "--::CONFIG";
|
||||
|
||||
while (true)
|
||||
{
|
||||
int beginParentIndex = script.IndexOf(beginParentTag, StringComparison.OrdinalIgnoreCase);
|
||||
int endParentIndex = script.IndexOf(endParentTag, StringComparison.OrdinalIgnoreCase);
|
||||
var beginParentIndex = script.IndexOf(beginParentTag, StringComparison.OrdinalIgnoreCase);
|
||||
var endParentIndex = script.IndexOf(endParentTag, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (beginParentIndex > 0 && endParentIndex > beginParentIndex)
|
||||
{
|
||||
var sectionText = script.Substring(beginParentIndex + beginParentTag.Length, (endParentIndex - beginParentIndex) - endParentTag.Length).Trim();
|
||||
var sectionText = script.Substring(beginParentIndex + beginParentTag.Length,
|
||||
(endParentIndex - beginParentIndex) - endParentTag.Length).Trim();
|
||||
|
||||
int beginConfigIndex = sectionText.IndexOf(beginConfigTag, StringComparison.OrdinalIgnoreCase);
|
||||
int endConfigIndex = sectionText.IndexOf(endConfigTag, StringComparison.OrdinalIgnoreCase);
|
||||
var beginConfigIndex = sectionText.IndexOf(beginConfigTag, StringComparison.OrdinalIgnoreCase);
|
||||
var endConfigIndex = sectionText.IndexOf(endConfigTag, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (beginConfigIndex >= 0 && endConfigIndex > beginConfigIndex)
|
||||
{
|
||||
var configText = sectionText.Substring(beginConfigIndex + beginConfigTag.Length, (endConfigIndex - beginConfigIndex) - endConfigTag.Length).Trim();
|
||||
var configText = sectionText.Substring(beginConfigIndex + beginConfigTag.Length,
|
||||
(endConfigIndex - beginConfigIndex) - endConfigTag.Length).Trim();
|
||||
|
||||
var configs = configText.Split("\n").Select(o => o.Trim())
|
||||
.Where(o => o.Contains('='))
|
||||
.Select(o => (Name: o.Split("=")[0], Field: o.Split("=")[1]));
|
||||
|
||||
var selectedConfig = configs.SingleOrDefault(o => string.Equals(o.Name, orderBy, StringComparison.OrdinalIgnoreCase));
|
||||
var selectedConfig = configs.SingleOrDefault(o =>
|
||||
string.Equals(o.Name, orderBy, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (selectedConfig == default)
|
||||
{
|
||||
throw new Exception($"No order by mapping was found in '{filename}' for the field '{orderBy}'.");
|
||||
throw new Exception(
|
||||
$"在 '{filename}' 中找不到排序字段 '{orderBy}'的映射");
|
||||
}
|
||||
|
||||
script = script.Substring(0, beginParentIndex)
|
||||
+ $"ORDER BY\r\n\t{selectedConfig.Field} "
|
||||
+ (string.Equals(orderByDirection, "asc", StringComparison.InvariantCultureIgnoreCase) ? "asc" : "desc")
|
||||
+ script.Substring(endParentIndex + endParentTag.Length);
|
||||
+ $"ORDER BY\r\n\t{selectedConfig.Field} "
|
||||
+ (string.Equals(orderByDirection, "asc", StringComparison.InvariantCultureIgnoreCase)
|
||||
? "asc"
|
||||
: "desc")
|
||||
+ script.Substring(endParentIndex + endParentTag.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"No order configuration was found in '{filename}'.");
|
||||
throw new Exception($"在 '{filename}'中找不到配置");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -71,4 +79,4 @@ namespace ZelWiki.Repository
|
||||
return script;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
--Remove the previous page file revision attachment, if any.
|
||||
DELETE FROM PageRevisionAttachment
|
||||
WHERE
|
||||
PageId = @PageId
|
||||
@@ -6,7 +5,7 @@ WHERE
|
||||
AND FileRevision = @PreviousFileRevision
|
||||
AND PageRevision = @PageRevision;
|
||||
|
||||
--Associate the file revision record with the page revision.
|
||||
|
||||
INSERT INTO PageRevisionAttachment
|
||||
(
|
||||
PageId,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
--This proc is exactly like GetAllUsersPaged except it has no filter on personal infomation so it can be used for public info.
|
||||
|
||||
SELECT
|
||||
U.UserId,
|
||||
U.AccountName,
|
||||
|
||||
@@ -9,7 +9,6 @@ FROM
|
||||
T.PageId,
|
||||
COUNT(DISTINCT T.Token) / (@TokenCount + 0.0) as [Match],
|
||||
SUM(T.[Weight] * 1.5) as [Weight],
|
||||
--Extra weight on score for exact matches:
|
||||
SUM(T.[Weight] * 1.5) * (COUNT(DISTINCT T.Token) / (@TokenCount + 0.0)) as [Score]
|
||||
FROM
|
||||
PageToken as T
|
||||
|
||||
@@ -9,7 +9,6 @@ FROM
|
||||
T.PageId,
|
||||
COUNT(DISTINCT T.DoubleMetaphone) / (@TokenCount + 0.0) as [Match],
|
||||
SUM(T.[Weight] * 1.0) as [Weight],
|
||||
--No weight benefits on score for fuzzy matching weight for exact matches:
|
||||
(COUNT(DISTINCT T.DoubleMetaphone) / (@TokenCount + 0.0)) as [Score]
|
||||
FROM
|
||||
PageToken as T
|
||||
|
||||
@@ -19,7 +19,7 @@ INNER JOIN PageRevisionAttachment as PRA
|
||||
ON PRA.PageId = P.Id
|
||||
AND PRA.PageFileId = PF.Id
|
||||
AND PRA.PageRevision = PR.Revision
|
||||
AND PRA.FileRevision = PF.Revision --Latest file revision.
|
||||
AND PRA.FileRevision = PF.Revision
|
||||
INNER JOIN PageFileRevision as PFR
|
||||
ON PFR.PageFileId = PF.Id
|
||||
AND PFR.Revision = PRA.FileRevision
|
||||
|
||||
@@ -23,7 +23,7 @@ SELECT
|
||||
ON PRA.PageId = P.Id
|
||||
AND PRA.PageFileId = PF.Id
|
||||
AND PRA.PageRevision = PR.Revision
|
||||
AND PRA.FileRevision = PF.Revision --Latest file revision.
|
||||
AND PRA.FileRevision = PF.Revision
|
||||
INNER JOIN PageFileRevision as PFR
|
||||
ON PFR.PageFileId = PF.Id
|
||||
AND PFR.Revision = PRA.FileRevision
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# Database Upgrade Initialization
|
||||
|
||||
When TightWiki is run, any scripts in the folders contained in "TightWiki.Repository\Scripts\Initialization\Versions"
|
||||
are executed. The "previous version" of TightWiki is stored in the Config database VersionState table.
|
||||
|
||||
The scripts are executed in the order denoted by the name of the folders in "Version\*", these folders are
|
||||
expected to be named with a three-part version scheme. MM.mm.pp (major.minor.patch).
|
||||
|
||||
The scripts are only executed if the three-part folder version is
|
||||
greater than the "previous version" from the VersionState table.
|
||||
|
||||
Theses scripts are executed in the order of their name as well, their name consists of three parts:
|
||||
"\^EXECUTION_ORDER\^DATABASE_NAME\^SCRIPT_NAME" where the execution order should be a zero padded numeric string,
|
||||
database name is the key from ManagedDataStorage.Collection, and script name is whatever you want to call it.
|
||||
@@ -1,4 +1,3 @@
|
||||
--Insert the actual file data.
|
||||
INSERT INTO PageFileRevision
|
||||
(
|
||||
PageFileId,
|
||||
|
||||
@@ -5,7 +5,6 @@ INSERT INTO deletedpages_db.[PageFileRevision] SELECT * FROM PageFileRevision WH
|
||||
INSERT INTO deletedpages_db.[PageFile] SELECT * FROM [PageFile] WHERE PageId = @PageId;
|
||||
INSERT INTO deletedpages_db.[Page] SELECT * FROM [Page] WHERE Id = @PageId;
|
||||
|
||||
--We save these so we can search for deleted pages.
|
||||
INSERT INTO deletedpages_db.[PageTag] SELECT * FROM [PageTag] WHERE PageId = @PageId;
|
||||
INSERT INTO deletedpages_db.[PageToken] SELECT * FROM [PageToken] WHERE PageId = @PageId;
|
||||
INSERT INTO deletedpages_db.[PageProcessingInstruction] SELECT * FROM [PageProcessingInstruction] WHERE PageId = @PageId;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--Cleanup
|
||||
|
||||
DELETE FROM DeletionMeta WHERE PageId = @PageId;
|
||||
|
||||
DELETE FROM [PageTag] WHERE PageId = @PageId;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
--Delete orphaned PageFileRevision.
|
||||
DELETE FROM PageFileRevision WHERE PageFileId = @PageFileId AND Revision = @Revision;
|
||||
|
||||
--Delete orphaned PageFile.
|
||||
DELETE FROM PageFile
|
||||
WHERE Id = @PageFileId
|
||||
AND Id NOT IN (SELECT PFR.PageFileId FROM PageFileRevision as PFR WHERE PFR.PageFileId = @PageFileId);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
--Delete orphaned PageFileRevision.
|
||||
|
||||
DELETE FROM PageFileRevision
|
||||
WHERE (PageFileId, Revision) IN (
|
||||
SELECT
|
||||
@@ -19,7 +19,7 @@ WHERE (PageFileId, Revision) IN (
|
||||
PRA.PageFileId IS NULL
|
||||
);
|
||||
|
||||
--Delete orphaned PageFile.
|
||||
|
||||
DELETE FROM PageFile
|
||||
WHERE Id NOT IN (SELECT PageFileId FROM PageFileRevision);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--Restore:
|
||||
|
||||
INSERT INTO [Page] SELECT * FROM deletedpages_db.[Page] WHERE Id = @PageId;
|
||||
INSERT INTO [PageRevision] SELECT * FROM deletedpages_db.[PageRevision] WHERE PageId = @PageId;
|
||||
INSERT INTO [PageFile] SELECT * FROM deletedpages_db.[PageFile] WHERE PageId = @PageId;
|
||||
@@ -6,7 +6,7 @@ INSERT INTO [PageFileRevision] SELECT * FROM deletedpages_db.PageFileRevision WH
|
||||
INSERT INTO [PageRevisionAttachment] SELECT * FROM deletedpages_db.[PageRevisionAttachment] WHERE PageId = @PageId;
|
||||
INSERT INTO [PageComment] SELECT * FROM deletedpages_db.[PageComment] WHERE PageId = @PageId;
|
||||
|
||||
--Cleanup
|
||||
|
||||
DELETE FROM deletedpages_db.DeletionMeta WHERE PageId = @PageId;
|
||||
|
||||
DELETE FROM deletedpages_db.[PageTag] WHERE PageId = @PageId;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
-- Deleting non-current page revisions
|
||||
DELETE FROM PageRevision
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
@@ -11,7 +10,6 @@ WHERE EXISTS (
|
||||
AND PageRevision.Revision < MostRecent.MaxRevision
|
||||
);
|
||||
|
||||
-- Deleting non-current attachments.
|
||||
DELETE FROM PageRevisionAttachment
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
@@ -25,7 +23,6 @@ WHERE EXISTS (
|
||||
AND PageRevisionAttachment.FileRevision < MostRecent.MaxFileRevision
|
||||
);
|
||||
|
||||
-- Deleting non-current page revision attachments
|
||||
DELETE FROM PageRevisionAttachment
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
@@ -39,7 +36,6 @@ WHERE EXISTS (
|
||||
AND PageRevisionAttachment.PageRevision < MostRecent.MaxPageRevision
|
||||
);
|
||||
|
||||
-- Deleting non-current page file revisions.
|
||||
DELETE FROM PageFileRevision
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
@@ -52,19 +48,16 @@ WHERE EXISTS (
|
||||
AND PageFileRevision.Revision < MostRecent.MaxPageRevision
|
||||
);
|
||||
|
||||
-- Delete orphaned PageFileRevision
|
||||
DELETE FROM PageFileRevision
|
||||
WHERE PageFileId NOT IN (
|
||||
SELECT PageFileId FROM PageRevisionAttachment
|
||||
);
|
||||
|
||||
-- Delete orphaned PageFile
|
||||
DELETE FROM PageFile
|
||||
WHERE Id NOT IN (
|
||||
SELECT PageFileId FROM PageRevisionAttachment
|
||||
);
|
||||
|
||||
-- Assuming everything else worked, lets set all of the revisions back to 1.
|
||||
UPDATE [Page] SET Revision = 1;
|
||||
UPDATE PageRevision SET Revision = 1;
|
||||
UPDATE PageRevisionAttachment SET PageRevision = 1, FileRevision = 1;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
--The ReferencesPageId is NULL by default and needs to be filled in for pages that referece orphaned pages.
|
||||
UPDATE
|
||||
PageReference
|
||||
SET
|
||||
|
||||
@@ -11,7 +11,6 @@ DELETE FROM EmojiCategory WHERE Id IN
|
||||
AND TC.Value IS NULL
|
||||
);
|
||||
|
||||
--Insert previously non-existing categories.
|
||||
INSERT INTO EmojiCategory
|
||||
(
|
||||
EmojiId,
|
||||
|
||||
@@ -7,16 +7,10 @@ namespace ZelWiki.Repository
|
||||
{
|
||||
public static class SecurityRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Detect whether this is the first time the WIKI has ever been run and do some initialization.
|
||||
/// Adds the first user with the email and password contained in Constants.DEFAULTUSERNAME and Constants.DEFAULTPASSWORD
|
||||
/// </summary>
|
||||
public static async void ValidateEncryptionAndCreateAdminUser(UserManager<IdentityUser> userManager)
|
||||
{
|
||||
if (ConfigurationRepository.IsFirstRun())
|
||||
{
|
||||
//If this is the first time the app has run on this machine (based on an encryption key) then clear the admin password status.
|
||||
//This will cause the application to set the admin password to the default password and display a warning until it is changed.
|
||||
UsersRepository.SetAdminPasswordClear();
|
||||
}
|
||||
|
||||
@@ -36,7 +30,7 @@ namespace ZelWiki.Repository
|
||||
|
||||
user.EnsureNotNull();
|
||||
|
||||
user.Email = Constants.DEFAULTUSERNAME; // Ensure email is set or updated
|
||||
user.Email = Constants.DEFAULTUSERNAME;
|
||||
user.EmailConfirmed = true;
|
||||
var emailUpdateResult = await userManager.UpdateAsync(user);
|
||||
if (!emailUpdateResult.Succeeded)
|
||||
@@ -79,19 +73,15 @@ namespace ZelWiki.Repository
|
||||
|
||||
public static async void UpsertUserClaims(UserManager<IdentityUser> userManager, IdentityUser user, List<Claim> givenClaims)
|
||||
{
|
||||
// Get existing claims for the user
|
||||
var existingClaims = await userManager.GetClaimsAsync(user);
|
||||
|
||||
foreach (var givenClaim in givenClaims)
|
||||
{
|
||||
// Remove existing claims if they exist
|
||||
var firstNameClaim = existingClaims.FirstOrDefault(c => c.Type == givenClaim.Type);
|
||||
if (firstNameClaim != null)
|
||||
{
|
||||
await userManager.RemoveClaimAsync(user, firstNameClaim);
|
||||
}
|
||||
|
||||
// Add new claim.
|
||||
await userManager.AddClaimAsync(user, givenClaim);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace ZelWiki.Repository
|
||||
{
|
||||
if (DoesProfileAccountExist(Navigation.Clean(accountName)))
|
||||
{
|
||||
throw new Exception("An account with that name already exists");
|
||||
throw new Exception("帐户名已存在");
|
||||
}
|
||||
|
||||
var param = new
|
||||
|
||||
Reference in New Issue
Block a user