如何过滤SQLite系统表,仅安全清理用户自定义表数据?
解决SQLite自定义表清理的系统表安全问题
你的担心非常合理,依赖黑名单过滤已知系统表确实存在遗漏未来新增系统表的风险,以下是几个更稳妥的解决方案:
方案1:维护自定义表白名单
直接把你自己创建的所有表名列成白名单,只清理这些表。这种方式绝对安全,完全不会触碰任何系统表,哪怕SQLite后续新增系统表也不会有影响。
调整后的示例代码:
// 手动维护的自定义表白名单,新增表时同步更新即可 List<String> customTableNames = ["user_info", "order_record", "product_list"]; for (String tableName in customTableNames) { await customStatement("delete from $tableName;"); }
方案2:通过表名规则过滤系统表
SQLite官方的系统表几乎都以sqlite_为前缀(比如sqlite_sequence、sqlite_stat1等),再加上Android特有的android_metadata,可以直接在SQL层面完成过滤,避免后续代码处理的遗漏:
修改查询SQL:
select name from sqlite_master where type = 'table' and name not like 'sqlite_%' and name != 'android_metadata';
对应的Dart代码调整:
Future<List<String>> _getCustomTableNames() async { String selectTablesSql = """ select name from sqlite_master where type = 'table' and name not like 'sqlite_%' and name != 'android_metadata'; """; final result = await customWriteReturning(selectTablesSql); return result.map((row) => row.data["name"] as String).toList(); } // 执行清理 List<String> tableNameList = await _getCustomTableNames(); for (String tableName in tableNameList) { await customStatement("delete from $tableName;"); }
这种方式无需手动维护所有自定义表,同时能自动覆盖未来新增的sqlite_前缀系统表,兼顾便捷性和安全性。
方案3:用元数据表标记自定义表
如果你的自定义表数量多且频繁变动,可以创建一个专门的元数据表来记录所有自定义表:
create table if not exists app_custom_tables (table_name text primary key);
每次创建自定义表后,同步往这个元数据表插入记录:
insert or ignore into app_custom_tables (table_name) values ('user_info');
清理时直接从元数据表读取目标表名:
Future<List<String>> _getCustomTableNames() async { final result = await customWriteReturning("select table_name from app_custom_tables;"); return result.map((row) => row.data["table_name"] as String).toList(); }
这种方式灵活性最高,新增表时只需同步更新元数据表,无需修改清理逻辑。
内容的提问来源于stack exchange,提问作者stacktrace2234
相关产品推荐
相关产品推荐

