lib/search: make JaDBConnection into extension, add verifyTables
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:jadb/_data_ingestion/jmdict/table_names.dart';
|
||||
import 'package:jadb/_data_ingestion/kanjidic/table_names.dart';
|
||||
import 'package:jadb/_data_ingestion/radkfile/table_names.dart';
|
||||
import 'package:jadb/_data_ingestion/tanos-jlpt/table_names.dart';
|
||||
import 'package:jadb/search.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
import 'package:sqlite3/open.dart';
|
||||
|
||||
@@ -12,7 +9,7 @@ Future<Database> openLocalDb({
|
||||
String? libsqlitePath,
|
||||
String? jadbPath,
|
||||
bool readWrite = false,
|
||||
bool assertTablesExist = true,
|
||||
bool verifyTablesExist = true,
|
||||
bool walMode = false,
|
||||
}) async {
|
||||
libsqlitePath ??= Platform.environment['LIBSQLITE_PATH'];
|
||||
@@ -52,43 +49,9 @@ Future<Database> openLocalDb({
|
||||
),
|
||||
);
|
||||
|
||||
if (assertTablesExist) {
|
||||
await _assertTablesExist(db);
|
||||
if (verifyTablesExist) {
|
||||
await db.jadbVerifyTables();
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
Future<void> _assertTablesExist(Database db) async {
|
||||
final Set<String> tables = await db
|
||||
.query(
|
||||
'sqlite_master',
|
||||
columns: ['name'],
|
||||
where: 'type = ?',
|
||||
whereArgs: ['table'],
|
||||
)
|
||||
.then((result) {
|
||||
return result.map((row) => row['name'] as String).toSet();
|
||||
});
|
||||
|
||||
final Set<String> expectedTables = {
|
||||
...JMdictTableNames.allTables,
|
||||
...KANJIDICTableNames.allTables,
|
||||
...RADKFILETableNames.allTables,
|
||||
...TanosJLPTTableNames.allTables,
|
||||
};
|
||||
|
||||
final missingTables = expectedTables.difference(tables);
|
||||
|
||||
if (missingTables.isNotEmpty) {
|
||||
throw Exception([
|
||||
'Missing tables:',
|
||||
missingTables.map((table) => ' - $table').join('\n'),
|
||||
'',
|
||||
'Found tables:\n',
|
||||
tables.map((table) => ' - $table').join('\n'),
|
||||
'',
|
||||
'Please ensure the database is correctly set up.',
|
||||
].join('\n'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class QueryKanji extends Command {
|
||||
);
|
||||
|
||||
final time = Stopwatch()..start();
|
||||
final result = await JaDBConnection(db).searchKanji(
|
||||
final result = await JaDBConnection(db).jadbSearchKanji(
|
||||
argResults!.option('kanji') ?? '漢',
|
||||
);
|
||||
time.stop();
|
||||
|
||||
@@ -36,11 +36,11 @@ class QueryWord extends Command {
|
||||
final String searchWord = argResults!.option('word') ?? 'かな';
|
||||
|
||||
final time = Stopwatch()..start();
|
||||
final count = await JaDBConnection(db).searchWordCount(searchWord);
|
||||
final count = await JaDBConnection(db).jadbSearchWordCount(searchWord);
|
||||
time.stop();
|
||||
|
||||
final time2 = Stopwatch()..start();
|
||||
final result = await JaDBConnection(db).searchWord(searchWord);
|
||||
final result = await JaDBConnection(db).jadbSearchWord(searchWord);
|
||||
time2.stop();
|
||||
|
||||
if (result == null) {
|
||||
|
||||
39
lib/models/verifyTables.dart
Normal file
39
lib/models/verifyTables.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'package:jadb/_data_ingestion/jmdict/table_names.dart';
|
||||
import 'package:jadb/_data_ingestion/kanjidic/table_names.dart';
|
||||
import 'package:jadb/_data_ingestion/radkfile/table_names.dart';
|
||||
import 'package:jadb/_data_ingestion/tanos-jlpt/table_names.dart';
|
||||
import 'package:sqflite_common/sqlite_api.dart';
|
||||
|
||||
Future<void> verifyTablesWithDbConnection(DatabaseExecutor db) async {
|
||||
final Set<String> tables = await db
|
||||
.query(
|
||||
'sqlite_master',
|
||||
columns: ['name'],
|
||||
where: 'type = ?',
|
||||
whereArgs: ['table'],
|
||||
)
|
||||
.then((result) {
|
||||
return result.map((row) => row['name'] as String).toSet();
|
||||
});
|
||||
|
||||
final Set<String> expectedTables = {
|
||||
...JMdictTableNames.allTables,
|
||||
...KANJIDICTableNames.allTables,
|
||||
...RADKFILETableNames.allTables,
|
||||
...TanosJLPTTableNames.allTables,
|
||||
};
|
||||
|
||||
final missingTables = expectedTables.difference(tables);
|
||||
|
||||
if (missingTables.isNotEmpty) {
|
||||
throw Exception([
|
||||
'Missing tables:',
|
||||
missingTables.map((table) => ' - $table').join('\n'),
|
||||
'',
|
||||
'Found tables:\n',
|
||||
tables.map((table) => ' - $table').join('\n'),
|
||||
'',
|
||||
'Please ensure the database is correctly set up.',
|
||||
].join('\n'));
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:jadb/models/verifyTables.dart';
|
||||
import 'package:jadb/models/word_search/word_search_result.dart';
|
||||
import 'package:jadb/models/kanji_search/kanji_search_result.dart';
|
||||
import 'package:jadb/search/filter_kanji.dart';
|
||||
@@ -8,31 +9,32 @@ import 'package:jadb/search/kanji_search.dart';
|
||||
|
||||
import 'package:sqflite_common/sqlite_api.dart';
|
||||
|
||||
class JaDBConnection {
|
||||
final DatabaseExecutor _connection;
|
||||
|
||||
const JaDBConnection(this._connection);
|
||||
extension JaDBConnection on DatabaseExecutor {
|
||||
/// Ensure that the database contain all JaDB tables.
|
||||
///
|
||||
/// This will throw an exception if any of the tables are missing.
|
||||
Future<void> jadbVerifyTables() => verifyTablesWithDbConnection(this);
|
||||
|
||||
/// Search for a kanji in the database.
|
||||
Future<KanjiSearchResult?> searchKanji(String kanji) =>
|
||||
searchKanjiWithDbConnection(this._connection, kanji);
|
||||
Future<KanjiSearchResult?> jadbSearchKanji(String kanji) =>
|
||||
searchKanjiWithDbConnection(this, kanji);
|
||||
|
||||
/// Filter a list of characters, and return the ones that are listed in the kanji dictionary.
|
||||
Future<List<String>> filterKanji(
|
||||
List<String> kanji, {
|
||||
bool deduplicate = false,
|
||||
}) =>
|
||||
filterKanjiWithDbConnection(this._connection, kanji, deduplicate);
|
||||
filterKanjiWithDbConnection(this, kanji, deduplicate);
|
||||
|
||||
/// Search for a word in the database.
|
||||
Future<List<WordSearchResult>?> searchWord(
|
||||
Future<List<WordSearchResult>?> jadbSearchWord(
|
||||
String word, {
|
||||
SearchMode searchMode = SearchMode.Auto,
|
||||
int page = 0,
|
||||
int pageSize = 10,
|
||||
}) =>
|
||||
searchWordWithDbConnection(
|
||||
this._connection,
|
||||
this,
|
||||
word,
|
||||
searchMode,
|
||||
page,
|
||||
@@ -40,21 +42,21 @@ class JaDBConnection {
|
||||
);
|
||||
|
||||
/// Search for a word in the database, and return the count of results.
|
||||
Future<int?> searchWordCount(
|
||||
Future<int?> jadbSearchWordCount(
|
||||
String word, {
|
||||
SearchMode searchMode = SearchMode.Auto,
|
||||
}) =>
|
||||
searchWordCountWithDbConnection(this._connection, word, searchMode);
|
||||
searchWordCountWithDbConnection(this, word, searchMode);
|
||||
|
||||
/// Given a list of radicals, search which kanji contains all
|
||||
/// of the radicals, find their other radicals, and return those.
|
||||
/// This is used to figure out which remaining combinations of radicals
|
||||
/// the user can search for without getting zero results.
|
||||
Future<List<String>> searchRemainingRadicals(List<String> radicals) =>
|
||||
searchRemainingRadicalsWithDbConnection(this._connection, radicals);
|
||||
Future<List<String>> jadbSearchRemainingRadicals(List<String> radicals) =>
|
||||
searchRemainingRadicalsWithDbConnection(this, radicals);
|
||||
|
||||
/// Given a list of radicals, search which kanji contains all
|
||||
/// of the radicals, and return those.
|
||||
Future<List<String>> searchKanjiByRadicals(List<String> radicals) =>
|
||||
searchKanjiByRadicalsWithDbConnection(this._connection, radicals);
|
||||
Future<List<String>> jadbSearchKanjiByRadicals(List<String> radicals) =>
|
||||
searchKanjiByRadicalsWithDbConnection(this, radicals);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:jadb/const_data/kanji_grades.dart';
|
||||
import 'package:jadb/search.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'setup_database_connection.dart';
|
||||
@@ -7,7 +8,7 @@ void main() {
|
||||
test("Search a kanji", () async {
|
||||
final connection = await setup_database_connection();
|
||||
|
||||
final result = await connection.searchKanji('漢');
|
||||
final result = await connection.jadbSearchKanji('漢');
|
||||
expect(result, isNotNull);
|
||||
});
|
||||
|
||||
@@ -17,7 +18,7 @@ void main() {
|
||||
final connection = await setup_database_connection();
|
||||
|
||||
for (final character in characters) {
|
||||
final result = await connection.searchKanji(character);
|
||||
final result = await connection.jadbSearchKanji(character);
|
||||
expect(result, isNotNull);
|
||||
}
|
||||
}, timeout: Timeout.factor(10));
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:jadb/_data_ingestion/open_local_db.dart';
|
||||
import 'package:jadb/search.dart';
|
||||
import 'package:sqflite_common/sqlite_api.dart';
|
||||
|
||||
Future<JaDBConnection> setup_database_connection() async {
|
||||
Future<Database> setup_database_connection() async {
|
||||
final lib_sqlite_path = Platform.environment['LIBSQLITE_PATH'];
|
||||
final jadb_path = Platform.environment['JADB_PATH'];
|
||||
|
||||
@@ -24,5 +24,5 @@ Future<JaDBConnection> setup_database_connection() async {
|
||||
throw Exception("Failed to open database");
|
||||
}
|
||||
|
||||
return JaDBConnection(db_connection);
|
||||
return db_connection;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:jadb/search.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'setup_database_connection.dart';
|
||||
@@ -6,7 +7,7 @@ void main() {
|
||||
test("Search a word", () async {
|
||||
final connection = await setup_database_connection();
|
||||
|
||||
final result = await connection.searchWord("kana");
|
||||
final result = await connection.jadbSearchWord("kana");
|
||||
expect(result, isNotNull);
|
||||
});
|
||||
|
||||
@@ -17,7 +18,7 @@ void main() {
|
||||
|
||||
// Test serializing all words
|
||||
for (final letter in "aiueoksthnmyrw".split("")) {
|
||||
await connection.searchWord(letter);
|
||||
await connection.jadbSearchWord(letter);
|
||||
}
|
||||
},
|
||||
timeout: Timeout.factor(100),
|
||||
|
||||
Reference in New Issue
Block a user