Skip to content

Formbase 0.14.1

Choose a tag to compare

@github-actions github-actions released this 30 Sep 13:23
· 37 commits to main since this release

Pairs with MorphDB 0.14.x. Fixes for durable declarations: a declaration can no longer destroy the raw
documents of a single SQLite file, and the durable stores keep what a declaration says.

Added

  • DeclaredTableName — the rules every declaration writer applies before storing (IsReserved, Same,
    EnsureDeclarable, EnsureUnclaimed), and TableNameInUseException, raised when a declaration names a
    table another form type already projects into. Over HTTP it answers 409 /problems/table-name-in-use.

Fixed

  • A declaration can no longer name a table in the engine's fb_ namespace. On a single SQLite file, which
    keeps the raw documents, projection state and declarations beside the projected tables, a form type
    declared into fb_raw_documents replaced the raw table on its first projection — every document of
    every form type in the file was lost — and fb_field_hints or fb_projection_state broke the file the
    same way. InMemoryFieldHintSource.Declare, SqliteFieldHintSource.DeclareAsync and
    PostgresFieldHintSource.DeclareAsync now throw ArgumentException for a blank or fb_ table name, the
    host answers 400 /problems/invalid-declaration, and the SQLite projection store refuses to build or
    drop an fb_ table, so a declaration stored before this check still cannot reach one.

  • Two form types can no longer be declared into one table. Each rebuilt the table from its own documents,
    so a query of either read whichever projected last. The three declaration writers refuse the second
    (names compared ignoring case) with TableNameInUseException, atomically with the write; redeclaring a
    form type into its own table is unaffected. Declarations already stored that share a table keep
    projecting as before, but neither can be redeclared into that table until the other moves.

  • The durable declaration stores (SqliteFieldHintSource, PostgresFieldHintSource) kept only a
    declaration's table and fields: every declaration read back as version 1 with no relations. On the
    durable host the second replacement of a form type was therefore refused as a version conflict, and
    declared relations were gone after a restart — so a child relation declared through that host never
    reached MorphDB as a relation. Both stores now keep DeclarationVersion and
    Relations; a table written by an earlier version is upgraded in place on first use, and the
    declarations in it read back as version 1 with no relations — what they were stored as.
    Versions and relations declared before this release were never stored, so an upgraded store reads
    those declarations as version 1 with no relations until they are declared again (on the host, send
    expectedDeclarationVersion: 1 for that one replacement).

  • A form type stored as JSON — the target of a bound field inside a durable declaration — read back as
    the empty default, because FormTypeRef could be written but not read. On the SQLite and PostgreSQL
    stores a form type with a bound field (Snapshot or Reference with a Target) therefore could not be
    projected at all: resolving the target's table failed with "Value must be set" — and on the durable
    host, declaring one answered 500. It now reads back as
    the form type it was, including from declarations already on disk, so those form types project
    without being declared again.

Changed

  • FormTypeRef serializes as its identifier string ("work-order") rather than as an object
    ({"Value":"work-order"}); both forms are read.
  • A document skipped because an array arrived for a Text column is told both ways out: declare the column
    as Jsonb to keep the array as one value, or, when its items are rows of their own (a repeated section),
    append each item as a document of its own form type — projection does not split an array into rows.
    The skip used to name Jsonb only, which for a repeated section keeps every row in one column.