diff --git a/lib/model/db/db_extension.dart b/lib/model/db/db_extension.dart index 385fff5e0..a0d2a6659 100644 --- a/lib/model/db/db_extension.dart +++ b/lib/model/db/db_extension.dart @@ -1,15 +1,13 @@ import 'package:sqflite/sqflite.dart'; extension ExtraDatabase on Database { - // check table existence - // proper way is to select from `sqlite_master` but this meta table may be missing on some devices - // so we rely on failure check instead - bool tableExists(String table) { - try { - query(table, limit: 1); - return true; - } catch (error) { - return false; - } + // check table existence via `sqlite_master` + // `sqlite_schema` is the alias used in SQLite documentation, + // but it was introduced in SQLite v3.33.0 and it is unavailable on Android API < 34, + // and the historical alias `sqlite_master` is still supported. + // cf https://www.sqlite.org/faq.html#q7 + Future tableExists(String table) async { + final results = await query('sqlite_master', where: 'type = ? AND name = ?', whereArgs: ['table', table]); + return results.isNotEmpty; } } diff --git a/lib/model/db/db_sqflite_upgrade.dart b/lib/model/db/db_sqflite_upgrade.dart index 1442aa13c..bf7e8b122 100644 --- a/lib/model/db/db_sqflite_upgrade.dart +++ b/lib/model/db/db_sqflite_upgrade.dart @@ -62,7 +62,7 @@ class LocalMediaDbUpgrader { static Future _sanitize(Database db) async { // ensure all tables exist await Future.forEach(SqfliteLocalMediaDbSchema.allTables, (table) async { - if (!db.tableExists(table)) { + if (!(await db.tableExists(table))) { await SqfliteLocalMediaDbSchema.createTable(db, table); } }); @@ -464,7 +464,7 @@ class LocalMediaDbUpgrader { static Future _upgradeFrom13(Database db) async { debugPrint('upgrading DB from v13'); - if (db.tableExists(entryTable)) { + if (await db.tableExists(entryTable)) { // rename column 'dateModifiedSecs' to 'dateModifiedMillis' const newEntryTable = '${entryTable}TEMP'; await db.execute('CREATE TABLE $newEntryTable (' @@ -500,7 +500,7 @@ class LocalMediaDbUpgrader { // so we clear rebuildable tables final tables = [dateTakenTable, metadataTable, addressTable, trashTable, videoPlaybackTable]; await Future.forEach(tables, (table) async { - if (db.tableExists(table)) { + if (await db.tableExists(table)) { await db.delete(table, where: '1'); } }); diff --git a/lib/widgets/home/home_page.dart b/lib/widgets/home/home_page.dart index 8ea841bf0..cc4cd1875 100644 --- a/lib/widgets/home/home_page.dart +++ b/lib/widgets/home/home_page.dart @@ -274,7 +274,7 @@ class _HomePageState extends State { )); } catch (error, stack) { debugPrint('failed to setup app with error=$error\n$stack'); - _setupError = (error, stack); + setState(() => _setupError = (error, stack)); } }