2 MLE JavaScriptモジュールおよび環境

1つのJavaScriptモジュールは、スキーマ・オブジェクトとしてデータベースに格納される、MLEの言語コードの1つの単位です。

データベース内にコードを格納することは、MLEでJavaScriptを使用する主な利点の1つです。一連のアプリケーション・サーバーとそれぞれの独自のアプリケーションのコピーの管理はユーザーではなくデータベースによって実行されます。

また、Data Guardレプリケーションにより、同じコードが本番データベースとすべてのフィジカル・スタンバイ・データベースの両方に存在することが確実化されます。障害時リカバリの場所を呼び出すときに発生する一般的な問題である、構成ドリフトを軽減できます。

MLEのJavaScriptモジュールは、ECMAScript 6モジュールと同等です。MLEモジュールとJavaScriptモジュールという用語は同じ意味で使用されます。これらのコンテンツはJavaScriptに固有であり、データ定義言語(DDL)コマンドを使用して管理できます。

従来のJavaScript環境では、多くの場合、ディレクティブまたは構成スクリプトを使用して追加情報がランタイムに渡されます。MLEでは、これはMLE環境(MLEモジュールを補完する追加のメタデータ構造)を使用して実現できます。MLE環境は、JavaScriptモジュール・インポートの名前解決にも使用されます。名前解決は、コードを保守し、MLEで使用する様々なモジュールにコードを分離するために非常に重要です。

関連項目:

JavaScriptモジュールの詳細は、Developer.mozilla.orgを参照してください

トピック

MLEでのJavaScriptモジュールの使用

JavaScriptモジュールは、様々な方法で使用でき、一連のデータ定義言語(DDL)コマンドを使用して管理できます。

MLEモジュールで提供されているJavaScriptコードは、次の方法で使用できます:

  • MLEモジュールによってエクスポートされたJavaScriptファンクションは、MLEモジュール・コールと呼ばれるコール仕様を作成することで公開できます。これにより、SQLおよびPL/SQLからファンクションを直接コールできます。

  • JavaScript MLEモジュールによってエクスポートされた機能は、他のMLE JavaScriptモジュールにインポートできます。

  • DBMS_MLEのコード・スニペットは、JavaScriptの動的起動用のモジュールをインポートできます。

ユーザーがMLEモジュールを作成および実行できるようにするには、複数の権限を付与する必要があります。

関連項目:

トピック

データベースでのJavaScriptモジュールの管理

必要な権限がある場合は、SQLでMLEモジュールをスキーマ・オブジェクトとして作成できます。

独自のスキーマでMLEモジュールを作成または置換するには、少なくともCREATE MLE MODULE権限が必要です。また、ターゲットのJavaScript言語オブジェクトに対する実行権限も必要です。

関連項目:

  • MLE固有の権限の詳細は、「MLEでのJavaScriptの操作に必要なシステム権限およびオブジェクト権限」を参照してください

  • Oracle Databaseの権限およびロールの詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください

トピック

JavaScriptモジュールの名前付け

各JavaScriptモジュールの名前は、それが作成されるスキーマ内で一意である必要があります。完全修飾名が使用されないかぎり、現在のユーザーのスキーマが使用されます。

他のスキーマ・オブジェクト識別子と同様に、二重引用符で囲まれたモジュール名は大/小文字が区別されます。引用符で囲まれていない場合、名前は暗黙的に大文字に変換されます。

一意の名前を選択する場合、MLEオブジェクトは、表、ビュー、マテリアライズド・ビュー、順序、プライベート・シノニム、PL/SQLパッケージ、ファンクション、プロシージャおよびキャッシュ・グループとネームスペースを共有することに注意してください。

データベースでのJavaScriptモジュールの作成

JavaScriptモジュールは、CREATE MLE MODULE DDL文を使用して、MLEモジュールの名前とソース・コードを指定してデータベースに作成されます。

MLEモジュールが作成されるとすぐに、データベース・ディクショナリに保持されます。これは、DBMS_MLEを使用したJavaScriptコードの動的実行と比較した場合の違いの1つです。

指定された名前のMLEモジュールがすでに存在する場合、CREATE MLE MODULE (OR REPLACE句なし)はエラーをスローします。CREATE OR REPLACE MLE MODULEでは、既存のモジュールが存在する場合は置換され、存在しない場合は新しいモジュールが作成されます。MLEモジュールが置換される場合、そのモジュールに対する権限を再付与する必要はありません。

