Sun WBEM SDK 開発ガイド

WQL 照会の処理

WBEM クライアントは、CIMClient クラスの execQuery メソッドを使って、一連の検索条件に一致するインスタンスを検索します。CIM Object Manager は、CIM Object Manager Repository に格納されている CIM データのクライアント照会を処理すると共に、特定のプロバイダから提供される CIM データの照会をプロバイダに渡します。

すべてのインスタンスプロバイダは、com.sun.wbem.provider20 パッケージにある execQuery インタフェースを実装して、インスタンスプロバイダ自身が提供する動的データのクライアント照会を処理する必要があります。プロバイダは、com.sun.wbem.query パッケージにあるクラスやメソッドを使って、WQL (WBEM Query Language) の照会文字列をフィルタリングすることができます。インデックスを処理するエンティティへのアクセス権を持つプロバイダは、照会文字列をこのエンティティに渡して解析してもらうことができます。

照会 API による照会文字列の解析

com.sun.wbem.query パッケージ中のクラスやメソッドは、WQL パーサーと、解析する WQL 文字列を表しています。このパッケージには、照会文字列内の節を表すクラスと、これらの節の中の文字列を処理するメソッドが含まれています。

現在のところ解析可能な WQL 式のタイプは SELECT 式だけです。SELECT 式には次の部分が含まれています。

WQL の式

次の図は、WQL 式中の節と WBEM クラスの対応を表したものです。

図 5–1 WQL 式を表す WBEM クラス

Graphic

WQL 

WBEM 照会クラス 

SELECT attribute_expression

SelectList

FROM table_attribute

FromExp

WHERE conditional_expression

QueryExp

WQL は、CIM データモデルに基づいて格納されるデータを照会できるようになっています。CIM モデルでは、オブジェクトに関する情報は CIM クラスや CIM インスタンスに格納されます。CIM インスタンスには、名前、データ型、値からなるプロパティを持含めることができます。WQL は、次の表に示すように CIM オブジェクトモデルを SQL テーブルにマップします。

SQL 

WQL 

テーブル 

CIM クラス 

行 

CIM インスタンス 

列 

CIM プロパティ 

CIM の WQL 式は、次の形式で表すことができます。


SELECT FROM WHERE CIM property CIM class propertyA = 40

次はより実際的な WQL 式の例です。



SELECT * FROM Solaris_FileSystem WHERE (Name="home" OR Name="files") AND AvailableSpace > 2000000

SELECT 文

SelectExp クラスは、SELECT 分を表します。

SELECT 文は、情報検索に使用される SQL 文ですが、WQL SELECT 文には、WQL 特有の制約と拡張がいくつかあります。SQL SELECT 文は、通常データベース環境でテーブルから特定の列を検索するのに使用されます。WQL SELECT 文は、単一クラスのインスタンスを検索するのに使用されます。WQL では、複数のクラスに渡る照会はサポートされません。

検索リストは SELECT 式で表されます。SELECT 文には次の形式があります。

SELECT 文 

選択されるもの 

SELECT *

指定されたクラスとそのすべてのサブクラスのすべてのインスタンス。 

SELECT attr_exp, attr_exp...attr_exp

指定されたクラスとそのすべてのサブクラスのすべてのインスタンスのうち、指定された識別子をもっているものだけ。 

FROM 節

FROM 節は、abstract クラス fromExp によって表されます。現在のところ、fromExp の直接のサブクラスは NonJoinExp だけです。NonJoinExp は、1 つのテーブル (CIM クラス) だけを指定した FROM 節を表しています。select 操作はこのテーブルに対して行われます。

FROM 節では、照会文字列に一致するインスタンスが含まれているクラスを指定します。SQL では、FROM 節に修飾子付き属性式を指定します。これが検索するクラスの名前になります。修飾子付き属性式には、そのテーブルとクラスを指定します。現在のところ WQL FROM 節では、非 join 式だけがサポートされます。したがって、WQL FROM 節には 1 つのクラスしか指定できません。

WHERE 節

QueryExp クラスは、その各サブクラスが条件式を表している abstract クラスです。特定の CIMInstance がこれらの条件式に適用されると、ブール値を返します。

WHERE 節は、照会のスコープを狭めるためのものです。WHERE 節には条件式が含まれています。これらの条件式には、プロパティまたはキーワード、演算子、定数が含まれています。WHERE 節には、あらかじめ定義された WQL 演算子のいずれかを指定する必要があります。

SELECT 文の後に追加する WHERE 節の基本的な構文は、次のとおりです。

SELECT FROM WHERE CIM instance CIM class conditional_expression

WHERE 節の条件式は、次の形式です。

 
property operator constant

QueryExp クラスの次の各サブクラスは、WHERE 節における条件式の特定のタイプに対応しています。

WHERE 節の条件式は QueryExp クラスで表されます。条件式はツリー構造になっています。たとえば、条件式 (a=2 and b=3 or c=4) は、次のようなツリー構造で表されます。

