refactor(server): dedupe shard-state shaping, upsert builder, and config DB models
Address the SonarQube copy-paste findings that reflect real duplication (as
opposed to the intentional cross-package / admin-player mirror copies, which
are by-design and left as-is):
- shardState.model.js: listOnline() re-inlined the exact field mapping that
shapeOnline() already provides (used by listOnlineLinked). Collapse it onto
shapeOnline so the two can no longer drift.
- shardState.db.js: extract a single upsertRow(table, pkCol, pk, fields,
{coalesce}) builder for the five near-identical INSERT ... ON DUPLICATE KEY
UPDATE bodies (online/houses/champs/guilds/governors). shard_online keeps its
COALESCE-on-NULL semantics via the coalesce flag.
- botConfig/emailConfig/uoLinkConfig .db.js: generate get()/upsert() from a
shared singletonConfigDb(table, cols) factory instead of three byte-identical
copies.
Behavior unchanged; full server suite (381 tests) passes.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
35
server/src/model/singletonConfigDb.js
Normal file
35
server/src/model/singletonConfigDb.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const { query } = require('../utils/db')
|
||||
|
||||
// Factory for the singleton config tables (bot_config, email_config,
|
||||
// uo_link_config). Each is a one-row table keyed on id = 1: `get()` returns the
|
||||
// row (or null before the admin first saves it), and `upsert()` writes only the
|
||||
// columns the model prepared, leaving the rest untouched. The three tables share
|
||||
// this shape exactly, so the DB layer is generated rather than copy-pasted —
|
||||
// only the table name and column list differ.
|
||||
//
|
||||
// `fields` are already prepared by the model (secrets pre-encrypted); ordering
|
||||
// and encryption stay a model-layer concern.
|
||||
function singletonConfigDb(table, cols) {
|
||||
async function get() {
|
||||
const rows = await query(`SELECT ${cols} FROM ${table} WHERE id = 1 LIMIT 1`)
|
||||
return rows[0] || null
|
||||
}
|
||||
|
||||
async function upsert(fields) {
|
||||
const columns = Object.keys(fields)
|
||||
const vals = columns.map((c) => fields[c])
|
||||
const insertCols = ['id', ...columns].map((c) => `\`${c}\``).join(', ')
|
||||
const placeholders = ['1', ...columns.map(() => '?')].join(', ')
|
||||
const updates = columns.map((c) => `\`${c}\` = VALUES(\`${c}\`)`).join(', ')
|
||||
await query(
|
||||
`INSERT INTO ${table} (${insertCols}) VALUES (${placeholders})
|
||||
ON DUPLICATE KEY UPDATE ${updates}`,
|
||||
vals,
|
||||
)
|
||||
return get()
|
||||
}
|
||||
|
||||
return { get, upsert }
|
||||
}
|
||||
|
||||
module.exports = singletonConfigDb
|
||||
Reference in New Issue
Block a user