Java ストアドプロシージャの開発¶
Virtual DataPort は Java でカスタムのストアドプロシージャを開発するための API を備えています。
ストアドプロシージャを開発したら、そのプロシージャを Virtual DataPort サーバーにインポートする必要があります。その方法については、管理ガイドの「 Java ストアドプロシージャのインポート 」のセクションを参照してください。
Denodo Platform には、ストアドプロシージャのサンプルとそのソースコードがいくつか付属します。これらは <DENODO_HOME>/samples/vdp/storedProcedures
にあります。このパス内の README ファイルでは、これらのサンプルのコンパイルおよびインストールの手順について説明しています。
ストアドプロシージャを開発して Virtual DataPort にインポートした後は、Denodo ナレッジベースの記事「 How to debug Denodo custom extensions with Eclipse 」を読んでデバッグ方法について確認してください。
ストアドプロシージャを開発するためのクラスとインターフェイスは、パッケージ com.denodo.vdb.engine.storedprocedure
にあります。
ここでは、このパッケージのメインクラスの使用方法について簡単に説明します。各メインクラスとそのクラスのメソッドの詳細については、 Javadoc のドキュメント を参照してください。
ストアドプロシージャを作成するには、 com.denodo.vdb.engine.storedprocedure.AbstractStoredProcedure
を拡張する新しい Java クラスを作成します。
注釈
ストアドプロシージャが呼び出されるたびに、実行エンジンはこのクラスのインスタンスを作成します。そのため、このクラスは、プロシージャの実行中にその状態を格納する属性を持つことができます。たとえば、クエリで結果セットを処理する場合、処理された行の数などを持つことができます。
以下のメソッドをオーバーライドする必要があります。
public String getName()
このメソッドは、ストアドプロシージャの名前を返す必要があります。
NULL
を返すことはできません。public String getDescription()
このメソッドは、ストアドプロシージャの説明を返す必要があります。
NULL
を返すことはできません。public StoredProcedureParameter[] getParameters()
このメソッドは、プロシージャが呼び出されるたびに 1 回呼び出されます。
このメソッドは、ストアドプロシージャの入力パラメータと出力パラメータの配列を返す必要があります。各パラメータは
StoredProcedureParameter
オブジェクトで表されます。1 つのStoredProcedureParameter
オブジェクトで、1 つのパラメータの名前、型、方向 (入力、出力、またはこの両方)、および「NULL 可能性」 (NULL
値を受け入れるかどうか) を指定します。パラメータが複合型の場合は、そのフィールドについて説明する
StoredProcedureParameter
オブジェクトの配列を指定する必要があります。このメソッドは
NULL
を返すことはできません。入力パラメータも出力パラメータも持たない場合は、空の配列を返す必要があります。例: 「 Definition of the parameters of a stored procedure with compound fields 」には、以下のパラメータを持つストアドプロシージャの
getParameters()
メソッドが含まれています。text
型の入力パラメータ。レジスターの配列である出力パラメータ。これらのレジスターは、
field1
(text
) とfield2
(int
) の 2 つのフィールドを持っています。
public StoredProcedureParameter[] getParameters() {
return new StoredProcedureParameter[] {
new StoredProcedureParameter("parameter1", Types.VARCHAR, StoredProcedureParameter.DIRECTION_IN),
new StoredProcedureParameter("compound_field", Types.ARRAY, StoredProcedureParameter.DIRECTION_OUT,
true,
new StoredProcedureParameter[] {
new StoredProcedureParameter("field1", Types.VARCHAR,
StoredProcedureParameter.DIRECTION_OUT),
new StoredProcedureParameter("field2", Types.INTEGER,
StoredProcedureParameter.DIRECTION_OUT) }) };
}
public void doCall(Object[] inputValues)
このプロシージャが呼び出されると、実行エンジンはこのメソッドを呼び出します。
プロシージャが結果を返す必要がある場合は、スーパークラスの
getProcedureResultSet():StoredProcedureResultSet
メソッドを呼び出して、このプロシージャが返す行のリストの参照を取得する必要があります。その後、返す行ごとに、StoredProcedureResultSet
のaddRow(...)
メソッドを呼び出します。例: プロシージャが、「 Definition of the parameters of a stored procedure with compound fields 」で定義されているもののような
compound_field
という名前の単一の出力フィールドを持っているとします。この場合、次のコードスニペットは、個々の行を構築して結果セットに追加します。
@Override
protected void doCall(Object[] inputValues) throws
SynchronizeException, StoredProcedureException {
...
...
...
Object[] row = new Object[1];
List<Struct> compoundField = new ArrayList<Struct>(values.size());
List<String> fieldsNames = Arrays.asList("field1", "field2");
/*
* 'values' was generated before
*/
for (Map.Entry<String, Integer> value : values.entrySet()) {
List structValues = Arrays.asList(value.getKey()
, value.getValue());
Struct struct = super.createStruct(fieldsNames, structValues);
compoundField.add(struct);
}
row[0] = createArray(compoundField, Types.STRUCT);
getProcedureResultSet().addRow(row);
}
必要に応じて、以下のメソッドをオーバーライドすることもできます。
public void initialize(DatabaseEnvironment environment)
クエリによってこのストアドプロシージャが実行されるたびに、実行エンジンはこのメソッドを 1 回呼び出します。このメソッドを、初期化タスクを実行するようにオーバーライドすることができます。
DatabaseEnvironment クラスは、プロシージャの実行に役立つ以下のメソッドを備えています。
executeQuery
メソッドおよびexecuteUpdate
メソッドを使用して、クエリを実行します。これらのメソッドの一部のシグネチャは
Object[] parameterValues
パラメータを持ちます。これらのメソッドでは、VQL ステートメント内のパラメータをプレースホルダー?
で示し、その後、その値を配列で渡すことができます。ストアドプロシージャから実行されたすべてのクエリをキャンセルするには、以下を実行します。
((DatabaseEnvironmentImpl) this.environment).cancelQueries()
executeVqlCommand
メソッドを使用して VQL コマンドを実行します。このメソッドの一部のシグネチャは、コマンドが実行されるデータベースを示す
String databaseName
パラメータを持ちます。本番サーバーのメタデータを変更するコマンドは実行しないことを強くお勧めします。
他のストアドプロシージャへの参照を取得するには、
lookupProcedure(...)
を呼び出します。関数の参照を取得するには、
lookupFunction(...)
を呼び出します。新しいトランザクションを作成するには、
createTransaction(...)
を呼び出します。現在のトランザクションにストアドプロシージャを追加するには、
joinTransaction(...)
を呼び出します。サーバーのログにメッセージを書き込むには、
log(...)
を呼び出します。サーバーのプロパティの値を取得するには、
getDatabaseProperty(...)
を呼び出します。リクエストできるプロパティは、CURRENT_USER
(現在のユーザーのユーザー名) とCURRENT_DATABASE
(現在のデータベース) です。
super.getEnvironment()
を呼び出すことによって、DatabaseEnvironment
への参照を他のメソッドから取得できます。public boolean stop()
このストアドプロシージャに関連するクエリがキャンセルされると、実行エンジンはこのメソッドを呼び出します。
AbstractStoredProcedure
クラスが備えているこのメソッドのデフォルトの実装は、何も行わず、単にfalse
を返します。このプロシージャが実行するタスクがキャンセル可能なものであれば、このメソッドをオーバーライドして、タスクをキャンセルしてください。このプロシージャが他のシステムへのコネクションを開いたり、ファイルを開いたりする場合は、このメソッドからそれらのリソースを閉じます。
このメソッドが
true
を返したら、プロシージャは、このメソッドの呼び出し後に確実に完了する必要があります。メソッドがこのプロシージャの呼び出し後に完了しない場合は、false
を返すようにします。このプロシージャでこのメソッドを上書きしない場合、実行エンジンはこのプロシージャの実行を中断しようとします。そのため、このメソッドの上書きは、推奨されますが必須ではありません。
public void prepare()
実行エンジンは、このプロシージャに関連するトランザクションを開始しようとするときに、このメソッドを呼び出します。
public void commit()
実行エンジンは、現在のトランザクションを確定する場合にこのメソッドを呼び出します。
public void rollback()
実行エンジンは、現在のトランザクションを元に戻す場合にこのメソッドを呼び出します。
public boolean caseSensitiveParameters()
ストアドプロシージャで定義している入力パラメータと出力パラメータの名前で大文字と小文字が区別される場合は、このメソッドをオーバーライドして
true
を返すようにします。public void log(level, message)
Virtual DataPort のログシステムにメッセージを記録します。メッセージは、このプロシージャのクラスの名前が付いたログカテゴリに追加されます。つまり、プロシージャのクラスが
com.acme.procedure1
である場合、メッセージはカテゴリcom.acme.procedure1
に追加されます。このログカテゴリが有効化されていると、メッセージは
<DENODO_HOME>/logs/vdp/vdp.log
に記録されます。ログカテゴリを有効化するには、
<DENODO_HOME>/conf/vdp/log4j.xml
を変更するか、またはLOGCONTROLLER
ストアドプロシージャを呼び出します。詳細については、管理ガイドの「 ログエンジンの構成 」を参照してください。
AbstractStoredProcedure
には、この他にも以下の有用なメソッドがあります。
static java.sql.Struct createStruct(Collection values, int type)
: このメソッドは、SQL 型オブジェクトstruct
を作成します。エレメントのレジスターを作成するには、このメソッドを呼び出します。「 Stored procedures: building a row of a compound type 」の例を参照してください。static java.sql.Array createArray(Collection values, int type)
: このメソッドは配列を返します。エレメントの配列を作成するには、このメソッドを呼び出します。リスト内のエレメントはjava.sql.Struct
型でなければなりません。この型のエレメントはcreateStruct(...)
を呼び出すことによって作成できます。「 Stored procedures: building a row of a compound type 」の例を参照してください。