From 4d3ba54d50fecad02a609f440a9213f954976ff6 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Wed, 2 Apr 2025 14:02:58 -0400 Subject: [PATCH] rebuild burial site names on cemetery key change --- database/rebuildBurialSiteNames.d.ts | 2 + database/rebuildBurialSiteNames.js | 45 +++++++++++++ database/rebuildBurialSiteNames.ts | 70 ++++++++++++++++++++ database/updateCemetery.d.ts | 17 +++-- database/updateCemetery.js | 25 ++++++- database/updateCemetery.ts | 63 +++++++++++++++--- handlers/cemeteries-post/doUpdateCemetery.js | 15 ++++- handlers/cemeteries-post/doUpdateCemetery.ts | 21 +++++- public/javascripts/cemetery.edit.js | 18 +++-- public/javascripts/cemetery.edit.ts | 19 ++++-- 10 files changed, 265 insertions(+), 30 deletions(-) create mode 100644 database/rebuildBurialSiteNames.d.ts create mode 100644 database/rebuildBurialSiteNames.js create mode 100644 database/rebuildBurialSiteNames.ts diff --git a/database/rebuildBurialSiteNames.d.ts b/database/rebuildBurialSiteNames.d.ts new file mode 100644 index 00000000..0e79dbc9 --- /dev/null +++ b/database/rebuildBurialSiteNames.d.ts @@ -0,0 +1,2 @@ +import type { PoolConnection } from 'better-sqlite-pool'; +export default function rebuildBurialSiteNames(cemeteryId: number | string, user: User, connectedDatabase?: PoolConnection): Promise; diff --git a/database/rebuildBurialSiteNames.js b/database/rebuildBurialSiteNames.js new file mode 100644 index 00000000..e0f31947 --- /dev/null +++ b/database/rebuildBurialSiteNames.js @@ -0,0 +1,45 @@ +import { buildBurialSiteName } from '../helpers/burialSites.helpers.js'; +import getBurialSites from './getBurialSites.js'; +import getCemetery from './getCemetery.js'; +import { acquireConnection } from './pool.js'; +export default async function rebuildBurialSiteNames(cemeteryId, user, connectedDatabase) { + const database = connectedDatabase ?? (await acquireConnection()); + /* + * Get the cemetery key + */ + const cemetery = await getCemetery(cemeteryId, database); + if (cemetery === undefined) { + if (connectedDatabase === undefined) { + database.release(); + } + return 0; + } + /* + * Get the burial sites + */ + const burialSites = await getBurialSites({ + cemeteryId + }, { + limit: -1, + offset: 0 + }, database); + let updateCount = 0; + for (const burialSite of burialSites.burialSites) { + const burialSiteName = buildBurialSiteName(cemetery.cemeteryKey, burialSite); + if (burialSiteName !== burialSite.burialSiteName) { + const result = database + .prepare(`update BurialSites + set burialSiteName = ?, + recordUpdate_userName = ?, + recordUpdate_timeMillis = ? + where burialSiteId = ? + and recordDelete_timeMillis is null`) + .run(burialSiteName, user.userName, Date.now(), burialSite.burialSiteId); + updateCount += result.changes; + } + } + if (connectedDatabase === undefined) { + database.release(); + } + return updateCount; +} diff --git a/database/rebuildBurialSiteNames.ts b/database/rebuildBurialSiteNames.ts new file mode 100644 index 00000000..9b728f8f --- /dev/null +++ b/database/rebuildBurialSiteNames.ts @@ -0,0 +1,70 @@ +import type { PoolConnection } from 'better-sqlite-pool' + +import { buildBurialSiteName } from '../helpers/burialSites.helpers.js' + +import getBurialSites from './getBurialSites.js' +import getCemetery from './getCemetery.js' +import { acquireConnection } from './pool.js' + +export default async function rebuildBurialSiteNames( + cemeteryId: number | string, + user: User, + connectedDatabase?: PoolConnection +): Promise { + const database = connectedDatabase ?? (await acquireConnection()) + + /* + * Get the cemetery key + */ + + const cemetery = await getCemetery(cemeteryId, database) + + if (cemetery === undefined) { + if (connectedDatabase === undefined) { + database.release() + } + + return 0 + } + + /* + * Get the burial sites + */ + + const burialSites = await getBurialSites( + { + cemeteryId + }, + { + limit: -1, + offset: 0 + }, + database + ) + + let updateCount = 0 + + for (const burialSite of burialSites.burialSites) { + const burialSiteName = buildBurialSiteName(cemetery.cemeteryKey, burialSite) + + if (burialSiteName !== burialSite.burialSiteName) { + const result = database + .prepare( + `update BurialSites + set burialSiteName = ?, + recordUpdate_userName = ?, + recordUpdate_timeMillis = ? + where burialSiteId = ? + and recordDelete_timeMillis is null` + ) + .run(burialSiteName, user.userName, Date.now(), burialSite.burialSiteId) + + updateCount += result.changes + } + } + + if (connectedDatabase === undefined) { + database.release() + } + return updateCount +} diff --git a/database/updateCemetery.d.ts b/database/updateCemetery.d.ts index c4c03f9b..18871f16 100644 --- a/database/updateCemetery.d.ts +++ b/database/updateCemetery.d.ts @@ -1,16 +1,19 @@ export interface UpdateCemeteryForm { cemeteryId: string; - cemeteryName: string; - cemeteryKey: string; cemeteryDescription: string; - cemeterySvg: string; - cemeteryLatitude: string; - cemeteryLongitude: string; + cemeteryKey: string; + cemeteryName: string; cemeteryAddress1: string; cemeteryAddress2: string; cemeteryCity: string; - cemeteryProvince: string; cemeteryPostalCode: string; + cemeteryProvince: string; cemeteryPhoneNumber: string; + cemeteryLatitude: string; + cemeteryLongitude: string; + cemeterySvg: string; } -export default function updateCemetery(updateForm: UpdateCemeteryForm, user: User): Promise; +export default function updateCemetery(updateForm: UpdateCemeteryForm, user: User): Promise<{ + doRebuildBurialSiteNames: boolean; + success: boolean; +}>; diff --git a/database/updateCemetery.js b/database/updateCemetery.js index b309a02e..9e82ee66 100644 --- a/database/updateCemetery.js +++ b/database/updateCemetery.js @@ -1,3 +1,6 @@ +import { buildBurialSiteName } from '../helpers/burialSites.helpers.js'; +import { getConfigProperty } from '../helpers/config.helpers.js'; +import getBurialSites from './getBurialSites.js'; import { acquireConnection } from './pool.js'; export default async function updateCemetery(updateForm, user) { const database = await acquireConnection(); @@ -24,6 +27,26 @@ export default async function updateCemetery(updateForm, user) { : updateForm.cemeteryLatitude, updateForm.cemeteryLongitude === '' ? undefined : updateForm.cemeteryLongitude, updateForm.cemeteryAddress1, updateForm.cemeteryAddress2, updateForm.cemeteryCity, updateForm.cemeteryProvince, updateForm.cemeteryPostalCode, updateForm.cemeteryPhoneNumber, user.userName, Date.now(), updateForm.cemeteryId); + /* + * Check if burial site names need to be updated + */ + let doRebuildBurialSiteNames = false; + if (getConfigProperty('settings.burialSites.burialSiteNameSegments.includeCemeteryKey')) { + const burialSites = await getBurialSites({ cemeteryId: updateForm.cemeteryId }, { limit: 1, offset: 0 }, database); + if (burialSites.count > 0 && + buildBurialSiteName(updateForm.cemeteryKey, { + burialSiteNameSegment1: burialSites.burialSites[0].burialSiteNameSegment1, + burialSiteNameSegment2: burialSites.burialSites[0].burialSiteNameSegment2, + burialSiteNameSegment3: burialSites.burialSites[0].burialSiteNameSegment3, + burialSiteNameSegment4: burialSites.burialSites[0].burialSiteNameSegment4, + burialSiteNameSegment5: burialSites.burialSites[0].burialSiteNameSegment5 + }) !== burialSites.burialSites[0].burialSiteName) { + doRebuildBurialSiteNames = true; + } + } database.release(); - return result.changes > 0; + return { + doRebuildBurialSiteNames, + success: result.changes > 0 + }; } diff --git a/database/updateCemetery.ts b/database/updateCemetery.ts index 424b76d9..14ecaf06 100644 --- a/database/updateCemetery.ts +++ b/database/updateCemetery.ts @@ -1,25 +1,33 @@ +import { buildBurialSiteName } from '../helpers/burialSites.helpers.js' +import { getConfigProperty } from '../helpers/config.helpers.js' + +import getBurialSites from './getBurialSites.js' import { acquireConnection } from './pool.js' export interface UpdateCemeteryForm { cemeteryId: string - cemeteryName: string - cemeteryKey: string + cemeteryDescription: string - cemeterySvg: string - cemeteryLatitude: string - cemeteryLongitude: string + cemeteryKey: string + cemeteryName: string + cemeteryAddress1: string cemeteryAddress2: string cemeteryCity: string - cemeteryProvince: string cemeteryPostalCode: string + cemeteryProvince: string + cemeteryPhoneNumber: string + + cemeteryLatitude: string + cemeteryLongitude: string + cemeterySvg: string } export default async function updateCemetery( updateForm: UpdateCemeteryForm, user: User -): Promise { +): Promise<{ doRebuildBurialSiteNames: boolean; success: boolean; }> { const database = await acquireConnection() const result = database @@ -64,7 +72,46 @@ export default async function updateCemetery( updateForm.cemeteryId ) + /* + * Check if burial site names need to be updated + */ + + let doRebuildBurialSiteNames = false + + if ( + getConfigProperty( + 'settings.burialSites.burialSiteNameSegments.includeCemeteryKey' + ) + ) { + const burialSites = await getBurialSites( + { cemeteryId: updateForm.cemeteryId }, + { limit: 1, offset: 0 }, + database + ) + + if ( + burialSites.count > 0 && + buildBurialSiteName(updateForm.cemeteryKey, { + burialSiteNameSegment1: + burialSites.burialSites[0].burialSiteNameSegment1, + burialSiteNameSegment2: + burialSites.burialSites[0].burialSiteNameSegment2, + burialSiteNameSegment3: + burialSites.burialSites[0].burialSiteNameSegment3, + burialSiteNameSegment4: + burialSites.burialSites[0].burialSiteNameSegment4, + burialSiteNameSegment5: + burialSites.burialSites[0].burialSiteNameSegment5 + }) !== burialSites.burialSites[0].burialSiteName + ) { + doRebuildBurialSiteNames = true + } + } + database.release() - return result.changes > 0 + return { + doRebuildBurialSiteNames, + success: result.changes > 0 + } } diff --git a/handlers/cemeteries-post/doUpdateCemetery.js b/handlers/cemeteries-post/doUpdateCemetery.js index 74c26935..663ac6d6 100644 --- a/handlers/cemeteries-post/doUpdateCemetery.js +++ b/handlers/cemeteries-post/doUpdateCemetery.js @@ -1,8 +1,17 @@ +import rebuildBurialSiteNames from '../../database/rebuildBurialSiteNames.js'; import updateCemetery from '../../database/updateCemetery.js'; +import { clearNextPreviousBurialSiteIdCache } from '../../helpers/burialSites.helpers.js'; export default async function handler(request, response) { - const success = await updateCemetery(request.body, request.session.user); + const result = await updateCemetery(request.body, request.session.user); response.json({ - success, - cemeteryId: request.body.cemeteryId + success: result.success, + cemeteryId: request.body.cemeteryId, + doRebuildBurialSiteNames: result.doRebuildBurialSiteNames }); + if (result.doRebuildBurialSiteNames) { + response.on('finish', () => { + void rebuildBurialSiteNames(request.body.cemeteryId, request.session.user); + clearNextPreviousBurialSiteIdCache(); + }); + } } diff --git a/handlers/cemeteries-post/doUpdateCemetery.ts b/handlers/cemeteries-post/doUpdateCemetery.ts index f31c3147..775934f7 100644 --- a/handlers/cemeteries-post/doUpdateCemetery.ts +++ b/handlers/cemeteries-post/doUpdateCemetery.ts @@ -1,20 +1,35 @@ import type { Request, Response } from 'express' +import rebuildBurialSiteNames from '../../database/rebuildBurialSiteNames.js' import updateCemetery, { type UpdateCemeteryForm } from '../../database/updateCemetery.js' +import { clearNextPreviousBurialSiteIdCache } from '../../helpers/burialSites.helpers.js' export default async function handler( request: Request, response: Response ): Promise { - const success = await updateCemetery( + const result = await updateCemetery( request.body, request.session.user as User ) response.json({ - success, - cemeteryId: request.body.cemeteryId + success: result.success, + + cemeteryId: request.body.cemeteryId, + doRebuildBurialSiteNames: result.doRebuildBurialSiteNames }) + + if (result.doRebuildBurialSiteNames) { + response.on('finish', () => { + void rebuildBurialSiteNames( + request.body.cemeteryId, + request.session.user as User + ) + + clearNextPreviousBurialSiteIdCache() + }) + } } diff --git a/public/javascripts/cemetery.edit.js b/public/javascripts/cemetery.edit.js index 07eec6c1..184cd053 100644 --- a/public/javascripts/cemetery.edit.js +++ b/public/javascripts/cemetery.edit.js @@ -45,10 +45,20 @@ Object.defineProperty(exports, "__esModule", { value: true }); globalThis.location.href = sunrise.getCemeteryURL(responseJSON.cemeteryId, true); } else { - bulmaJS.alert({ - message: 'Cemetery Updated Successfully', - contextualColorName: 'success' - }); + if (responseJSON.doRebuildBurialSiteNames ?? false) { + bulmaJS.alert({ + message: `Cemetery Updated Successfully
+ Note that rebuilding burial site names may take a few minutes.`, + messageIsHtml: true, + contextualColorName: 'warning' + }); + } + else { + bulmaJS.alert({ + message: 'Cemetery Updated Successfully', + contextualColorName: 'success' + }); + } } } else { diff --git a/public/javascripts/cemetery.edit.ts b/public/javascripts/cemetery.edit.ts index 0fd69ebd..7fb08d54 100644 --- a/public/javascripts/cemetery.edit.ts +++ b/public/javascripts/cemetery.edit.ts @@ -71,6 +71,7 @@ declare const exports: Record const responseJSON = rawResponseJSON as { success: boolean cemeteryId?: number + doRebuildBurialSiteNames?: boolean errorMessage?: string } @@ -83,10 +84,20 @@ declare const exports: Record true ) } else { - bulmaJS.alert({ - message: 'Cemetery Updated Successfully', - contextualColorName: 'success' - }) + if (responseJSON.doRebuildBurialSiteNames ?? false) { + bulmaJS.alert({ + message: `Cemetery Updated Successfully
+ Note that rebuilding burial site names may take a few minutes.`, + messageIsHtml: true, + contextualColorName: 'warning' + }) + } else { + + bulmaJS.alert({ + message: 'Cemetery Updated Successfully', + contextualColorName: 'success' + }) + } } } else { bulmaJS.alert({