Add `pipekit export` / `pipekit apply` (pipekit/config_io.py) to serialise the DB's config — drivers, connections, modules (+ columns, watermarks, hooks), groups, schedules — to a git-trackable text tree under config/, and rehydrate it. SQLite stays runtime state; definitions become diffable/reviewable/ revertible. - config only: run_log/group_run/settings and per-run state columns excluded - name-keyed refs (portable across databases); source_query in .sql sidecars; columns as real JSON arrays for line-by-line diffs - newline-normalised so CRLF-vs-LF is never a spurious change - apply is create/update by name; child collections fully synced; top-level deletes gated behind --prune; --dry-run prints the plan - round-trip is identity (export -> apply --dry-run == nothing to do) Commits the current config/ as the first baseline, capturing the freshly populated columns_json for rm00101/rm00301/iv00101. Documented in SPEC.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
31 lines
1.7 KiB
SQL
31 lines
1.7 KiB
SQL
--source-side extract for cms.terms (pipekit CMS module)
|
|
--CMS terms live in the generic CODE table (A2 = 'NN'); the structured attributes are
|
|
--packed into the fixed-width CHAR column A215 at fixed byte offsets. Parse them HERE on
|
|
--DB2 where A215 is intact -- do NOT sync raw A215 and parse in Postgres: the transfer
|
|
--strips leading spaces on discount-bearing rows, which shifts every offset.
|
|
--offsets verified against the working query in sql/db2/CMS/AR/terms/Terms Codes.sql
|
|
--REPLACE(...,' ','0') guards each numeric field: unpopulated term types leave those
|
|
--positions blank, and a bare INT()/FLOAT() over a space would fail the whole extract.
|
|
SELECT
|
|
LTRIM(RTRIM(A9)) AS term
|
|
,LTRIM(RTRIM(A30)) AS descr
|
|
--discount % offered (e.g. 1.00 = 1%); A215 pos 102-105, scaled by 10000
|
|
,ROUND(FLOAT(REPLACE(SUBSTR(A215,102,4),' ','0')) / FLOAT(10000),2) AS disc_pct
|
|
--days within which the discount may be taken; A215 pos 84-86
|
|
,INT(REPLACE(SUBSTR(A215,84,3),' ','0')) AS disc_days
|
|
--net pay days; A215 pos 64-66
|
|
,INT(REPLACE(SUBSTR(A215,64,3),' ','0')) AS pay_days
|
|
--pay percent (rarely used split-term %); A215 pos 10-12
|
|
,FLOAT(REPLACE(SUBSTR(A215,10,3),' ','0')) AS pay_perc
|
|
--fixed pay date (seasonal/dated terms): A215 pos 28-33 packed MMDDYY -> YYYY-MM-DD
|
|
--emitted as ISO text (null when the date field is zero) so a malformed packed value
|
|
--cannot fail the extract; cast to date in Postgres on read
|
|
,CASE
|
|
WHEN INT(REPLACE(SUBSTR(A215,28,6),' ','0')) = 0 THEN CAST(NULL AS CHAR(10))
|
|
ELSE '20' || SUBSTR(A215,32,2) || '-' || SUBSTR(A215,28,2) || '-' || SUBSTR(A215,30,2)
|
|
END AS pay_date
|
|
FROM
|
|
LGDAT.CODE
|
|
WHERE
|
|
A2 = 'NN'
|