From 949c4390858af952d11b173053e51356513b3b4d Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Fri, 26 Feb 2021 11:55:04 -0500 Subject: [PATCH] Temp functions, button to fill all empty guids. (#1037) --- Backend.Tests/Mocks/WordRepositoryMock.cs | 5 + Backend/Controllers/WordController.cs | 9 ++ Backend/Interfaces/IWordRepository.cs | 1 + Backend/Services/WordRepository.cs | 93 +++++++++++++++++++ src/backend/index.tsx | 8 ++ .../SiteSettings/SiteSettingsComponent.tsx | 8 +- 6 files changed, 123 insertions(+), 1 deletion(-) diff --git a/Backend.Tests/Mocks/WordRepositoryMock.cs b/Backend.Tests/Mocks/WordRepositoryMock.cs index 7877903832..7d584e9d88 100644 --- a/Backend.Tests/Mocks/WordRepositoryMock.cs +++ b/Backend.Tests/Mocks/WordRepositoryMock.cs @@ -78,5 +78,10 @@ public Task Add(Word word) _words.Add(word.Clone()); return Task.FromResult(word.Clone()); } + + public Task PopulateAllGuids() // ToDo: Remove after used on live server. + { + return Task.FromResult(false); + } } } diff --git a/Backend/Controllers/WordController.cs b/Backend/Controllers/WordController.cs index 2337a78613..3d87bfa6cf 100644 --- a/Backend/Controllers/WordController.cs +++ b/Backend/Controllers/WordController.cs @@ -34,6 +34,15 @@ public WordController(IWordRepository repo, IWordService wordService, IProjectSe [HttpGet] public async Task Get(string projectId) { + // ToDo: Remove this if-statement after used on live server. + if (projectId == "populateguids") + { + Console.WriteLine("Starting to populate guids..."); + await _wordRepo.PopulateAllGuids(); + Console.WriteLine("Done populating guids! Please verify success in mongo."); + return new OkResult(); + } + if (!await _permissionService.HasProjectPermission(HttpContext, Permission.WordEntry)) { return new ForbidResult(); diff --git a/Backend/Interfaces/IWordRepository.cs b/Backend/Interfaces/IWordRepository.cs index 604e238cf8..17d63801da 100644 --- a/Backend/Interfaces/IWordRepository.cs +++ b/Backend/Interfaces/IWordRepository.cs @@ -9,6 +9,7 @@ public interface IWordRepository Task> GetAllWords(string projectId); Task GetWord(string projectId, string wordId); Task Create(Word word); + Task PopulateAllGuids(); // ToDo: Remove after used on live server. Task Add(Word word); Task DeleteAllWords(string projectId); Task> GetFrontier(string projectId); diff --git a/Backend/Services/WordRepository.cs b/Backend/Services/WordRepository.cs index c2779ad29f..ba33f66ba0 100644 --- a/Backend/Services/WordRepository.cs +++ b/Backend/Services/WordRepository.cs @@ -103,6 +103,65 @@ internal static void PopulateWordGuids(Word word) } } + /// This method should be removed once all legacy data has been converted. + private async Task PopulateGuidsAndUpdateWord(Word word, Guid? guid = null) + { + if ((word.Guid is null || Guid.Empty.Equals(word.Guid)) && guid != null) + { + word.Guid = guid; + } + PopulateWordGuids(word); + return await UpdateWord(word); + } + + /// This method should be removed once all legacy data has been converted. + private async Task PopulateGuidInHistory(Word word) + { + PopulateWordGuids(word); + var idsToUpdate = new List(word.History) { word.Id }; + var success = true; + foreach (var priorId in idsToUpdate) + { + var priorWord = await GetWord(word.ProjectId, priorId); + if (priorWord != null) + { + success &= await PopulateGuidsAndUpdateWord(priorWord, word.Guid); + } + } + return success; + } + + /// This method should be removed once all legacy data has been converted. + public async Task PopulateAllGuids() + { + var success = true; + + // Update frontier words and their predecessors. + var frontierWords = await _wordDatabase.Frontier.Find(w => true).ToListAsync(); + foreach (var w in frontierWords) + { + success &= await PopulateGuidInHistory(w); + success &= await UpdateFrontier(w); + } + + // Update deleted words and their predecessors. + // Note: this could error if a deleted word has another deleted word in its history. + var deletedWords = await _wordDatabase.Words.Find(w => w.Accessibility == State.Deleted).ToListAsync(); + foreach (var w in deletedWords) + { + success &= await PopulateGuidInHistory(w); + } + + // Catch stragglers. + var allWords = await _wordDatabase.Words.Find(w => true).ToListAsync(); + foreach (var w in allWords) + { + success &= await PopulateGuidsAndUpdateWord(w); + } + + return success; + } + /// Adds a only to the WordsCollection /// /// If the Created or Modified time fields are blank, they will automatically calculated using the current @@ -141,5 +200,39 @@ public async Task DeleteFrontier(string projectId, string wordId) var deleted = await _wordDatabase.Frontier.DeleteOneAsync(filter); return deleted.DeletedCount > 0; } + + /// Updates in the Frontier collection with same wordId and projectId + /// A bool: success of operation + public async Task UpdateFrontier(Word word) + { + var filterDef = new FilterDefinitionBuilder(); + var filter = filterDef.And( + filterDef.Eq(x => x.ProjectId, word.ProjectId), + filterDef.Eq(x => x.Id, word.Id)); + + var deleted = (await _wordDatabase.Frontier.DeleteOneAsync(filter)).DeletedCount > 0; + if (deleted) + { + await AddFrontier(word); + } + return deleted; + } + + /// Updates in the Words collection with same wordId and projectId + /// A bool: success of operation + private async Task UpdateWord(Word word) + { + var filterDef = new FilterDefinitionBuilder(); + var filter = filterDef.And( + filterDef.Eq(x => x.ProjectId, word.ProjectId), + filterDef.Eq(x => x.Id, word.Id)); + + var deleted = (await _wordDatabase.Words.DeleteOneAsync(filter)).DeletedCount > 0; + if (deleted) + { + await Add(word); + } + return deleted; + } } } diff --git a/src/backend/index.tsx b/src/backend/index.tsx index 95572701f3..b4d8ec6deb 100644 --- a/src/backend/index.tsx +++ b/src/backend/index.tsx @@ -194,6 +194,14 @@ export async function getAllUsersInCurrentProject(): Promise { return resp.data; } +// ToDo: Remove this function after used on live server. +export async function populateAllGuids() { + const resp = await backendServer.get("projects/populateguids/words", { + headers: authHeader(), + }); + return resp.data; +} + export async function getUser(id: string): Promise { let resp = await backendServer.get(`users/${id}`, { headers: authHeader() }); return resp.data; diff --git a/src/components/SiteSettings/SiteSettingsComponent.tsx b/src/components/SiteSettings/SiteSettingsComponent.tsx index 0bbeb504b6..b94ec0030c 100644 --- a/src/components/SiteSettings/SiteSettingsComponent.tsx +++ b/src/components/SiteSettings/SiteSettingsComponent.tsx @@ -1,8 +1,9 @@ -import { Grid } from "@material-ui/core"; +import { Button, Grid } from "@material-ui/core"; import { List, People } from "@material-ui/icons"; import React from "react"; import { Translate } from "react-localize-redux"; +import { populateAllGuids } from "backend"; import BaseSettingsComponent from "components/BaseSettings/BaseSettingsComponent"; import ProjectManagement from "components/SiteSettings/ProjectManagement/ProjectManagement"; import UserManagement from "components/SiteSettings//UserManagement/UserManagement"; @@ -10,6 +11,11 @@ import UserManagement from "components/SiteSettings//UserManagement/UserManageme export default function SiteSettingsComponent() { return ( + {/* ToDo: Remove this Button after used on live server. */} + + {/* Project List */} }