treewide: redo handling of kanjidic radicals
This commit is contained in:
@@ -21,20 +21,17 @@ class CodePoint extends SQLWritable {
|
||||
|
||||
class Radical extends SQLWritable {
|
||||
final String kanji;
|
||||
final String type;
|
||||
final String radical;
|
||||
final int radicalId;
|
||||
|
||||
const Radical({
|
||||
required this.kanji,
|
||||
required this.type,
|
||||
required this.radical,
|
||||
required this.radicalId,
|
||||
});
|
||||
|
||||
@override
|
||||
Map<String, Object?> get sqlValue => {
|
||||
'kanji': kanji,
|
||||
'type': type,
|
||||
'radical': radical,
|
||||
'radicalId': radicalId,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -224,7 +221,7 @@ class Character extends SQLWritable {
|
||||
|
||||
final List<String> radicalName;
|
||||
final List<CodePoint> codepoints;
|
||||
final List<Radical> radicals;
|
||||
final Radical? radical;
|
||||
final List<int> strokeMiscounts;
|
||||
final List<Variant> variants;
|
||||
final List<DictionaryReference> dictionaryReferences;
|
||||
@@ -244,7 +241,7 @@ class Character extends SQLWritable {
|
||||
this.jlpt,
|
||||
this.radicalName = const [],
|
||||
this.codepoints = const [],
|
||||
this.radicals = const [],
|
||||
required this.radical,
|
||||
this.strokeMiscounts = const [],
|
||||
this.variants = const [],
|
||||
this.dictionaryReferences = const [],
|
||||
|
||||
@@ -14,14 +14,24 @@ Future<void> seedKANJIDICData(List<Character> characters, Database db) async {
|
||||
// print(c.dictionaryReferences.map((e) => e.sqlValue).toList());
|
||||
// }
|
||||
b.insert(KANJIDICTableNames.character, c.sqlValue);
|
||||
|
||||
for (final n in c.radicalName) {
|
||||
b.insert(KANJIDICTableNames.radicalName, {'kanji': c.literal, 'name': n});
|
||||
assert(c.radical != null, 'Radical name without radical');
|
||||
b.insert(
|
||||
KANJIDICTableNames.radicalName,
|
||||
{
|
||||
'radicalId': c.radical!.radicalId,
|
||||
'name': n,
|
||||
},
|
||||
conflictAlgorithm: ConflictAlgorithm.ignore,
|
||||
);
|
||||
}
|
||||
|
||||
for (final cp in c.codepoints) {
|
||||
b.insert(KANJIDICTableNames.codepoint, cp.sqlValue);
|
||||
}
|
||||
for (final r in c.radicals) {
|
||||
b.insert(KANJIDICTableNames.radical, r.sqlValue);
|
||||
if (c.radical != null) {
|
||||
b.insert(KANJIDICTableNames.radical, c.radical!.sqlValue);
|
||||
}
|
||||
for (final sm in c.strokeMiscounts) {
|
||||
b.insert(
|
||||
|
||||
@@ -42,17 +42,16 @@ List<Character> parseKANJIDICData(XmlElement root) {
|
||||
)
|
||||
.toList() ??
|
||||
[],
|
||||
radicals: radical
|
||||
radical: radical
|
||||
?.findElements('rad_value')
|
||||
.where((e) => e.getAttribute('rad_type') == 'classical')
|
||||
.map(
|
||||
(e) => Radical(
|
||||
kanji: kanji,
|
||||
type: e.getAttribute('rad_type')!,
|
||||
radical: e.innerText,
|
||||
radicalId: int.parse(e.innerText),
|
||||
),
|
||||
)
|
||||
.toList() ??
|
||||
[],
|
||||
.firstOrNull,
|
||||
strokeMiscounts: misc
|
||||
.findElements('stroke_count')
|
||||
.skip(1)
|
||||
|
||||
@@ -4,37 +4,48 @@ class KanjiSearchRadical extends Equatable {
|
||||
/// The radical symbol.
|
||||
final String symbol;
|
||||
|
||||
/// The names of this radical.
|
||||
///
|
||||
/// Each name might refer to a specific form of the radical.
|
||||
final List<String> names;
|
||||
|
||||
/// The radical forms used in this kanji.
|
||||
///
|
||||
/// (e.g. "亻" for "人", "氵" for "水")
|
||||
final List<String> forms;
|
||||
|
||||
/// The meaning of the radical.
|
||||
final String meaning;
|
||||
/// The meanings of the radical.
|
||||
final List<String> meanings;
|
||||
|
||||
// ignore: public_member_api_docs
|
||||
const KanjiSearchRadical({
|
||||
required this.symbol,
|
||||
this.forms = const [],
|
||||
required this.meaning,
|
||||
required this.names,
|
||||
required this.forms,
|
||||
required this.meanings,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [
|
||||
symbol,
|
||||
this.names,
|
||||
forms,
|
||||
meaning,
|
||||
meanings,
|
||||
];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'symbol': symbol,
|
||||
'names': names,
|
||||
'forms': forms,
|
||||
'meaning': meaning,
|
||||
'meanings': meanings,
|
||||
};
|
||||
|
||||
factory KanjiSearchRadical.fromJson(Map<String, dynamic> json) {
|
||||
return KanjiSearchRadical(
|
||||
symbol: json['symbol'] as String,
|
||||
names: (json['names'] as List).map((e) => e as String).toList(),
|
||||
forms: (json['forms'] as List).map((e) => e as String).toList(),
|
||||
meaning: json['meaning'] as String,
|
||||
meanings: (json['meanings'] as List).map((e) => e as String).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,17 +49,17 @@ class KanjiSearchResult extends Equatable {
|
||||
|
||||
const KanjiSearchResult({
|
||||
required this.kanji,
|
||||
this.taughtIn,
|
||||
this.jlptLevel,
|
||||
this.newspaperFrequencyRank,
|
||||
required this.taughtIn,
|
||||
required this.jlptLevel,
|
||||
required this.newspaperFrequencyRank,
|
||||
required this.strokeCount,
|
||||
required this.meanings,
|
||||
this.kunyomi = const [],
|
||||
this.onyomi = const [],
|
||||
required this.kunyomi,
|
||||
required this.onyomi,
|
||||
// this.kunyomiExamples = const [],
|
||||
// this.onyomiExamples = const [],
|
||||
this.radical,
|
||||
this.parts = const [],
|
||||
required this.radical,
|
||||
required this.parts,
|
||||
required this.codepoints,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:jadb/models/kanji_search/kanji_search_radical.dart';
|
||||
import 'package:jadb/models/kanji_search/kanji_search_result.dart';
|
||||
import 'package:sqflite_common/sqflite.dart';
|
||||
|
||||
@@ -62,10 +63,21 @@ Future<KanjiSearchResult?> searchKanjiWithDbConnection(
|
||||
);
|
||||
|
||||
late final List<Map<String, Object?>> radicals;
|
||||
final radicals_query = connection.query(
|
||||
"KANJIDIC_Radical",
|
||||
where: "KANJIDIC_Radical.kanji = ?",
|
||||
whereArgs: [kanji],
|
||||
final radicals_query = connection.rawQuery(
|
||||
'''
|
||||
SELECT DISTINCT
|
||||
"XREF__KANJIDIC_Radical__RADKFILE"."radicalSymbol" AS "symbol",
|
||||
"names"
|
||||
FROM "KANJIDIC_Radical"
|
||||
JOIN "XREF__KANJIDIC_Radical__RADKFILE" USING ("radicalId")
|
||||
LEFT JOIN (
|
||||
SELECT "radicalId", group_concat("name") AS "names"
|
||||
FROM "KANJIDIC_RadicalName"
|
||||
GROUP BY "radicalId"
|
||||
) USING ("radicalId")
|
||||
WHERE "KANJIDIC_Radical"."kanji" = ?
|
||||
''',
|
||||
[kanji],
|
||||
);
|
||||
|
||||
late final List<Map<String, Object?>> parts;
|
||||
@@ -124,6 +136,18 @@ Future<KanjiSearchResult?> searchKanjiWithDbConnection(
|
||||
|
||||
final entry = characters.first;
|
||||
|
||||
assert(radicals.length <= 1, 'There should be at most one radical per kanji');
|
||||
final radical = radicals.isNotEmpty
|
||||
? KanjiSearchRadical(
|
||||
symbol: radicals.first['symbol'] as String,
|
||||
names: (radicals.first['names'] as String).split(','),
|
||||
// TODO: add radical form data
|
||||
forms: [],
|
||||
// TODO: add radical meaning data
|
||||
meanings: [],
|
||||
)
|
||||
: null;
|
||||
|
||||
final String? grade = {
|
||||
1: 'grade 1',
|
||||
2: 'grade 2',
|
||||
@@ -155,6 +179,7 @@ Future<KanjiSearchResult?> searchKanjiWithDbConnection(
|
||||
kunyomi: kunyomis.map((item) => item['yomi'] as String).toList(),
|
||||
parts: parts.map((item) => item['radical'] as String).toList(),
|
||||
onyomi: onyomis.map((item) => item['yomi'] as String).toList(),
|
||||
radical: radical,
|
||||
codepoints: {
|
||||
for (final codepoint in codepoints)
|
||||
codepoint['type'] as String: codepoint['codepoint'] as String,
|
||||
|
||||
@@ -6,12 +6,6 @@ CREATE TABLE "KANJIDIC_Character" (
|
||||
"jlpt" INTEGER
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE TABLE "KANJIDIC_RadicalName" (
|
||||
"kanji" CHAR(1) NOT NULL REFERENCES "KANJIDIC_Character"("literal"),
|
||||
"name" TEXT NOT NULL,
|
||||
PRIMARY KEY("kanji", "name")
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE TABLE "KANJIDIC_Codepoint" (
|
||||
"kanji" CHAR(1) NOT NULL REFERENCES "KANJIDIC_Character"("literal"),
|
||||
"type" VARCHAR(6) NOT NULL CHECK ("type" IN ('jis208', 'jis212', 'jis213', 'ucs')),
|
||||
@@ -22,12 +16,25 @@ CREATE TABLE "KANJIDIC_Codepoint" (
|
||||
CREATE INDEX "KANJIDIC_Codepoint_byCharacter" ON "KANJIDIC_Codepoint"("kanji");
|
||||
|
||||
CREATE TABLE "KANJIDIC_Radical" (
|
||||
"kanji" CHAR(1) NOT NULL REFERENCES "KANJIDIC_Character"("literal"),
|
||||
"type" VARCHAR(9) NOT NULL CHECK ("type" IN ('classical', 'nelson_c')),
|
||||
"radical" INTEGER NOT NULL CHECK ("radical" BETWEEN 1 AND IIF("type" = 'classical', 214, 213)),
|
||||
PRIMARY KEY("kanji", "type")
|
||||
"kanji" CHAR(1) NOT NULL PRIMARY KEY REFERENCES "KANJIDIC_Character"("literal"),
|
||||
"radicalId" INTEGER NOT NULL CHECK ("radicalId" BETWEEN 1 AND 214)
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE INDEX "KANJIDIC_Radical_byRadicalId" ON "KANJIDIC_Radical"("radicalId");
|
||||
|
||||
CREATE TABLE "KANJIDIC_RadicalNelsonCId" (
|
||||
"radicalId" INTEGER NOT NULL PRIMARY KEY CHECK ("radicalId" BETWEEN 1 AND 214),
|
||||
"nelsonId" INTEGER UNIQUE NOT NULL CHECK ("nelsonId" BETWEEN 1 AND 213)
|
||||
);
|
||||
|
||||
CREATE TABLE "KANJIDIC_RadicalName" (
|
||||
"radicalId" INTEGER NOT NULL CHECK ("radicalId" BETWEEN 1 AND 214),
|
||||
"name" TEXT NOT NULL,
|
||||
PRIMARY KEY("radicalId", "name")
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE INDEX "KANJIDIC_RadicalName_byRadicalId" ON "KANJIDIC_RadicalName"("radicalId");
|
||||
|
||||
CREATE TABLE "KANJIDIC_StrokeMiscount" (
|
||||
"kanji" CHAR(1) NOT NULL REFERENCES "KANJIDIC_Character"("literal"),
|
||||
"strokeCount" INTEGER NOT NULL,
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
CREATE TABLE "XREF__KANJIDIC_Radical__RADKFILE"(
|
||||
"radicalId" INTEGER NOT NULL,
|
||||
"radicalSymbol" CHAR(1) NOT NULL REFERENCES "RADKFILE"("radical"),
|
||||
"radicalType" VARCHAR(9) NOT NULL CHECK ("radicalType" IN ('classical', 'nelson_c')) DEFAULT 'classical',
|
||||
PRIMARY KEY ("radicalId", "radicalSymbol", "radicalType"),
|
||||
FOREIGN KEY ("radicalId", "radicalType") REFERENCES "KANJIDIC_Radical"("radical", "type")
|
||||
"radicalId" INTEGER NOT NULL CHECK ("radicalId" BETWEEN 1 AND 214),
|
||||
"radicalSymbol" CHAR(1) UNIQUE NOT NULL REFERENCES "RADKFILE"("radical"),
|
||||
PRIMARY KEY ("radicalId", "radicalSymbol")
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE INDEX "XREF__KANJIDIC_Radical__RADKFILE__byRadicalId" ON "XREF__KANJIDIC_Radical__RADKFILE"("radicalId");
|
||||
CREATE INDEX "XREF__KANJIDIC_Radical__RADKFILE__byRadicalSymbol_byRadicalType" ON "XREF__KANJIDIC_Radical__RADKFILE"("radicalSymbol", "radicalType");
|
||||
CREATE INDEX "XREF__KANJIDIC_Radical__RADKFILE__byRadicalSymbol" ON "XREF__KANJIDIC_Radical__RADKFILE"("radicalSymbol");
|
||||
|
||||
/* Source: https://ctext.org/kangxi-zidian */
|
||||
INSERT INTO "XREF__KANJIDIC_Radical__RADKFILE"("radicalId", "radicalSymbol") VALUES
|
||||
|
||||
Reference in New Issue
Block a user