createOrFirst method

Future<TRow> createOrFirst(
  1. MssqlCondition where,
  2. TRow build()
)

Tries the insert first, then reads the winner after error 2601 or 2627.

The conflicting unique index cannot be identified reliably; prefer getOrCreate when the expected index is known.

Implementation

Future<TRow> createOrFirst(
  MssqlCondition where,
  TRow Function() build,
) async {
  try {
    return await insert(build());
  } on MssqlException catch (error) {
    if (error.code != 2601 && error.code != 2627) rethrow;
    if (sessionIsDoomed(session)) {
      throw MssqlUniqueConflictException(
        table: binding.qualifiedName,
        indexName: duplicateKeyName(error.message) ?? '(unknown)',
        reason:
            'the insert collided and the transaction is doomed, so the '
            'winning row cannot be read back. Roll it back and retry.',
      );
    }
    final existing = await firstWhere(where);
    if (existing != null) return existing;
    rethrow;
  }
}