PL/SQLの知識のある方は、これがPL/SQLプログラム・ユニットの動作とまったく同じであることに注意してください。

モジュール名がすでに使用されている場合に既存のモジュールを置換しない場合は、CREATE OR REPLACEではなくIF NOT EXISTS句を使用できます。このバリエーションの構文を例2-1に示します。IF NOT EXISTS句とOR REPLACE句は相互に排他的です。

関連項目:

IF [NOT] EXISTS構文の使用の詳細は、『Oracle Database開発ガイド』を参照してください。

例2-1 データベースでのJavaScriptモジュールの作成

この例は、MLEモジュールの作成および単純なJavaScriptファンクションのエクスポートを示しています。

CREATE MLE MODULE IF NOT EXISTS po_module LANGUAGE JAVASCRIPT AS

/**
* get the value of all line items in an order
* @param {array} lineItems - all the line items in a purchase order
* @returns {number} the total value of all line items in a purchase order
*/
export function orderValue(lineItems) {
    
    return lineItems
        .map( x => x.Part.UnitPrice * x.Quantity )
        .reduce( 
            (accumulator, currentValue) => accumulator + currentValue, 0
        );
}
/

このコード・ブロックの最初の行は、JavaScriptモジュール名をpo_moduleとして指定しています。残りの行は、実際のJavaScriptコードを定義します。ECMAScript標準に従い、exportキーワードは、モジュールの潜在的なコール元にエクスポートされるファンクションを示すことに注意してください。MLEは、ECMAScript 2022標準に準拠したコードを受け入れます。

シングルバイト文字セットの使用によるデータベースでのJavaScriptコードの格納

文字セット標準と、MLEでシングルバイト文字セットを使用する際の注意事項。

JavaScriptはUnicodeでエンコードされます。Unicode規格は、世界中で話されているほとんどの言語のあらゆる文字を定義する文字コード・システムです。これは、他の文字セット・エンコーディングの制限事項を克服するために開発されました。

データベースの作成には、AL32UTF8文字セットを使用することをお薦めします。データベースでAL32UTF8文字セットを使用すると、最新バージョンのUnicode標準が確実に使用され、文字セット変換エラーの可能性が最小限に抑えられます。

データベースで依然としてUS7ASCII、WE8ISO8859-n、WE8MSWIN1252などのシングルバイト文字セットが使用されている場合は、MLE JavaScriptコードでUnicode機能を使用しないように注意する必要があります。このことは、そのようなデータベースで他のタイプの入力データを処理する場合と変わりありません。

コード分析

MLEでは、JavaScriptコードの正確性またはコーディングのベスト・プラクティスに関するチェックは実行されません。したがって、開発者は、CREATE MLE MODULEコマンドを実行する前に、最適なlintツールを使用して分析を実行する必要があります。

MLEモジュールをデータベースに作成する場合は、他のJavaScriptプロジェクトを制御するのと同じ方法で、十分に確立されたツールチェーンを使用する必要があります。この意味では、CREATE MLE MODULEのコールは、サーバー・アプリケーションのデプロイと同様に、デプロイメント・ステップとみなすことができます。コード・チェックは、デプロイの前に、継続的インテグレーション/継続的デプロイメント(CI/CD)パイプラインなどによって、ビルド・ステップ中に実行する必要があります。

コードをソース・コード・リポジトリにチェックインする前に、linterと呼ばれるツールでコードを処理することは、業界のベスト・プラクティスとみなされています。他の開発プロジェクトと同様に、自分自身とチームにとって最適なオプションを自由に選択できます。考えられるオプションには、ESLint、JSHint、JSLint、および静的コード分析を実行して構文エラー、バグ、その他の問題のあるコードにフラグを付けるものがあります。また、これらを使用して特定のコーディング・スタイルを適用することもできます。多くの統合開発環境(IDE)では組込み機能としてlintが提供され、ファイルがディスクに保存されるとすぐにこのツールを起動して、問題にフラグを付けます。

lintの動的実行に加えて、高度に自動化されたDevOps環境を使用してコード分析を自動化し、ビルド・パイプラインの一部としてlintを起動できます。通常、このステップは、JavaScriptモジュールをデータベースに送信する前に発生します。

