ponshu-room-lite/lib/services/migration_service.dart

71 lines
2.3 KiB
Dart

import 'package:flutter/foundation.dart'; // debugPrint
import 'package:hive_flutter/hive_flutter.dart';
import '../models/sake_item.dart';
class MigrationService {
static const String _boxName = 'sake_items';
static const String _backupBoxName = 'sake_items_backup';
/// Runs the migration process with safety backup.
/// Should be called after Hive.init and Adapter registration, but before app UI loads.
static Future<void> runMigration() async {
debugPrint('[Migration] Starting Phase 0 Migration...');
// 1. Open Boxes
final box = await Hive.openBox<SakeItem>(_boxName);
// 2. Backup Strategy
try {
final backupBox = await Hive.openBox<SakeItem>(_backupBoxName);
if (backupBox.isEmpty && box.isNotEmpty) {
debugPrint('[Migration] detailed backup started...');
// Copy all
for (var key in box.keys) {
final SakeItem? item = box.get(key);
if (item != null) {
await backupBox.put(key, item.copyWith());
}
}
debugPrint('[Migration] Backup completed. ${backupBox.length} items secured.');
} else {
debugPrint('[Migration] Backup skipped (Existing backup found or Empty source).');
}
// Close backup to ensure flush
await backupBox.close();
} catch (e) {
debugPrint('[Migration] CRITICAL ERROR during Backup: $e');
// If backup fails, do we abort?
// Yes, abort migration to be safe.
return;
}
// 3. Migration (In-Place)
int migratedCount = 0;
for (var key in box.keys) {
final SakeItem? item = box.get(key);
if (item != null) {
try {
// ensureMigrated checks if displayData is null.
// If null, it populates it from legacy fields.
bool performed = item.ensureMigrated();
if (performed) {
await item.save(); // Persist the new structure (DisplayData, etc)
migratedCount++;
}
} catch (e) {
debugPrint('[Migration] Error migrating item $key: $e');
}
}
}
if (migratedCount > 0) {
debugPrint('[Migration] Successfully migrated $migratedCount items to Schema v2.0.');
} else {
debugPrint('[Migration] No items needed migration.');
}
}
}