using NTDLS.SqliteDapperWrapper; using ZelWiki.Caching; using ZelWiki.Models.DataModels; namespace ZelWiki.Repository { public static class PageFileRepository { public static void DetachPageRevisionAttachment(string pageNavigation, string fileNavigation, int pageRevision) { var param = new { PageNavigation = pageNavigation, FileNavigation = fileNavigation, PageRevision = pageRevision }; ManagedDataStorage.Pages.Execute("DetachPageRevisionAttachment.sql", param); } public static List GetOrphanedPageAttachmentsPaged( int pageNumber, string? orderBy = null, string? orderByDirection = null) { int pageSize = ConfigurationRepository.Get("Customization", "Pagination Size"); var param = new { PageNumber = pageNumber, PageSize = pageSize }; var query = RepositoryHelper.TransposeOrderby("GetOrphanedPageAttachments.sql", orderBy, orderByDirection); return ManagedDataStorage.Pages.Query(query, param).ToList(); } public static void PurgeOrphanedPageAttachments() => ManagedDataStorage.Pages.Execute("PurgeOrphanedPageAttachments.sql"); public static void PurgeOrphanedPageAttachment(int pageFileId, int revision) { var param = new { PageFileId = pageFileId, Revision = revision }; ManagedDataStorage.Pages.Execute("PurgeOrphanedPageAttachment.sql", param); } public static List GetPageFilesInfoByPageNavigationAndPageRevisionPaged(string pageNavigation, int pageNumber, int? pageSize = null, int? pageRevision = null) { pageSize ??= ConfigurationRepository.Get("Customization", "Pagination Size"); var param = new { PageNumber = pageNumber, PageSize = pageSize, PageNavigation = pageNavigation, PageRevision = pageRevision }; return ManagedDataStorage.Pages.Query("GetPageFilesInfoByPageNavigationAndPageRevisionPaged.sql", param).ToList(); } public static PageFileAttachmentInfo? GetPageFileAttachmentInfoByPageNavigationPageRevisionAndFileNavigation(string pageNavigation, string fileNavigation, int? pageRevision = null) { var param = new { PageNavigation = pageNavigation, FileNavigation = fileNavigation, PageRevision = pageRevision }; return ManagedDataStorage.Pages.QuerySingleOrDefault("GetPageFileAttachmentInfoByPageNavigationPageRevisionAndFileNavigation.sql", param); } public static PageFileAttachment? GetPageFileAttachmentByPageNavigationFileRevisionAndFileNavigation(string pageNavigation, string fileNavigation, int? fileRevision = null) { var param = new { PageNavigation = pageNavigation, FileNavigation = fileNavigation, FileRevision = fileRevision }; return ManagedDataStorage.Pages.QuerySingleOrDefault("GetPageFileAttachmentByPageNavigationFileRevisionAndFileNavigation.sql", param); } public static PageFileAttachment? GetPageFileAttachmentByPageNavigationPageRevisionAndFileNavigation(string pageNavigation, string fileNavigation, int? pageRevision = null, bool allowCache = true) { if (allowCache) { var cacheKey = WikiCacheKeyFunction.Build(WikiCache.Category.Page, [pageNavigation, fileNavigation, pageRevision]); if (!WikiCache.TryGet(cacheKey, out var result)) { if ((result = GetPageFileAttachmentByPageNavigationPageRevisionAndFileNavigation(pageNavigation, fileNavigation, pageRevision, false)) != null) { WikiCache.Put(cacheKey, result); } } return result; } var param = new { PageNavigation = pageNavigation, FileNavigation = fileNavigation, PageRevision = pageRevision }; return ManagedDataStorage.Pages.QuerySingleOrDefault( "GetPageFileAttachmentByPageNavigationPageRevisionAndFileNavigation.sql", param); } public static List GetPageFileAttachmentRevisionsByPageAndFileNavigationPaged(string pageNavigation, string fileNavigation, int pageNumber) { int pageSize = ConfigurationRepository.Get("Customization", "Pagination Size"); var param = new { PageNavigation = pageNavigation, FileNavigation = fileNavigation, PageNumber = pageNumber, PageSize = pageSize }; return ManagedDataStorage.Pages.Ephemeral(o => { using var users_db = o.Attach("users.db", "users_db"); var result = o.Query( "GetPageFileAttachmentRevisionsByPageAndFileNavigationPaged.sql", param).ToList(); return result; }); } public static List GetPageFilesInfoByPageId(int pageId) { var param = new { PageId = pageId }; return ManagedDataStorage.Pages.Query("GetPageFilesInfoByPageId.sql", param).ToList(); } public static PageFileRevisionAttachmentInfo? GetPageFileInfoByFileNavigation(ManagedDataStorageInstance connection, int pageId, string fileNavigation) { var param = new { PageId = pageId, Navigation = fileNavigation, }; return connection.QuerySingleOrDefault("GetPageFileInfoByFileNavigation.sql", param); } public static PageFileRevisionAttachmentInfo? GetPageCurrentRevisionAttachmentByFileNavigation(ManagedDataStorageInstance connection, int pageId, string fileNavigation) { var param = new { PageId = pageId, Navigation = fileNavigation, }; return connection.QuerySingleOrDefault("GetPageCurrentRevisionAttachmentByFileNavigation.sql", param); } public static void UpsertPageFile(PageFileAttachment item, Guid userId) { bool hasFileChanged = false; ManagedDataStorage.Pages.Ephemeral(o => { var transaction = o.BeginTransaction(); try { var pageFileInfo = GetPageFileInfoByFileNavigation(o, item.PageId, item.FileNavigation); if (pageFileInfo == null) { var InsertPageFileParam = new { PageId = item.PageId, Name = item.Name, FileNavigation = item.FileNavigation, ContentType = item.ContentType, Size = item.Size, CreatedDate = item.CreatedDate, Data = item.Data }; o.Execute("InsertPageFile.sql", InsertPageFileParam); pageFileInfo = GetPageFileInfoByFileNavigation(o, item.PageId, item.FileNavigation) ?? throw new Exception("Failed find newly inserted page attachment."); hasFileChanged = true; } int currentFileRevision = 0; var newDataHash = Security.Helpers.Crc32(item.Data); var currentlyAttachedFile = GetPageCurrentRevisionAttachmentByFileNavigation(o, item.PageId, item.FileNavigation); if (currentlyAttachedFile != null) { currentFileRevision = currentlyAttachedFile.Revision; hasFileChanged = currentlyAttachedFile.DataHash != newDataHash; } else { hasFileChanged = true; currentFileRevision = pageFileInfo.Revision; } if (hasFileChanged) { currentFileRevision++; int currentPageRevision = PageRepository.GetCurrentPageRevision(o, item.PageId); var updatePageFileRevisionParam = new { PageFileId = pageFileInfo.PageFileId, FileRevision = currentFileRevision }; o.Execute("UpdatePageFileRevision.sql", updatePageFileRevisionParam); var insertPageFileRevisionParam = new { PageFileId = pageFileInfo.PageFileId, ContentType = item.ContentType, Size = item.Size, CreatedDate = item.CreatedDate, CreatedByUserId = userId, Data = item.Data, FileRevision = currentFileRevision, DataHash = newDataHash, }; o.Execute("InsertPageFileRevision.sql", insertPageFileRevisionParam); var associatePageFileAttachmentWithPageRevisionParam = new { PageId = item.PageId, PageFileId = pageFileInfo.PageFileId, PageRevision = currentPageRevision, FileRevision = currentFileRevision, PreviousFileRevision = currentlyAttachedFile?.Revision }; o.Execute("AssociatePageFileAttachmentWithPageRevision.sql", associatePageFileAttachmentWithPageRevisionParam); } transaction.Commit(); } catch { transaction.Rollback(); throw; } }); } } }