この目的は、実行時に問題が発生する前に、できるだけ多くの潜在的な問題を検出することです。ユニット・テストはこれらのリスクをさらに軽減するために役立ち、開発プロセスへのユニット・テストの組込みは業界のベスト・プラクティスになっています。どの方法を選択しても、JavaScriptモジュールをデータベースに送信する前に、コード分析ステップが発生します。

MLEモジュール・コール用のJavaScriptコードの準備

MLEのJavaScriptモジュールは、モジュール用のECMAScript 6標準に従います。MLEモジュールのユーザーが使用すると予想されるファンクションと変数をエクスポートする必要があります。

エクスポートされない変数およびファンクションは、モジュール内でプライベートとみなされます。例2-3は、MLE JavaScriptモジュールでのパブリック・ファンクションとプライベート・ファンクションの両方の使用を示しています。

ECMAScriptモジュールは、インポート文または動的インポート・コールを使用して、他のECMAScriptモジュールをインポートできます。この機能は、MLEにもあります。MLE環境では、MLEモジュールを補完するメタデータが提供されます。

MLEのコンソール出力は、コンソール・オブジェクトを使用することで容易になることに注意してください。デフォルトでは、console.log()に書き込まれたものはすべてDBMS_OUTPUTにルーティングされ、最終的に画面に表示されます。

例2-1のようなJavaScriptコードは、コール仕様なしでSQLまたはPL/SQLからアクセスすることはできません。コール仕様は、PL/SQLプログラム・ユニット(ファンクション、プロシージャまたはパッケージ)と考えることができます。ここで、例2-2に示すように、そのPL/SQL本体がJavaScriptモジュールおよびファンクションへの参照に置き換えられます。コール仕様の詳細は、「MLE JavaScriptファンクション」を参照してください。

例2-2 パブリック・ファンクションのコール仕様の作成

この例では、例2-1で作成したモジュールpo_moduleを使用します。po_moduleでエクスポートされる唯一のファンクションであるorderValue()のコール仕様は、次のように記述できます:


CREATE OR REPLACE FUNCTION order_value(
    p_line_items JSON
) RETURN NUMBER AS
MLE MODULE po_module
SIGNATURE 'orderValue';
/

ファンクションを作成すると、特定の購買オーダーの値を計算できます:


SELECT
    po.po_document.PONumber,
    order_value(po.po_document.LineItems[*]) order_value
FROM
    j_purchaseorder po;

結果:


PONUMBER   ORDER_VALUE
---------- -----------
1600             279.3
672              359.5

例2-3 JavaScriptモジュールのパブリック・ファンクションとプライベート・ファンクション

パブリック(エクスポート済)ファンクションに加えて、モジュールにプライベートなファンクションを追加できます。この例では、値の計算はmap()ファンクションから取り出され、別のファンクションに移動されます(リファクタリング)。

次のコードの最初のファンクションlineItemValue()はプライベートとみなされ、2番目のファンクションorderValue()はパブリックです。exportキーワードは、このコード・リストの最後に指定されていますが、例2-1に示すように、変数およびファンクションの接頭辞として出現することもあります。どちらのバリエーションも有効なJavaScript構文です。


CREATE OR REPLACE MLE MODULE po_module LANGUAGE JAVASCRIPT AS

/**
* calculate the value of a given line item. Factored out of the public 
* function to allow for currency conversions in a later step
* @param {number} unitPrice - the price of a single article
* @param {number} quantity - the quantity of articles ordered
* @returns {number} the monetary value of the line item
*/
function lineItemValue(unitPrice, quantity) {
    return unitPrice * quantity;
}

/**
* get the value of all line items in an order
* @param {array} lineItems - all the line items in a purchase order
* @returns {number} the total value of all line items in a purchase order
*/
function orderValue(lineItems) {
    
    return lineItems
                .map( x => lineItemValue(x.Part.UnitPrice, x.Quantity) )
                .reduce( 
                    (accumulator, currentValue) => accumulator + currentValue, 0 
                );
}

export { orderValue }
/

MLEにJavaScriptコードを指定するための追加オプション

MLEモジュールのJavaScriptソース・コードは、PL/SQLを使用してインラインで指定できますが、BFILE、BLOBまたはCLOBを使用して指定することもできます。この場合、ソース・ファイルはUTF8でエンコードする必要があります。

