parseDataType function
Parse a raw type token using SQLite's affinity rules. Unknown / empty declarations don't throw — they get NUMERIC affinity (or BLOB when completely empty), matching what real-world DDL relies on.
Implementation
DataType parseDataType(String s) {
final low = s.toLowerCase();
if (low.isEmpty) return DataType.blob;
// MySQL datetime types are stored as ISO-8601 TEXT (YEAR as INTEGER).
// Listed before the "contains int" rule so DATETIME / TIMESTAMP do
// not accidentally hit INTEGER via the substring 'int' in 'int'erval-
// free names. (They don't contain 'int' today, but be defensive.)
if (low == 'date' ||
low == 'datetime' ||
low == 'timestamp' ||
low == 'time') {
return DataType.text;
}
if (low == 'year') return DataType.integer;
// 1. Contains "INT" -> INTEGER (catches INT, INTEGER, BIGINT, SMALLINT…)
if (low.contains('int')) return DataType.integer;
// 2. Contains TEXT/CHAR/CLOB -> TEXT.
if (low.contains('char') ||
low.contains('clob') ||
low.contains('text') ||
low == 'string' ||
low == 'varchar') {
return DataType.text;
}
// 3. Contains BLOB -> BLOB.
if (low.contains('blob')) return DataType.blob;
// 4. Contains REAL/FLOA/DOUB -> REAL.
if (low.contains('real') || low.contains('floa') || low.contains('doub')) {
return DataType.real;
}
// 5. BOOLEAN keeps a strict boolean affinity (ours, not SQLite's).
if (low == 'bool' || low == 'boolean') return DataType.boolean;
// 6. ANY (STRICT escape hatch).
if (low == 'any') return DataType.any;
// 7. Default per SQLite affinity rule 5 — NUMERIC.
return DataType.numeric;
}