feat: Add support for the upsert and upsertRow ORM methods (#94)
This commit is contained in:
parent
c6a873d04c
commit
467df68a69
1 changed files with 796 additions and 19 deletions
|
|
@ -11,7 +11,15 @@ import 'package:serverpod_offline_sync_test_client/serverpod_offline_sync_test_c
|
|||
|
||||
import 'tables.dart';
|
||||
|
||||
enum Operation { select, insert, update, delete }
|
||||
enum Operation { select, insert, update, upsertInsert, upsertUpdate, delete }
|
||||
|
||||
extension OperationLabel on Operation {
|
||||
String get label => switch (this) {
|
||||
Operation.upsertInsert => 'upsert (insert)',
|
||||
Operation.upsertUpdate => 'upsert (update)',
|
||||
_ => name,
|
||||
};
|
||||
}
|
||||
|
||||
enum StorageStage { insert, update, delete }
|
||||
|
||||
|
|
@ -175,6 +183,74 @@ class TypesTableBenchmark extends AsyncBenchmarkBase {
|
|||
}
|
||||
}
|
||||
|
||||
/// Upserts a batch of updated copies of the seeded rows plus fresh rows
|
||||
/// without ids up to [rowCount], so the seeded count set by [_prepareCycle]
|
||||
/// determines the conflict-update vs insert mix.
|
||||
Future<void> _upsertTypes() async {
|
||||
final baseTimestamp = DateTime.now();
|
||||
final updated = _seededRows.map((row) {
|
||||
final i = _valueSeq++;
|
||||
return row.copyWith(
|
||||
aBool: i.isEven,
|
||||
aDateTime: baseTimestamp.add(Duration(seconds: i)),
|
||||
aText: 'Text $i',
|
||||
anInt: i,
|
||||
anInt64: BigInt.from(i),
|
||||
aReal: i.toDouble(),
|
||||
aBlob: _emptyBlob,
|
||||
optionalUuid: const Uuid().v7obj(),
|
||||
);
|
||||
}).toList();
|
||||
|
||||
final freshCount = rowCount - updated.length;
|
||||
final start = _valueSeq;
|
||||
_valueSeq += freshCount;
|
||||
final batch = [
|
||||
...updated,
|
||||
for (var j = 0; j < freshCount; j++) _createTypesRow(start + j, baseTimestamp),
|
||||
];
|
||||
|
||||
if (crdtEnabled) {
|
||||
_seededRows = await _crdtSession!.db.transactionForUser(
|
||||
_userId,
|
||||
(tx) async {
|
||||
return Types.db.upsert(
|
||||
_crdtSession!,
|
||||
batch,
|
||||
conflictColumns: (t) => [t.id],
|
||||
updateColumns: (t) => [
|
||||
t.aBool,
|
||||
t.aDateTime,
|
||||
t.aText,
|
||||
t.anInt,
|
||||
t.anInt64,
|
||||
t.aReal,
|
||||
t.aBlob,
|
||||
t.optionalUuid,
|
||||
],
|
||||
transaction: tx,
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
_seededRows = await Types.db.upsert(
|
||||
_plainSession,
|
||||
batch,
|
||||
conflictColumns: (t) => [t.id],
|
||||
updateColumns: (t) => [
|
||||
t.aBool,
|
||||
t.aDateTime,
|
||||
t.aText,
|
||||
t.anInt,
|
||||
t.anInt64,
|
||||
t.aReal,
|
||||
t.aBlob,
|
||||
t.optionalUuid,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Types>> _selectTypes() async {
|
||||
final rows = await Types.db.find(crdtEnabled ? _crdtSession! : _plainSession);
|
||||
if (rows.length != rowCount) {
|
||||
|
|
@ -228,6 +304,11 @@ class TypesTableBenchmark extends AsyncBenchmarkBase {
|
|||
case Operation.update:
|
||||
_seededRows = await _insertTypes(rowCount);
|
||||
return;
|
||||
case Operation.upsertInsert:
|
||||
return;
|
||||
case Operation.upsertUpdate:
|
||||
_seededRows = await _insertTypes(rowCount);
|
||||
return;
|
||||
case Operation.delete:
|
||||
_seededRows = await _insertTypes(rowCount);
|
||||
return;
|
||||
|
|
@ -305,6 +386,11 @@ class TypesTableBenchmark extends AsyncBenchmarkBase {
|
|||
await _updateTypesInPlace();
|
||||
_lastRowsCount = _seededRows.length;
|
||||
return;
|
||||
case Operation.upsertInsert:
|
||||
case Operation.upsertUpdate:
|
||||
await _upsertTypes();
|
||||
_lastRowsCount = _seededRows.length;
|
||||
return;
|
||||
case Operation.delete:
|
||||
await _deleteTypes(_seededRows);
|
||||
_seededRows = [];
|
||||
|
|
|
|||
Loading…
Reference in a new issue