BFILE句を使用してMLEモジュールを作成すると、GoldenGateなどの論理レプリケーションで問題が発生する可能性があります。DDLコマンドがターゲット・データベースで成功するには、ターゲット・データベースに同じディレクトリが存在する必要があります。さらに、このディレクトリに同じJavaScriptファイルが存在する必要があります。これらの条件が満たされないと、ターゲット・データベースでMLEモジュールを作成するコールが失敗します。

BFILEを使用するかわりに、BLOBまたはCLOBを使用して、MLEモジュールを作成することもできます。例2-5に、CLOBを使用してJavaScriptモジュールを作成する方法を示します。BLOBを使用する場合、構文は同じですが、BLOBの値はCLOBの値とは異なります。

例2-4 BFILEを使用したJavaScriptソース・コードの指定

この例では、JS_SRC_DIRは、myJavaScriptModule.jsというファイルにモジュールのソース・コードを含むローカル・ファイル・システム上の場所にマッピングするデータベース・ディレクトリ・オブジェクトです。ディレクトリの場所からファイルをロードすると、MLEはソース・コードをディクショナリに格納します。それ以降MLEモジュールをコールしても、ソース・コードがディスクからリフレッシュされることはありません。myJavaScriptModule.jsに新しいバージョンのモジュールが格納されている場合は、別のCREATE OR REPLACE MLE MODULEのコールを使用してデプロイする必要があります。

CREATE MLE MODULE mod_from_bfile
LANGUAGE JAVASCRIPT
USING BFILE(JS_SRC_DIR,'myJavaScriptModule.js');
/

例2-5 CLOBを使用したJavaScriptソース・コードの指定

CREATE OR REPLACE MLE MODULE mod_from_clob_inline
LANGUAGE JAVASCRIPT USING CLOB (
    SELECT q'~
    export function clob_hello(who){
        return `hello, ${who}`;
}
~')
/

別の方法として、表に格納されているJavaScriptソース・コードを使用することもできます。このバリエーションの例では、スキーマに、src列のJavaScriptソース・コードを含むjavascript_srcという名前の表と、追加のメタデータがあると想定しています。次の文は、CLOBをフェッチしてモジュールを作成します。

CREATE OR REPLACE MLE MODULE mod_from_clob_table
LANGUAGE JAVASCRIPT USING CLOB (
    SELECT src
    FROM javascript_src
    WHERE 
        id = 1 AND 
        commit_hash = 'ac1fd40'
)
/

このようなステージング表は、継続的インテグレーション(CI)パイプラインを使用してJavaScriptコードをデータベースにデプロイする環境にあります。

モジュール・バージョン情報の指定およびJSONメタデータの指定

MLEモジュールでは、オプションのメタデータをバージョン文字列および自由形式のJSON値メタデータの形式で保持できます。

どちらの種類のメタデータも純粋に情報を提供し、MLEの動作には影響しません。これらは、モジュールとともにデータ・ディクショナリに格納されます。

VERSIONフラグは、デプロイされているコードのバージョンに関する内部リマインダとして使用できます。VERSIONフィールドに格納された情報により、開発者および管理者は、バージョン管理システムでコードを識別できます。

JSONメタデータの形式はスキーマにバインドされません。開発者は有用なものや参考になるものを追加できます。MLEモジュールがrollup.jsやwebpackなどのツールで作成されたソースの集合である場合、関連するpackage-lock.jsonファイルをモジュールとともに格納すると便利です。

メタデータ・フィールドを使用して、ソフトウェア部品構成表(SBOM)を作成できます。これにより、セキュリティ・チームおよび管理者は、特にサードパーティ・モジュールが使用されている場合に、デプロイ済パッケージに関する情報を追跡できます。

アップストリーム・リポジトリの依存関係および脆弱性を追跡することにより、セキュリティの脆弱性がレポートされた後に更新が必要なコンポーネントを簡単に識別できます。

関連項目:

例2-6 CREATE MLE MODULEでのVERSION文字列の指定

CREATE OR REPLACE MLE MODULE version_mod
 LANGUAGE JAVASCRIPT
 VERSION '1.0.0.1.0' 
AS
export function sq(num) {
  return num * num;
}
/

例2-7 MLEモジュールへのJSONメタデータの追加

この例では、例2-6で作成したモジュールversion_modを使用します。

ALTER MLE MODULE version_mod
SET METADATA USING CLOB 
(SELECT 
  '{
    "name": "devel",
    "lockfileVersion": 2,
    "requires": true,
    "packages": {}
  }'
)
/

