3 Commits

Author SHA1 Message Date
59fae2e7ae
fix(csvx): read human null words as absent, unrecognized values as false
BoolishTimestamp defaulted unrecognized non-empty values to true: any
word it does not understand (a misspelling, "disabled", "banana")
behaved as on. Unrecognized values are now valid+false with the error
retained so callers can apply their own policy, and "disabled"/"disable"
are no longer true-like.

Both bool types now read the human "not supplied" set through one shared
isBoolNull sentinel: empty/whitespace-only, the exact PG dump sentinel
\N (case-sensitive), and the case-insensitive words null, \null, none,
unknown. Bool previously reached absent only by ParseBool failing; it
now matches BoolishTimestamp explicitly. Free-text types must not reuse
this set: most of these words are legitimate values there.
2026-10-23 23:00:57 -06:00
1753bd73d0
fix(csvx): skip blank records in ParseCSV, including before the header
Human-maintained sources (e.g. Google Sheets exports) routinely carry
stray blank rows. A blank row above the header was taken as the header,
so every data row decoded to zero values; blank data rows decoded as
empty records.

ParseCSV now wraps the stream in a streaming csvutil.Reader (skipBlanks)
that drops records whose cells are all empty or whitespace-only. Records
decode one at a time with a single record buffered; delimiter and
ragged-row behavior are unchanged, and all-blank input yields nil, nil.
2026-10-23 22:51:36 -06:00
ca6e271f66
feat: add database/{csvx,rowsync,csvdb,pgdb,sheetsdb} 2026-09-16 16:20:08 -06:00