11 カートリッジ・サービスの使用

カートリッジ・サービスの使用方法について説明します。

11.1 カートリッジ・サービスの概要

カートリッジ・サービスは、Oracle Extensibilityフレームワークでデータ・カートリッジを作成する際に役立つ一連のサービスです。

Oracleカートリッジ・サービスを使用すると、次のようなメリットがあります。

移植性

Oracleカートリッジ・サービスは、様々なマシン・アーキテクチャにまたがって作業できる柔軟性を提供します。

Oracle環境内での柔軟性

すべてのカートリッジ・サービスが、クライアントが購入した操作の構成に関係なくOracle Databaseで動作するという点で、新たなタイプの柔軟性を得られます。

言語独立性

グローバリゼーション・サポート・サービスの使用により、カートリッジを国際化できます。言語独立性とは、カートリッジの様々なインスタンスを異なる言語環境で操作できることを意味します。

サーバーとの緊密な統合

Oracle ORDBMSへのアクセスを容易にするために、各種のカートリッジ・サービスが設計されています。これにより、同じ操作を実行しようとするクライアント側プログラムのパフォーマンスが大幅に向上します。

保証付きの互換性

Oracle Databaseのテクノロジは急速に進化しており、すべてのクライアントが同じリリースのOracleを運用しているとはかぎりません。カートリッジ・サービスは、すべてのバージョンのOracle Databaseで動作します。

様々なカートリッジの統合

カートリッジ・サービスの統合により、様々なデータ・カートリッジの均一な統合を生成できます。

データ・カートリッジの一部として使用できるサービス・セットについて説明します。これらのインタフェースを記述するAPIについては、C、C++およびJavaを使用したカートリッジ・サービスを参照してください。

11.2 カートリッジ・ハンドル

カートリッジ・サービスは、次の2種類のOCIハンドルにカプセル化された各種のハンドルを必要とします。

環境ハンドル

環境ハンドルはOCIEnvまたはOCI_HTYPE_ENVです。セッションが使用できない場合は、プロセス・レベルで各種のカートリッジ・サービスが必要です。OCIInitialize()では、カートリッジ・サービスにOCI_OBJECTオプションを使用する必要があります。

ユーザー・セッション・ハンドル

ユーザー・セッション・ハンドルはOCISessionまたはOCI_HTYPE_SESSIONです。コールアウトでは、データベースへの接続をオープンしなくても、ハンドルが割り当てられる場合にサービスを使用できます。

すべてのカートリッジ・サービス・コールは、環境ハンドルまたはセッション・ハンドルである引数の1つとしてvoid * OCIハンドルを取ります。ほとんどのサービス・コールにはいずれかのハンドルを使用できますが、一方のハンドルでは無効なコールがあります。たとえば、環境ハンドルを使用してOCI_DURATION_SESSIONを割り当てるとエラーになる場合があります。通常、エラーはエラー・ハンドルで戻されます。

11.2.1 クライアント側での使用

ほとんどのカートリッジ・サービスは、クライアント側コードでも使用できます。制限事項については、各サービスを参照してください。クライアント側でカートリッジ・サービスを使用するには、OCI_OBJECTオプションを指定してOCI環境を初期化する必要があります。これは自動的にカートリッジに反映されます。

11.2.2 カートリッジ側での使用

この章で説明するサービスのほとんどはデータベース・カートリッジの開発に使用できますが、制限事項については各サービスのドキュメントを参照してください。コールアウトでセッション・ハンドルを取得するために、新規サービス・コールを使用できます。セッション・ハンドルは、サーバーへの接続をオープンせずに使用できます。

11.2.3 サービス・コール

いずれかのサービスを使用する前に、OCI環境ハンドルを初期化する必要があります。すべてのサービスは引数としてOCI環境(またはuser_session)ハンドルを取ります。エラーはOCIエラー・ハンドルで戻されます。各種サービス・コールに必要なサブ・ハンドルがOCI環境変数とともに割り当てられることはありません。環境を初期化する必要のあるサービスには、初期化メソッドが用意されています。例11-1に、この種のハンドルの初期化を示します。

例11-1 OCIハンドルの初期化

{
  OCIEnv *envhp;
  OCIError *errhp;
  (void) OCIInitialize(OCI_OBJECT, (dvoid *)0, 0, 0, 0);
  (void) OCIEnvInit(&envhp, OCI_OBJECT, (size_t)0, (dvoid **)0);
  (void) OCIHandleAlloc((dvoid *)envhp, (dvoid **)errhp,   OCI_HTYPE_ERROR, 
      (size_t)0, (dvoid **)0);
  /* ... use the handles ... */
  (void) OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR);
}

