coerce function
Coerce a raw value (from parser literal or client JSON) into the storage
representation for type, or throw FormatException if it cannot.
Implementation
Object? coerce(Object? value, DataType type) {
if (value == null) return null;
switch (type) {
case DataType.integer:
if (value is int) return value;
if (value is double && value == value.truncateToDouble()) {
return value.toInt();
}
if (value is bool) return value ? 1 : 0;
if (value is String) {
final v = int.tryParse(value);
if (v != null) return v;
}
throw FormatException('Cannot coerce $value to INTEGER');
case DataType.real:
if (value is num) return value.toDouble();
if (value is String) {
final v = double.tryParse(value);
if (v != null) return v;
}
throw FormatException('Cannot coerce $value to REAL');
case DataType.text:
return value.toString();
case DataType.boolean:
if (value is bool) return value;
if (value is num) return value != 0;
if (value is String) {
final s = value.toLowerCase();
if (s == 'true' || s == '1') return true;
if (s == 'false' || s == '0') return false;
}
throw FormatException('Cannot coerce $value to BOOLEAN');
case DataType.blob:
if (value is Uint8List) return value;
if (value is List<int>) return Uint8List.fromList(value);
if (value is String) return Uint8List.fromList(utf8.encode(value));
throw FormatException('Cannot coerce $value to BLOB');
case DataType.numeric:
// SQLite NUMERIC affinity: prefer INTEGER, then REAL, otherwise the
// value is left in whatever form it arrived in (TEXT or BLOB).
if (value is int) return value;
if (value is double) {
if (value.isFinite && value == value.truncateToDouble()) {
return value.toInt();
}
return value;
}
if (value is bool) return value ? 1 : 0;
if (value is String) {
final s = value.trim();
final i = int.tryParse(s);
if (i != null) return i;
final d = double.tryParse(s);
if (d != null) {
if (d.isFinite && d == d.truncateToDouble()) return d.toInt();
return d;
}
return value; // keep as TEXT — SQLite NUMERIC keeps non-numeric text
}
return value;
case DataType.any:
// STRICT ANY columns store the value verbatim.
return value;
}
}