diff --git a/server/src/scripts/sync-database.ts b/server/src/scripts/sync-database.ts index 1e4dad979..f1fcfcecd 100644 --- a/server/src/scripts/sync-database.ts +++ b/server/src/scripts/sync-database.ts @@ -14,12 +14,16 @@ import { ChartDocument, FolderDocument, Game, + GoalDocument, + MilestoneDocument, + MilestoneSetDocument, SongDocument, TableDocument, } from "tachi-common"; import { RecalcAllScores } from "utils/calculations/recalc-scores"; import { UpdateGameSongIDCounter } from "utils/db"; import { InitaliseFolderChartLookup } from "utils/folder"; +import { IsSupported } from "utils/misc"; interface SyncInstructions { pattern: RegExp; @@ -60,7 +64,8 @@ async function GenericUpsert( collection: ICollection, field: keyof T, logger: KtLogger, - remove = false + remove = false, + update = true ) { logger.verbose(`Running bulkwrite.`); @@ -89,7 +94,7 @@ async function GenericUpsert( // @ts-expect-error Actually, T is assignable to OptionalId. insertOne: { document }, }); - } else if (fjsh.hash(document, "sha256") !== fjsh.hash(exists, "sha256")) { + } else if (update && fjsh.hash(document, "sha256") !== fjsh.hash(exists, "sha256")) { bwriteOps.push({ replaceOne: { // @ts-expect-error Known X->Y generic issue. @@ -243,6 +248,21 @@ const syncInstructions: SyncInstructions[] = [ await GenericUpsert(bmsCourseDocuments, collection, "md5sums", logger); }, }, + { + pattern: /^goals/u, + handler: async (goals: GoalDocument[], collection: ICollection, logger) => { + // never remove goals. Never update goals either. Only insert new ones as + // they come in. + await GenericUpsert( + goals.filter((e) => IsSupported(e.game)), + collection, + "goalID", + logger, + false, + false + ); + }, + }, ]; const logger = CreateLogCtx("Database Sync"); diff --git a/server/src/utils/misc.ts b/server/src/utils/misc.ts index a4b1d30ce..a89a36c1b 100644 --- a/server/src/utils/misc.ts +++ b/server/src/utils/misc.ts @@ -2,7 +2,7 @@ import { exec } from "child_process"; import crypto from "crypto"; import { ONE_HOUR } from "lib/constants/time"; import { TachiConfig } from "lib/setup/config"; -import { Game, GamePTConfig, GetGameConfig, integer, Playtypes } from "tachi-common"; +import { Game, GamePTConfig, GetGameConfig, integer, Playtype, Playtypes } from "tachi-common"; import { URL } from "url"; // https://github.com/sindresorhus/escape-string-regexp/blob/main/index.js @@ -199,3 +199,10 @@ export function HumanisedJoinArray(arr: string[], lastJoiner = "or") { export function FormatMaxDP(num: number, points = 2) { return parseFloat(num.toFixed(points)).toString(); } + +/** + * Returns whether this game is supported by this instance of tachi or not. + */ +export function IsSupported(game: Game) { + return TachiConfig.GAMES.includes(game); +}