refactor: implement conditional imports for database connection

This commit is contained in:
2025-05-04 13:09:06 +03:00
parent 1b97a921b2
commit 1153ed6f23
4 changed files with 61 additions and 118 deletions
+6 -118
View File
@@ -2,9 +2,10 @@
import 'package:drift/drift.dart';
// Условный импорт бэкенда базы данных
import 'database_connection/connection.dart'
if (dart.library.html) 'database_connection/connection_web.dart'
if (dart.library.io) 'database_connection/connection_native.dart';
// Выбирает реализацию connect() в зависимости от платформы
import 'database_connection/connection.dart' // Базовый импорт
if (dart.library.html) 'database_connection/connection_web.dart' // Для Веб
if (dart.library.io) 'database_connection/connection_native.dart'; // Для Нативных платформ (Android, iOS, Desktop)
// Импортируем модель категории для возвращаемого типа и утилиты
import '../models/category.dart';
@@ -29,6 +30,8 @@ class Transactions extends Table {
@DriftDatabase(tables: [Transactions])
class AppDatabase extends _$AppDatabase {
// Используем функцию connect() из условного импорта для создания соединения
// Во время компиляции будет выбрана правильная реализация connect()
// из connection_web.dart или connection_native.dart.
AppDatabase() : super(connect());
// Версия схемы. Увеличивайте при изменении структуры таблиц.
@@ -127,118 +130,3 @@ class AppDatabase extends _$AppDatabase {
}
}
}
// --- Старый способ с _openConnection ---
/*
import 'dart:io'; // Нужен только для NativeDatabase
import 'package:drift/drift.dart';
import 'package:drift/native.dart'; // Для NativeDatabase
import 'package:drift/web.dart'; // Для WebDatabase
import 'package:flutter/foundation.dart'; // Для kIsWeb
import 'package:path_provider/path_provider.dart'; // Для NativeDatabase
import 'package:path/path.dart' as p; // Для NativeDatabase
// ... (остальной код database.dart как выше) ...
// Функция для открытия соединения с базой данных (старый вариант)
QueryExecutor _openConnection() {
// Вычисление пути к файлу базы данных в папке документов приложения
if (kIsWeb) {
print("Using WebDatabase (IndexedDB)");
// Используем WebDatabase для веба. 'db' - имя базы данных в IndexedDB.
// logStatements: true полезен для отладки SQL-запросов (в консоли браузера)
return WebDatabase('db', logStatements: false);
} else {
// Используем NativeDatabase для нативных платформ (Android, iOS, Desktop)
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
// Создаем файл 'db.sqlite' в этой папке
final file = File(p.join(dbFolder.path, 'db.sqlite'));
print("Database file path (Native): ${file.path}"); // Логируем путь для отладки
// Используем NativeDatabase для открытия соединения
// logStatements: true полезен для отладки SQL-запросов
return NativeDatabase(file, logStatements: false);
});
}
}
*/
// --- Новый способ с условным импортом ---
// Создайте 3 новых файла в папке lib/database/database_connection/
// Файл 1: lib/database/database_connection/connection.dart
// Этот файл будет пустым или содержать общие абстракции, если нужно.
// Он нужен для указания базового пути для условного импорта.
/*
// lib/database/database_connection/connection.dart
import 'package:drift/drift.dart';
// Можно оставить пустым или определить общие типы/функции,
// но для простого соединения достаточно пустого файла.
// Главное, чтобы он существовал для разрешения импорта.
// Определим функцию-заглушку, чтобы основной файл мог ее импортировать
QueryExecutor connect() => throw UnimplementedError('Platform not supported');
*/
// Файл 2: lib/database/database_connection/connection_web.dart
/*
// lib/database/database_connection/connection_web.dart
import 'package:drift/drift.dart';
import 'package:drift/web.dart';
QueryExecutor connect() {
print("Using WebDatabase (IndexedDB)");
// logStatements: true полезен для отладки SQL-запросов (в консоли браузера)
return WebDatabase('db', logStatements: false);
}
*/
// Файл 3: lib/database/database_connection/connection_native.dart
/*
// lib/database/database_connection/connection_native.dart
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart'; // Импорт для настройки sqlite3
import 'package:sqlite3/sqlite3.dart'; // Импорт для настройки sqlite3
QueryExecutor connect() {
// Используем LazyDatabase для отложенной инициализации на нативных платформах
return LazyDatabase(() async {
// Настройка пути к библиотеке sqlite3 для Windows/Linux
// На Android/iOS/macOS это обычно не требуется, так как используется sqlite3_flutter_libs
if (Platform.isWindows || Platform.isLinux) {
// Эта часть может потребовать адаптации в зависимости от вашей системы сборки
// и того, как вы распространяете нативные библиотеки.
// Пример: final libraryNextToScript = File('sqlite3.so'); // или .dll
// applyWorkaroundToOpenSqlite3Library(library: libraryNextToScript);
// Или используйте пакет sqlite3_flutter_libs, который пытается сделать это автоматически
}
// Настройка для FFI (может быть не нужна с последними версиями drift/sqlite3_flutter_libs)
// sqlite3.open.overrideFor(OperatingSystem.windows, openSqliteOnWindows); // Пример для Windows
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
print("Database file path (Native): ${file.path}");
// Применяем обходной путь для открытия библиотеки sqlite3, если нужно
// Это важно для некоторых платформ, особенно Windows/Linux
// await applyWorkaroundToOpenSqlite3Library(checkIsolate: false); // Используйте по необходимости
// Используем NativeDatabase
return NativeDatabase(file, logStatements: false);
});
}
// Пример функции для Windows (может потребоваться адаптация)
// DynamicLibrary openSqliteOnWindows() {
// final scriptDir = File(Platform.script.toFilePath()).parent;
// final libraryNextToScript = File(p.join(scriptDir.path, 'sqlite3.dll'));
// return DynamicLibrary.open(libraryNextToScript.path);
// }
*/
@@ -0,0 +1,12 @@
// lib/database/database_connection/connection.dart
import 'package:drift/drift.dart';
// Этот файл служит базой для условного импорта.
// Реализации находятся в connection_web.dart и connection_native.dart.
// Определим функцию-заглушку, чтобы основной файл database.dart
// мог ее импортировать без ошибок анализатора.
// Во время выполнения будет вызвана реализация из соответствующего
// файла (web или native) благодаря условному импорту.
QueryExecutor connect() => throw UnsupportedError(
'Stub connect function should not be called. Ensure conditional imports are set up correctly.');
@@ -0,0 +1,33 @@
// lib/database/database_connection/connection_native.dart
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
// sqlite3_flutter_libs и sqlite3 импортируются для возможной тонкой настройки,
// но часто NativeDatabase справляется автоматически.
// import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
// import 'package:sqlite3/sqlite3.dart';
QueryExecutor connect() {
print("Connecting to database using NativeDatabase (Lazy)");
// Используем LazyDatabase для отложенной инициализации на нативных платформах
return LazyDatabase(() async {
// Получаем папку для хранения документов приложения
final dbFolder = await getApplicationDocumentsDirectory();
// Создаем путь к файлу 'db.sqlite' в этой папке
final file = File(p.join(dbFolder.path, 'db.sqlite'));
print("Database file path (Native): ${file.path}"); // Логируем путь для отладки
// Настройка библиотеки sqlite3 (обычно не требуется для Android/iOS/macOS с sqlite3_flutter_libs)
// if (Platform.isWindows || Platform.isLinux) {
// // Может потребоваться дополнительная настройка для Desktop
// // await applyWorkaroundToOpenSqlite3Library();
// }
// Используем NativeDatabase для открытия соединения
// logStatements: true полезен для отладки SQL-запросов
return NativeDatabase(file, logStatements: false);
});
}
@@ -0,0 +1,10 @@
// lib/database/database_connection/connection_web.dart
import 'package:drift/drift.dart';
import 'package:drift/web.dart';
QueryExecutor connect() {
print("Connecting to database using WebDatabase (IndexedDB)");
// Используем WebDatabase для веба. 'db' - имя базы данных в IndexedDB.
// logStatements: true полезен для отладки SQL-запросов (в консоли браузера)
return WebDatabase('db', logStatements: false);
}