JavaScriptモジュールの削除

DROP MLE MODULE DDL文を使用して、MLEモジュールを削除します。

DROP文は、削除するモジュールの名前およびオプションでスキーマを指定します。スキーマが指定されていない場合は、現在のユーザーのスキーマとみなされます。

存在しないMLEモジュールを削除しようとすると、エラーがスローされます。これが望ましくない場合は、IF EXISTS句を使用できます。指定されたMLEモジュールが存在しない場合、DROP MLE MODULEコマンドは暗黙的にスキップされます。

例2-8 MLEモジュールの削除

DROP MLE MODULE unused_mod;

例2-9 IF EXISTSを使用したMLEモジュールの削除

DROP MLE MODULE IF EXISTS unused_mod;

JavaScriptモジュールの変更

MLEモジュールの属性は、ALTER MLE MODULE文を使用して割り当てまたは変更できます。

ALTER MLE MODULE文は、変更するモジュールの名前およびオプションでスキーマを指定します。モジュール名にスキーマの接頭辞が付けられていない場合は、現在のユーザーのスキーマとみなされます。

例2-10 MLEモジュールの変更

ALTER MLE MODULE change_mod
  SET METADATA USING CLOB(SELECT'{...}');

組込みJavaScriptモジュールの概要

MLEには、任意の実行コンテキストでインポートできる一連の組込みJavaScriptモジュールが用意されています。

組込みモジュールは、ユーザー定義のMLEモジュールとしてデータベースにデプロイされませんが、MLEランタイムの一部として含まれます。特に、MLEは、次の3つの組込みJavaScriptモジュールを提供します:

  • mle-js-oracledbは、JavaScript MLE SQLドライバです。

  • mle-js-bindingsは、PL/SQLエンジンから値をインポートおよびエクスポートする機能を提供します。

  • mle-js-plsqltypesは、PL/SQLラッパー型の定義を提供します。たとえば、PL/SQLをラップするJavaScript型と、OracleNumberなどのSQL型です。

  • mle-js-fetchには、フェッチAPIポリフィルの一部が提供されており、開発者は外部リソースを起動できます。

  • mle-encode-base64には、base64でエンコードされたデータを操作するためのコードが含まれます。

これらのモジュールを使用して、データベースと対話し、JavaScriptエンジンとデータベース・エンジンの間の型変換を提供します。

関連項目:

組込みJavaScriptモジュールの詳細は、サーバー側JavaScript APIのドキュメントを参照してください

MLE JavaScriptモジュールに関連するディクショナリ・ビュー

データ・ディクショナリには、JavaScriptモジュールの詳細が含まれます。

トピック

USER_SOURCE

各JavaScriptモジュールのソース・コードは、[USER | ALL | DBA | CDB]_SOURCEディクショナリ・ビューを使用して外部化されます。

BFILE演算子を使用してファイル・システムを参照して作成されたモジュールには、モジュールの作成時のコードが表示されます。

*_SOURCEの詳細は、『Oracle Databaseリファレンス』を参照してください。

例2-11 JavaScriptモジュールのソース・コードの外部化

SELECT
    line,
    text
FROM
    USER_SOURCE
WHERE
    name = 'PO_MODULE';

出力例:

   
 LINE TEXT
----- -------------------------------------------------------------
    1 /**
    2  * calculate the value of a given line item. Factored out of the public
    3  * function to allow for currency conversions in a later step
    4  * @param {number} unitPrice - the price of a single article
    5  * @param {number} quantity - the quantity of articles ordered
    6  * @returns {number} the monetary value of the line item
    7  */
    8 function lineItemValue(unitPrice, quantity) {
    9     return unitPrice * quantity;
   10 }
   11
   12
   13 /**
   14  * get the value of all line items in an order
   15  * @param {array} lineItems - all the line items in a purchase order
   16  * @returns {number} the total value of all line items in a purchase order
   17  */
   18 export function orderValue(lineItems) {
   19
   20     return lineItems
   21                 .map( x => lineItemValue(x.Part.UnitPrice, x.Quantity) )
   22                 .reduce(
   23                     (accumulator, currentValue) => accumulator + currentValue, 0
   24                 );
   25 }
USER_MLE_MODULES

JavaScript MLEモジュールに関連するメタデータは、[USER | ALL | DBA | CDB]_MLE_MODULESにあります。

