kanji-inspector
Version:
A TypeScript library that provides Unihan data as type-safe constants for Kanji and CJK ideographs.
132 lines (131 loc) • 6.23 kB
JavaScript
import fs from 'fs';
import path from 'path';
import { DatabaseManager } from './DatabaseManager.js';
import { Codepoint } from '../common/Codepoint.js';
// データベースディレクトリのパス
const DB_DIR = path.join(process.cwd(), 'dist', 'db');
// codepointをnumberに変換する関数
function toCodepoint(codepoint) {
return new Codepoint(codepoint).getValue();
}
// データベースからデータを取得する関数
async function getData(tableName, codepoint) {
const codepointNum = toCodepoint(codepoint);
return new Promise((resolve, reject) => {
const db = DatabaseManager.getInstance().getConnection(tableName);
db.get(`SELECT * FROM ${tableName} WHERE codepoint = ?`, [codepointNum], (err, row) => {
if (err) {
reject(err);
return;
}
resolve(row || null);
});
});
}
// データベースから複数のデータを取得する関数
async function getDataList(tableName, codepoints) {
const codepointNums = codepoints.map(toCodepoint);
return new Promise((resolve, reject) => {
const db = DatabaseManager.getInstance().getConnection(tableName);
const placeholders = codepointNums.map(() => '?').join(',');
db.all(`SELECT * FROM ${tableName} WHERE codepoint IN (${placeholders})`, codepointNums, (err, rows) => {
if (err) {
reject(err);
return;
}
resolve(rows);
});
});
}
// 利用可能なテーブル名のリストを取得
function listAvailableTables() {
if (!fs.existsSync(DB_DIR)) {
return [];
}
return fs.readdirSync(DB_DIR)
.filter(file => file.endsWith('.db'))
.map(file => path.basename(file, '.db'));
}
// データ取得関数のエクスポート
export const getDictionaryIndex = (codepoint) => getData('DictionaryIndices', codepoint);
export const getDictionaryLikeData = (codepoint) => getData('DictionaryLikeData', codepoint);
export const getIRGSource = (codepoint) => getData('IRGSources', codepoint);
export const getNumericValue = (codepoint) => getData('NumericValues', codepoint);
export const getOtherMapping = (codepoint) => getData('OtherMappings', codepoint);
export const getRadicalStrokeCount = (codepoint) => getData('RadicalStrokeCounts', codepoint);
export const getReading = (codepoint) => getData('Readings', codepoint);
export const getVariant = (codepoint) => getData('Variants', codepoint);
// 複数データ取得関数のエクスポート
export const getDictionaryIndices = (codepoints) => getDataList('DictionaryIndices', codepoints);
export const getDictionaryLikeDataList = (codepoints) => getDataList('DictionaryLikeData', codepoints);
export const getIRGSources = (codepoints) => getDataList('IRGSources', codepoints);
export const getNumericValues = (codepoints) => getDataList('NumericValues', codepoints);
export const getOtherMappings = (codepoints) => getDataList('OtherMappings', codepoints);
export const getRadicalStrokeCounts = (codepoints) => getDataList('RadicalStrokeCounts', codepoints);
export const getReadings = (codepoints) => getDataList('Readings', codepoints);
export const getVariants = (codepoints) => getDataList('Variants', codepoints);
// 利用可能なテーブル名のエクスポート
export const getAvailableTables = () => listAvailableTables();
// データベース接続を閉じる関数のエクスポート
export const closeDatabase = () => DatabaseManager.getInstance().closeAll();
export const closeTableConnection = (tableName) => DatabaseManager.getInstance().closeConnection(tableName);
export const getKanjiDetail = async (codepoint) => {
const cp = new Codepoint(codepoint);
const codepointNum = toCodepoint(codepoint);
return {
char: cp.toChar(),
codepoint: codepointNum,
codepointStr: cp.toString(),
dictionaryIndex: await getDictionaryIndex(codepointNum),
dictionaryLikeData: await getDictionaryLikeData(codepointNum),
iRGSource: await getIRGSource(codepointNum),
numericValue: await getNumericValue(codepointNum),
otherMapping: await getOtherMapping(codepointNum),
radicalStrokeCount: await getRadicalStrokeCount(codepointNum),
reading: await getReading(codepointNum),
variant: await getVariant(codepointNum)
};
};
export const getKanjiDetailList = async (codepoints) => {
const codepointNums = codepoints.map(toCodepoint);
const [dictionaryIndices, dictionaryLikeDataList, iRGSources, numericValues, otherMappings, radicalStrokeCounts, readings, variants] = await Promise.all([
getDictionaryIndices(codepointNums),
getDictionaryLikeDataList(codepointNums),
getIRGSources(codepointNums),
getNumericValues(codepointNums),
getOtherMappings(codepointNums),
getRadicalStrokeCounts(codepointNums),
getReadings(codepointNums),
getVariants(codepointNums)
]);
return codepointNums.map(codepoint => {
const cp = new Codepoint(codepoint);
const dictionaryIndex = dictionaryIndices.find(d => d.codepoint === codepoint);
const dictionaryLikeData = dictionaryLikeDataList.find(d => d.codepoint === codepoint);
const iRGSource = iRGSources.find(d => d.codepoint === codepoint);
const numericValue = numericValues.find(d => d.codepoint === codepoint);
const otherMapping = otherMappings.find(d => d.codepoint === codepoint);
const radicalStrokeCount = radicalStrokeCounts.find(d => d.codepoint === codepoint);
const reading = readings.find(d => d.codepoint === codepoint);
const variant = variants.find(d => d.codepoint === codepoint);
return {
char: cp.toChar(),
codepoint,
codepointStr: cp.toString(),
dictionaryIndex,
dictionaryLikeData,
iRGSource,
numericValue,
otherMapping,
radicalStrokeCount,
reading,
variant
};
});
};
// Codepointクラスのエクスポート
export { Codepoint };
export default {
getKanjiDetail,
getKanjiDetailList,
};