11.2.4 エラーの処理

通常、エラーを戻すルーチンにより、OCI_SUCCESSまたはOCI_ERRORが戻されます。OCI_SUCCESS_WITH_INFOOCI_INVALID_HANDLEまたはOCI_NO_DATAを戻すルーチンもあります。OCI_ERRORまたはOCI_SUCCESS_WITH_INFOが戻された場合は、例11-2で示すように、OCIErrorGetをコールすることでエラー・コード、エラー機能および場合によってはエラー・メッセージを取得できます。

例11-2 OCIErrorGet()を使用したエラー情報の取得

{
  OCIError *errhp;
  ub4 errcode;
  text buffer[512];
  (void) OCIErrorGet((dvoid *)errhp, 1, (text *)NULL, &errcode, buffer,
      sizeof(buffer), OCI_HTYPE_ERROR);
}

11.3 メモリー・サービス

メモリー・サービスにより、クライアントはメモリー・チャンクを割り当てたり解放できます。各メモリー・チャンクは期間に関連付けられています。これにより、クライアントは期間に関連付けられている全メモリーを(期間の終了時に)自動的に解放できます。期間により、メモリーの割当てに使用されるヒープが決定されます。メモリー・サービスでは、コール(OCI_DURATION_CALL)、文(OCI_DURATION_STATEMENT)およびセッション(OCI_DURATION_SESSION)という3種類の期間が事前定義されます。

クライアントはユーザー期間を作成することもできます。クライアントは、ユーザー期間を明示的に開始および終了する必要があります。そのため、クライアントはユーザー期間の長さを制御できます。事前定義済の期間と同様に、ユーザー期間を使用して割当て期間を指定できます(たとえば、メモリー・チャンクはユーザー期間の終了時に解放されます)。

各ユーザー期間には親期間があります。親期間が終了すると、ユーザー期間が暗黙的に終了します。親期間として、コール期間、文期間、トランザクション期間、セッション期間または他のユーザー期間を使用できます。ユーザー期間中に割り当てられたメモリーは、親期間のヒープから取り込まれます。

Oracle RDBMSメモリー・マネージャは、様々なメモリー・モデルをサポートしています。現在、コールアウトはそのコールアウトの期間についてメモリーをサポートしています。外部索引付けをサポートするように行ソースが拡張されており、期間のメモリー所要量はコールアウトの場合よりも大きくなっています。

次の機能がサポートされています。

  • 次の期間のメモリー(永続および非永続)の割当て。

    • エージェント・プロセスのコール

    • セッション

    • カートリッジの共有属性(メタデータ)

  • メモリー再割当て機能。

  • サブ期間メモリー(親ヒープが解放されると解放されるサブ・ヒープ)の作成機能。このサブ・ヒープのメモリーを割り当てて解放できます。

  • ゼロ指定メモリーの指定機能。

  • 連続する大きいメモリーの割当て機能。

11.4 コンテキストの維持

コンテキスト管理により、クライアントは複数のコールにまたがって値を格納できます。カートリッジ・サービスは、コンテキストを保存およびリストアするためのメカニズムを提供します。

スレッドをサポートしているほとんどのオペレーティング・システムには、スレッド・コンテキストの概念があります。スレッドでは、このコンテキスト(または状態)にスレッド固有のデータを格納し、任意の時点で取り出すことができます。これにより、スレッド・グローバル変数の表記法が提供されます。通常は、構造のルートを指すポインタがコンテキストに格納されます。

行ソース・メカニズムが外部化される場合は、同じ行ソースへの複数のコール間で状態を維持するためのメカニズムが必要です。

セッション、文およびプロセスの状態を維持する必要があります。セッションの状態には、オープンしている複数の文、セッションのグローバリゼーション・サポート設定に基づくメッセージ・ファイルなどの情報が含まれます。プロセスの状態には、共有メタデータ(システム単位のメタデータなど)、メッセージ・ファイルなどが含まれます。カートリッジ・アプリケーションが実際にマルチ・スレッド化されているかどうかに応じて、情報をプロセス・レベルまたはシステム・レベルで共有できます。

ユーザーは必要に応じて複数のカートリッジを使用できるため、カートリッジごとに状態を維持する必要があります。そのために、ユーザーは期間ごとにキーを入力するように要求されます。

11.4.1 期間