指定されたJSONメタデータ、バージョン情報、言語、名前および所有者は、このビューで確認できます。

*_MLE_MODULESの詳細は、『Oracle Databaseリファレンス』を参照してください。

例2-12 スキーマに定義されているMLEモジュールの検索

SELECT MODULE_NAME, VERSION, METADATA
FROM USER_MLE_MODULES
WHERE LANGUAGE_NAME='JAVASCRIPT'
/

出力例:

MODULE_NAME                    VERSION    METADATA
------------------------------ ---------- -----------
MY_MOD01                       1.0.0.1
MY_MOD02                       1.0.1.1
MY_MOD03                       

MLEモジュールの環境の指定

MLE環境は、データベース内のスキーマ・オブジェクトです。それらの機能と管理方法について説明します。

MLE環境はMLEモジュールを補完し、次のことを可能にします:

  • 言語オプションを設定して、実行コンテキストでJavaScriptランタイムをカスタマイズします

  • インポートする特定のMLEモジュールを有効にします

  • 名前解決およびインポート・チェーンを管理します

トピック

データベースでのMLE環境の作成

SQL DDLでは、MLE環境の作成がサポートされています。

MLEモジュールと同様に、MLE環境はデータベース内のスキーマ・オブジェクトであり、データ・ディクショナリに保持されます。

独自のスキーマでMLE環境を作成または置換するには、少なくともCREATE MLE MODULE権限が必要です。

関連項目:

  • MLEでJavaScriptコードを作成および実行するために必要な権限の詳細は、「MLEでのJavaScriptの操作に必要なシステム権限およびオブジェクト権限」を参照してください

  • Oracle Databaseの権限およびロールの詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください

トピック

MLE環境の名前付け

各JavaScript環境の名前は、それが作成されるスキーマ内で一意である必要があります。完全修飾名が使用されないかぎり、現在のユーザーのスキーマが使用されます。

他のスキーマ・オブジェクト識別子と同様に、二重引用符で囲まれた名前は大/小文字が区別されます。引用符で囲まれていない場合、名前は暗黙的に大文字に変換されます。

MLE環境には、MLE組込みモジュールの名前(mle-js-oracledbmle-js-bindingsmle-js-plsqltypesmle-js-fetchおよびmle-encode-base64)と競合するインポート・マッピングを含めることはできません。CREATE MLE ENV DDLまたはALTER MLE ENV DDLを使用してそのようなマッピングを追加しようとすると、操作はエラーで失敗します。

空のMLE環境の作成

DDL文CREATE MLE ENVを使用してMLE環境を作成できます。

最も基本的な形式では、次のスニペットに示すように空の環境を作成できます:

CREATE MLE ENV MyEnv

それ以降のALTER MLE ENVのコールを使用して、環境にプロパティを追加できます。

MLEモジュールと同様に、OR REPLACE句を追加して、エラーをスローするのではなく、既存のMLE環境を置き換えるようにデータベースに指示できます。

また、OR REPLACE句のかわりにIF NOT EXISTS句を使用して、同じ名前の環境がすでに存在する場合に、新しいMLE環境が作成されないようにすることもできます。この場合、環境の作成に使用される文は、次のように変更されます:

CREATE MLE ENV IF NOT EXISTS MyEnv

ノート:

IF NOT EXISTS句とOR REPLACE句は相互に排他的です。

関連項目:

既存の環境の編集の詳細は、「MLE環境の変更」を参照してください

既存の環境のクローンとしての環境の作成

必要に応じて、既存の環境のポイント・イン・タイム・コピーとして新しい環境を作成できます。

新しい環境は、そのソースのすべての設定を継承します。その後のソースに対する変更はクローンに伝播されません。次の文に示すようにクローンを作成できます:

CREATE MLE ENV MyEnvDuplicate CLONE MyEnv
インポート解決のためのMLE環境の使用

インポート文を使用して、あるJavaScriptモジュールによってエクスポートされた機能を別のモジュールにインポートできます。

コードの分離により、変更をより細かく制御し、より再利用可能なコードを記述できます。コードの保守が簡素化されることも、このアプローチのプラスの効果です。

exportキーワードでマークされた識別子のみがインポートの対象となります。

