A generated module referred to a SQL and report API that had never been
written on the .NET side: SQL.*, ASqlCursor, ASqlBinding, ASqlResult,
ASqlException, sqlca, BaseFGLReport, and the aggCount/aggSum family.
Compilation stopped at the first missing type, which hid the rest - so
what looked like two errors was ninety-one once the first two were
stubbed out.
Runtime, all built on the existing FglSql/FglCursor/FglRow layer:
ASqlBinding an ordered value list - the generator uses the same
construct for SQL host variables, DISPLAY and INPUT
ASqlResult one row, with GetData in both the by-ordinal and the
out-parameter form the generator emits
ASqlCursor a declared cursor, with the four SCROLL/WITH HOLD
combinations and the insert cursor
ASql the throwing face of FglSql: generated code wraps every
statement in a try/catch built from the WHENEVER state,
which only works if the operation raises
BaseFGLReport the page engine, driven through events rather than
inheritance so one module can declare several reports
agg* COUNT, SUM, AVG, MIN, MAX and PERCENT
SQL and sqlca are instance properties on FglModule rather than statics,
so the connection and status area stay on the session and two programs
can run in one process.
Generator fixes found while doing it:
- DECLARE SCROLL CURSOR WITH HOLD emitted ScrollCursor and plain
SCROLL CURSOR emitted ScrollCursorWithHold - the two branches were
swapped. The non-scroll branch below was already right.
- PAGENO and LINENO were emitted bare, referring to identifiers that
were never declared. They only mean anything inside a report, so
they now name the report's driver.
- USING emitted a bare Using(), unreachable from a nested report
class; it now lowers to the runtime's formatter, which also grew a
date-mask path since USING applies to DATE as well as to numbers.
- START REPORT ... WITH PAGE LENGTH / MARGINS lowered to setter calls
on the report object that were never emitted. They are now, and
they ignore the -1 the generator passes for an option the source
did not give - otherwise a report that set margins in its OUTPUT
section had them wiped the moment it started.
- WITH TOP OF PAGE called setTopMargin. Copy-paste.
Two page-layout details came out of diffing against the C runtime
rather than from reading it: the page trailer sits against the bottom
margin rather than directly under the last body line, and its height
has to be measured before the first page is laid out or the body takes
one row too many and the break lands in the wrong place. The trailer is
run into a buffer for both.
A 4GL report - page header, ON EVERY ROW, PAGE TRAILER with PAGENO, ON
LAST ROW with COUNT(*) and SUM(), USING masks, margins and page length
- now produces byte-identical output through both toolchains across
three pages, and is added to the end-to-end probe as report.4gl.
Fidelity: 27 semantics, 8 UI, 30 USING, the 66-line report, and 5
end-to-end programs all agree with C. 203 runtime tests pass.