SET PATH *LIBL ; 

CREATE OR REPLACE FUNCTION RESTAPI.GENERATE_DBML_V2 ( 
	INAPPVER VARCHAR(10) , 
	INAPPNAME VARCHAR(128) ) 
	RETURNS CLOB(2147483647)   
	LANGUAGE SQL 
	SPECIFIC RESTAPI.GENERATE_DBML_V2 
	NOT DETERMINISTIC 
	READS SQL DATA 
	CALLED ON NULL INPUT 
	SET OPTION  ALWBLK = *ALLREAD , 
	ALWCPYDTA = *OPTIMIZE , 
	COMMIT = *NONE , 
	DBGVIEW = *SOURCE , 
	DECRESULT = (31, 31, 00) , 
	DYNDFTCOL = *NO , 
	DYNUSRPRF = *OWNER , 
	SRTSEQ = *HEX   
	BEGIN 
DECLARE V_RESULT CLOB ( 2 G ) ; 
WITH EP AS ( 
SELECT * 
FROM RESTAPI . API_ENDPOINTS 
WHERE APPVER = INAPPVER 
AND APPNAME = INAPPNAME 
AND ENABLED = 'Y' 
) , 
P AS (  -- discovered placeholders from your SQL text 
SELECT P . APPVER , P . APPNAME , P . APPFUNC , P . APPPARAM , P . PARAMPOS 
FROM TABLE ( 
RESTAPI . GET_PARAM_PLACEHOLDERS ( 
INAPPVER , INAPPNAME , NULL ) 
) P 
) , 
-- single best rule per param (by priority) 
RULE_PICK AS ( 
SELECT P . APPVER , P . APPNAME , P . APPFUNC , P . APPPARAM , 
( 
SELECT R . RESTNAME 
FROM RESTAPI . API_PARAM_RULES R 
WHERE ( R . APPNAME IS NULL 
OR UPPER ( R . APPNAME ) = UPPER ( P . APPNAME ) ) 
AND ( R . APPFUNC IS NULL 
OR UPPER ( R . APPFUNC ) = UPPER ( P . APPFUNC ) ) 
AND REGEXP_LIKE ( P . APPPARAM , R . PATTERN , 
'i' ) 
ORDER BY R . PRIORITY 
FETCH FIRST 1 ROW ONLY ) AS R_RESTNAME , 
( 
SELECT R . LOCATION 
FROM RESTAPI . API_PARAM_RULES R 
WHERE ( R . APPNAME IS NULL 
OR UPPER ( R . APPNAME ) = UPPER ( P . APPNAME ) ) 
AND ( R . APPFUNC IS NULL 
OR UPPER ( R . APPFUNC ) = UPPER ( P . APPFUNC ) ) 
AND REGEXP_LIKE ( P . APPPARAM , R . PATTERN , 
'i' ) 
ORDER BY R . PRIORITY 
FETCH FIRST 1 ROW ONLY ) AS R_LOCATION , 
( 
SELECT R . TYPE_NAME 
FROM RESTAPI . API_PARAM_RULES R 
WHERE ( R . APPNAME IS NULL 
OR UPPER ( R . APPNAME ) = UPPER ( P . APPNAME ) ) 
AND ( R . APPFUNC IS NULL 
OR UPPER ( R . APPFUNC ) = UPPER ( P . APPFUNC ) ) 
AND REGEXP_LIKE ( P . APPPARAM , R . PATTERN , 
'i' ) 
ORDER BY R . PRIORITY 
FETCH FIRST 1 ROW ONLY ) AS R_TYPE , 
( 
SELECT R . NULLABLE 
FROM RESTAPI . API_PARAM_RULES R 
WHERE ( R . APPNAME IS NULL 
OR UPPER ( R . APPNAME ) = UPPER ( P . APPNAME ) ) 
AND ( R . APPFUNC IS NULL 
OR UPPER ( R . APPFUNC ) = UPPER ( P . APPFUNC ) ) 
AND REGEXP_LIKE ( P . APPPARAM , R . PATTERN , 
'i' ) 
ORDER BY R . PRIORITY 
FETCH FIRST 1 ROW ONLY ) AS R_NULLABLE , 
( 
SELECT R . PRECISION 
FROM RESTAPI . API_PARAM_RULES R 
WHERE ( R . APPNAME IS NULL 
OR UPPER ( R . APPNAME ) = UPPER ( P . APPNAME ) ) 
AND ( R . APPFUNC IS NULL 
OR UPPER ( R . APPFUNC ) = UPPER ( P . APPFUNC ) ) 
AND REGEXP_LIKE ( P . APPPARAM , R . PATTERN , 
'i' ) 
ORDER BY R . PRIORITY 
FETCH FIRST 1 ROW ONLY ) AS R_PREC , 
( 
SELECT R . CCSID 
FROM RESTAPI . API_PARAM_RULES R 
WHERE ( R . APPNAME IS NULL 
OR UPPER ( R . APPNAME ) = UPPER ( P . APPNAME ) ) 
AND ( R . APPFUNC IS NULL 
OR UPPER ( R . APPFUNC ) = UPPER ( P . APPFUNC ) ) 
AND REGEXP_LIKE ( P . APPPARAM , R . PATTERN , 
'i' ) 
ORDER BY R . PRIORITY 
FETCH FIRST 1 ROW ONLY ) AS R_CCSID 
FROM P P 
) , 
-- resolve final mapping (override > rule > path auto-detect > defaults) 
PL AS ( 
SELECT P . APPVER , P . APPNAME , P . APPFUNC , P . PARAMPOS , P . APPPARAM , 
COALESCE ( O . RESTNAME , RP . R_RESTNAME , P . APPPARAM ) 
AS RESTNAME , 
/* location precedence: 
1) explicit override 
2) rule 
3) path auto-detect if {RESTNAME} appears in template 
4) query for known cases (inEnvList) or default FORM 
*/ 
COALESCE ( 
O . LOCATION , RP . R_LOCATION , 
CASE 
WHEN 
LOCATE ( 
'{' || 
UPPER ( 
COALESCE ( 
O . RESTNAME , RP . R_RESTNAME , 
P . APPPARAM ) ) || '}' , UPPER ( 
E . PATH_TEMPLATE ) ) > 0 THEN 'PATH' 
END , 
CASE 
WHEN UPPER ( P . APPPARAM ) = 'INENVLIST' THEN 'QUERY' 
END , 'FORM' ) AS LOCATION , 
COALESCE ( O . TYPE_NAME , RP . R_TYPE , 'CLOB' ) AS TYPE_NAME , 
COALESCE ( O . NULLABLE , RP . R_NULLABLE , 'Y' ) AS NULLABLE , 
COALESCE ( O . PRECISION , RP . R_PREC , 2147483647 ) 
AS PRECISION , 
COALESCE ( O . CCSID , RP . R_CCSID , 1208 ) AS CCSID 
FROM P P 
JOIN EP E 
ON E . APPVER = P . APPVER 
AND E . APPNAME = P . APPNAME 
AND E . APPFUNC = P . APPFUNC 
LEFT JOIN RESTAPI . API_PARAM_OVERRIDES O 
ON O . APPVER = P . APPVER 
AND O . APPNAME = P . APPNAME 
AND O . APPFUNC = P . APPFUNC 
AND UPPER ( O . APPPARAM ) = UPPER ( P . APPPARAM ) 
LEFT JOIN RULE_PICK RP 
ON RP . APPVER = P . APPVER 
AND RP . APPNAME = P . APPNAME 
AND RP . APPFUNC = P . APPFUNC 
AND RP . APPPARAM = P . APPPARAM 
) , 
PARAM_STR AS ( 
SELECT P . APPVER , P . APPNAME , P . APPFUNC , 
LISTAGG ( 
'''' || P . APPPARAM || ''':' || '?' , ', ' ) 
WITHIN GROUP ( ORDER BY P . PARAMPOS ) AS PARAMS_TXT 
FROM P P 
GROUP BY P . APPVER , P . APPNAME , P . APPFUNC 
) , 
DATA_XML AS ( 
SELECT PL . APPVER , PL . APPNAME , PL . APPFUNC , 
XMLAGG ( XMLELEMENT ( NAME "data" , XMLATTRIBUTES ( CHAR ( 
PL . CCSID ) AS "ccsid" , PL . APPPARAM AS "name" , 
CASE 
WHEN PL . NULLABLE = 'Y' THEN 'true' 
ELSE 'false' 
END AS "nullable" , CHAR ( PL . PRECISION ) AS "precision" , 
CASE 
WHEN PL . LOCATION = 'PATH' THEN PL . RESTNAME 
END AS "restInPathParam" , 
CASE 
WHEN PL . LOCATION = 'QUERY' THEN PL . RESTNAME 
END AS "restInQueryParam" , 
CASE 
WHEN PL . LOCATION = 'FORM' THEN PL . RESTNAME 
END AS "restInFormParam" , PL . TYPE_NAME AS "type" , 
'input' AS "usage" ) ) ORDER BY PL . PARAMPOS ) 
AS DATA_FRAGMENT 
FROM PL PL 
GROUP BY PL . APPVER , PL . APPNAME , PL . APPFUNC 
) 
SELECT XMLSERIALIZE ( CONTENT XMLELEMENT ( NAME "dbml" , XMLATTRIBUTES ( 
'/v1' AS "restUriPathTemplate" , '1.0' AS "version" ) , XMLAGG ( 
XMLELEMENT ( NAME "program" , XMLATTRIBUTES ( '' AS "errormessage" , 
'*NONE' AS "httpheaders" , '500' AS "httpstatusonfailure" , 
E . SUCCESS_CODE AS "httpstatusonsuccess" , 'get' || 
UPPER ( SUBSTR ( E . APPFUNC , 1 , 1 ) ) || SUBSTR ( E . APPFUNC , 2 ) || 
'Input' AS "inputWrapperIdentifier" , 'get' || 
UPPER ( SUBSTR ( E . APPFUNC , 1 , 1 ) ) || SUBSTR ( E . APPFUNC , 2 ) AS 
"name" , 'get' || UPPER ( SUBSTR ( E . APPFUNC , 1 , 1 ) ) || 
SUBSTR ( E . APPFUNC , 2 ) || 'Result' AS 
"outputWrapperIdentifier" , 'media-resource' AS "querytype" , 
E . CONSUMES AS "restConsumes" , E . HTTP_METHOD AS 
"restHttpRequestMethod" , E . PRODUCES AS "restProduces" , 
E . PATH_TEMPLATE AS "restUriPathTemplate" , '*ERRORS' AS 
"returnsqlstate" , 'true' AS "treatwarningaserror" , '*TRAILING' 
AS "trimmode" , 'false' AS "wrapInputParams" , 'true' AS 
"wrapOutputParam" ) 
, XMLELEMENT ( NAME "sql" , XMLATTRIBUTES ( 
'Values Restapi.Execute_Sql(''' || E . APPVER || ''',''' || 
E . APPNAME || ''',''' || E . APPFUNC || 
''', Cast(Json_Object(' || COALESCE ( PS . PARAMS_TXT , '' ) || 
' ) As Varchar(10240) CCSID 37))' AS "statement" ) 
, DX . DATA_FRAGMENT ) ) ORDER BY E . APPFUNC ) ) AS CLOB ( 2 G ) ) 
INTO V_RESULT 
FROM EP E 
LEFT JOIN PARAM_STR PS 
ON PS . APPVER = E . APPVER 
AND PS . APPNAME = E . APPNAME 
AND PS . APPFUNC = E . APPFUNC 
LEFT JOIN DATA_XML DX 
ON DX . APPVER = E . APPVER 
AND DX . APPNAME = E . APPNAME 
AND DX . APPFUNC = E . APPFUNC ; 
RETURN V_RESULT ; 
END  ; 

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

GRANT EXECUTE   
ON SPECIFIC FUNCTION RESTAPI.GENERATE_DBML_V2 
TO PUBLIC ; 

