Files
onebox/ts/database/migrations/migration-012-gfs-retention.ts
Juergen Kunz 49998c4c32
Some checks failed
CI / Type Check & Lint (push) Failing after 36s
CI / Build Test (Current Platform) (push) Failing after 1m8s
CI / Build All Platforms (push) Successful in 8m29s
add migration
2026-03-15 12:45:13 +00:00

98 lines
3.8 KiB
TypeScript

import { BaseMigration } from './base-migration.ts';
import type { TQueryFunction } from '../types.ts';
export class Migration012GfsRetention extends BaseMigration {
readonly version = 12;
readonly description = 'GFS retention policy schema';
up(query: TQueryFunction): void {
// Recreate backup_schedules with GFS retention columns
query(`
CREATE TABLE backup_schedules_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
scope_type TEXT NOT NULL DEFAULT 'service',
scope_pattern TEXT,
service_id INTEGER,
service_name TEXT,
cron_expression TEXT NOT NULL,
retention_hourly INTEGER NOT NULL DEFAULT 0,
retention_daily INTEGER NOT NULL DEFAULT 7,
retention_weekly INTEGER NOT NULL DEFAULT 4,
retention_monthly INTEGER NOT NULL DEFAULT 12,
enabled INTEGER NOT NULL DEFAULT 1,
last_run_at REAL,
next_run_at REAL,
last_status TEXT,
last_error TEXT,
created_at REAL NOT NULL,
updated_at REAL NOT NULL,
FOREIGN KEY (service_id) REFERENCES services(id) ON DELETE CASCADE
)
`);
// Migrate existing data - convert old retention_tier to new format
query(`
INSERT INTO backup_schedules_new (
id, scope_type, scope_pattern, service_id, service_name, cron_expression,
retention_hourly, retention_daily, retention_weekly, retention_monthly,
enabled, last_run_at, next_run_at, last_status, last_error, created_at, updated_at
)
SELECT
id, scope_type, scope_pattern, service_id, service_name, cron_expression,
0,
CASE WHEN retention_tier = 'daily' THEN 7 ELSE 0 END,
CASE WHEN retention_tier IN ('daily', 'weekly') THEN 4 ELSE 0 END,
CASE WHEN retention_tier IN ('daily', 'weekly', 'monthly') THEN 12
WHEN retention_tier = 'yearly' THEN 24 ELSE 12 END,
enabled, last_run_at, next_run_at, last_status, last_error, created_at, updated_at
FROM backup_schedules
`);
query('DROP TABLE backup_schedules');
query('ALTER TABLE backup_schedules_new RENAME TO backup_schedules');
query(
'CREATE INDEX IF NOT EXISTS idx_backup_schedules_service ON backup_schedules(service_id)',
);
query(
'CREATE INDEX IF NOT EXISTS idx_backup_schedules_enabled ON backup_schedules(enabled)',
);
query(
'CREATE INDEX IF NOT EXISTS idx_backup_schedules_scope ON backup_schedules(scope_type)',
);
// Recreate backups table without retention_tier column
query(`
CREATE TABLE backups_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
service_id INTEGER NOT NULL,
service_name TEXT NOT NULL,
filename TEXT NOT NULL,
size_bytes INTEGER NOT NULL,
created_at REAL NOT NULL,
includes_image INTEGER NOT NULL,
platform_resources TEXT NOT NULL DEFAULT '[]',
checksum TEXT NOT NULL,
schedule_id INTEGER REFERENCES backup_schedules(id) ON DELETE SET NULL,
FOREIGN KEY (service_id) REFERENCES services(id) ON DELETE CASCADE
)
`);
query(`
INSERT INTO backups_new (
id, service_id, service_name, filename, size_bytes, created_at,
includes_image, platform_resources, checksum, schedule_id
)
SELECT
id, service_id, service_name, filename, size_bytes, created_at,
includes_image, platform_resources, checksum, schedule_id
FROM backups
`);
query('DROP TABLE backups');
query('ALTER TABLE backups_new RENAME TO backups');
query('CREATE INDEX IF NOT EXISTS idx_backups_service ON backups(service_id)');
query('CREATE INDEX IF NOT EXISTS idx_backups_created ON backups(created_at DESC)');
query('CREATE INDEX IF NOT EXISTS idx_backups_schedule ON backups(schedule_id)');
}
}