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 」の例を参照してください。