QueryExp クラスは照会式ツリーのトップレベルだけを返します (上の例では ORQueryExp)。これによって、プロバイダは、そのクラス内のメソッドを使って照会式ツリーの分岐を下方にたどることができます。

canonize メソッドの使用

プロバイダが WQL 照会文字列を別のエンティティに渡し、この文字列を解析させるには、次のメソッドが便利です。

WQL 照会文字列を解析するプロバイダの作成

照会 API を使って WQL 照会文字列を解析するプロバイダを作成する一般的な手順は、次のとおりです。

WQL 照会文字列を解析するプロバイダを作成する方法
  1. WQL パーサーを初期化します。以下に例を示します。


     
        /* CIM Object Manager から execQuery に渡された
           照会文字列を入力データストリームに読み込む */
        ByteArrayInputStream in = new ByteArrayInputStream(query.getBytes()); 
    
        /* 入力データストリームを使ってパーサーを初期化する */
        WQLParser parser = new WQLParser(in);
           

  2. 照会結果を格納するベクトルを作成します。以下に例を示します。


     
        Vector result = new Vector();

  3. 照会から select 式を取得します。以下に例を示します。


     
        /* querySpecification がパーサーから WQL 式を返す
          (SelectExp)parser が WQL 式を select 式にキャストする */
        SelectExp q = (SelectExp)parser.querySpecification();  

  4. select 式から select リストを取得します。以下に例を示します。


     
        /* SelectExp クラスの SelectList メソッドを使って
           select リストを返す。select リストとは、
           属性または CIM プロパティのリスト */
        SelectList attrs = q.getSelectList();     

  5. From 節を取得します。以下に例を示します。


     
        /* SelectExp クラスの getFromClause メソッドを使って
           From 節を返す。From 節を非 join 式 
           (単一の CIM クラスを表すテーブル) にキャストする */
        NonJoinExp from = (NonJoinExp)q.getFromClause();

  6. enumInstances メソッドを使ってクラスの詳細列挙を返します。以下に例を示します。


     
       /* 指定されたクラス (cc) に属するすべてのインスタンス
          (継承されたプロパティとローカルプロパティを含む) を返す */
        Vector v = new Vector();
        v = enumInstances(op, true, cc, true);
        ...  

  7. 列挙のインスタンスを 1 つずつ処理し、その中で各インスタンスを照会式および select リストと比較します。以下に例を示します。


     
      /* WHERE 節の照会式が CIM インスタンスと 
    	   一致するかを比較する。select リストを CIM インスタンスに 
         適用し、select リストと一致するインスタンス  
         (CIM プロパティのリスト) を結果に追加する。 */
      for (int i = 0; i < v.size(); i++) {
    	  if ((where == null) || // WHERE 節があるか
      	    (where.apply((CIMInstance)v.elementAt(i)) == true)) { 
    	         result.addElement(attrs.apply((CIMInstance)v.elementAt(i)));
       ...        

  8. 照会結果を返します。以下に例を示します。

    return result;

例 — execQuery メソッドの実装

例 5–6 のサンプルプログラムでは、execQuery メソッドによって渡された WQL 文字列を、照会 API を使って解析します。このプログラムは、照会文字列中の Select 式を解析し、クラスを詳細列挙します。そして、列挙の各インスタンスを 1 つずつ処理して、各インスタンスを照会式および select リストと比較します。最後にプログラムは、照会文字列と一致するインスタンスの列挙が含まれているベクトルを返します。


例 5–6 execQuery メソッドを実装するプロバイダ

/*
     * execQuery メソッドは、部分的なキーマッチングに基づく限られた照会 
     * しかサポートしない。照会によって選択されたエントリがないと、
     * 空の Vector を返す
     *
     * @param	op			返される CIM インスタンスの CIM オブジェクトパス
     * @param	query	CIM 照会式
     * @param	ql			CIM 照会言語のインジケータ
     * @param	cc			CIM クラス参照
     *
     * @return	CIM オブジェクトインスタンスのリスト
     *
     * @version    1.19	01/26/00
     * @author	   Sun Microsystems, Inc.
     */
    public Vector execQuery(CIMObjectPath op, 
			    String query, 
			    int ql,
			    CIMClass cc) 
	    throws CIMException {

	ByteArrayInputStream in = new ByteArrayInputStream(query.getBytes());
	WQLParser parser = new WQLParser(in);
	Vector result = new Vector();
	try {
	    SelectExp q = (SelectExp)parser.querySpecification();
	    SelectList attrs = q.getSelectList();
	    NonJoinExp from = (NonJoinExp)q.getFromClause();
	    QueryExp where = q.getWhereClause();

	    Vector v = new Vector();
	    v = enumInstances(op, false, cc, true);

	    // インスタンスをフィルタリングする
	    for (int i = 0; i < v.size(); i++) {
		    if ((where == null) || (where.apply((CIMInstance)v.elementAt(i)) == true)) {
		        result.addElement(attrs.apply((CIMInstance)v.elementAt(i)));
		     } 
	    }
	} catch (Exception e) {
	    throw new CIMException(CIMException.CIM_ERR_FAILED, e.toString());
	}
	return result;
    } // execQuery
}