MssqlTableBinding<TRow> constructor
MssqlTableBinding<TRow> ({
- required String schema,
- required String table,
- required List<
MssqlBoundColumn> columns, - required TRow fromRow(
- MssqlRow row
- required Map<
String, Object?> toColumns(- TRow row
- required Object? readColumn(
- TRow row,
- String column
- TRow applyIdentity(
- TRow row,
- Object? identity
- TRow applyRelations()?,
- bool isRelationLoaded(
- TRow row,
- String name
- List<
String> primaryKey = const <String>[], - String? identityColumn,
- MssqlInsertStrategy insertStrategy = MssqlInsertStrategy.noKeyReadback,
- String schemaFingerprint = '',
- MssqlDecimalMode decimalMode = MssqlDecimalMode.exact,
- int apiVersion = MssqlApiVersion.current,
- MssqlSoftDelete? softDelete,
- MssqlTimestamps timestamps = const MssqlTimestamps(),
- List<
MssqlScope> scopes = const <MssqlScope>[],
Implementation
MssqlTableBinding({
required this.schema,
required this.table,
required List<MssqlBoundColumn> columns,
required this.fromRow,
required this.toColumns,
required this.readColumn,
this.applyIdentity,
this.applyRelations,
this.isRelationLoaded,
List<String> primaryKey = const <String>[],
this.identityColumn,
this.insertStrategy = MssqlInsertStrategy.noKeyReadback,
this.schemaFingerprint = '',
this.decimalMode = MssqlDecimalMode.exact,
this.apiVersion = MssqlApiVersion.current,
MssqlSoftDelete? softDelete,
MssqlTimestamps timestamps = const MssqlTimestamps(),
List<MssqlScope> scopes = const <MssqlScope>[],
}) : columns = List<MssqlBoundColumn>.unmodifiable(columns),
primaryKey = List<String>.unmodifiable(primaryKey),
scopes = List<MssqlScope>.unmodifiable(scopes),
// Convention columns are resolved to the schema's own spelling here,
// once, rather than at each place that reads them. Lookup is
// case-insensitive, so a configuration saying `deletedat` validates
// against `DeletedAt` — and then every predicate and assignment built
// from it has to say `DeletedAt` too, or the SQL breaks on a database
// with a case-sensitive collation.
softDelete = _canonicalSoftDelete(softDelete, columns),
timestamps = _canonicalTimestamps(timestamps, columns) {
for (final key in this.primaryKey) {
if (column(key) == null) {
throw ArgumentError.value(
key,
'primaryKey',
'Names a column $schema.$table does not have.',
);
}
}
// Validation reads the fields, not the parameters: those are the
// canonicalized values, and they are what every message should name.
final soft = this.softDelete;
_validateConventionColumn(soft?.column, 'softDelete');
if (soft != null) {
final softColumn = column(soft.column)!;
if (soft.deletedValue == null && !_storesServerClock(softColumn)) {
throw ArgumentError.value(
soft.column,
'softDelete',
'A timestamp soft-delete column must use a date/time SQL type.',
);
}
if (soft.aliveValue == null && !softColumn.nullable) {
throw ArgumentError.value(
soft.column,
'softDelete',
'A null-means-live soft-delete column must be nullable.',
);
}
if (soft.aliveValue != null && soft.deletedValue == null) {
throw ArgumentError.value(
soft.column,
'softDelete',
'A value-based soft-delete convention needs deletedValue.',
);
}
}
final stamps = this.timestamps;
_validateConventionColumn(stamps.createdColumn, 'timestamps.createdColumn');
_validateConventionColumn(stamps.updatedColumn, 'timestamps.updatedColumn');
for (final name in <String?>[stamps.createdColumn, stamps.updatedColumn]) {
if (name != null && !_storesServerClock(column(name)!)) {
throw ArgumentError.value(
name,
'timestamps',
'Timestamp columns must use a date/time SQL type.',
);
}
}
if (stamps.createdColumn != null &&
stamps.createdColumn!.toLowerCase() ==
stamps.updatedColumn?.toLowerCase()) {
throw ArgumentError.value(
stamps.createdColumn,
'timestamps',
'Created and updated timestamps must use different columns.',
);
}
if (!MssqlApiVersion.supports(apiVersion)) {
throw ArgumentError(
MssqlApiVersion.mismatchMessage(apiVersion, '$schema.$table'),
);
}
final softName = softDelete?.column.toLowerCase();
if (softName != null &&
(softName == timestamps.createdColumn?.toLowerCase() ||
softName == timestamps.updatedColumn?.toLowerCase())) {
throw ArgumentError.value(
softDelete!.column,
'softDelete',
'A soft-delete column cannot also be a timestamp column.',
);
}
final scopeNames = <String>{};
for (final scope in this.scopes) {
final name = scope.name.trim();
if (name.isEmpty) {
throw ArgumentError.value(
scope.name,
'scopes',
'A scope needs a name.',
);
}
if (!scopeNames.add(name)) {
throw ArgumentError.value(
scope.name,
'scopes',
'Scope names must be unique within $schema.$table.',
);
}
}
}