Files
jadb/lib/search/radical_search.dart
h7x4 81db60ccf7
Some checks failed
Build database / evals (push) Has been cancelled
Add some docstrings
2026-02-24 15:13:33 +09:00

60 lines
1.8 KiB
Dart

import 'package:jadb/table_names/radkfile.dart';
import 'package:sqflite_common/sqlite_api.dart';
// TODO: validate that the list of radicals all are valid radicals
/// Returns a list of radicals that are part of any kanji that contains all of the input radicals.
///
/// This can be used to limit the choices of additional radicals provided to a user,
/// so that any choice they make will still yield at least one kanji.
Future<List<String>> searchRemainingRadicalsWithDbConnection(
DatabaseExecutor connection,
List<String> radicals,
) async {
final distinctRadicals = radicals.toSet();
final queryResult = await connection.rawQuery(
'''
SELECT DISTINCT "radical"
FROM "${RADKFILETableNames.radkfile}"
WHERE "kanji" IN (
SELECT "kanji"
FROM "${RADKFILETableNames.radkfile}"
WHERE "radical" IN (${List.filled(distinctRadicals.length, '?').join(',')})
GROUP BY "kanji"
HAVING COUNT(DISTINCT "radical") = ?
)
''',
[...distinctRadicals, distinctRadicals.length],
);
final remainingRadicals = queryResult
.map((row) => row['radical'] as String)
.toList();
return remainingRadicals;
}
/// Returns a list of kanji that contain all of the input radicals.
Future<List<String>> searchKanjiByRadicalsWithDbConnection(
DatabaseExecutor connection,
List<String> radicals,
) async {
final distinctRadicals = radicals.toSet();
final queryResult = await connection.rawQuery(
'''
SELECT "kanji"
FROM "${RADKFILETableNames.radkfile}"
WHERE "radical" IN (${List.filled(distinctRadicals.length, '?').join(',')})
GROUP BY "kanji"
HAVING COUNT(DISTINCT "radical") = ?
''',
[...distinctRadicals, distinctRadicals.length],
);
final kanji = queryResult.map((row) => row['kanji'] as String).toList();
return kanji;
}