SqlProjection<R> constructor

SqlProjection<R>({
  1. required Iterable<SqlSelection<Object?>> columns,
  2. required R decode(
    1. SqlProjectionRow row
    ),
})

Creates a projection whose columns define the SQL result order.

The decoder reads those same selection objects through SqlProjectionRow.read, so application fields never depend on numeric result positions.

Implementation

factory SqlProjection({
  required Iterable<SqlSelection<Object?>> columns,
  required R Function(SqlProjectionRow row) decode,
}) {
  final copied = List<SqlSelection<Object?>>.unmodifiable(columns);
  if (copied.isEmpty) {
    throw ArgumentError('A SQL projection requires at least one column.');
  }
  for (final (index, selection) in copied.indexed) {
    for (var previous = 0; previous < index; previous++) {
      if (identical(copied[previous], selection)) {
        throw ArgumentError(
          'Selection "${selection._resultColumn.name}" is used more than '
          'once in one SQL projection. Create a distinct alias for each '
          'result position.',
        );
      }
    }
  }
  return SqlProjection<R>._(copied, decode);
}