2025-11-16 11:25:27 +00:00
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
import 'package:mnemo_cards_backend/cron/task.dart';
|
|
|
|
|
|
|
|
|
|
import '../main.dart';
|
|
|
|
|
|
|
|
|
|
class Backup with Task {
|
|
|
|
|
final backupDir;
|
|
|
|
|
|
|
|
|
|
static const _maxBackups = 6;
|
|
|
|
|
static const _maxBackupAgeDays = 2;
|
|
|
|
|
|
|
|
|
|
Backup(String dir) : backupDir = dir.endsWith('/') ? dir : '$dir/';
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
String get name => 'backup';
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Future<void> task() async {
|
|
|
|
|
print('$name waiting 5 seconds for other tasks to complete');
|
|
|
|
|
await Future.delayed(Duration(seconds: 5));
|
|
|
|
|
final t = DateTime.now();
|
|
|
|
|
final timeString =
|
|
|
|
|
'${t.year}_${t.month.toString().padLeft(2, '0')}_${t.day.toString().padLeft(2, '0')}_'
|
|
|
|
|
'${t.hour.toString().padLeft(2, '0')}_${t.minute.toString().padLeft(2, '0')}';
|
2025-12-13 20:55:50 +00:00
|
|
|
final filename = 'db_backup_$timeString.sql';
|
2025-11-16 11:25:27 +00:00
|
|
|
final to = '${backupDir}$filename';
|
|
|
|
|
final dir = Directory(backupDir)..createSync(recursive: true);
|
|
|
|
|
await _deleteOldBackups(dir);
|
2025-12-13 20:55:50 +00:00
|
|
|
// TODO: Implement PostgreSQL backup
|
|
|
|
|
// await database.backupToFile(to);
|
|
|
|
|
// print('$name database backup saved to $to');
|
2025-11-16 11:25:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> _deleteOldBackups(Directory dir) async {
|
|
|
|
|
final now = DateTime.now();
|
|
|
|
|
final backups = dir.listSync().whereType<File>();
|
|
|
|
|
if (backups.length > _maxBackups) {
|
|
|
|
|
final oldBackups = backups
|
|
|
|
|
.where(
|
|
|
|
|
(f) =>
|
|
|
|
|
now.difference(f.lastModifiedSync()).inDays > _maxBackupAgeDays,
|
|
|
|
|
)
|
|
|
|
|
.toList();
|
|
|
|
|
if (oldBackups.length != backups.length) {
|
|
|
|
|
oldBackups.sort(
|
|
|
|
|
(a, b) => a.lastModifiedSync().compareTo(b.lastModifiedSync()));
|
|
|
|
|
oldBackups.take(backups.length - _maxBackups).forEach((b) {
|
|
|
|
|
try {
|
|
|
|
|
b.deleteSync();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
print('$name error when deleting backup file $e');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
int get intervalSeconds => 60 * 60 * 12;
|
|
|
|
|
}
|