diff --git a/bin/jadb.dart b/bin/jadb.dart index d05ffd8..cb01112 100644 --- a/bin/jadb.dart +++ b/bin/jadb.dart @@ -1,153 +1,8 @@ -import 'dart:convert'; -import 'dart:ffi'; -import 'dart:io'; - -import 'package:args/args.dart'; import 'package:args/command_runner.dart'; -import 'package:jadb/_data_ingestion/seed_database.dart'; -import 'package:jadb/search.dart'; -import 'package:sqflite_common_ffi/sqflite_ffi.dart'; -import 'package:sqlite3/open.dart'; -void addLibsqliteArg(ArgParser argParser) { - argParser.addOption( - 'libsqlite', - help: - 'Path to the SQLite library. This is used to load the SQLite library dynamically.', - valueHelp: 'PATH', - defaultsTo: Platform.environment['LIBSQLITE_PATH'], - ); -} - -void addJadbArg(ArgParser argParser) { - argParser.addOption( - 'jadb', - abbr: 'f', - help: 'Path to the SQLite database file.', - valueHelp: 'PATH', - defaultsTo: Platform.environment['JADB_PATH'], - ); -} - -class CreateDb extends Command { - final name = "create-db"; - final description = "Create the database"; - - CreateDb() { - addLibsqliteArg(argParser); - } - - Future run() async { - if (argResults!.option('libsqlite') == null) { - print(argParser.usage); - exit(64); - } - - final db = await createDatabaseFactoryFfi(ffiInit: () { - open.overrideForAll( - () => DynamicLibrary.open(argResults!.option('libsqlite')!), - ); - }).openDatabase( - Directory.current.uri.resolve('jadb.sqlite').path, - options: OpenDatabaseOptions( - onOpen: (db) { - db.execute("PRAGMA foreign_keys = ON"); - }, - ), - ); - - seedData(db).then((_) { - print("Database created successfully"); - }).catchError((error) { - print("Error creating database: $error"); - }).whenComplete(() { - db.close(); - }); - } -} - -class QueryKanji extends Command { - final name = "query-kanji"; - final description = "Query the database for kanji data"; - - QueryKanji() { - addLibsqliteArg(argParser); - addJadbArg(argParser); - } - - Future run() async { - if (argResults!.option('libsqlite') == null || - argResults!.option('jadb') == null) { - print(argParser.usage); - exit(64); - } - - final db = await createDatabaseFactoryFfi(ffiInit: () { - open.overrideForAll( - () => DynamicLibrary.open(argResults!.option('libsqlite')!), - ); - }).openDatabase( - Directory.current.uri.resolve(argResults!.option('jadb')!).path, - options: OpenDatabaseOptions( - readOnly: true, - onOpen: (db) { - db.execute("PRAGMA foreign_keys = ON"); - }, - ), - ); - - final result = await JaDBConnection(db).searchKanji('漢'); - - if (result == null) { - print("No such kanji"); - } else { - print(JsonEncoder.withIndent(' ').convert(result.toJson())); - } - } -} - -class QueryWord extends Command { - final name = "query-word"; - final description = "Query the database for word data"; - - QueryWord() { - addLibsqliteArg(argParser); - addJadbArg(argParser); - } - - Future run() async { - if (argResults!.option('libsqlite') == null || - argResults!.option('jadb') == null) { - print(argParser.usage); - exit(64); - } - - final db = await createDatabaseFactoryFfi(ffiInit: () { - open.overrideForAll( - () => DynamicLibrary.open(argResults!.option('libsqlite')!), - ); - }).openDatabase( - Directory.current.uri.resolve(argResults!.option('jadb')!).path, - options: OpenDatabaseOptions( - readOnly: true, - onOpen: (db) { - db.execute("PRAGMA foreign_keys = ON"); - }, - ), - ); - - final result = await JaDBConnection(db).searchWord('kana'); - - if (result == null) { - print("Invalid search"); - } else if (result.isEmpty) { - print("No matches"); - } else { - print(JsonEncoder.withIndent(' ') - .convert(result.map((e) => e.toJson()).toList())); - } - } -} +import 'package:jadb/cli/commands/create_db.dart'; +import 'package:jadb/cli/commands/query_kanji.dart'; +import 'package:jadb/cli/commands/query_word.dart'; Future main(List args) async { final runner = CommandRunner( diff --git a/lib/_data_ingestion/open_local_db.dart b/lib/_data_ingestion/open_local_db.dart new file mode 100644 index 0000000..03ab19b --- /dev/null +++ b/lib/_data_ingestion/open_local_db.dart @@ -0,0 +1,35 @@ +import 'dart:ffi'; +import 'dart:io'; + +import 'package:sqflite_common_ffi/sqflite_ffi.dart'; +import 'package:sqlite3/open.dart'; + +Future openLocalDb({ + String? libsqlitePath, + String? jadbPath, + bool readWrite = false, +}) async { + if (libsqlitePath == null) { + libsqlitePath = Platform.environment['LIBSQLITE_PATH']; + } + + if (jadbPath == null) { + jadbPath = Platform.environment['JADB_PATH'] ?? + Directory.current.uri.resolve('jadb.sqlite').path; + } + + final db = await createDatabaseFactoryFfi( + ffiInit: () => + open.overrideForAll(() => DynamicLibrary.open(libsqlitePath!)), + ).openDatabase( + jadbPath, + options: OpenDatabaseOptions( + onOpen: (db) { + db.execute("PRAGMA foreign_keys = ON"); + }, + readOnly: !readWrite, + ), + ); + + return db; +} diff --git a/lib/cli/args.dart b/lib/cli/args.dart new file mode 100644 index 0000000..967d555 --- /dev/null +++ b/lib/cli/args.dart @@ -0,0 +1,23 @@ +import 'dart:io'; + +import 'package:args/args.dart'; + +void addLibsqliteArg(ArgParser argParser) { + argParser.addOption( + 'libsqlite', + help: + 'Path to the SQLite library. This is used to load the SQLite library dynamically.', + valueHelp: 'PATH', + defaultsTo: Platform.environment['LIBSQLITE_PATH'], + ); +} + +void addJadbArg(ArgParser argParser) { + argParser.addOption( + 'jadb', + abbr: 'f', + help: 'Path to the SQLite database file.', + valueHelp: 'PATH', + defaultsTo: Platform.environment['JADB_PATH'], + ); +} diff --git a/lib/cli/commands/create_db.dart b/lib/cli/commands/create_db.dart new file mode 100644 index 0000000..e77d987 --- /dev/null +++ b/lib/cli/commands/create_db.dart @@ -0,0 +1,41 @@ +import 'dart:io'; + +import 'package:jadb/_data_ingestion/open_local_db.dart'; +import 'package:jadb/_data_ingestion/seed_database.dart'; + +import 'package:args/command_runner.dart'; +import 'package:jadb/cli/args.dart'; + +class CreateDb extends Command { + final name = "create-db"; + final description = "Create the database"; + + CreateDb() { + addLibsqliteArg(argParser); + } + + Future run() async { + if (argResults!.option('libsqlite') == null) { + print(argParser.usage); + exit(64); + } + + final db = await openLocalDb( + libsqlitePath: argResults!.option('libsqlite')!, + readWrite: true, + ); + + if (db == null) { + print("Failed to open database"); + exit(1); + } + + seedData(db).then((_) { + print("Database created successfully"); + }).catchError((error) { + print("Error creating database: $error"); + }).whenComplete(() { + db.close(); + }); + } +} diff --git a/lib/cli/commands/query_kanji.dart b/lib/cli/commands/query_kanji.dart new file mode 100644 index 0000000..a298de5 --- /dev/null +++ b/lib/cli/commands/query_kanji.dart @@ -0,0 +1,45 @@ + +import 'dart:convert'; +import 'dart:io'; + +import 'package:jadb/_data_ingestion/open_local_db.dart'; +import 'package:jadb/cli/args.dart'; +import 'package:jadb/search.dart'; + +import 'package:args/command_runner.dart'; + +class QueryKanji extends Command { + final name = "query-kanji"; + final description = "Query the database for kanji data"; + + QueryKanji() { + addLibsqliteArg(argParser); + addJadbArg(argParser); + } + + Future run() async { + if (argResults!.option('libsqlite') == null || + argResults!.option('jadb') == null) { + print(argParser.usage); + exit(64); + } + + final db = await openLocalDb( + jadbPath: argResults!.option('jadb')!, + libsqlitePath: argResults!.option('libsqlite')!, + ); + + if (db == null) { + print("Failed to open database"); + exit(1); + } + + final result = await JaDBConnection(db).searchKanji('漢'); + + if (result == null) { + print("No such kanji"); + } else { + print(JsonEncoder.withIndent(' ').convert(result.toJson())); + } + } +} diff --git a/lib/cli/commands/query_word.dart b/lib/cli/commands/query_word.dart new file mode 100644 index 0000000..28f3f14 --- /dev/null +++ b/lib/cli/commands/query_word.dart @@ -0,0 +1,48 @@ + +import 'dart:convert'; +import 'dart:io'; + +import 'package:jadb/_data_ingestion/open_local_db.dart'; +import 'package:jadb/cli/args.dart'; +import 'package:jadb/search.dart'; + +import 'package:args/command_runner.dart'; + +class QueryWord extends Command { + final name = "query-word"; + final description = "Query the database for word data"; + + QueryWord() { + addLibsqliteArg(argParser); + addJadbArg(argParser); + } + + Future run() async { + if (argResults!.option('libsqlite') == null || + argResults!.option('jadb') == null) { + print(argParser.usage); + exit(64); + } + + final db = await openLocalDb( + jadbPath: argResults!.option('jadb')!, + libsqlitePath: argResults!.option('libsqlite')!, + ); + + if (db == null) { + print("Failed to open database"); + exit(1); + } + + final result = await JaDBConnection(db).searchWord('kana'); + + if (result == null) { + print("Invalid search"); + } else if (result.isEmpty) { + print("No matches"); + } else { + print(JsonEncoder.withIndent(' ') + .convert(result.map((e) => e.toJson()).toList())); + } + } +} diff --git a/test/search/setup_database_connection.dart b/test/search/setup_database_connection.dart index f983a50..8c77d43 100644 --- a/test/search/setup_database_connection.dart +++ b/test/search/setup_database_connection.dart @@ -1,9 +1,7 @@ -import 'dart:ffi'; import 'dart:io'; +import 'package:jadb/_data_ingestion/open_local_db.dart'; import 'package:jadb/search.dart'; -import 'package:sqflite_common_ffi/sqflite_ffi.dart'; -import 'package:sqlite3/open.dart'; Future setup_database_connection() async { final lib_sqlite_path = Platform.environment['LIBSQLITE_PATH']; @@ -17,18 +15,14 @@ Future setup_database_connection() async { throw Exception("JADB_PATH is not set"); } - final db_connection = createDatabaseFactoryFfi(ffiInit: () { - open.overrideForAll( - () => DynamicLibrary.open(lib_sqlite_path), - ); - }).openDatabase( - jadb_path, - options: OpenDatabaseOptions( - onOpen: (db) { - db.execute("PRAGMA foreign_keys = ON"); - }, - ), + final db_connection = await openLocalDb( + libsqlitePath: lib_sqlite_path, + jadbPath: jadb_path, ); - return JaDBConnection(await db_connection); + if (db_connection == null) { + throw Exception("Failed to open database"); + } + + return JaDBConnection(db_connection); }