更新upsert
This commit is contained in:
@@ -282,8 +282,10 @@ class UserRepositoryImpl implements UserRepository {
|
||||
@override
|
||||
Future<void> insertOrReplaceUser(User user) async {
|
||||
if (user.requireUpsert) {
|
||||
await _storage.insertOrReplace<DriftUser>(_toCompanion(user));
|
||||
await upsertUser(user);
|
||||
}
|
||||
|
||||
await _storage.insertOrReplace<DriftUser>(_toCompanion(user));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -331,7 +333,9 @@ class UserRepositoryImpl implements UserRepository {
|
||||
///
|
||||
/// 内部委托给 [upsertUsers]。
|
||||
@override
|
||||
Future<void> upsertUser(User user) => upsertUsers([user]);
|
||||
Future<void> upsertUser(User user) async {
|
||||
await _storage.insertOnConflictUpdate<DriftUser>(_toPartialCompanion(user));
|
||||
}
|
||||
|
||||
/// 批量 upsert:不存在则插入,存在则仅更新非 null 字段。
|
||||
///
|
||||
@@ -343,16 +347,10 @@ class UserRepositoryImpl implements UserRepository {
|
||||
/// 适用场景:从服务端收到部分用户信息,不希望覆盖本地已有的其他字段。
|
||||
@override
|
||||
Future<void> upsertUsers(List<User> users) async {
|
||||
await _storage.transaction(() async {
|
||||
for (final user in users) {
|
||||
await _storage.insert<DriftUser>(_toCompanion(user));
|
||||
await _storage.updateWhere<DriftUser, $UsersTable>(
|
||||
_toPartialCompanion(user),
|
||||
(t) => t.uid.equals(user.uid),
|
||||
await _storage.batchInsertOnConflictUpdate<DriftUser>(
|
||||
users.map(_toPartialCompanion).toList(),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ── 删除 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -49,6 +49,30 @@ class DatabaseRepositoryImpl implements DatabaseRepository {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> insertOnConflictUpdate<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
) async {
|
||||
final db = _db;
|
||||
if (db == null) return;
|
||||
await db.into(table).insertOnConflictUpdate(companion);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> batchInsertOnConflictUpdate<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
List<Insertable<D>> companions,
|
||||
) async {
|
||||
final db = _db;
|
||||
if (db == null) return;
|
||||
await db.transaction(() async {
|
||||
for (final companion in companions) {
|
||||
await db.into(table).insertOnConflictUpdate(companion);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ── 更新 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
|
||||
@@ -13,7 +13,10 @@ import 'package:drift/drift.dart';
|
||||
abstract class DatabaseRepository {
|
||||
// ── 插入 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 插入或替换(主键冲突时覆盖)。
|
||||
/// 插入或替换(主键冲突时删除原行再插入)。
|
||||
///
|
||||
/// 注意:底层是 DELETE + INSERT,rowid 变更,触发 DELETE 级联。
|
||||
/// 如需原地更新,请使用 [insertOnConflictUpdate]。
|
||||
Future<void> insertOrReplace<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
@@ -25,12 +28,35 @@ abstract class DatabaseRepository {
|
||||
Insertable<D> companion,
|
||||
);
|
||||
|
||||
/// 批量插入或替换。
|
||||
/// 批量插入或替换(主键冲突时删除原行再插入)。
|
||||
///
|
||||
/// 注意:底层是 DELETE + INSERT,rowid 变更,触发 DELETE 级联。
|
||||
/// 如需原地更新,请使用 [batchInsertOnConflictUpdate]。
|
||||
Future<void> batchInsertOrReplace<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
List<Insertable<D>> companions,
|
||||
);
|
||||
|
||||
/// 插入,主键冲突时原地更新全部字段(INSERT ... ON CONFLICT DO UPDATE SET)。
|
||||
///
|
||||
/// 与 [insertOrReplace] 的区别:
|
||||
/// - [insertOrReplace] → DELETE + INSERT,rowid 变更,触发 DELETE 级联
|
||||
/// - [insertOnConflictUpdate] → 原地 UPDATE,rowid 不变,不触发 DELETE 级联
|
||||
///
|
||||
/// 适用场景:upsert 语义,且不希望影响依赖 rowid 的其他逻辑。
|
||||
Future<void> insertOnConflictUpdate<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
Insertable<D> companion,
|
||||
);
|
||||
|
||||
/// 批量插入,主键冲突时原地更新全部字段。
|
||||
///
|
||||
/// 与 [batchInsertOrReplace] 的区别同 [insertOnConflictUpdate]。
|
||||
Future<void> batchInsertOnConflictUpdate<T extends Table, D>(
|
||||
TableInfo<T, D> table,
|
||||
List<Insertable<D>> companions,
|
||||
);
|
||||
|
||||
// ── 更新 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 按条件更新。
|
||||
|
||||
@@ -79,7 +79,10 @@ abstract class StorageSdkApi {
|
||||
|
||||
// ── 插入 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 插入或替换(主键冲突时覆盖)。
|
||||
/// 插入或替换(主键冲突时删除原行再插入)。
|
||||
///
|
||||
/// 注意:底层是 DELETE + INSERT,会导致 rowid 变更,并触发 DELETE 级联。
|
||||
/// 如需原地更新,请使用 [insertOnConflictUpdate]。
|
||||
///
|
||||
/// 示例:
|
||||
/// ```dart
|
||||
@@ -92,9 +95,26 @@ abstract class StorageSdkApi {
|
||||
/// 插入或忽略(主键冲突时跳过)。
|
||||
Future<void> insert<D>(Insertable<D> companion);
|
||||
|
||||
/// 批量插入或替换。
|
||||
/// 批量插入或替换(主键冲突时删除原行再插入)。
|
||||
///
|
||||
/// 注意:底层是 DELETE + INSERT,rowid 变更,触发 DELETE 级联。
|
||||
/// 如需原地更新,请使用 [batchInsertOnConflictUpdate]。
|
||||
Future<void> batchInsertOrReplace<D>(List<Insertable<D>> companions);
|
||||
|
||||
/// 插入,主键冲突时原地更新全部字段(INSERT ... ON CONFLICT DO UPDATE SET)。
|
||||
///
|
||||
/// 与 [insertOrReplace] 的区别:
|
||||
/// - [insertOrReplace] → DELETE + INSERT,rowid 变更,触发 DELETE 级联
|
||||
/// - [insertOnConflictUpdate] → 原地 UPDATE,rowid 不变,不触发 DELETE 级联
|
||||
///
|
||||
/// 适用场景:upsert 语义,且不希望影响依赖 rowid 的其他逻辑。
|
||||
Future<void> insertOnConflictUpdate<D>(Insertable<D> companion);
|
||||
|
||||
/// 批量插入,主键冲突时原地更新全部字段。
|
||||
///
|
||||
/// 与 [batchInsertOrReplace] 的区别同 [insertOnConflictUpdate]。
|
||||
Future<void> batchInsertOnConflictUpdate<D>(List<Insertable<D>> companions);
|
||||
|
||||
// ── 更新 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/// 按条件更新。
|
||||
|
||||
@@ -67,6 +67,14 @@ class StorageSdkApiImpl implements StorageSdkApi, StorageSdkLifecycle {
|
||||
Future<void> batchInsertOrReplace<D>(List<Insertable<D>> companions) =>
|
||||
_core.repo.batchInsertOrReplace(_tableFor<Table, D>(), companions);
|
||||
|
||||
@override
|
||||
Future<void> insertOnConflictUpdate<D>(Insertable<D> companion) =>
|
||||
_core.repo.insertOnConflictUpdate(_tableFor<Table, D>(), companion);
|
||||
|
||||
@override
|
||||
Future<void> batchInsertOnConflictUpdate<D>(List<Insertable<D>> companions) =>
|
||||
_core.repo.batchInsertOnConflictUpdate(_tableFor<Table, D>(), companions);
|
||||
|
||||
// ── 更新 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user