Transform your SQL Results with Mustache and ORDS JavaScript Handlers
https://peterobrien.blog/2024/07/16/transform-your-sql-results-with-mustache-and-ords-javascript-handlers/この記事では、テンプレート・エンジンのmustacheのMLE ModuleをOracle Database 23aiに作成し、それをORDSのMLE JavaScriptハンドラ内で呼び出しています。ORDSのMLEハンドラ内で、データベースの検索結果をテンプレートに穴埋めし結果のXMLファイルを出力しています。
データベースでのテンプレート処理というのは、Oracle APEXの処理の基本です。MLEのJavaScriptでのテンプレート処理の実用性はさておき、データベースでのテンプレート処理をJavaScriptで実装してみます。それが、Oracle APEXの理解につながれば幸いです。
以前に、MLE Moduleの作成やORDS MLE Handlerの作成を助けるアプリケーションを作成しています。
ORDSのハンドラをMLEのJavaScriptで記述する
https://apexugj.blogspot.com/2024/07/sample-mle-javascript-ords-handler.html
<employees>{{#rows}} <employee empno="{{EMPNO}}" ename="{{ENAME}}" salary="{{SAL}}"/>{{/rows}}</employees>
この問合せ文とテンプレートを表EBSJ_REGIONSに保存します。
insert into ebsj_regions(query, template)
values(
'select * from emp',
q'~<employees>{{#rows}} <employee empno="{{EMPNO}}" ename="{{ENAME}}" salary="{{SAL}}"/>{{/rows}}</employees>~');
ボタンResolve Onceをクリックします。mustacheは他に依存しているモジュールがないため、対話モード・レポートに変化はありません。
ボタンCreate Mle Moduleをクリックし、mustacheのMLE Moduleを作成します。
ボタンAdd Importsをクリックし、MLE環境LIBRARY_ENVの作成と、作成したMLE環境にmustacheをインポートとして追加します。
以上でmustachをMLEハンドラから呼び出せるようになりました。
それぞれのアプリケーションをインポートするのが面倒なので、ひとつにまとめました。
このアプリケーションをAPEXのワークスペースにインポートします。
この他にパッケージUTL_MLE_NPMの作成が必要です。
以下より、テンプレート処理を行なうMLE JavaScriptハンドラを実装します。
RESTfulサービスのページを開き、サンプル・サービスのリセットを実施します。今回はサンプル・サービスに含まれるテンプレートemployees/:idのGETハンドラを、MLE JavaScriptハンドラに置き換えます。
テンプレート処理に使うSELECT文とテンプレートを保持する、表EBSJ_REGIONSを作成します。
create table ebsj_regions (
id number generated by default on null as identity
constraint ebsj_regions_id_pk primary key,
query varchar2(400 char) not null,
template clob not null
);
穴埋めに使用する問合せ文は以下とします。
select * from emp
テンプレートは以下です。
この問合せ文とテンプレートを表EBSJ_REGIONSに保存します。
insert into ebsj_regions(query, template)
values(
'select * from emp',
q'~<employees>{{#rows}} <employee empno="{{EMPNO}}" ename="{{ENAME}}" salary="{{SAL}}"/>{{/rows}}</employees>~');
ハンドラ呼び出し時の引数となるIDの値を確認します。
select * from ebsj_regions
今回のIDは1でした。
インポートしたアプリケーションMLEを実行します。
Module Nameにmustache、MLE EnvにLIBRARY_ENVを入力します。
ボタンAdd Es Moduleをクリックします。対話モード・レポートにmustacheが追加されます。
オブジェクト・ブラウザのMLE環境からLIBRARY_ENVを開くと、MLE Moduleであるmustacheのインポート名を確認できます。
MLE Handlerを作成します。Module Nameはoracle.example.hr、Patternはemployees/:id、MethodはGETになります。Source Typeはmle/javascript、MLE Env NameはLIBRARY_ENVです。
Sourceとして以下を記述し、Define Handlerをクリックします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(req, resp) => { | |
/* | |
* 表EBSJ_REGIONSから、IDで指定されたSELECT 文とテンプレートを取り出す。 | |
*/ | |
var query; | |
var template; | |
const regionQuery = 'select query, template from ebsj_regions where id = :1'; | |
const regionDef = session.execute(regionQuery, [req.uri_parameters.id]); | |
if ( regionDef.rows.length > 0 ) { | |
query = regionDef.rows[0].QUERY; | |
template = regionDef.rows[0].TEMPLATE.getData(); | |
} | |
/* | |
* 取り出したSELECT文の結果をテンプレートに埋め込む。 | |
*/ | |
const res = session.execute(query); | |
const mustache = await import('/npm/mustache@4.2.0/+esm'); | |
var output = mustache.default.render(template, res); | |
/* | |
* XMLを出力する。 | |
*/ | |
resp.content_type('application/xml'); | |
resp.status(200); | |
resp.send(output); | |
} |
RESTfulサービスを開き、テンプレートemployees/:idの完全なURLを確認します。
URLの最後の:idに1を与えて、ORDSのハンドラを呼び出すとXMLの出力を確認できます。
問合せとテンプレートの組みを追加します。
insert into ebsj_regions(query, template)
values(
'select * from dept',
q'~<departments>{{#rows}} <department deptno="{{DEPTNO}}" dname="{{DNAME}}" loc="{{LOC}}"/>{{/rows}}</departments>~');