データベースに格納されている他のモジュールから機能をインポートしようとするモジュールには、名前解決を実行するためにMLE環境が必要です。その情報を使用してMLE環境を作成するには、IMPORTS句を使用する必要があります。例2-13は、識別子po_moduleとJavaScriptモジュールPO_MODULE (例2-1で作成)の間のマッピングの作成方法を示しています。

複数のインポートをカンマ区切りリストとして指定できます。例2-13の一重引用符で囲まれた最初のパラメータは、インポート名と呼ばれます。インポート名は、別のモジュールのインポート文で使用されます。この場合、'po_module'はインポート名で、同じ名前のモジュールを参照します。

ノート:

インポート名はモジュール名と一致する必要はありません。任意の有効なJavaScript識別子を使用できます。インポート名が参照先のモジュール名と一致するほど、2つの間のリンクを識別しやすくなります。

IMPORTS句で参照されているモジュールが存在しないか、ユーザーがアクセスできない場合、CREATE MLE ENVコマンドは失敗します。

組込みJavaScriptモジュールは、追加のMLE環境を指定することなく直接インポートできます。

関連項目:

組込みモジュールの詳細は、「組込みのJavaScriptモジュールの概要」

例2-13 JavaScriptモジュールへの識別子のマップ


CREATE OR REPLACE MLE ENV 
    po_env
IMPORTS (
    'po_module' MODULE PO_MODULE
);

例2-14 モジュール機能のインポート


CREATE OR REPLACE MLE MODULE import_example_module
LANGUAGE JAVASCRIPT AS
 
import * as po from "po_module";
/**
* use po_module's getValue() function to calculate the value of
* a purchase order. In later chapters, when discussing the MLE
* JavaScript SQL driver the hard-coded value used as the PO will
* be replaced by calls to the database
* @returns {number} the value of all line items in the purchase order
*/
export function purchaseOrderValue() {
 
    const purchaseOrder = {
        "PONumber": 1600,
        "Reference": "ABULL-20140421",
        "Requestor": "Alexis Bull",
        "User": "ABULL",
        "CostCenter": "A50",
        "ShippingInstructions": {
            "name": "Alexis Bull",
            "Address": {
                "street": "200 Sporting Green",
                "city": "South San Francisco",
                "state": "CA",
                "zipCode": 99236,
                "country": "United States of America"
            },
            "Phone": [
                {
                    "type": "Office",
                    "number": "909-555-7307"
                },
                {
                    "type": "Mobile",
                    "number": "415-555-1234"
                }
            ]
        },
        "Special Instructions": null,
        "AllowPartialShipment": true,
        "LineItems": [
            {
                "ItemNumber": 1,
                "Part": {
                    "Description": "One Magic Christmas",
                    "UnitPrice": 19.95,
                    "UPCCode": 13131092899
                },
                "Quantity": 9.0
            },
            {
                "ItemNumber": 2,
                "Part": {
                    "Description": "Lethal Weapon",
                    "UnitPrice": 19.95,
                    "UPCCode": 85391628927
                },
                "Quantity": 5.0
            }
        ]
    };
 
    return po.orderValue(purchaseOrder.LineItems);
}
/
次のコール仕様では、purchaseOrderValueファンクションをコールできます:

CREATE FUNCTION purchase_order_value
RETURN NUMBER AS
MLE MODULE import_example_module
ENV po_env
SIGNATURE 'purchaseOrderValue';
/

SELECT purchase_order_value;
/

結果:


PURCHASE_ORDER_VALUE
--------------------
               279.3
言語オプションの指定

MLEでは、MLE環境で言語固有のオプションを設定して、JavaScriptのランタイムをカスタマイズできます。

MLE環境で指定されたオプションは、デフォルト設定よりも優先されます。

複数の言語オプションを'<key>=<value>'文字列のカンマ区切りリストとして指定できます。次のスニペットは、JavaScriptの厳密モードを適用する方法を示しています。

CREATE MLE ENV MyEnvOpt
    LANGUAGE OPTIONS 'js.strict=true';

環境の言語オプションに加えられた変更は、その環境を使用してすでに作成されている実行コンテキストには伝播されません。既存のコンテキストに対して変更を有効にするには、そのコンテキストを削除して再作成する必要があります。

ノート:

キー、等号および値の間に空白文字は使用できません。

トピック

JavaScript言語オプション

MLEで使用できるJavaScript言語オプションの完全なリストが含まれています。

表2-1 JavaScript言語オプション

