updatePatch method

Future<TRow> updatePatch(
  1. TKey key,
  2. MssqlWriteAssignments patch, {
  3. Object? expectedVersion,
})

Applies patch, optionally guarded by the last-read expectedVersion.

A guarded write matching no rows throws MssqlConcurrencyException. The argument is rejected when the table has no rowversion column.

Implementation

Future<TRow> updatePatch(
  TKey key,
  MssqlWriteAssignments patch, {
  Object? expectedVersion,
}) async {
  _requireKey('updatePatch');
  _checkDecimalAgreement();
  final values = _stampUpdate(patch);
  if (values.isEmpty) {
    throw StateError(
      'Updating ${binding.qualifiedName} would write no columns.',
    );
  }
  final where = <MssqlCondition>[_keyCondition(key)];
  final version = expectedVersion;
  if (version != null) {
    final rv = binding.rowVersionColumn;
    if (rv == null) {
      throw StateError(
        '${binding.qualifiedName} has no rowversion column, so '
        'expectedVersion cannot guard the write. Use update() for an '
        'unguarded full-row write.',
      );
    }
    where.add(Col(rv.name).eq(rv.bind(version)));
  }
  final engine = await _engine();
  final outcome = await engine.updateWhere(
    operation: 'updatePatch',
    values: values,
    where: where,
    scopes: _scopeConditions,
    readRows: true,
  );
  if (version != null && outcome.affectedRows == 0) {
    throw MssqlConcurrencyException(
      table: binding.qualifiedName,
      operation: 'updatePatch',
      key: key,
    );
  }
  if (outcome.rows.isNotEmpty) {
    return binding.fromRow(outcome.rows.first);
  }
  final row = await findById(key);
  if (row != null) return row;
  throw MssqlRowNotFoundException(binding.qualifiedName, key);
}