#1476 launch error handling reload;

DB: table existence check via sqlite_master
This commit is contained in:
Thibault Deckers 2025-03-25 19:49:33 +01:00
parent 509c402227
commit 9d7e6bb9ff
3 changed files with 12 additions and 14 deletions

View file

@ -1,15 +1,13 @@
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
extension ExtraDatabase on Database { extension ExtraDatabase on Database {
// check table existence // check table existence via `sqlite_master`
// proper way is to select from `sqlite_master` but this meta table may be missing on some devices // `sqlite_schema` is the alias used in SQLite documentation,
// so we rely on failure check instead // but it was introduced in SQLite v3.33.0 and it is unavailable on Android API < 34,
bool tableExists(String table) { // and the historical alias `sqlite_master` is still supported.
try { // cf https://www.sqlite.org/faq.html#q7
query(table, limit: 1); Future<bool> tableExists(String table) async {
return true; final results = await query('sqlite_master', where: 'type = ? AND name = ?', whereArgs: ['table', table]);
} catch (error) { return results.isNotEmpty;
return false;
}
} }
} }

View file

@ -62,7 +62,7 @@ class LocalMediaDbUpgrader {
static Future<void> _sanitize(Database db) async { static Future<void> _sanitize(Database db) async {
// ensure all tables exist // ensure all tables exist
await Future.forEach(SqfliteLocalMediaDbSchema.allTables, (table) async { await Future.forEach(SqfliteLocalMediaDbSchema.allTables, (table) async {
if (!db.tableExists(table)) { if (!(await db.tableExists(table))) {
await SqfliteLocalMediaDbSchema.createTable(db, table); await SqfliteLocalMediaDbSchema.createTable(db, table);
} }
}); });
@ -464,7 +464,7 @@ class LocalMediaDbUpgrader {
static Future<void> _upgradeFrom13(Database db) async { static Future<void> _upgradeFrom13(Database db) async {
debugPrint('upgrading DB from v13'); debugPrint('upgrading DB from v13');
if (db.tableExists(entryTable)) { if (await db.tableExists(entryTable)) {
// rename column 'dateModifiedSecs' to 'dateModifiedMillis' // rename column 'dateModifiedSecs' to 'dateModifiedMillis'
const newEntryTable = '${entryTable}TEMP'; const newEntryTable = '${entryTable}TEMP';
await db.execute('CREATE TABLE $newEntryTable (' await db.execute('CREATE TABLE $newEntryTable ('
@ -500,7 +500,7 @@ class LocalMediaDbUpgrader {
// so we clear rebuildable tables // so we clear rebuildable tables
final tables = [dateTakenTable, metadataTable, addressTable, trashTable, videoPlaybackTable]; final tables = [dateTakenTable, metadataTable, addressTable, trashTable, videoPlaybackTable];
await Future.forEach(tables, (table) async { await Future.forEach(tables, (table) async {
if (db.tableExists(table)) { if (await db.tableExists(table)) {
await db.delete(table, where: '1'); await db.delete(table, where: '1');
} }
}); });

View file

@ -274,7 +274,7 @@ class _HomePageState extends State<HomePage> {
)); ));
} catch (error, stack) { } catch (error, stack) {
debugPrint('failed to setup app with error=$error\n$stack'); debugPrint('failed to setup app with error=$error\n$stack');
_setupError = (error, stack); setState(() => _setupError = (error, stack));
} }
} }