メモリーおよびコンテキスト管理コールでは、各種の事前定義済期間がサポートされています。これらのコールのもう1つのパラメータがコンテキストです。

  • OCI_DURATION_CALL。この操作の期間はコールアウトの期間です。

  • OCI_DURATION_STATEMENT。この操作の期間は外部行ソースです。

  • OCI_DURATION_SESSION。この操作の期間はユーザー・セッションです。

  • OCI_DURATION_PROCESS。この操作の期間はエージェント・プロセスです。

11.5 グローバリゼーション・サポート

多言語アプリケーションをサポートするために、カートリッジとコールアウトにはグローバリゼーション・サポート機能が必要です。NLSRTLは現在RDBMSで使用されているマルチプラットフォーム多言語ライブラリであり、すべてのOracle製品に一貫性のあるグローバリゼーション・サポート動作を提供します。

グローバリゼーション・サポートの基本サービスは、言語および文化に依存する次の機能を提供します。

  • ロケール情報の検索

  • マルチバイトおよびワイド・キャラクタの書式による文字列の操作

  • Unicodeサポートを含むキャラクタ・セット変換

  • メッセージング・メカニズム

11.5.1 グローバリゼーション・サポートの言語情報検索

Oracleロケールは、言語、地域およびキャラクタ・セット定義で構成されています。ロケールにより、システム固有の曜日名、月名、日付書式、時刻書式、数値書式および通貨書式などの変換が決定されます。国際化されたアプリケーションは、ユーザーのロケール設定と各国対応変換に従います。たとえば、ドイツ語ロケール設定では、ユーザーは曜日名と月名がドイツ語のスペルで表示されるものと想定します。次のインタフェースは、ローカル依存情報を取り出す最も単純な方法を提供します。

11.5.2 文字列操作

文字列操作の場合、マルチバイト文字列およびワイド・キャラクタ文字列という2種類のデータ構造がサポートされています。マルチバイト文字列にはシステム固有のOracleキャラクタ・セット・エンコーディングが使用され、それに対するファンクションは文字列全体を1単位として取ります。ワイド・キャラクタ文字列ファンクションは文字列操作よりも柔軟性が高く、キャラクタ・ベースと文字列ベースの操作をサポートします。

ここで使用するワイド・キャラクタ・データ型はOracle固有であり、ANSI/ISO C標準で定義されているwchar_tと混同しないでください。Oracleワイド・キャラクタはすべてのプラットフォームで常に4バイトですが、wchar_tは実装およびプラットフォームに依存します。Oracleワイド・キャラクタの考え方は、マルチバイト文字を処理が容易になるように固定幅に標準化するというものです。Oracleワイド・キャラクタとネイティブ・キャラクタ・セットとの間のラウンドトリップ変換が保証されます。

文字列操作は、次のカテゴリに分類できます。

  • マルチバイト・キャラクタとワイド・キャラクタとの間の文字列変換

  • 文字の分類

  • 大/小文字の変換

  • 表示長の計算

  • 比較、連結および検索などの一般的な文字列操作

11.6 パラメータ・マネージャ・インタフェース

パラメータ・マネージャは、ファイルまたは文字列からのパラメータを処理する一連のルーチンを提供します。各ルーチンは、入力を処理してキーと値のペアを取得するために提供されます。このキーと値のペアはメモリーに格納され、格納されたパラメータの値にアクセスできるルーチンが提供されます。

入力処理ルーチンは、ファイルの内容または文字列を既存の構文と照合し、入力に含まれるキー名をユーザーが登録した既知のキーのリストと比較します。入力処理ルーチンの動作は、フラグ引数に設定されるビットに応じて構成できます。

パラメータは一度に1つずつ取得するか、格納されているパラメータに対して反復するファンクションをコールして同時にすべてを取得できます。

11.6.1 特殊文字の入力処理とサポート

パラメータはキー名(またはパラメータ名)、型および値で構成され、key = valueの形式で指定する必要があります。

パラメータには、オプションで値リストをカッコで囲んで次のように指定できます。key = (value1, ..., valuen)またはkey = value1, ..., valuen

値は文字列、整数、OCINumberまたはブールです。yまたはtで始まるブール値はTRUEに対応し、nまたはfで始まるブール値はFALSEに対応します。ブール値の照合では大/小文字は区別されません。

パラメータ・マネージャには、特定の文字がリテラルに解析されない特殊文字として表示されます。表11-1に、特殊文字とその意味を示します。

表11-1 特殊文字

文字 説明

#

コメント(ファイルのみ)

(

値リストの開始

)

値リストの終了

"

引用符で囲む文字列の開始または終了

'

引用符で囲む文字列の開始または終了

=

