Skip to content

Commit d64f31b

Browse files
Merge pull request #61 from tom-writes-code/add-wrapper
Add wrapper function to support notebooks
2 parents 6cdc1e0 + 69d2ebd commit d64f31b

36 files changed

Lines changed: 275 additions & 5 deletions

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,54 @@ replEquals('two plus two': 4: result);
129129
// Result: TEST-SUCCESS ✓
130130
```
131131

132+
## SQL Stored Procedure: `REPL_EXECUTE`
133+
134+
`REPL_EXECUTE` provides a single-call SQL interface for running RPG snippets
135+
programmatically — used by the [vscode-db2i](https://github.com/halcyon-tech/vscode-db2i)
136+
notebook extension, but available for any SQL caller.
137+
138+
**Signature:**
139+
140+
```sql
141+
CALL {lib}.REPL_EXECUTE(source, session_id)
142+
```
143+
144+
| Parameter | Type | Description |
145+
| ------------ | ------------- | -------------------------------------------- |
146+
| `source` | `CLOB(256K)` | RPG source code (lines separated by newline) |
147+
| `session_id` | `VARCHAR(28)` | Unique session identifier to isolate results |
148+
149+
**Returns:** A result set (via `DYNAMIC RESULT SETS 1`) with one row per result:
150+
151+
| Column | Type | Description |
152+
| -------------------- | --------------- | -------------------------------------------------- |
153+
| `LINE_NUMBER` | `DEC(4,0)` | Source line that produced the result |
154+
| `RESULT_NUMBER` | `DEC(4,0)` | Sequential result ID for the line |
155+
| `RESULT_DESCRIPTION` | `VARCHAR(1000)` | The result text |
156+
| `LOOP_COUNT` | `DEC(5,0)` | Loop iteration count |
157+
| `RESULT_TYPE` | `CHAR(32)` | `EVALUATION`, `TEST-SUCCESS`, `TEST-FAILURE`, etc. |
158+
159+
**Example:**
160+
161+
```sql
162+
CALL RPGLEREPL.REPL_EXECUTE(
163+
'dcl-s greeting char(20);
164+
greeting = ''Hello from RPG!'';
165+
replPrint(greeting);',
166+
'my-session-001'
167+
);
168+
```
169+
170+
**How it works:** The procedure parses the source into lines, inserts them into
171+
`REPLSRC` as a named snippet, runs the full REPL pipeline (generate → compile →
172+
run) via `QCMDEXC`, and returns matching rows from `REPLRSLT`. Source lines are
173+
cleaned up automatically; result rows persist tagged by session ID.
174+
175+
**Library list:** The caller's SQL job must have the RPGLE-REPL library in its
176+
library list (the vscode-db2i extension does this automatically via `ADDLIBLE`).
177+
If calling manually, run `ADDLIBLE {lib}` first or ensure the library is in your
178+
job's library list.
179+
132180
## Building from Source
133181

134182
This project uses **IBM TOBI** for builds. See [TOBI-MIGRATION.md](TOBI-MIGRATION.md) for the full

bnd/Rules.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ REPLLOAD.PGM: REPLLOAD.MODULE REPL_PSEU.SRVPGM
3333
REPLWRPR.PGM: REPLWRPR.MODULE REPL_CMPL.SRVPGM REPL_EVAL.SRVPGM REPL_GEN.SRVPGM REPL_HLPR.SRVPGM REPL_PSEU.SRVPGM REPL_USR.SRVPGM
3434

3535
REPLPRTR.PGM: REPLPRTR.MODULE REPL_PSEU.SRVPGM
36+
37+
REPLEXEC.PGM: REPLEXEC.MODULE REPL_CMPL.SRVPGM REPL_EVAL.SRVPGM REPL_GEN.SRVPGM REPL_HLPR.SRVPGM REPL_PSEU.SRVPGM REPL_USR.SRVPGM

cmd/REPL.CMDSRC

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
/* @version v3.1.0 */
12
cmd prompt('repl')

cmd/REPLPRTR.CMDSRC

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* @version v3.1.0 */
12
cmd prompt('repl result printer')
23

34
parm kwd(std) type(*char) len(1) prompt('stdout verbosity')

cmd/REPLWRPR.CMDSRC

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* @version v3.1.0 */
12
cmd prompt('repl wrapper')
23

34
parm kwd(lib) type(*char) len(10) prompt('source library') +

db/REPLEXEC.SQL

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
-- @version v3.1.0
2+
-- repl_execute: SQL stored procedure for notebook integration
3+
--
4+
-- This is self-contained. No external procedure registration needed.
5+
-- The RPG program REPLEXEC is called via QCMDEXC.
6+
7+
CREATE OR REPLACE PROCEDURE repl_execute (
8+
IN P_SOURCE CLOB(256K) CCSID 1208,
9+
IN P_SESSION_ID VARCHAR(28)
10+
)
11+
DYNAMIC RESULT SETS 1
12+
LANGUAGE SQL
13+
SET OPTION COMMIT = *NONE
14+
15+
BEGIN
16+
DECLARE v_snippetName CHAR(20) CCSID 37;
17+
DECLARE v_lineNum INT DEFAULT 1;
18+
DECLARE v_pos INT DEFAULT 1;
19+
DECLARE v_nextPos INT;
20+
DECLARE v_line VARCHAR(200) CCSID 37;
21+
DECLARE v_sourceLen INT;
22+
DECLARE v_cmd VARCHAR(200) CCSID 37;
23+
DECLARE v_source CLOB(256K) CCSID 37;
24+
DECLARE c_LF CHAR(1) CCSID 37 DEFAULT x'25';
25+
26+
-- Convert UTF-8 input to EBCDIC for table operations
27+
SET v_source = CAST(P_SOURCE AS CLOB(256K) CCSID 37);
28+
SET v_snippetName = LEFT(CAST(P_SESSION_ID AS VARCHAR(28) CCSID 37), 20);
29+
SET v_sourceLen = LENGTH(v_source);
30+
31+
-- Clear previous source for this snippet
32+
DELETE FROM replsrc WHERE save_name = v_snippetName;
33+
34+
-- Parse source into lines (split on EBCDIC LF x'25')
35+
IF v_sourceLen > 0 THEN
36+
WHILE v_pos <= v_sourceLen DO
37+
SET v_nextPos = LOCATE(c_LF, v_source, v_pos);
38+
39+
IF v_nextPos = 0 THEN
40+
-- Last line (no trailing newline)
41+
SET v_line = CAST(SUBSTRING(v_source, v_pos, v_sourceLen - v_pos + 1) AS VARCHAR(200));
42+
SET v_pos = v_sourceLen + 1;
43+
ELSE
44+
IF v_nextPos > v_pos THEN
45+
SET v_line = CAST(SUBSTRING(v_source, v_pos, v_nextPos - v_pos) AS VARCHAR(200));
46+
ELSE
47+
SET v_line = '';
48+
END IF;
49+
SET v_pos = v_nextPos + 1;
50+
END IF;
51+
52+
-- Strip trailing CR if present (handles CRLF)
53+
IF LENGTH(v_line) > 0
54+
AND SUBSTRING(v_line, LENGTH(v_line), 1) = x'0D' THEN
55+
SET v_line = LEFT(v_line, LENGTH(v_line) - 1);
56+
END IF;
57+
58+
INSERT INTO replsrc
59+
(session_id, line_number, code, save_name, owner, source_type)
60+
VALUES
61+
('', v_lineNum, v_line, v_snippetName,
62+
CURRENT_USER, 'mainline');
63+
64+
SET v_lineNum = v_lineNum + 1;
65+
END WHILE;
66+
END IF;
67+
68+
-- Call RPG pipeline runner via QCMDEXC (no procedure registration needed)
69+
SET v_cmd = 'CALL PGM(REPLEXEC) PARM(''' || REPLACE(v_snippetName, '''', '''''') || ''')';
70+
CALL QSYS2.QCMDEXC(v_cmd);
71+
72+
-- Tag results with external session ID
73+
UPDATE replrslt SET external_session_id = P_SESSION_ID
74+
WHERE session_id = (QSYS2.JOB_NAME)
75+
AND (external_session_id IS NULL OR external_session_id = '');
76+
77+
-- Return results
78+
BEGIN
79+
DECLARE c_results CURSOR WITH RETURN FOR
80+
SELECT line_number, result_number, result_description, loop_count, result_type
81+
FROM replrslt
82+
WHERE external_session_id = P_SESSION_ID
83+
ORDER BY line_number, result_number;
84+
85+
OPEN c_results;
86+
END;
87+
88+
-- Clean up source
89+
DELETE FROM replsrc WHERE save_name = v_snippetName;
90+
END;
91+
92+
COMMENT ON PROCEDURE repl_execute IS
93+
'Run RPG source through RPGLE-REPL and return results';

db/REPLRSLT.TABLE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
-- @version v3.1.0
12
CREATE OR REPLACE TABLE replrslt
23
(
34
--Primary Key

db/REPLSRC.TABLE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
-- @version v3.1.0
12
CREATE OR REPLACE TABLE replsrc
23
(
34
--Primary Key
@@ -7,7 +8,7 @@ CREATE OR REPLACE TABLE replsrc
78
--Columns
89
session_id VARCHAR(28),
910
line_number FOR COLUMN lineNumber DEC(6,0) NOT NULL,
10-
code VARCHAR(71) NOT NULL,
11+
code VARCHAR(200) NOT NULL,
1112
save_name char(20),
1213
last_update FOR COLUMN lastupdate TIMESTAMP,
1314
owner CHAR(10),

db/REPLVARS.TABLE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
-- @version v3.1.0
12
-- Table Definition
23
CREATE OR REPLACE TABLE replvars
34
(

db/Rules.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
REPLRSLT.SQL: REPLRSLT.TABLE
22
REPLSRC.SQL: REPLSRC.TABLE
33
REPLVARS.SQL: REPLVARS.TABLE
4+
REPLEXEC.SQL: REPLEXEC.SQL

0 commit comments

Comments
 (0)