addFieldDefs method
Implementation
@override
void addFieldDefs(TSQLCursor cursor, TFieldDefs fieldDefs) {
final c = cursor as TWapCursor;
// @@@ Type inference: the gateway returns JSON rows with no field-type metadata,
// @@@ so every row is scanned and the type is decided from the first non-null value; an all-null column is treated as
// @@@ ftString. A string field's size is set to the actual maximum length seen (at least 255).
if (c.rows.isEmpty) {
// @@@ An empty result set: if there's columns metadata, builds ftString fields (type unknown,
// @@@ uniformly treated as strings — an empty set never actually reads values anyway, what matters is that the field exists);
// @@@ without it, fieldDefs stays empty (a backend limitation)
final cols = c.columns;
if (cols != null) {
var no = 1;
for (final n in cols) {
addFieldDef(fieldDefs, no, n, TFieldType.ftString, 255, 0,
false, false, false);
no++;
}
}
return;
}
final names = c.rows.first.keys.toList();
var fieldNo = 1;
for (final n in names) {
dynamic sample;
for (final row in c.rows) {
if (row[n] != null) {
sample = row[n];
break;
}
}
TFieldType ft;
var size = 0;
if (sample == null) {
ft = TFieldType.ftString;
size = 255;
} else if (sample is int) {
// @@@ A Dart-web trap: JS only has a `number` type, so `15000.0 is int` would
// @@@ return true. If ftInteger were inferred from this, a subsequently-stored value with a decimal (like
// @@@ 12345.67) would get rounded to 12345 by TLongintField. The pragmatic solution:
// @@@ always infer ftFloat for numeric fields (it can losslessly hold integer values too); when integer
// @@@ semantics are needed, the caller can convert via asInteger when reading it.
// @@@ (On native platforms, an int also goes through this same ftFloat branch, so the behavior is consistent)
ft = TFieldType.ftFloat;
} else if (sample is double) {
ft = TFieldType.ftFloat;
} else if (sample is bool) {
ft = TFieldType.ftBoolean;
} else if (sample is DateTime) {
ft = TFieldType.ftDateTime;
} else if (sample is Uint8List) {
ft = TFieldType.ftBlob;
size = 0;
} else {
ft = TFieldType.ftString;
var maxLen = 0;
for (final row in c.rows) {
final v = row[n];
if (v != null && '$v'.length > maxLen) maxLen = '$v'.length;
}
size = maxLen < 255 ? 255 : maxLen;
}
addFieldDef(fieldDefs, fieldNo, n, ft, size, 0, false, false, false);
fieldNo++;
}
}