更新数据库
This commit is contained in:
@@ -45,7 +45,7 @@ class DatabaseDataSource {
|
||||
}
|
||||
|
||||
final file = File('${dbDir.path}/$uid.sqlite');
|
||||
_db = _databaseFactory(NativeDatabase(file));
|
||||
_db = _databaseFactory(NativeDatabase.createInBackground(file));
|
||||
return _db!;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,14 @@ import '../wiring/storage_sdk_wiring.dart';
|
||||
|
||||
/// 本地数据库的统一公开接口。
|
||||
///
|
||||
/// 通过 [StorageSdkApi] 工厂方法获取实例,传入 App 侧的数据库工厂即可:
|
||||
/// 通过 [StorageSdkApi] 工厂方法获取实例,传入 App 侧的数据库工厂和表注册表即可:
|
||||
///
|
||||
/// ```dart
|
||||
/// final api = StorageSdkApi(
|
||||
/// databaseFactory: (executor) => AppDatabase(executor),
|
||||
/// tableRegistry: (db) => {
|
||||
/// User: (db as AppDatabase).users,
|
||||
/// },
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
@@ -19,98 +22,124 @@ import '../wiring/storage_sdk_wiring.dart';
|
||||
///
|
||||
/// 内部接口,仅供 App 层生命周期管理使用
|
||||
abstract class StorageSdkLifecycle {
|
||||
/// 打开指定用户的数据库(按 uid 隔离文件)。
|
||||
Future<void> openDatabase(int uid);
|
||||
|
||||
/// 关闭当前数据库连接。
|
||||
Future<void> closeDatabase();
|
||||
|
||||
/// 是否已开库。
|
||||
bool get isDatabaseOpen;
|
||||
}
|
||||
///
|
||||
///
|
||||
|
||||
/// ## CRUD
|
||||
/// 所有 CRUD 方法均为泛型,接受 Drift 的 [TableInfo],与具体业务表解耦。
|
||||
/// App 层传入自己定义的 Table 即可复用全部操作。
|
||||
/// 所有 CRUD 方法均通过泛型数据类型查找对应表,与具体业务表解耦。
|
||||
/// App 层通过 [tableRegistry] 注入表映射,无需在调用时传入 [TableInfo]。
|
||||
abstract class StorageSdkApi {
|
||||
/// 创建 SDK 实例。
|
||||
///
|
||||
/// [databaseFactory] 由 App 层提供:接受 [QueryExecutor],
|
||||
/// 返回自定义的 [GeneratedDatabase] 子类(含表定义和迁移策略)。
|
||||
///
|
||||
/// [tableRegistry] 由 App 层提供:将数据类映射到对应的表信息,
|
||||
/// storage_sdk 不感知具体表结构。
|
||||
///
|
||||
/// 示例:
|
||||
/// ```dart
|
||||
/// final api = StorageSdkApi(
|
||||
/// databaseFactory: (executor) => AppDatabase(executor),
|
||||
/// tableRegistry: (db) => {
|
||||
/// User: (db as AppDatabase).users,
|
||||
/// },
|
||||
/// );
|
||||
/// ```
|
||||
factory StorageSdkApi({
|
||||
required GeneratedDatabase Function(QueryExecutor) databaseFactory,
|
||||
required Map<Type, TableInfo> Function(GeneratedDatabase) tableRegistry,
|
||||
}) =>
|
||||
StorageSdkWiring.build(databaseFactory: databaseFactory);
|
||||
StorageSdkWiring.build(
|
||||
databaseFactory: databaseFactory,
|
||||
tableRegistry: tableRegistry,
|
||||
);
|
||||
|
||||
// ── 插入 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 插入或替换(主键冲突时覆盖)。
|
||||
Future<void> insertOrReplace<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
);
|
||||
///
|
||||
/// 示例:
|
||||
/// ```dart
|
||||
/// await sdk.insertOrReplace<UsersCompanion>(
|
||||
/// UsersCompanion.insert(nickname: Value('Edmund')),
|
||||
/// );
|
||||
/// ```
|
||||
Future<void> insertOrReplace<D>(Insertable<D> companion);
|
||||
|
||||
/// 插入或忽略(主键冲突时跳过)。
|
||||
Future<void> insert<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
);
|
||||
Future<void> insert<D>(Insertable<D> companion);
|
||||
|
||||
/// 批量插入或替换。
|
||||
Future<void> batchInsertOrReplace<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
List<Insertable<D>> companions,
|
||||
);
|
||||
Future<void> batchInsertOrReplace<D>(List<Insertable<D>> companions);
|
||||
|
||||
// ── 更新 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 按条件更新。
|
||||
Future<void> updateWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
///
|
||||
/// 示例:
|
||||
/// ```dart
|
||||
/// await sdk.updateWhere<User, $UsersTable>(
|
||||
/// UsersCompanion(nickname: Value('NewName')),
|
||||
/// (t) => t.uid.equals(123),
|
||||
/// );
|
||||
/// ```
|
||||
Future<void> updateWhere<D, T extends Table>(
|
||||
Insertable<D> companion,
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
|
||||
// ── 删除 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 按条件删除。
|
||||
Future<void> deleteWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
Future<void> deleteWhere<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
|
||||
/// 清空整张表。
|
||||
Future<void> deleteAll<T extends Table, D>(TableInfo<T, D> table);
|
||||
Future<void> deleteAll<D>();
|
||||
|
||||
// ── 查询 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 查询全部记录。
|
||||
Future<List<D>> selectAll<T extends Table, D>(TableInfo<T, D> table);
|
||||
///
|
||||
/// 示例:
|
||||
/// ```dart
|
||||
/// final users = await sdk.selectAll<User>();
|
||||
/// ```
|
||||
Future<List<D>> selectAll<D>();
|
||||
|
||||
/// 按条件查询。
|
||||
Future<List<D>> selectWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
Future<List<D>> selectWhere<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
|
||||
/// 查询第一条匹配记录。
|
||||
Future<D?> selectFirst<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
Future<D?> selectFirst<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
|
||||
// ── 监听 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 监听全部记录(实时流)。
|
||||
Stream<List<D>> watchAll<T extends Table, D>(TableInfo<T, D> table);
|
||||
Stream<List<D>> watchAll<D>();
|
||||
|
||||
/// 按条件监听(实时流)。
|
||||
Stream<List<D>> watchWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
Stream<List<D>> watchWhere<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
|
||||
/// 监听第一条匹配记录(实时流)。
|
||||
Stream<D?> watchFirst<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
Stream<D?> watchFirst<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
);
|
||||
|
||||
// ── 原始 SQL ─────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -123,8 +152,7 @@ abstract class StorageSdkApi {
|
||||
// ── 统计 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 统计记录数。
|
||||
Future<int> count<T extends Table, D>(
|
||||
TableInfo<T, D> table, {
|
||||
Future<int> count<D, T extends Table>({
|
||||
Expression<bool> Function(T)? filter,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,29 @@ import 'storage_sdk_core.dart';
|
||||
/// [StorageSdkApi] 的实现,委托给 [StorageSdkCore]。
|
||||
class StorageSdkApiImpl implements StorageSdkApi, StorageSdkLifecycle {
|
||||
final StorageSdkCore _core;
|
||||
final Map<Type, TableInfo> Function(GeneratedDatabase) _tableRegistry;
|
||||
|
||||
StorageSdkApiImpl({required StorageSdkCore core}) : _core = core;
|
||||
StorageSdkApiImpl({
|
||||
required StorageSdkCore core,
|
||||
required Map<Type, TableInfo> Function(GeneratedDatabase) tableRegistry,
|
||||
}) : _core = core,
|
||||
_tableRegistry = tableRegistry;
|
||||
|
||||
// ── 表查找 ───────────────────────────────────────────────────────────────
|
||||
|
||||
/// 根据泛型数据类型从注册表中查找对应的 [TableInfo]。
|
||||
TableInfo<T, D> _tableFor<T extends Table, D>() {
|
||||
final db = _core.dataSource.current;
|
||||
if (db == null) throw StateError('数据库未开启,请先调用 openDatabase()');
|
||||
final table = _tableRegistry(db)[D];
|
||||
if (table == null) throw StateError('未注册类型 $D 对应的表,请检查 tableRegistry');
|
||||
return table as TableInfo<T, D>;
|
||||
}
|
||||
|
||||
// ── 生命周期 ─────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<void> openDatabase(int uid) =>
|
||||
_core.dataSource.openDatabase(uid);
|
||||
Future<void> openDatabase(int uid) => _core.dataSource.openDatabase(uid);
|
||||
|
||||
@override
|
||||
Future<void> closeDatabase() => _core.dataSource.closeDatabase();
|
||||
@@ -24,88 +39,73 @@ class StorageSdkApiImpl implements StorageSdkApi, StorageSdkLifecycle {
|
||||
// ── 插入 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<void> insertOrReplace<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
) =>
|
||||
_core.repo.insertOrReplace(table, companion);
|
||||
Future<void> insertOrReplace<D>(Insertable<D> companion) =>
|
||||
_core.repo.insertOrReplace(_tableFor<Table, D>(), companion);
|
||||
|
||||
@override
|
||||
Future<void> insert<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
) =>
|
||||
_core.repo.insert(table, companion);
|
||||
Future<void> insert<D>(Insertable<D> companion) =>
|
||||
_core.repo.insert(_tableFor<Table, D>(), companion);
|
||||
|
||||
@override
|
||||
Future<void> batchInsertOrReplace<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
List<Insertable<D>> companions,
|
||||
) =>
|
||||
_core.repo.batchInsertOrReplace(table, companions);
|
||||
Future<void> batchInsertOrReplace<D>(List<Insertable<D>> companions) =>
|
||||
_core.repo.batchInsertOrReplace(_tableFor<Table, D>(), companions);
|
||||
|
||||
// ── 更新 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<void> updateWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.updateWhere(table, companion, filter);
|
||||
Future<void> updateWhere<D, T extends Table>(
|
||||
Insertable<D> companion,
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.updateWhere(_tableFor<T, D>(), companion, filter);
|
||||
|
||||
// ── 删除 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<void> deleteWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.deleteWhere(table, filter);
|
||||
Future<void> deleteWhere<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.deleteWhere(_tableFor<T, D>(), filter);
|
||||
|
||||
@override
|
||||
Future<void> deleteAll<T extends Table, D>(TableInfo<T, D> table) =>
|
||||
_core.repo.deleteAll(table);
|
||||
Future<void> deleteAll<D>() =>
|
||||
_core.repo.deleteAll(_tableFor<Table, D>());
|
||||
|
||||
// ── 查询 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<List<D>> selectAll<T extends Table, D>(TableInfo<T, D> table) =>
|
||||
_core.repo.selectAll(table);
|
||||
Future<List<D>> selectAll<D>() =>
|
||||
_core.repo.selectAll(_tableFor<Table, D>());
|
||||
|
||||
@override
|
||||
Future<List<D>> selectWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.selectWhere(table, filter);
|
||||
Future<List<D>> selectWhere<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.selectWhere(_tableFor<T, D>(), filter);
|
||||
|
||||
@override
|
||||
Future<D?> selectFirst<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.selectFirst(table, filter);
|
||||
Future<D?> selectFirst<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.selectFirst(_tableFor<T, D>(), filter);
|
||||
|
||||
// ── 监听 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Stream<List<D>> watchAll<T extends Table, D>(TableInfo<T, D> table) =>
|
||||
_core.repo.watchAll(table);
|
||||
Stream<List<D>> watchAll<D>() =>
|
||||
_core.repo.watchAll(_tableFor<Table, D>());
|
||||
|
||||
@override
|
||||
Stream<List<D>> watchWhere<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.watchWhere(table, filter);
|
||||
Stream<List<D>> watchWhere<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.watchWhere(_tableFor<T, D>(), filter);
|
||||
|
||||
@override
|
||||
Stream<D?> watchFirst<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.watchFirst(table, filter);
|
||||
Stream<D?> watchFirst<D, T extends Table>(
|
||||
Expression<bool> Function(T) filter,
|
||||
) =>
|
||||
_core.repo.watchFirst(_tableFor<T, D>(), filter);
|
||||
|
||||
// ── 原始 SQL ─────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -120,9 +120,8 @@ class StorageSdkApiImpl implements StorageSdkApi, StorageSdkLifecycle {
|
||||
// ── 统计 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<int> count<T extends Table, D>(
|
||||
TableInfo<T, D> table, {
|
||||
Future<int> count<D, T extends Table>({
|
||||
Expression<bool> Function(T)? filter,
|
||||
}) =>
|
||||
_core.repo.count(table, filter: filter);
|
||||
}
|
||||
_core.repo.count(_tableFor<T, D>(), filter: filter);
|
||||
}
|
||||
@@ -8,12 +8,15 @@ import 'storage_sdk_api_impl.dart';
|
||||
|
||||
/// SDK 依赖装配入口。
|
||||
///
|
||||
/// 调用方传入数据库工厂,SDK 负责连接生命周期和 CRUD 机制。
|
||||
/// 调用方传入数据库工厂和表注册表,SDK 负责连接生命周期和 CRUD 机制。
|
||||
///
|
||||
/// 示例(im_app 的 DI 层):
|
||||
/// ```dart
|
||||
/// StorageSdkWiring.build(
|
||||
/// databaseFactory: (executor) => AppDatabase(executor),
|
||||
/// tableRegistry: (db) => {
|
||||
/// User: (db as AppDatabase).users,
|
||||
/// },
|
||||
/// );
|
||||
/// ```
|
||||
class StorageSdkWiring {
|
||||
@@ -21,10 +24,11 @@ class StorageSdkWiring {
|
||||
|
||||
static StorageSdkApi build({
|
||||
required GeneratedDatabase Function(QueryExecutor) databaseFactory,
|
||||
required Map<Type, TableInfo> Function(GeneratedDatabase) tableRegistry,
|
||||
}) {
|
||||
final dataSource = DatabaseDataSource(databaseFactory: databaseFactory);
|
||||
final repo = DatabaseRepositoryImpl(dataSource);
|
||||
final core = StorageSdkCore(dataSource: dataSource, repo: repo);
|
||||
return StorageSdkApiImpl(core: core);
|
||||
return StorageSdkApiImpl(core: core, tableRegistry: tableRegistry);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user