import 'dart:ffi'; import 'dart:io'; import 'package:jadb/_data_ingestion/jmdict/table_names.dart'; import 'package:jadb/_data_ingestion/kanjidic/table_names.dart'; import 'package:jadb/_data_ingestion/radkfile/table_names.dart'; import 'package:jadb/_data_ingestion/tanos-jlpt/table_names.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:sqlite3/open.dart'; Future openLocalDb({ String? libsqlitePath, String? jadbPath, bool readWrite = false, bool assertTablesExist = true, bool walMode = false, }) async { libsqlitePath ??= Platform.environment['LIBSQLITE_PATH']; jadbPath ??= Platform.environment['JADB_PATH']; jadbPath ??= Directory.current.uri.resolve('jadb.sqlite').path; libsqlitePath = (libsqlitePath == null) ? null : File(libsqlitePath).resolveSymbolicLinksSync(); jadbPath = File(jadbPath).resolveSymbolicLinksSync(); if (libsqlitePath == null) { throw Exception("LIBSQLITE_PATH is not set"); } if (!File(libsqlitePath).existsSync()) { throw Exception("LIBSQLITE_PATH does not exist: $libsqlitePath"); } if (!File(jadbPath).existsSync()) { throw Exception("JADB_PATH does not exist: $jadbPath"); } final db = await createDatabaseFactoryFfi( ffiInit: () => open.overrideForAll(() => DynamicLibrary.open(libsqlitePath!)), ).openDatabase( jadbPath, options: OpenDatabaseOptions( onConfigure: (db) async { if (walMode) { await db.execute("PRAGMA journal_mode = WAL"); } await db.execute("PRAGMA foreign_keys = ON"); }, readOnly: !readWrite, ), ); if (assertTablesExist) { await _assertTablesExist(db); } return db; } Future _assertTablesExist(Database db) async { final Set tables = await db .query( 'sqlite_master', columns: ['name'], where: 'type = ?', whereArgs: ['table'], ) .then((result) { return result.map((row) => row['name'] as String).toSet(); }); final Set expectedTables = { ...JMdictTableNames.allTables, ...KANJIDICTableNames.allTables, ...RADKFILETableNames.allTables, ...TanosJLPTTableNames.allTables, }; final missingTables = expectedTables.difference(tables); if (missingTables.isNotEmpty) { throw Exception([ 'Missing tables:', missingTables.map((table) => ' - $table').join('\n'), '', 'Found tables:\n', tables.map((table) => ' - $table').join('\n'), '', 'Please ensure the database is correctly set up.', ].join('\n')); } }