SET PATH *LIBL ; 

CREATE OR REPLACE FUNCTION RESTAPI.GENERATE_DBML ( 
	INAPPVER VARCHAR(10) , 
	INAPPNAME VARCHAR(128) ) 
	RETURNS CLOB(2147483647)   
	LANGUAGE SQL 
	SPECIFIC RESTAPI.GENERATE_DBML 
	NOT DETERMINISTIC 
	READS SQL DATA 
	CALLED ON NULL INPUT 
	SET OPTION  ALWBLK = *ALLREAD , 
	ALWCPYDTA = *OPTIMIZE , 
	COMMIT = *NONE , 
	DBGVIEW = *SOURCE , 
	DECRESULT = (31, 31, 00) , 
	DLYPRP = *NO , 
	DYNDFTCOL = *NO , 
	DYNUSRPRF = *OWNER , 
	SRTSEQ = *HEX   
	BEGIN 
DECLARE V_RESULT CLOB ( 2 G ) ; 
SELECT XMLSERIALIZE ( CONTENT 
XMLELEMENT ( NAME "dbml" , XMLATTRIBUTES ( '/' || INAPPVER AS 
"restUriPathTemplate" , '1.0' AS "version" ) , XMLAGG ( 
XMLELEMENT ( NAME "program" , XMLATTRIBUTES ( COALESCE ( 
Q . ERRORMSG , 'Internal server error' ) AS "errormessage" , 
'*NONE' AS "httpheaders" , COALESCE ( 
Q . HTTPSTATUSFAILURE , '500' ) AS "httpstatusonfailure" , 
COALESCE ( Q . HTTPSTATUSSUCCESS , '200' ) AS 
"httpstatusonsuccess" , Q . PROGNAME || 'Input' AS 
"inputWrapperIdentifier" , Q . PROGNAME AS "name" , Q . PROGNAME || 
'Result' AS "outputWrapperIdentifier" , COALESCE ( 
Q . QUERYTYPE , 'media-resource' ) AS "querytype" , COALESCE ( 
Q . RESTCONSUMES , '*/*' ) AS "restConsumes" , Q . FUNCMETHOD AS 
"restHttpRequestMethod" , COALESCE ( 
Q . RESTPRODUCES , 'application/json' ) AS "restProduces" , 
Q . RESTURI AS "restUriPathTemplate" , '*ERRORS' AS 
"returnsqlstate" , 'true' AS "treatwarningaserror" , COALESCE ( 
Q . TRIMMODE , '*TRAILING' ) AS "trimmode" , COALESCE ( 
Q . WRAPINPUT , 'false' ) AS "wrapInputParams" , COALESCE ( 
Q . WRAPOUTPUT , 'true' ) AS "wrapOutputParam" ) , XMLELEMENT ( 
NAME "sql" , XMLATTRIBUTES ( 
-- Use SQLSTMT directly, replacing {{param}} with ? 
Q . SQLSTMT_CONVERTED AS "statement" ) , Q . DATATAGS ) ) ORDER BY 
Q . APPFUNC ) ) AS CLOB ( 2 G ) ) 
INTO V_RESULT 
FROM 
( 
SELECT C . APPVER , C . APPNAME , C . APPFUNC , C . FUNCMETHOD , 
C . RESTURI , C . QUERYTYPE , C . HTTPSTATUSSUCCESS , 
C . HTTPSTATUSFAILURE , C . RESTCONSUMES , C . RESTPRODUCES , 
C . TRIMMODE , C . WRAPINPUT , C . WRAPOUTPUT , 
-- Extract first 500 error message from FUNCERRORS JSON array 
( SELECT E . ERRMSG 
FROM JSON_TABLE ( 
C . FUNCERRORS , 
'$[*]' 
COLUMNS ( 
ERRMSG VARCHAR ( 256 ) PATH '$."500"' 
) 
) AS E 
WHERE E . ERRMSG IS NOT NULL 
FETCH FIRST 1 ROW ONLY ) AS ERRORMSG , 
-- Use APPFUNC directly as program name 
C . APPFUNC AS PROGNAME , 
-- Convert SQLSTMT: replace {{param}} with ? markers 
REGEXP_REPLACE ( C . SQLSTMT , '\{\{[^}]+\}\}' , '?' ) 
AS SQLSTMT_CONVERTED , 
-- Build XML data elements using XMLCONCAT for path, form (no default), form (wi--th default) 
XMLCONCAT ( 
-- Path params 
( 
SELECT XMLAGG ( 
XMLELEMENT ( NAME "data" , XMLATTRIBUTES ( '37' AS "ccsid" , 
PP . PARAMNAME AS "name" , 
CASE 
WHEN PP . PARAMREQ = 'true' THEN 'false' 
ELSE 'true' 
END AS "nullable" , CAST ( PP . PARAMLEN AS VARCHAR ( 20 ) ) AS 
"precision" , PP . PARAMNAME AS "restInPathParam" , PP . PARAMTYPE 
AS "type" , 'input' AS "usage" ) ) ORDER BY PP . PARAMPOS ) 
FROM JSON_TABLE ( 
C . FUNCPARAMS , 
'$[*]' 
COLUMNS ( 
PARAMPOS INT PATH '$.pos' , 
PARAMNAME VARCHAR ( 128 ) PATH '$.name' , 
PARAMTYPE VARCHAR ( 20 ) PATH '$.type' , 
PARAMLEN INT PATH '$.length' , 
PARAMREQ VARCHAR ( 10 ) PATH '$.required' , 
PARAMLOC VARCHAR ( 20 ) PATH '$.location' 
) 
) AS PP 
WHERE PP . PARAMLOC = 'path' ) , 
-- Body/form params that are REQUIRED (no restInParamDefaultValue) 
( 
SELECT XMLAGG ( 
XMLELEMENT ( NAME "data" , XMLATTRIBUTES ( '37' AS "ccsid" , 
PF . PARAMNAME AS "name" , 'false' AS "nullable" , CAST ( 
PF . PARAMLEN AS VARCHAR ( 20 ) ) AS "precision" , PF . PARAMNAME 
AS "restInFormParam" , PF . PARAMTYPE AS "type" , 'input' AS 
"usage" ) ) ORDER BY PF . PARAMPOS ) 
FROM JSON_TABLE ( 
C . FUNCPARAMS , 
'$[*]' 
COLUMNS ( 
PARAMPOS INT PATH '$.pos' , 
PARAMNAME VARCHAR ( 128 ) PATH '$.name' , 
PARAMTYPE VARCHAR ( 20 ) PATH '$.type' , 
PARAMLEN INT PATH '$.length' , 
PARAMREQ VARCHAR ( 10 ) PATH '$.required' , 
PARAMLOC VARCHAR ( 20 ) PATH '$.location' 
) 
) AS PF 
WHERE PF . PARAMLOC <> 'path' 
AND PF . PARAMREQ = 'true' ) , 
-- Body/form params that are OPTIONAL (add restInParamDefaultValue) 
( 
SELECT XMLAGG ( 
XMLELEMENT ( NAME "data" , XMLATTRIBUTES ( '37' AS "ccsid" , 
PD . PARAMNAME AS "name" , 'true' AS "nullable" , CAST ( 
PD . PARAMLEN AS VARCHAR ( 20 ) ) AS "precision" , PD . PARAMNAME 
AS "restInFormParam" , 'null' AS "restInParamDefaultValue" , 
PD . PARAMTYPE AS "type" , 'input' AS "usage" ) ) ORDER BY 
PD . PARAMPOS ) 
FROM JSON_TABLE ( 
C . FUNCPARAMS , 
'$[*]' 
COLUMNS ( 
PARAMPOS INT PATH '$.pos' , 
PARAMNAME VARCHAR ( 128 ) PATH '$.name' , 
PARAMTYPE VARCHAR ( 20 ) PATH '$.type' , 
PARAMLEN INT PATH '$.length' , 
PARAMREQ VARCHAR ( 10 ) PATH '$.required' , 
PARAMLOC VARCHAR ( 20 ) PATH '$.location' , 
PARAMDEFAULT VARCHAR ( 256 ) PATH 
'$.default' 
) 
) AS PD 
WHERE PD . PARAMLOC <> 'path' 
AND PD . PARAMREQ = 'false' ) ) AS DATATAGS 
FROM RESTAPI . API_CONFIG C 
LEFT JOIN JSON_TABLE ( 
C . FUNCPARAMS , 
'$[*]' 
COLUMNS ( 
PARAMPOS INT PATH '$.pos' , 
PARAMNAME VARCHAR ( 128 ) PATH '$.name' , 
PARAMLOC VARCHAR ( 20 ) PATH '$.location' 
) 
) AS P 
ON 1 = 1 
WHERE ( C . APPVER , C . APPNAME ) = ( INAPPVER , INAPPNAME ) 
GROUP BY C . APPVER , C . APPNAME , C . APPFUNC , C . FUNCMETHOD , 
C . RESTURI , C . QUERYTYPE , C . HTTPSTATUSSUCCESS , 
C . HTTPSTATUSFAILURE , C . RESTCONSUMES , 
C . RESTPRODUCES , C . TRIMMODE , C . WRAPINPUT , 
C . WRAPOUTPUT , C . FUNCPARAMS , C . FUNCERRORS , 
C . SQLSTMT 
) AS Q ; 
RETURN CISTOOLS . STRIP_SPACES ( V_RESULT ) ; 
END  ; 

GRANT ALTER , EXECUTE   
ON SPECIFIC FUNCTION RESTAPI.GENERATE_DBML 
TO AMAPICS WITH GRANT OPTION ; 

GRANT EXECUTE   
ON SPECIFIC FUNCTION RESTAPI.GENERATE_DBML 
TO PUBLIC ; 

