fix: insert initial data exclusively in onCreate

This commit is contained in:
2025-05-04 22:40:49 +03:00
parent f14cde0247
commit a0f3c016fa
+24 -30
View File
@@ -58,42 +58,35 @@ class AppDatabase extends _$AppDatabase {
MigrationStrategy get migration => MigrationStrategy(
onCreate: (m) async {
await m.createAll();
// Optionally insert initial data on creation
await insertInitialDataIfNeeded(isCreating: true);
// Вставляем начальные данные ТОЛЬКО при создании базы данных
print("Database created. Inserting initial data...");
// ИЗМЕНЕНО: Вызов insertInitialDataIfNeeded теперь только здесь
await insertInitialDataIfNeeded();
},
onUpgrade: (m, from, to) async {
// Drift автоматически обработает добавление новых таблиц (Categories)
// при обновлении до версии 4.
// Нам нужно только обработать специфичные изменения, как добавление колонки type.
if (from == 1) {
// Миграция с версии 1 на 2: добавляем колонку type
// ИСПРАВЛЕНО: Убран параметр defaultValue. Drift использует .withDefault() из определения колонки.
await m.addColumn(transactions, transactions.type);
// Drift's default migration will add the column and use the
// default value specified in the table definition for existing rows.
}
// Add more migration steps for future versions here
// if (from < 3) { ... }
// If migrating to version 4 where Categories table was added,
// Drift handles creating the new table automatically.
// We might want to ensure initial data is inserted if upgrading
// from a version before initial data logic was robust.
if (from < 4) {
// Ensure the categories table exists if upgrading from a version before it was defined
// (Drift's createAll in onCreate handles new tables, but onUpgrade might need it)
// However, `m.createAll()` is usually for onCreate.
// For adding tables in upgrades, you typically use `m.createTable(categories);`
// But Drift's default strategy handles adding new tables defined in the @DriftDatabase annotation.
// So, we mainly need to ensure the initial data gets inserted if needed.
await insertInitialDataIfNeeded(isCreating: false); // Check and insert if missing
}
// ИЗМЕНЕНО: Удален вызов insertInitialDataIfNeeded отсюда
// Не нужно вставлять начальные данные при обновлении существующей БД.
},
beforeOpen: (details) async {
// ИЗМЕНЕНО: Удален вызов insertInitialDataIfNeeded отсюда
// Логика вставки начальных данных теперь полностью в onCreate.
if (details.wasCreated) {
print("Database was created. Initial data should have been inserted via onCreate.");
} else {
print("Opening existing database version ${details.versionNow}. Checking if initial data needs insertion (e.g., if DB was created empty before initial data logic).");
// Check and insert initial data if the database exists but might be empty
// (e.g., if created before the initial data logic was in onCreate or migration)
await insertInitialDataIfNeeded(isCreating: false);
print("Opening existing database version ${details.versionNow}.");
}
// Можно добавить здесь другие проверки или настройки при открытии, если нужно.
return Future.value(); // beforeOpen должен возвращать Future<void>
},
);
@@ -196,17 +189,16 @@ class AppDatabase extends _$AppDatabase {
}
// Добавление начальных данных (если база данных пуста)
Future<void> insertInitialDataIfNeeded({bool isCreating = false}) async {
// Проверяем, есть ли уже категории
// ИСПРАВЛЕНО: Используем 'categories' (имя экземпляра таблицы) вместо 'category'
// Добавление начальных данных (вызывается только из onCreate)
// ИЗМЕНЕНО: Убран необязательный параметр isCreating, т.к. вызывается только при создании
Future<void> insertInitialDataIfNeeded() async {
// Проверяем, есть ли уже категории (на всякий случай, хотя в onCreate их быть не должно)
final categoriesCountResult = await (selectOnly(categories)..addColumns([categories.id.count()])).getSingleOrNull();
final categoriesCount = categoriesCountResult?.read(categories.id.count()) ?? 0;
if (categoriesCount == 0) {
print("Categories table is empty. Inserting initial categories...");
print("Inserting initial categories...");
await batch((batch) {
// ИСПРАВЛЕНО: Используем 'categories' (имя экземпляра таблицы) вместо 'category'
batch.insertAll(categories, [
// Используем CategoriesCompanion (сгенерированный для таблицы Categories)
CategoriesCompanion.insert(name: 'Groceries', icon: 'shopping_cart_outlined', color: c.Colors.green.shade400.value),
@@ -222,16 +214,17 @@ class AppDatabase extends _$AppDatabase {
});
print("Initial categories inserted.");
} else {
// Эта ветка не должна выполняться при вызове из onCreate, но оставим для отладки
print("Categories table already contains data ($categoriesCount categories). Skipping initial category insertion.");
}
// Проверяем, есть ли уже транзакции
// Проверяем, есть ли уже транзакции (аналогично, не должно быть в onCreate)
final countResult = await (selectOnly(transactions)..addColumns([transactions.id.count()])).getSingleOrNull();
final transactionCount = countResult?.read(transactions.id.count()) ?? 0;
// Вставляем данные только если таблица транзакций пуста
if (transactionCount == 0) {
print("Transactions table is empty${isCreating ? ' (during creation)' : ''}. Inserting initial transactions...");
print("Inserting initial transactions...");
// Используем batch для эффективной вставки нескольких записей
await batch((batch) {
batch.insertAll(transactions, [
@@ -251,6 +244,7 @@ class AppDatabase extends _$AppDatabase {
});
print("Initial transactions inserted successfully.");
} else {
// Эта ветка не должна выполняться при вызове из onCreate
print("Transactions table already contains data ($transactionCount transactions). Skipping initial transaction insertion.");
}
}