Formbase 0.16.0
Pairs with MorphDB 0.14.x. An optional field whose value cannot be converted no longer drops its
document, and a timestamp without an offset reads the same on every host. Breaking for code that
implements IProjectionState.
Changed
- An optional field whose value cannot be converted empties that field instead of dropping the
document. A nullable column holding a value its type cannot take ("next week"in aTimestamp, an
array in aText) used to skip the whole document, so one bad value hid every other value it carried
from every query. The row now lands with that column empty, and the emptied field is recorded (see
Added). A required column that fails the same way still skips the document, as documented: the row
cannot stand without it. Re-projecting an existing store can therefore insert rows that were skipped
before.
Added
- Emptied fields are recorded like skipped documents.
ProjectionFieldSkip(document, field,
reason) for each optional field a run emptied: inProjectionResult.SkippedFields, recorded with the
run byIProjectionState(GetFieldSkipsAsync,FormbaseEngine.GetProjectionFieldSkipsAsync) so it
survives a restart, and replaced by the next run. They are counted neither inSkipped(the row
landed) nor inAbsentFieldCounts(the document did carry a value). Host:skippedFieldson the
projection run response,skippedFieldsandfieldCountonGET /formtypes/{type}/projection/skips,
andlastRun.skippedFieldCounton the projection status. - Breaking for
IProjectionStateimplementers:SetProjectedAsynctakes the field skips next to
the skips, andGetFieldSkipsAsyncis new. The SQLite and PostgreSQL adapters keep them in a table of
their own (fb_projection_field_skips/projection_field_skips), created on first use in an
existing store.
Fixed
- A timestamp written without an offset is read as UTC, not in the host's zone. A date alone
("2026-01-15") or a date and time with no zone projected to a different instant on every machine
that ran the projection — a date alone became the previous day east of Greenwich. Such a value is now
that moment in UTC, so a date alone is its UTC midnight and reads back as the date written. Query
filter values follow the same rule, so a filter written like the documents matches them. A value with
an offset keeps it, as before.