From 1153ed6f23bc153b16f6468b0d9ee9716c7fe216 Mon Sep 17 00:00:00 2001 From: "Sanders (aider)" Date: Sun, 4 May 2025 13:09:06 +0300 Subject: [PATCH] refactor: implement conditional imports for database connection --- finance_app/lib/database/database.dart | 124 +----------------- .../database_connection/connection.dart | 12 ++ .../connection_native.dart | 33 +++++ .../database_connection/connection_web.dart | 10 ++ 4 files changed, 61 insertions(+), 118 deletions(-) create mode 100644 lib/database/database_connection/connection.dart create mode 100644 lib/database/database_connection/connection_native.dart create mode 100644 lib/database/database_connection/connection_web.dart diff --git a/finance_app/lib/database/database.dart b/finance_app/lib/database/database.dart index 6132f7f..8bebc82 100644 --- a/finance_app/lib/database/database.dart +++ b/finance_app/lib/database/database.dart @@ -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); -// } -*/ diff --git a/lib/database/database_connection/connection.dart b/lib/database/database_connection/connection.dart new file mode 100644 index 0000000..ace0070 --- /dev/null +++ b/lib/database/database_connection/connection.dart @@ -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.'); diff --git a/lib/database/database_connection/connection_native.dart b/lib/database/database_connection/connection_native.dart new file mode 100644 index 0000000..ebab0da --- /dev/null +++ b/lib/database/database_connection/connection_native.dart @@ -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); + }); +} diff --git a/lib/database/database_connection/connection_web.dart b/lib/database/database_connection/connection_web.dart new file mode 100644 index 0000000..d2369fb --- /dev/null +++ b/lib/database/database_connection/connection_web.dart @@ -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); +}