refactor(db): typed query helpers, shared test FormData helper
Replace raw db.execute tuple casts with queryRows/rowsFrom/execResult/ affectedRows helpers from lib/db, drop redundant mysql2 casts on typed query builders, and centralize per-test fakeForm into test/fake-form. Update db mocks in tests so helpers resolve against mocked execute.
This commit is contained in:
1 parent
2e25b39364
commit
8638e81444
116 files changed
+866
-897
No files matched your search
@@ -3,7 +3,7 @@ import { existsSync, promises as fs } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import { and, eq, type SQL, sql } from "drizzle-orm";
|
||||
import { CatalogPages, db, ItemsBase } from "@/lib/db";
|
||||
import { CatalogPages, db, execResult, ItemsBase, queryRows } from "@/lib/db";
|
||||
import { officialHabboEnrichmentWarning } from "@/lib/habbo-gamedata-hotel";
|
||||
import { logger } from "@/lib/logger";
|
||||
import { logServerError } from "@/lib/server-log";
|
||||
@@ -146,10 +146,10 @@ async function dedupeCatalogPage(
|
||||
parentId: number,
|
||||
justCreatedId: number,
|
||||
): Promise<number> {
|
||||
const [rows] = (await db.execute(sql`
|
||||
const rows = await queryRows<{ id: number }>(sql`
|
||||
SELECT MIN(id) AS id FROM catalog_pages
|
||||
WHERE caption_save = ${captionSave} AND parent_id = ${parentId}
|
||||
`)) as unknown as [Array<{ id: number }>, unknown];
|
||||
`);
|
||||
const winner = rows[0]?.id ?? justCreatedId;
|
||||
if (winner !== justCreatedId) {
|
||||
// Never delete a page that already received catalog items.
|
||||
@@ -304,13 +304,13 @@ export async function reconcileImportedOfferIds(): Promise<{
|
||||
fixed: number;
|
||||
}> {
|
||||
const parentId = await getOrCreateImportedParentPage();
|
||||
const [result] = (await db.execute(sql`
|
||||
const result = await execResult(sql`
|
||||
UPDATE catalog_items ci
|
||||
JOIN catalog_pages cp ON cp.id = ci.page_id
|
||||
SET ci.offer_id = ci.id
|
||||
WHERE cp.parent_id = ${parentId}
|
||||
AND ci.offer_id <> ci.id
|
||||
`)) as unknown as [Record<string, unknown>, unknown];
|
||||
`);
|
||||
return { fixed: Number(result.affectedRows ?? 0) };
|
||||
}
|
||||
|
||||
@@ -486,9 +486,11 @@ export async function allocateCatalogItemId<T>(
|
||||
catalogNextId === null ||
|
||||
Date.now() - catalogIdLastUsed > CATALOG_ID_REFRESH_MS
|
||||
) {
|
||||
const [maxIdResult] = (await db.execute(sql`
|
||||
const maxIdResult = await queryRows<{
|
||||
maxId: number | bigint | null;
|
||||
}>(sql`
|
||||
SELECT MAX(id) as maxId FROM catalog_items
|
||||
`)) as unknown as [Array<{ maxId: number | bigint | null }>, unknown];
|
||||
`);
|
||||
catalogNextId = Number(maxIdResult[0]?.maxId ?? 0) + 1;
|
||||
}
|
||||
} finally {
|
||||
@@ -1067,9 +1069,12 @@ export async function importSingleFurni(params: {
|
||||
const itemIdStr = String(itemId);
|
||||
|
||||
// Check if this item already exists anywhere in the catalog
|
||||
const [existingCatalog] = (await db.execute(sql`
|
||||
const existingCatalog = await queryRows<{
|
||||
id: number;
|
||||
page_id: string;
|
||||
}>(sql`
|
||||
SELECT id, page_id FROM catalog_items WHERE FIND_IN_SET(${itemIdStr}, REPLACE(item_ids, ';', ',')) > 0 LIMIT 1
|
||||
`)) as unknown as [Array<{ id: number; page_id: string }>, unknown];
|
||||
`);
|
||||
|
||||
if (existingCatalog.length > 0) {
|
||||
catalogItemId = existingCatalog[0].id;
|
||||
@@ -1177,7 +1182,7 @@ export async function fixDatabaseConsistencyAfterImport(): Promise<{
|
||||
costCreditsFixed: number;
|
||||
}> {
|
||||
// 1. Fill empty catalog_name from items_base.public_name
|
||||
const [nameResult] = (await db.execute(sql`
|
||||
const nameResult = await execResult(sql`
|
||||
UPDATE catalog_items c
|
||||
JOIN items_base i ON c.item_ids = i.id
|
||||
SET c.catalog_name = CASE
|
||||
@@ -1185,23 +1190,23 @@ export async function fixDatabaseConsistencyAfterImport(): Promise<{
|
||||
ELSE i.public_name
|
||||
END
|
||||
WHERE c.catalog_name IS NULL OR c.catalog_name = ''
|
||||
`)) as unknown as [Record<string, unknown>, unknown];
|
||||
`);
|
||||
const catalogNameFixed = Number(nameResult.affectedRows ?? 0);
|
||||
|
||||
// 2. Set have_offer = '1' where it was '0'
|
||||
const [offerResult] = (await db.execute(sql`
|
||||
const offerResult = await execResult(sql`
|
||||
UPDATE catalog_items
|
||||
SET have_offer = '1'
|
||||
WHERE have_offer = '0'
|
||||
`)) as unknown as [Record<string, unknown>, unknown];
|
||||
`);
|
||||
const haveOfferFixed = Number(offerResult.affectedRows ?? 0);
|
||||
|
||||
// 3. Set cost_credits = 3 where it was <= 0
|
||||
const [creditResult] = (await db.execute(sql`
|
||||
const creditResult = await execResult(sql`
|
||||
UPDATE catalog_items
|
||||
SET cost_credits = 3
|
||||
WHERE cost_credits <= 0
|
||||
`)) as unknown as [Record<string, unknown>, unknown];
|
||||
`);
|
||||
const costCreditsFixed = Number(creditResult.affectedRows ?? 0);
|
||||
|
||||
return { catalogNameFixed, haveOfferFixed, costCreditsFixed };
|
||||
|
||||
Reference in new issue
Block a user