coerce function

Object? coerce(
  1. Object? value,
  2. DataType type
)

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;
  }
}