store, ipc: type the routine status, defend the framing with tests (V-410)
Two review threads from PR 4, and the answer to the third. The routine status was a bare string with its legal set in a comment. Nothing caught a typo at compile time, nothing enumerated the set for a test, and a bad value surfaced as a /routines row that neither accepts nor dismisses. It is a RoutineStatus now, with the three constants, a RoutineStatuses slice as the single source of truth, and Valid(). Listing by an unknown status is refused with ErrRoutineStatus instead of answering "no rows", which is what a correct query says about an empty table. A round-trip test moves a routine into each state and reads it back, so a constant that drifts from the inline SQL fails loudly. The hand-rolled framing stays, and frame.go now says why: ninety lines, readable with socat, and every standard replacement brings schema machinery this boundary does not want. What was wrong was inheriting it untested. frame_test.go covers the paths a real socket produces and the round-trip test never does — truncated header, truncated body, one byte per Read, two frames back to back, and a non-JSON body. Empty input is the only EOF. The unanswered question in the same file is answered in place: a routine object stays a local string, not a Nexus ref, because nothing acts on it. It is the word he used, replayed back to him, compared only against itself for the UNIQUE key. Canonical refs arrive if a routine ever drives a Hexis call, which is V-272. The mood enum has the same shape and is not done here: it is spelled in the GBNF grammar, three prompts and the parse, so it is its own change.
This commit is contained in:
@@ -36,6 +36,13 @@ const maxFrame = 4 << 20
|
||||
// (we read the length but not the body), so the caller must close it.
|
||||
var ErrFrameTooLarge = errors.New("ipc: frame too large")
|
||||
|
||||
// The framing is hand-rolled and it stays that way (Vikunja #410): ninety
|
||||
// lines, readable on the wire with socat, and every standard replacement
|
||||
// brings schema machinery this boundary does not want. The condition is that
|
||||
// it is defended by tests rather than inherited untested — truncated header,
|
||||
// truncated body, partial reads, frame boundaries and a non-JSON body all
|
||||
// live in frame_test.go.
|
||||
//
|
||||
// writeFrame encodes v as JSON and frames it as a 4-byte big-endian length
|
||||
// prefix + body. length-prefixed JSON (not a tighter binary schema) is the
|
||||
// deferred-but-picked wire format: debuggable with `socat`/`nc`, trivial to
|
||||
|
||||
Reference in New Issue
Block a user