lib: implement stub for word search

This commit is contained in:
2025-04-19 12:12:07 +02:00
parent a27925d359
commit 84e80fe876
5 changed files with 149 additions and 4 deletions

View File

@@ -88,6 +88,41 @@ class QueryKanji extends Command {
}
}
class QueryWord extends Command {
final name = "query-word";
final description = "Query the database for word data";
QueryWord() {
addLibsqliteArg(argParser);
addJadbArg(argParser);
}
Future<void> run() async {
if (argResults!.option('libsqlite') == null ||
!argResults!.wasParsed('jadb')) {
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);
final result = await JaDBConnection(db).searchWord('かな');
if (result == null) {
print("Invalid search");
} else if (result.isEmpty) {
print("No matches");
} else {
print(JsonEncoder.withIndent(' ')
.convert(result.map((e) => e.toJson()).toList()));
}
}
}
Future<void> main(List<String> args) async {
final runner = CommandRunner(
'jadb',
@@ -96,6 +131,7 @@ Future<void> main(List<String> args) async {
runner.addCommand(CreateDb());
runner.addCommand(QueryKanji());
runner.addCommand(QueryWord());
runner.run(args);
}

View File

@@ -0,0 +1 @@
enum JlptLevel { none, n5, n4, n3, n2, n1 }

View File

@@ -1,3 +1,5 @@
class WordSearchResult {
// TODO: implement me
Map<String, dynamic> toJson() => {};
}

View File

@@ -1,6 +1,7 @@
import 'package:jadb/models/jmdict/word_search_result.dart';
import 'package:jadb/models/kanjidic/kanji_search_result.dart';
import 'package:jadb/models/radkfile/radicals_search_result.dart';
import 'package:jadb/search/jmdict.dart';
import 'package:jadb/search/kanji.dart';
@@ -14,11 +15,11 @@ class JaDBConnection {
Future<KanjiSearchResult?> searchKanji(String kanji) async =>
searchKanjiWithDbConnection(this._connection, kanji);
Future<RadicalsSearchResult> searchKanjiByRadicals(List<String> radicals) {
Future<RadicalsSearchResult> searchKanjiByRadicals(
List<String> radicals) async {
throw UnimplementedError();
}
Future<WordSearchResult> searchWord(String word) async {
throw UnimplementedError();
}
Future<List<WordSearchResult>?> searchWord(String word) async =>
searchWordWithDbConnection(this._connection, word);
}

105
lib/search/jmdict.dart Normal file
View File

@@ -0,0 +1,105 @@
import 'package:jadb/models/jmdict/word_search_result.dart';
import 'package:sqflite_common/sqlite_api.dart';
// TODO: Support globs
// TODO: Support tags
// TODO: Prefer original kana type when sorting results
// TODO: Support mixing kana and romaji
Future<List<WordSearchResult>?> searchWordWithDbConnection(
DatabaseExecutor connection,
String word, {
bool isKana = true,
}) async {
if (word.isEmpty) {
return null;
}
late final List<int> matches;
if (isKana) {
matches = (await connection.query(
'JMdict_EntryByKana',
where: 'kana LIKE ?',
whereArgs: ['%$word%'],
))
.map((row) => row['id'] as int)
.toList();
} else {
matches = (await connection.query(
'JMdict_EntryByEnglish',
where: 'english LIKE ?',
whereArgs: ['%$word%'],
))
.map((row) => row['id'] as int)
.toList();
}
if (matches.isEmpty) {
return [];
}
late final List<int> senseIds;
final Future<List<int>> senseIds_query = connection
.query(
'JMdict_Sense',
where: 'id IN (${matches.join(',')})',
)
.then((rows) => rows.map((row) => row['id'] as int).toList());
late final List<Map<String, Object?>> readingElements;
final Future<List<Map<String, Object?>>> readingElements_query =
connection.query(
'JMdict_ReadingElement',
where: 'entry_id IN (${matches.join(',')})',
);
late final List<Map<String, Object?>> kanjiElements;
final Future<List<Map<String, Object?>>> kanjiElements_query =
connection.query(
'JMdict_KanjiElement',
where: 'entry_id IN (${matches.join(',')})',
);
Future.wait([
senseIds_query.then((value) => senseIds = value),
readingElements_query.then((value) => readingElements = value),
kanjiElements_query.then((value) => kanjiElements = value),
]);
print(senseIds);
print(readingElements);
print(kanjiElements);
// JMdict_EntryByEnglish
// JMdict_EntryByKana
//
// JMdict_ExampleSentence
// JMdict_InfoDialect
// JMdict_InfoField
// JMdict_InfoKanji
// JMdict_InfoMisc
// JMdict_InfoPOS
// JMdict_InfoReading
// JMdict_KanjiElement
// JMdict_KanjiElementInfo
// JMdict_ReadingElement
// JMdict_ReadingElementInfo
// JMdict_ReadingElementRestriction
// JMdict_Sense
// JMdict_SenseAntonym
// JMdict_SenseDialect
// JMdict_SenseField
// JMdict_SenseGlossary
// JMdict_SenseInfo
// JMdict_SenseLanguageSource
// JMdict_SenseMisc
// JMdict_SensePOS
// JMdict_SenseRestrictedToKanji
// JMdict_SenseRestrictedToReading
// JMdict_SenseSeeAlso
throw UnimplementedError();
}