updateMatching method

Future<int> updateMatching(
  1. List<MssqlCondition> where,
  2. MssqlWriteAssignments patch, {
  3. Object? expectedVersion,
  4. int? expectAffected,
})

Writes patch to every row matching where.

expectedVersion adds the rowversion token to the WHERE. Zero rows with a token is MssqlConcurrencyException. expectAffected runs the write through MssqlWriteEngine.guard.

Implementation

Future<int> updateMatching(
  List<MssqlCondition> where,
  MssqlWriteAssignments patch, {
  Object? expectedVersion,
  int? expectAffected,
}) async {
  _checkDecimalAgreement();
  if (where.isEmpty) {
    throw MssqlUnsafeWriteException(binding.qualifiedName, 'update');
  }
  final values = _stampUpdate(patch);
  if (values.isEmpty) {
    throw StateError(
      'Updating ${binding.qualifiedName} would write no columns.',
    );
  }
  final filters = <MssqlCondition>[...where];
  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.',
      );
    }
    filters.add(Col(rv.name).eq(rv.bind(version)));
  }
  final engine = await _engine();
  Future<MssqlWriteOutcome> write(MssqlWriteEngine<TRow> e) => e.updateWhere(
    operation: 'update',
    values: values,
    where: filters,
    scopes: _scopeConditions,
  );
  final outcome = expectAffected == null
      ? await write(engine)
      : await engine.guard(
          operation: 'update',
          expected: expectAffected,
          write: write,
        );
  if (version != null && outcome.affectedRows == 0) {
    throw MssqlConcurrencyException(
      table: binding.qualifiedName,
      operation: 'update',
    );
  }
  return outcome.affectedRows;
}