Compare commits
4 Commits
keep-data-
...
library-li
| Author | SHA1 | Date | |
|---|---|---|---|
|
45a5810de1
|
|||
|
923f5e48f6
|
|||
|
353d5c4c39
|
|||
|
a280c9e77a
|
@@ -5,6 +5,7 @@ import 'dart:io';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:jadb/search.dart';
|
||||
import 'package:mugiten/models/verify_tables.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
@@ -119,10 +120,12 @@ Future<Database> openAndMigrateDatabase(
|
||||
},
|
||||
onOpen: (db) async {
|
||||
log('Verifying jadb tables...');
|
||||
|
||||
db.jadbVerifyTables();
|
||||
|
||||
log('jadb opened successfully');
|
||||
log('Verifying jadb tables...');
|
||||
verifyMugitenTablesWithDbConnection(db);
|
||||
|
||||
log('Database tables verified successfully');
|
||||
},
|
||||
);
|
||||
return database;
|
||||
|
||||
@@ -31,4 +31,12 @@ abstract class HistoryTableNames {
|
||||
/// - language CHAR(1)?
|
||||
static const String historyEntryOrderedByTimestamp =
|
||||
'Mugiten_HistoryEntry_orderedByTimestamp';
|
||||
|
||||
static Set<String> get allTables => {
|
||||
historyEntry,
|
||||
historyEntryKanji,
|
||||
historyEntryTimestamp,
|
||||
historyEntryWord,
|
||||
historyEntryOrderedByTimestamp,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,4 +20,10 @@ abstract class LibraryListTableNames {
|
||||
/// Attributes:
|
||||
/// - name TEXT
|
||||
static const String libraryListOrdered = 'Mugiten_LibraryList_Ordered';
|
||||
|
||||
static Set<String> get allTables => {
|
||||
libraryList,
|
||||
libraryListEntry,
|
||||
libraryListOrdered,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:mugiten/database/library_list/table_names.dart';
|
||||
|
||||
import '../../database/database.dart';
|
||||
@@ -10,9 +11,9 @@ import 'library_entry.dart';
|
||||
class LibraryList {
|
||||
final String name;
|
||||
|
||||
const LibraryList._byName(this.name);
|
||||
const LibraryList.byName(this.name);
|
||||
|
||||
static const LibraryList favourites = LibraryList._byName('favourites');
|
||||
static const LibraryList favourites = LibraryList.byName('favourites');
|
||||
|
||||
/// Get all entries within the library, in their custom order
|
||||
Future<List<LibraryEntry>> get entries async {
|
||||
@@ -48,7 +49,7 @@ class LibraryList {
|
||||
static Future<List<LibraryList>> get allLibraries async {
|
||||
final query = await db().query(LibraryListTableNames.libraryListOrdered);
|
||||
return query
|
||||
.map((lib) => LibraryList._byName(lib['name']! as String))
|
||||
.map((lib) => LibraryList.byName(lib['name']! as String))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -83,7 +84,7 @@ class LibraryList {
|
||||
return Map.fromEntries(
|
||||
query.map(
|
||||
(lib) => MapEntry(
|
||||
LibraryList._byName(lib['name']! as String),
|
||||
LibraryList.byName(lib['name']! as String),
|
||||
lib['exists']! as int == 1,
|
||||
),
|
||||
),
|
||||
@@ -249,6 +250,32 @@ class LibraryList {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> insertJsonEntries(
|
||||
List<Map<String, Object?>> jsonEntries,
|
||||
) async {
|
||||
List<LibraryEntry> entries =
|
||||
jsonEntries.map((e) => LibraryEntry.fromJson(e)).toList();
|
||||
|
||||
// TODO: batch
|
||||
for (final entry in entries) {
|
||||
if (entry.kanji != null) {
|
||||
await insertEntry(
|
||||
kanji: entry.kanji,
|
||||
jmdictEntryId: null,
|
||||
position: null,
|
||||
lastModified: entry.lastModified,
|
||||
);
|
||||
} else if (entry.jmdictEntryId != null) {
|
||||
await insertEntry(
|
||||
jmdictEntryId: entry.jmdictEntryId,
|
||||
kanji: null,
|
||||
position: null,
|
||||
lastModified: entry.lastModified,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Deletes an entry within a list
|
||||
/// Will throw an exception if the entry is not in the library
|
||||
Future<void> deleteEntry({
|
||||
@@ -418,7 +445,7 @@ class LibraryList {
|
||||
'name': libraryName,
|
||||
'prevList': prevList.name,
|
||||
});
|
||||
return LibraryList._byName(libraryName);
|
||||
return LibraryList.byName(libraryName);
|
||||
}
|
||||
|
||||
/// Delete this library from the database
|
||||
|
||||
35
lib/models/verify_tables.dart
Normal file
35
lib/models/verify_tables.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
import 'package:mugiten/database/history/table_names.dart';
|
||||
import 'package:mugiten/database/library_list/table_names.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
Future<void> verifyMugitenTablesWithDbConnection(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 = {
|
||||
...HistoryTableNames.allTables,
|
||||
...LibraryListTableNames.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,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:confirm_dialog/confirm_dialog.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
@@ -80,16 +81,20 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
}
|
||||
|
||||
Future<void> clearAll(context) async {
|
||||
final historyCount = await HistoryEntry.amountOfEntries();
|
||||
final libraryCount = await LibraryList.libraryCount();
|
||||
|
||||
if (!context.mounted) return;
|
||||
int? historyCount;
|
||||
int? libraryCount;
|
||||
try {
|
||||
historyCount = await HistoryEntry.amountOfEntries();
|
||||
libraryCount = await LibraryList.libraryCount();
|
||||
} catch (e) {
|
||||
log('Error getting counts: $e');
|
||||
}
|
||||
|
||||
final bool userIsSure = await confirm(
|
||||
context,
|
||||
content: Text(
|
||||
'Are you sure you want to delete $historyCount history entries '
|
||||
'and $libraryCount libraries?',
|
||||
'Are you sure you want to delete ${historyCount ?? '?'} history entries '
|
||||
'and ${libraryCount ?? '?'} libraries?',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Future<Directory> tmpdir() async =>
|
||||
|
||||
Future<Directory> unpackZipToTempDir(String zipFilePath) async {
|
||||
final outputDir = await tmpdir();
|
||||
extractFileToDisk(
|
||||
await extractFileToDisk(
|
||||
zipFilePath,
|
||||
outputDir.path,
|
||||
);
|
||||
@@ -148,5 +148,33 @@ Future<void> exportLibraryListsTo(
|
||||
|
||||
// TODO: how do we handle lists that already exist? There seems to be no good way to merge them?
|
||||
Future<void> importLibraryListsFrom(Directory libraryListsDir) async {
|
||||
print('TODO: Implement importLibraryLists');
|
||||
for (final file in libraryListsDir.listSync()) {
|
||||
if (file is! File) continue;
|
||||
|
||||
assert(file.path.endsWith('.json'));
|
||||
|
||||
final libraryName =
|
||||
file.uri.pathSegments.last.replaceFirst(RegExp(r'\.json$'), '');
|
||||
|
||||
if (await LibraryList.exists(libraryName)) {
|
||||
if ((await LibraryList.byName(libraryName).length) > 0) {
|
||||
print(
|
||||
'Library list "$libraryName" already exists and is not empty. Skipping import.');
|
||||
continue;
|
||||
} else {
|
||||
print('Library list "$libraryName" already exists but is empty. '
|
||||
'Importing entries from file ${file.path}.');
|
||||
}
|
||||
} else {
|
||||
LibraryList.insert(libraryName);
|
||||
}
|
||||
|
||||
final content = await file.readAsString();
|
||||
final List<Map<String, Object?>> jsonEntries = (jsonDecode(content) as List)
|
||||
.map((e) => e as Map<String, Object?>)
|
||||
.toList();
|
||||
|
||||
final libraryList = LibraryList.byName(libraryName);
|
||||
await libraryList.insertJsonEntries(jsonEntries);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user