diff --git a/packages/backend/src/core/chart/core.ts b/packages/backend/src/core/chart/core.ts index 2092b13b7e..d352adcc1f 100644 --- a/packages/backend/src/core/chart/core.ts +++ b/packages/backend/src/core/chart/core.ts @@ -11,9 +11,9 @@ import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; import type { Repository, DataSource } from 'typeorm'; -const columnPrefix = '___' as const; -const uniqueTempColumnPrefix = 'unique_temp___' as const; -const columnDot = '_' as const; +const COLUMN_PREFIX = '___' as const; +const UNIQUE_TEMP_COLUMN_PREFIX = 'unique_temp___' as const; +const COLUMN_DELIMITER = '_' as const; type Schema = Record; -type KeyToColumnName = T extends `${infer R1}.${infer R2}` ? `${R1}${typeof columnDot}${KeyToColumnName}` : T; +type KeyToColumnName = T extends `${infer R1}.${infer R2}` ? `${R1}${typeof COLUMN_DELIMITER}${KeyToColumnName}` : T; type Columns = { - [K in keyof S as `${typeof columnPrefix}${KeyToColumnName}`]: number; + [K in keyof S as `${typeof COLUMN_PREFIX}${KeyToColumnName}`]: number; }; type TempColumnsForUnique = { - [K in keyof S as `${typeof uniqueTempColumnPrefix}${KeyToColumnName}`]: S[K]['uniqueIncrement'] extends true ? string[] : never; + [K in keyof S as `${typeof UNIQUE_TEMP_COLUMN_PREFIX}${KeyToColumnName}`]: S[K]['uniqueIncrement'] extends true ? string[] : never; }; type RawRecord = { @@ -138,20 +138,20 @@ export default abstract class Chart { private static convertSchemaToColumnDefinitions(schema: Schema): Record { const columns = {} as Record; for (const [k, v] of Object.entries(schema)) { - const name = k.replaceAll('.', columnDot); + const name = k.replaceAll('.', COLUMN_DELIMITER); const type = v.range === 'big' ? 'bigint' : v.range === 'small' ? 'smallint' : 'integer'; if (v.uniqueIncrement) { - columns[uniqueTempColumnPrefix + name] = { + columns[UNIQUE_TEMP_COLUMN_PREFIX + name] = { type: 'varchar', array: true, default: '{}', }; - columns[columnPrefix + name] = { + columns[COLUMN_PREFIX + name] = { type, default: 0, }; } else { - columns[columnPrefix + name] = { + columns[COLUMN_PREFIX + name] = { type, default: 0, }; @@ -253,8 +253,8 @@ export default abstract class Chart { @bindThis private convertRawRecord(x: RawRecord): KVs { const kvs = {} as Record; - for (const k of Object.keys(x).filter((k) => k.startsWith(columnPrefix)) as (keyof Columns)[]) { - kvs[(k as string).substr(columnPrefix.length).split(columnDot).join('.')] = x[k] as unknown as number; + for (const k of Object.keys(x).filter((k) => k.startsWith(COLUMN_PREFIX)) as (keyof Columns)[]) { + kvs[(k as string).substr(COLUMN_PREFIX.length).split(COLUMN_DELIMITER).join('.')] = x[k] as unknown as number; } return kvs as KVs; } @@ -357,8 +357,8 @@ export default abstract class Chart { const columns = {} as Record; for (const [k, v] of Object.entries(data)) { - const name = k.replaceAll('.', columnDot); - columns[columnPrefix + name] = v; + const name = k.replaceAll('.', COLUMN_DELIMITER); + columns[COLUMN_PREFIX + name] = v; } // 新規ログ挿入 @@ -419,13 +419,13 @@ export default abstract class Chart { const queryForDay: Record, number | (() => string)> = {} as any; for (const [k, v] of Object.entries(finalDiffs)) { if (typeof v === 'number') { - const name = columnPrefix + k.replaceAll('.', columnDot) as string & keyof Columns; + const name = COLUMN_PREFIX + k.replaceAll('.', COLUMN_DELIMITER) as string & keyof Columns; if (v > 0) queryForHour[name] = () => `"${name}" + ${v}`; if (v < 0) queryForHour[name] = () => `"${name}" - ${Math.abs(v)}`; if (v > 0) queryForDay[name] = () => `"${name}" + ${v}`; if (v < 0) queryForDay[name] = () => `"${name}" - ${Math.abs(v)}`; } else if (Array.isArray(v) && v.length > 0) { // ユニークインクリメント - const tempColumnName = uniqueTempColumnPrefix + k.replaceAll('.', columnDot) as string & keyof TempColumnsForUnique; + const tempColumnName = UNIQUE_TEMP_COLUMN_PREFIX + k.replaceAll('.', COLUMN_DELIMITER) as string & keyof TempColumnsForUnique; // TODO: item をSQLエスケープ const itemsForHour = v.filter(item => !(logHour[tempColumnName] as unknown as string[]).includes(item)).map(item => `"${item}"`); const itemsForDay = v.filter(item => !(logDay[tempColumnName] as unknown as string[]).includes(item)).map(item => `"${item}"`); @@ -437,8 +437,8 @@ export default abstract class Chart { // bake unique count for (const [k, v] of Object.entries(finalDiffs)) { if (this.schema[k].uniqueIncrement) { - const name = columnPrefix + k.replaceAll('.', columnDot) as keyof Columns; - const tempColumnName = uniqueTempColumnPrefix + k.replaceAll('.', columnDot) as keyof TempColumnsForUnique; + const name = COLUMN_PREFIX + k.replaceAll('.', COLUMN_DELIMITER) as keyof Columns; + const tempColumnName = UNIQUE_TEMP_COLUMN_PREFIX + k.replaceAll('.', COLUMN_DELIMITER) as keyof TempColumnsForUnique; queryForHour[name] = new Set([...(v as string[]), ...(logHour[tempColumnName] as unknown as string[])]).size; queryForDay[name] = new Set([...(v as string[]), ...(logDay[tempColumnName] as unknown as string[])]).size; } @@ -449,15 +449,15 @@ export default abstract class Chart { for (const [k, v] of Object.entries(this.schema)) { const intersection = v.intersection; if (intersection) { - const name = columnPrefix + k.replaceAll('.', columnDot) as keyof Columns; + const name = COLUMN_PREFIX + k.replaceAll('.', COLUMN_DELIMITER) as keyof Columns; const firstKey = intersection[0]; - const firstTempColumnName = uniqueTempColumnPrefix + firstKey.replaceAll('.', columnDot) as keyof TempColumnsForUnique; + const firstTempColumnName = UNIQUE_TEMP_COLUMN_PREFIX + firstKey.replaceAll('.', COLUMN_DELIMITER) as keyof TempColumnsForUnique; const firstValues = finalDiffs[firstKey] as string[] | undefined; const currentValuesForHour = new Set([...(firstValues ?? []), ...(logHour[firstTempColumnName] as unknown as string[])]); const currentValuesForDay = new Set([...(firstValues ?? []), ...(logDay[firstTempColumnName] as unknown as string[])]); for (let i = 1; i < intersection.length; i++) { const targetKey = intersection[i]; - const targetTempColumnName = uniqueTempColumnPrefix + targetKey.replaceAll('.', columnDot) as keyof TempColumnsForUnique; + const targetTempColumnName = UNIQUE_TEMP_COLUMN_PREFIX + targetKey.replaceAll('.', COLUMN_DELIMITER) as keyof TempColumnsForUnique; const targetValues = finalDiffs[targetKey] as string[] | undefined; const targetValuesForHour = new Set([...(targetValues ?? []), ...(logHour[targetTempColumnName] as unknown as string[])]); const targetValuesForDay = new Set([...(targetValues ?? []), ...(logDay[targetTempColumnName] as unknown as string[])]); @@ -510,7 +510,7 @@ export default abstract class Chart { const columns = {} as Record, number>; for (const [k, v] of Object.entries(data) as ([keyof typeof data, number])[]) { - const name = columnPrefix + (k as string).replaceAll('.', columnDot) as keyof Columns; + const name = COLUMN_PREFIX + (k as string).replaceAll('.', COLUMN_DELIMITER) as keyof Columns; columns[name] = v; } @@ -556,7 +556,7 @@ export default abstract class Chart { const columns = {} as Record, []>; for (const [k, v] of Object.entries(this.schema)) { if (v.uniqueIncrement) { - const name = uniqueTempColumnPrefix + k.replaceAll('.', columnDot) as keyof TempColumnsForUnique; + const name = UNIQUE_TEMP_COLUMN_PREFIX + k.replaceAll('.', COLUMN_DELIMITER) as keyof TempColumnsForUnique; columns[name] = []; } }