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 ;