import moment from "moment-timezone"; import { getRepository, In } from "typeorm"; import { DBDateFormat } from "../../utils"; import { connection } from "../db"; import { Config } from "../entities/Config"; const CLEAN_PER_LOOP = 50; export async function cleanupConfigs() { const configRepository = getRepository(Config); let cleaned = 0; let rows; // >1 month old: 1 config retained per month const oneMonthCutoff = moment .utc() .subtract(30, "days") .format(DBDateFormat); do { rows = await connection.query( ` WITH _configs AS ( SELECT id, \`key\`, YEAR(edited_at) AS \`year\`, MONTH(edited_at) AS \`month\`, ROW_NUMBER() OVER ( PARTITION BY \`key\`, \`year\`, \`month\` ORDER BY edited_at ) AS row_num FROM configs WHERE is_active = 0 AND edited_at < ? ) SELECT * FROM _configs WHERE row_num > 1 `, [oneMonthCutoff], ); if (rows.length > 0) { await configRepository.delete({ id: In(rows.map(r => r.id)), }); } cleaned += rows.length; } while (rows.length === CLEAN_PER_LOOP); // >2 weeks old: 1 config retained per day const twoWeekCutoff = moment .utc() .subtract(2, "weeks") .format(DBDateFormat); do { rows = await connection.query( ` WITH _configs AS ( SELECT id, \`key\`, DATE(edited_at) AS \`date\`, ROW_NUMBER() OVER ( PARTITION BY \`key\`, \`date\` ORDER BY edited_at ) AS row_num FROM configs WHERE is_active = 0 AND edited_at < ? AND edited_at >= ? ) SELECT * FROM _configs WHERE row_num > 1 `, [twoWeekCutoff, oneMonthCutoff], ); if (rows.length > 0) { await configRepository.delete({ id: In(rows.map(r => r.id)), }); } cleaned += rows.length; } while (rows.length === CLEAN_PER_LOOP); return cleaned; }