restore method

Future<DVRecord> restore(
  1. Object id, {
  2. String? actor,
  3. String? tenant,
})

Restores a soft-deleted record.

Refused rather than forced when a live record holds one of its unique fields, because the alternative is two live rows claiming one value.

Implementation

Future<DVRecord> restore(Object id, {String? actor, String? tenant}) async {
  tenant = _tenant(tenant);
  final DVRecord? current = await read(id, withDeleted: true);
  if (current == null) {
    throw StateError('$table[$id] does not exist, so it cannot be restored.');
  }
  if (current.deletedAt == null) return current;

  final Set<String> taken = <String>{};
  for (final String field in unique) {
    final Object? value = current.values[field];
    if (value == null) continue;
    final List<Map<String, Object?>> holders = await database.query(
      'SELECT $key FROM $table WHERE $field = ? AND $deletedColumn IS NULL'
      '$_scopeAnd',
      <Object?>[value, ..._scopeParams],
    );
    if (holders.any((Map<String, Object?> row) => !_same(row[key], id))) {
      taken.add(field);
    }
  }
  if (taken.isNotEmpty) {
    throw DVRestoreConflictError(table: table, key: id, fields: taken);
  }

  return _update(current, current.values,
      deletedAt: null, actor: actor, tenant: tenant, restored: true);
}