言語オプション 受け入れられる値の型 デフォルト 説明
js.strict ブール false 厳密モードを適用します。
js.console ブール true consoleグローバル・プロパティを指定します。
js.polyglot-builtin ブール true Polyglotグローバル・プロパティを指定します。

MLE環境の削除

不要になったMLE環境は、DROP MLE ENVコマンドを使用して削除できます。

次のスニペットは、MLEモジュールを削除する基本的な例を示しています:

DROP MLE ENV myOldEnv;

MLEモジュールと同様に、IF EXISTS句は、次のスニペットに示すように、指定されたMLE環境が存在しない場合のエラーを防ぎます:

DROP MLE ENV IF EXISTS myOldEnv;

MLE環境の変更

既存のMLE環境は、ALTER MLE ENVコマンドを使用して変更できます。

言語オプションとインポート句を変更できます。

トピック

言語オプションの変更

MLEモジュールに指定されている言語オプションを変更できます。

次のスニペットに示すように、ALTER MLE ENV句を使用して言語オプションを変更します:

ALTER MLE ENV MyEnvOpt
    SET LANGUAGE OPTIONS 'js.strict=false';
モジュール・インポートの変更

MLEモジュール・インポートのコンテキストで、ALTER MLE ENVコマンドを使用すると、追加のインポートを追加したり、既存のインポートを変更および削除できます。

環境の作成中に指定されていないインポートは、ADD IMPORTS句を使用して既存のMLE環境に追加できます。定義したインポート名は静的であり、必要に応じて追加する前に削除する必要があります。例2-1IMPORT_EXAMPLE_MODULEをモジュール名IMPORT_EXAMPLE_MODULE_V2に置き換えるために新しいCREATE MLE DDLを実行したとすると、次の文が正常に実行されます:


ALTER MLE ENV po_env 
ADD IMPORTS (
    'import_example' MODULE IMPORT_EXAMPLE_MODULE_V2
);

不要になったインポートは、DROP IMPORTS句を使用して削除できます:

ALTER MLE ENV po_env DROP IMPORTS('import_example');

インポート識別子の大/小文字は、データ・ディクショナリのUSER_MLE_ENV_IMPORTSビューのものと一致する必要があります。

MLE JavaScript環境に関連するディクショナリ・ビュー

MLE環境の詳細は、USER_MLE_ENVSビューおよびUSER_MLE_ENV_IMPORTSビューのファミリで入手できます。

USER接頭辞に加えて、これらのビューは、すべてのネームスペース(CDBDBAALLおよびUSER)に存在します。

トピック

USER_MLE_ENVS

USER_MLE_ENVSビューには、使用可能なすべてのMLE環境が定義済の言語オプションとともにリスト表示されます。

*_MLE_ENVSの詳細は、『Oracle Databaseリファレンス』を参照してください。

例2-15 USER_MLE_ENVSを使用した使用可能なMLE環境のリスト表示

SELECT ENV_NAME, LANGUAGE_OPTIONS
FROM USER_MLE_ENVS
WHERE ENV_NAME='MYENVOPT'
/

SQL*Plus出力の例:

ENV_OWNER            ENV_NAME   LANGUAGE_OPTIONS
-------------------- ---------- ----------------------
JSDEV01              MYENVOPT   js.strict=true
USER_MLE_ENV_IMPORTS

ビューの[USER | ALL | DBA | CDB]_MLE_ENV_IMPORTSファミリには、インポートされたモジュールがリスト表示されます。

MLE環境は、インポートされたモジュールの名前を解決するための主要なイネーブラです。例2-16は、IMPORT_NAMEMODULE_OWNERおよびMODULE_NAMEをリスト表示するUSER_MLE_ENV_IMPORTSに対する問合せを示しています。

*_MLE_ENV_IMPORTSの詳細は、『Oracle Databaseリファレンス』を参照してください

例2-16 USER_MLE_ENV_IMPORTSを使用したモジュール・インポート情報のリスト表示

SELECT IMPORT_NAME, MODULE_OWNER, MODULE_NAME
    FROM USER_MLE_ENV_IMPORTS
    WHERE ENV_NAME='MYFACTORIALENV';
/

SQL*Plus出力:

IMPORT_NAME            MODULE_OWNER              MODULE_NAME
---------------------- ------------------------- ------------------
FACTORIAL_MOD          DEVELOPER1                FACTORIAL_MOD