Both workarounds existed because Five was missing two features that
just landed upstream:
Five 7629f95 (variadic PValue) makes FUNCTION foo(...) / PValue()
actually return the caller's variadic args instead of the caller's
first LOCAL slot. AP_RPUTS / AP_ECHO can go back to their `( ... )`
signature now.
Five f3e0ffe (file-local STATIC FUNCTION) gives each .prg its own
namespace for `STATIC FUNCTION name`, so the seven duplicate
`STATIC FUNCTION fn_HGet` definitions across labdb's api/*.prg
files no longer collide. The sed-renamed unique names can revert
to the upstream definitions.
Files
app/bridge/bridge_request.prg ← cp from fivenode/native/
app/api/{device-status,record-detail,records-list,session-detail,
session-stats,sessions-list,session-export}.prg
← cp from fivenode/labdb/api/
fivenode-upstream is now byte-identical to fivenode_go's app/ copy
of those files. No more "// fivenode_go patch" comments, no more
file-prefix renames.
Verified end-to-end against the same live postgres@16 cluster:
/api/admin-stats.prg -> {"active_sessions":1,"devices":2,...}
/api/sessions-list.prg -> 2 rows w/ full session data
/api/admin-devices.prg -> 2 devices w/ api_key, created_at
/api/hello.prg -> hello (unchanged)
/ -> 200 text/html (static)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
53 lines
1.6 KiB
Plaintext
53 lines
1.6 KiB
Plaintext
// api/records-list.prg — Format records list (summary or full)
|
|
// ctx:
|
|
// session_id, total, fields ("summary"|"full")
|
|
// rows (JSON array of record rows)
|
|
FUNCTION Main()
|
|
LOCAL aRows, aOut, hRow, hOut, cFields, aChannels, hCh, aChOut
|
|
|
|
aRows := hb_jsonDecode(ctx_get("rows", "[]"))
|
|
cFields := ctx_get("fields", "summary")
|
|
IF ! HB_ISARRAY(aRows) ; aRows := {} ; ENDIF
|
|
|
|
aOut := {}
|
|
FOR EACH hRow IN aRows
|
|
hOut := { ;
|
|
"rowIndex" => fn_HGet(hRow, "row_index"), ;
|
|
"timestamp" => fn_HGet(hRow, "timestamp"), ;
|
|
"commandType" => fn_HGet(hRow, "command_type"), ;
|
|
"raaStatus" => fn_HGet(hRow, "raa_status") ;
|
|
}
|
|
IF cFields == "full"
|
|
hOut["sensor"] := fn_HGet(hRow, "sensor")
|
|
hOut["channels"] := fn_HGet(hRow, "channels")
|
|
ELSE
|
|
// Summary: keep only ch, peak, peakIdx
|
|
aChannels := fn_HGet(hRow, "channels")
|
|
aChOut := {}
|
|
IF HB_ISARRAY(aChannels)
|
|
FOR EACH hCh IN aChannels
|
|
IF HB_ISHASH(hCh)
|
|
AAdd(aChOut, { ;
|
|
"ch" => fn_HGet(hCh, "ch"), ;
|
|
"peak" => fn_HGet(hCh, "peak"), ;
|
|
"peakIdx" => fn_HGet(hCh, "peakIdx") ;
|
|
})
|
|
ENDIF
|
|
NEXT
|
|
ENDIF
|
|
hOut["channels"] := aChOut
|
|
ENDIF
|
|
AAdd(aOut, hOut)
|
|
NEXT
|
|
|
|
AP_JSONRESPONSE({ ;
|
|
"sessionId" => ctx_get("session_id", ""), ;
|
|
"total" => Val(ctx_get("total", "0")), ;
|
|
"records" => aOut ;
|
|
})
|
|
RETURN NIL
|
|
|
|
STATIC FUNCTION fn_HGet(h, k)
|
|
IF HB_ISHASH(h) .AND. hb_HHasKey(h, k) ; RETURN h[k] ; ENDIF
|
|
RETURN ""
|