キーワードと値のセパレータ

\

エスケープ文字

特殊文字をリテラルに処理する必要がある場合は、エスケープ文字で始めるか、文字列全体を一重引用符または二重引用符で囲む必要があります。

キー文字列に使用できるのは英数字のみです。値には任意の文字を使用できます。ただし、特殊文字を使用するには、引用符で囲むかエスケープ文字を付ける必要があります。

11.6.2 パラメータ・マネージャの動作フラグ

ファイルまたは文字列を処理するルーチンは、パラメータ・マネージャのデフォルト特性を変更する動作フラグを使用します。フラグには、次のビットを設定できます。

  • OCI_EXTRACT_CASE_SENSITIVEすべての比較で大/小文字が区別されます。デフォルトでは、大/小文字を区別しない比較が使用されます。

  • OCI_EXTRACT_UNIQUE_ABBREVSキーに一意の略語を使用できます。デフォルトでは一意の略語は使用できません。

  • OCI_EXTRACT_APPEND_VALUES特定のキーに1つ以上の値が格納されている場合は、このキーの新規の値を追加する必要があります。デフォルトではエラーが戻されます。

11.6.3 キーの登録

入力処理ルーチン(OCIExtractFromFile()またはOCIExtractFromString())を起動する前に、OCIExtractSetNumKeys()に続けてOCIExtractSetKey()をコールして次の情報を指定し、すべてのキーを登録する必要があります。

  • キー名。

  • キーの型(integerstringbooleanOCINumber)。

  • 複数の値が許可される場合は、フラグ値にOCI_EXTRACT_MULTIPLEが設定されます(デフォルト: 許可される値は1つのみ)。

  • キーに使用するデフォルト値(NULL可)。

  • 開始値から終了値の範囲で指定した整数値の許容範囲(NULL可)。

  • 許容可能な文字列値のリスト(NULL可)。

11.6.4 パラメータの格納と取出し

キーと値のペアへの入力を処理した結果が格納されます。パラメータの妥当性は、メモリーへの格納前にチェックされます。値がチェックされて、適切な型かどうかが確認されます。また、必要な場合は、値をチェックして整数値の一定範囲に含まれるか、列挙した文字列値のリストのメンバーであるかを確認できます。キーに複数の値が許可されるように指定していない場合は、キーが特定の入力ソースで2回以上指定されているとエラーが戻されます。キーが不明な場合にもエラーが戻されます。処理の完了後に、文字列、整数、OCINumberまたはブール値を取り出す特定のルーチンを使用して、キー値を取り出すことができます。

すべてのパラメータを一度に取り出すことができます。最初にファンクションOCIExtractToList()をコールして、メモリーに格納されたパラメータ構造から作成されるパラメータのリストを生成する必要があります。OCIExtractToList()は、メモリーに格納されている一意キーの数を戻します。これにより、OCIExtractFromList()をコールして、各キーに関連付けられている値のリストを戻すことができます。

11.6.5 パラメータ・マネージャのコンテキスト

パラメータ・マネージャは、OCI環境ハンドル内で独自のコンテキストを維持します。このコンテキストには、すべての処理済パラメータ情報と一部の内部情報が格納されます。このコンテキストの初期化にはOCIExtractInit()のコール、クリーン・アップにはOCIExtractTerm()のコールを使用する必要があります。

11.7 ファイルI/O

OCIファイルI/Oパッケージは、複数のプラットフォームにまたがってファイルI/Oの一貫したビューを提供することで、ファイル・システムと相互作用する移植可能コードを容易に記述できるように設計されています。

このパッケージをデータ・カートリッジ環境で使用する際には、2つの問題に注意する必要があります。第1の問題は、ファイルを書込み用にオープンするときや、ファイルおよびディレクトリに対するオペレーティング・システム保護で提供されるセキュリティ以外のディレクトリに新規ファイルを作成するときには、このパッケージはセキュリティを提供しないことです。第2の問題は、このパッケージが、マルチスレッド化されたサーバー環境で複数のコールにまたがるファイル・ディスクリプタの使用をサポートしないことです。

11.8 文字列の書式設定

OCI文字列書式設定パッケージにより、OCIFormatString()ルーチンを使用して、文字列操作を処理する移植可能コードを容易に記述できます。これは、標準のsprintfにない追加機能とエラー・チェックを組み込むように改良されたsprintfの移植可能バージョンです。この追加機能は次のとおりです。

  • 任意の引数の選択

  • 可変幅および精度の指定

  • バッファの長さチェック

  • 国際化のためのOracleグローバリゼーション・サポート