From 93b76ed66049c2ddd5330b12bfefb6da5274307c Mon Sep 17 00:00:00 2001 From: h7x4 Date: Wed, 16 Jul 2025 18:32:28 +0200 Subject: [PATCH] word_search: include data for cross references --- .../word_search/word_search_xref_entry.dart | 8 + lib/search/word_search/data_query.dart | 43 +++++- lib/search/word_search/regrouping.dart | 137 ++++++++++-------- lib/search/word_search/word_search.dart | 63 +------- 4 files changed, 127 insertions(+), 124 deletions(-) diff --git a/lib/models/word_search/word_search_xref_entry.dart b/lib/models/word_search/word_search_xref_entry.dart index d458b7a..0a1c39c 100644 --- a/lib/models/word_search/word_search_xref_entry.dart +++ b/lib/models/word_search/word_search_xref_entry.dart @@ -1,3 +1,5 @@ +import 'package:jadb/models/word_search/word_search_result.dart'; + /// A cross-reference entry from one word-result to another entry. class WordSearchXrefEntry { /// The ID of the entry that this entry cross-references to. @@ -13,11 +15,15 @@ class WordSearchXrefEntry { /// database (and hence might be incorrect). final bool ambiguous; + /// The result of the cross-reference, may or may not be included in the query. + final WordSearchResult? xrefResult; + const WordSearchXrefEntry({ required this.entryId, required this.ambiguous, required this.baseWord, required this.furigana, + required this.xrefResult, }); Map toJson() => { @@ -25,6 +31,7 @@ class WordSearchXrefEntry { 'ambiguous': ambiguous, 'baseWord': baseWord, 'furigana': furigana, + 'xrefResult': xrefResult?.toJson(), }; factory WordSearchXrefEntry.fromJson(Map json) => @@ -33,5 +40,6 @@ class WordSearchXrefEntry { ambiguous: json['ambiguous'] as bool, baseWord: json['baseWord'] as String, furigana: json['furigana'] as String?, + xrefResult: null, ); } diff --git a/lib/search/word_search/data_query.dart b/lib/search/word_search/data_query.dart index 71158e0..6161a70 100644 --- a/lib/search/word_search/data_query.dart +++ b/lib/search/word_search/data_query.dart @@ -1,6 +1,5 @@ import 'package:jadb/table_names/jmdict.dart'; import 'package:jadb/table_names/tanos_jlpt.dart'; -import 'package:jadb/util/sqlite_utils.dart'; import 'package:sqflite_common/sqflite.dart'; class LinearWordQueryData { @@ -25,6 +24,9 @@ class LinearWordQueryData { final List> readingElementRestrictions; final List> kanjiElementInfos; + final LinearWordQueryData? senseAntonymData; + final LinearWordQueryData? senseSeeAlsoData; + const LinearWordQueryData({ required this.senses, required this.readingElements, @@ -46,13 +48,16 @@ class LinearWordQueryData { required this.readingElementInfos, required this.readingElementRestrictions, required this.kanjiElementInfos, + required this.senseAntonymData, + required this.senseSeeAlsoData, }); } Future fetchLinearWordQueryData( DatabaseExecutor connection, - List entryIds, -) async { + List entryIds, { + bool fetchXrefData = true, +}) async { late final List> senses; final Future>> senses_query = connection.query( JMdictTableNames.sense, @@ -266,8 +271,35 @@ Future fetchLinearWordQueryData( whereArgs: kanjiIds, ); + // Xref data queries await Future.wait([ senseAntonyms_query.then((value) => senseAntonyms = value), + senseSeeAlsos_query.then((value) => senseSeeAlsos = value), + ]); + + late final LinearWordQueryData? senseAntonymData; + final Future senseAntonymData_query = + fetchXrefData + ? fetchLinearWordQueryData( + connection, + senseAntonyms + .map((antonym) => antonym['xrefEntryId'] as int) + .toList(), + fetchXrefData: false, + ) + : Future.value(null); + + late final LinearWordQueryData? senseSeeAlsoData; + final Future senseSeeAlsoData_query = + fetchXrefData + ? fetchLinearWordQueryData( + connection, + senseSeeAlsos.map((seeAlso) => seeAlso['xrefEntryId'] as int).toList(), + fetchXrefData: false, + ) + : Future.value(null); + + await Future.wait([ senseDialects_query.then((value) => senseDialects = value), senseFields_query.then((value) => senseFields = value), senseGlossaries_query.then((value) => senseGlossaries = value), @@ -281,13 +313,14 @@ Future fetchLinearWordQueryData( senseRestrictedToReadings_query.then( (value) => senseRestrictedToReadings = value, ), - senseSeeAlsos_query.then((value) => senseSeeAlsos = value), exampleSentences_query.then((value) => exampleSentences = value), readingElementInfos_query.then((value) => readingElementInfos = value), readingElementRestrictions_query.then( (value) => readingElementRestrictions = value, ), kanjiElementInfos_query.then((value) => kanjiElementInfos = value), + senseAntonymData_query.then((value) => senseAntonymData = value), + senseSeeAlsoData_query.then((value) => senseSeeAlsoData = value), ]); return LinearWordQueryData( @@ -311,5 +344,7 @@ Future fetchLinearWordQueryData( readingElementInfos: readingElementInfos, readingElementRestrictions: readingElementRestrictions, kanjiElementInfos: kanjiElementInfos, + senseAntonymData: senseAntonymData, + senseSeeAlsoData: senseSeeAlsoData, ); } diff --git a/lib/search/word_search/regrouping.dart b/lib/search/word_search/regrouping.dart index 775ab23..858d335 100644 --- a/lib/search/word_search/regrouping.dart +++ b/lib/search/word_search/regrouping.dart @@ -12,47 +12,32 @@ import 'package:jadb/models/word_search/word_search_sense.dart'; import 'package:jadb/models/word_search/word_search_sense_language_source.dart'; import 'package:jadb/models/word_search/word_search_sources.dart'; import 'package:jadb/models/word_search/word_search_xref_entry.dart'; +import 'package:jadb/search/word_search/data_query.dart'; import 'package:jadb/search/word_search/entry_id_query.dart'; List regroupWordSearchResults({ required List entryIds, - required List> readingElements, - required List> kanjiElements, - required List> jlptTags, - required List> commonEntries, - required List> senses, - required List> senseAntonyms, - required List> senseDialects, - required List> senseFields, - required List> senseGlossaries, - required List> senseInfos, - required List> senseLanguageSources, - required List> senseMiscs, - required List> sensePOSs, - required List> senseRestrictedToKanjis, - required List> senseRestrictedToReadings, - required List> senseSeeAlsos, - required List> exampleSentences, - required List> readingElementInfos, - required List> readingElementRestrictions, - required List> kanjiElementInfos, + required LinearWordQueryData linearWordQueryData, }) { final List results = []; - final commonEntryIds = commonEntries + final commonEntryIds = linearWordQueryData.commonEntries .map((entry) => entry['entryId'] as int) .toSet(); for (final scoredEntryId in entryIds) { - final List> entryReadingElements = readingElements + final List> entryReadingElements = linearWordQueryData + .readingElements .where((element) => element['entryId'] == scoredEntryId.entryId) .toList(); - final List> entryKanjiElements = kanjiElements + final List> entryKanjiElements = linearWordQueryData + .kanjiElements .where((element) => element['entryId'] == scoredEntryId.entryId) .toList(); - final List> entryJlptTags = jlptTags + final List> entryJlptTags = linearWordQueryData + .jlptTags .where((element) => element['entryId'] == scoredEntryId.entryId) .toList(); @@ -65,7 +50,7 @@ List regroupWordSearchResults({ final isCommon = commonEntryIds.contains(scoredEntryId.entryId); - final List> entrySenses = senses + final List> entrySenses = linearWordQueryData.senses .where((element) => element['entryId'] == scoredEntryId.entryId) .toList(); @@ -73,25 +58,28 @@ List regroupWordSearchResults({ entryId: scoredEntryId.entryId, readingElements: entryReadingElements, kanjiElements: entryKanjiElements, - readingElementInfos: readingElementInfos, - readingElementRestrictions: readingElementRestrictions, - kanjiElementInfos: kanjiElementInfos, + readingElementInfos: linearWordQueryData.readingElementInfos, + readingElementRestrictions: + linearWordQueryData.readingElementRestrictions, + kanjiElementInfos: linearWordQueryData.kanjiElementInfos, ); final List entrySensesGrouped = _regroup_senses( senses: entrySenses, - senseAntonyms: senseAntonyms, - senseDialects: senseDialects, - senseFields: senseFields, - senseGlossaries: senseGlossaries, - senseInfos: senseInfos, - senseLanguageSources: senseLanguageSources, - senseMiscs: senseMiscs, - sensePOSs: sensePOSs, - senseRestrictedToKanjis: senseRestrictedToKanjis, - senseRestrictedToReadings: senseRestrictedToReadings, - senseSeeAlsos: senseSeeAlsos, - exampleSentences: exampleSentences, + senseAntonyms: linearWordQueryData.senseAntonyms, + senseDialects: linearWordQueryData.senseDialects, + senseFields: linearWordQueryData.senseFields, + senseGlossaries: linearWordQueryData.senseGlossaries, + senseInfos: linearWordQueryData.senseInfos, + senseLanguageSources: linearWordQueryData.senseLanguageSources, + senseMiscs: linearWordQueryData.senseMiscs, + sensePOSs: linearWordQueryData.sensePOSs, + senseRestrictedToKanjis: linearWordQueryData.senseRestrictedToKanjis, + senseRestrictedToReadings: linearWordQueryData.senseRestrictedToReadings, + senseSeeAlsos: linearWordQueryData.senseSeeAlsos, + exampleSentences: linearWordQueryData.exampleSentences, + senseSeeAlsosXrefData: linearWordQueryData.senseSeeAlsoData, + senseAntonymsXrefData: linearWordQueryData.senseAntonymData, ); results.add( @@ -221,6 +209,8 @@ List _regroup_senses({ required List> senseRestrictedToReadings, required List> senseSeeAlsos, required List> exampleSentences, + required LinearWordQueryData? senseSeeAlsosXrefData, + required LinearWordQueryData? senseAntonymsXrefData, }) { final groupedSenseAntonyms = senseAntonyms.groupListsBy( (element) => element['senseId'] as int, @@ -272,31 +262,58 @@ List _regroup_senses({ groupedSenseRestrictedToReadings[senseId] ?? []; final seeAlsos = groupedSenseSeeAlsos[senseId] ?? []; + final List seeAlsosWordResults = + senseSeeAlsosXrefData != null + ? regroupWordSearchResults( + entryIds: seeAlsos + .map((e) => ScoredEntryId(e['xrefEntryId'] as int, 0)) + .toList(), + linearWordQueryData: senseSeeAlsosXrefData, + ) + : []; + final List antonymsWordResults = + senseAntonymsXrefData != null + ? regroupWordSearchResults( + entryIds: antonyms + .map((e) => ScoredEntryId(e['xrefEntryId'] as int, 0)) + .toList(), + linearWordQueryData: senseAntonymsXrefData, + ) + : []; + final resultSense = WordSearchSense( englishDefinitions: glossaries.map((e) => e['phrase'] as String).toList(), partsOfSpeech: pos .map((e) => JMdictPOS.fromId(e['pos'] as String)) .toList(), - seeAlso: seeAlsos - .map( - (e) => WordSearchXrefEntry( - entryId: e['xrefEntryId'] as int, - baseWord: e['base'] as String, - furigana: e['furigana'] as String?, - ambiguous: e['ambiguous'] == 1, - ), - ) - .toList(), - antonyms: antonyms - .map( - (e) => WordSearchXrefEntry( - entryId: e['xrefEntryId'] as int, - baseWord: e['base'] as String, - furigana: e['furigana'] as String?, - ambiguous: e['ambiguous'] == 1, - ), - ) - .toList(), + seeAlso: seeAlsos.asMap().entries.map((mapEntry) { + final i = mapEntry.key; + final e = mapEntry.value; + + return WordSearchXrefEntry( + entryId: e['xrefEntryId'] as int, + baseWord: e['base'] as String, + furigana: e['furigana'] as String?, + ambiguous: e['ambiguous'] == 1, + xrefResult: seeAlsosWordResults.isNotEmpty + ? seeAlsosWordResults[i] + : null, + ); + }).toList(), + antonyms: antonyms.asMap().entries.map((mapEntry) { + final i = mapEntry.key; + final e = mapEntry.value; + + return WordSearchXrefEntry( + entryId: e['xrefEntryId'] as int, + baseWord: e['base'] as String, + furigana: e['furigana'] as String?, + ambiguous: e['ambiguous'] == 1, + xrefResult: antonymsWordResults.isNotEmpty + ? antonymsWordResults[i] + : null, + ); + }).toList(), restrictedToReading: restrictedToReadings .map((e) => e['reading'] as String) .toList(), diff --git a/lib/search/word_search/word_search.dart b/lib/search/word_search/word_search.dart index ede4f24..bf03cc6 100644 --- a/lib/search/word_search/word_search.dart +++ b/lib/search/word_search/word_search.dart @@ -48,26 +48,7 @@ Future?> searchWordWithDbConnection( final result = regroupWordSearchResults( entryIds: entryIds, - readingElements: linearWordQueryData.readingElements, - kanjiElements: linearWordQueryData.kanjiElements, - jlptTags: linearWordQueryData.jlptTags, - commonEntries: linearWordQueryData.commonEntries, - senses: linearWordQueryData.senses, - senseAntonyms: linearWordQueryData.senseAntonyms, - senseDialects: linearWordQueryData.senseDialects, - senseFields: linearWordQueryData.senseFields, - senseGlossaries: linearWordQueryData.senseGlossaries, - senseInfos: linearWordQueryData.senseInfos, - senseLanguageSources: linearWordQueryData.senseLanguageSources, - senseMiscs: linearWordQueryData.senseMiscs, - sensePOSs: linearWordQueryData.sensePOSs, - senseRestrictedToKanjis: linearWordQueryData.senseRestrictedToKanjis, - senseRestrictedToReadings: linearWordQueryData.senseRestrictedToReadings, - senseSeeAlsos: linearWordQueryData.senseSeeAlsos, - exampleSentences: linearWordQueryData.exampleSentences, - readingElementInfos: linearWordQueryData.readingElementInfos, - readingElementRestrictions: linearWordQueryData.readingElementRestrictions, - kanjiElementInfos: linearWordQueryData.kanjiElementInfos, + linearWordQueryData: linearWordQueryData, ); return result; @@ -115,26 +96,7 @@ Future getWordByIdWithDbConnection( final result = regroupWordSearchResults( entryIds: [ScoredEntryId(id, 0)], - readingElements: linearWordQueryData.readingElements, - kanjiElements: linearWordQueryData.kanjiElements, - jlptTags: linearWordQueryData.jlptTags, - commonEntries: linearWordQueryData.commonEntries, - senses: linearWordQueryData.senses, - senseAntonyms: linearWordQueryData.senseAntonyms, - senseDialects: linearWordQueryData.senseDialects, - senseFields: linearWordQueryData.senseFields, - senseGlossaries: linearWordQueryData.senseGlossaries, - senseInfos: linearWordQueryData.senseInfos, - senseLanguageSources: linearWordQueryData.senseLanguageSources, - senseMiscs: linearWordQueryData.senseMiscs, - sensePOSs: linearWordQueryData.sensePOSs, - senseRestrictedToKanjis: linearWordQueryData.senseRestrictedToKanjis, - senseRestrictedToReadings: linearWordQueryData.senseRestrictedToReadings, - senseSeeAlsos: linearWordQueryData.senseSeeAlsos, - exampleSentences: linearWordQueryData.exampleSentences, - readingElementInfos: linearWordQueryData.readingElementInfos, - readingElementRestrictions: linearWordQueryData.readingElementRestrictions, - kanjiElementInfos: linearWordQueryData.kanjiElementInfos, + linearWordQueryData: linearWordQueryData, ); assert( @@ -162,26 +124,7 @@ Future> getWordsByIdsWithDbConnection( final results = regroupWordSearchResults( entryIds: entryIds, - readingElements: linearWordQueryData.readingElements, - kanjiElements: linearWordQueryData.kanjiElements, - jlptTags: linearWordQueryData.jlptTags, - commonEntries: linearWordQueryData.commonEntries, - senses: linearWordQueryData.senses, - senseAntonyms: linearWordQueryData.senseAntonyms, - senseDialects: linearWordQueryData.senseDialects, - senseFields: linearWordQueryData.senseFields, - senseGlossaries: linearWordQueryData.senseGlossaries, - senseInfos: linearWordQueryData.senseInfos, - senseLanguageSources: linearWordQueryData.senseLanguageSources, - senseMiscs: linearWordQueryData.senseMiscs, - sensePOSs: linearWordQueryData.sensePOSs, - senseRestrictedToKanjis: linearWordQueryData.senseRestrictedToKanjis, - senseRestrictedToReadings: linearWordQueryData.senseRestrictedToReadings, - senseSeeAlsos: linearWordQueryData.senseSeeAlsos, - exampleSentences: linearWordQueryData.exampleSentences, - readingElementInfos: linearWordQueryData.readingElementInfos, - readingElementRestrictions: linearWordQueryData.readingElementRestrictions, - kanjiElementInfos: linearWordQueryData.kanjiElementInfos, + linearWordQueryData: linearWordQueryData, ); return {for (var r in results) r.entryId: r};