%Dictionary クラスの使用
ここでは、クラス定義クラスについて説明します。このクラスは、すべてのクラス定義にオブジェクト・アクセスと SQL アクセスを提供する永続クラスのセットです。
クラス定義クラスの概要
クラス定義クラスは、すべてのクラス定義へのオブジェクト・アクセスと SQL アクセスを提供します。これらのクラスを使用して、クラス定義の調査、クラス定義の修正、新規クラスの生成をプログラムでできます。ドキュメントを自動生成するプログラムを記述することもできます。これらのクラスは、%Dictionary パッケージに含まれます。
%Library パッケージには、従来の一連のクラス定義クラスがあります。これらは既存のアプリケーションとの互換性のために保存されています。新規のコードでは、%Dictionary パッケージ内のクラスを使用する必要があります。これらのクラスを使用するときは、正しいパッケージ名を指定してください。
クラス定義クラスには、定義クラスとコンパイル・クラスの 2 つの並列セットがあります。
定義クラス定義は、特定のクラスの定義を表します。それは、そのクラスによって定義された情報のみを含み、スーパークラスから継承された情報は含みません。ディクショナリのクラスに関する情報を提供するだけでなく、これらのクラスを使用して、プログラム的にクラス定義を変更したり新規作成できます。
コンパイル・クラス定義は、スーパークラスから継承されるクラス・メンバをすべて含みます。コンパイル・クラス定義オブジェクトは、コンパイルされたクラスからインスタンスを生成するだけです。コンパイル・クラス定義は保存できません。
この付録では、定義クラス定義のみ説明します。コンパイル・クラス定義のオペレーションも類似しています。
定義クラスを表すクラス定義のファミリには、以下のものが含まれます。
クラス | 説明 |
---|---|
%Dictionary.ClassDefinitionOpens in a new tab | クラス定義を表します。クラス・メンバ定義を含むコレクションと、クラス・キーワードを含みます。 |
%Dictionary.ForeignKeyDefinitionOpens in a new tab | クラス内の外部キー定義を表します。 |
%Dictionary.IndexDefinitionOpens in a new tab | クラス内のインデックス定義を表します。 |
%Dictionary.MethodDefinitionOpens in a new tab | クラス内のメソッド定義を表します。 |
%Dictionary.ParameterDefinitionOpens in a new tab | クラス内のパラメータ定義を表します。 |
%Dictionary.PropertyDefinitionOpens in a new tab | クラス内のプロパティ定義を表します。 |
%Dictionary.QueryDefinitionOpens in a new tab | クラス内のクエリ定義を表します。 |
%Dictionary.TriggerDefinitionOpens in a new tab | クラス内の SQL トリガ定義を表します。 |
繰り返しますが、コンパイルされていないクラス定義 (%Dictionary.ClassDefinitionOpens in a new tab のインスタンスとして) の内容は、コンパイル済みクラス定義 (%Dictionary.CompiledClassOpens in a new tab のインスタンスとして) の内容と必ずしも同一ではありません。 %Dictionary.ClassDefinitionOpens in a new tab クラスは、クラスの定義を調査または変更する API を提供しますが、継承を解決したコンパイル済みクラスを表すことはありません。一方、%Dictionary.CompiledClassOpens in a new tab は、継承を解決したコンパイル済みクラスを表します。
例えば、クラス定義内の特定のキーワードの値を特定しようとする場合は、%Dictionary.ClassDefinitionOpens in a new tab の keywordnameIsDefined() メソッド (OdbcTypeIsDefined()Opens in a new tab や ServerOnlyIsDefined()Opens in a new tab など) を使用します。このブーリアン・メソッドが false を返す場合、キーワードはそのクラスに対して明示的に定義されていません。クラス定義のキーワードの値を調べると、それは既定値です。ただし、コンパイル (継承の解決を含む) の後では、キーワードの値は、継承によって決定され、定義されていた値とは異なることがあります。
クラス定義のブラウズ
管理ポータルの SQL ページを使用すると、クラス定義クラスを参照できます。
同様に、クラス定義全体をプログラムで参照することもできます。これは、その他の種類のデータを参照するために使用するのと同じ手法を使用します。ダイナミック SQL を使用したり、特定のクラス定義を表す永続オブジェクトをインスタンス化したりできます。
例えば、InterSystems IRIS® データ・プラットフォームのプロセスから、以下の %Dictionary.ClassDefinition:Summary() クエリを使用して、現在のネームスペースのディクショナリ内で定義されているすべてのクラスのリストを取得できます。
set stmt=##class(%SQL.Statement).%New()
set status = stmt.%PrepareClassQuery("%Dictionary.ClassDefinition","Summary")
if $$$ISERR(status) {write "%Prepare failed:" do $SYSTEM.Status.DisplayError(status) quit}
set rset=stmt.%Execute()
if (rset.%SQLCODE '= 0) {write "%Execute failed:", !, "SQLCODE ", rset.%SQLCODE, ": ", rset.%Message quit}
while rset.%Next()
{
write rset.%Get("Name"),!
}
if (rset.%SQLCODE < 0) {write "%Next failed:", !, "SQLCODE ", rset.%SQLCODE, ": ", rset.%Message quit}
このサンプル・メソッドは、現在のネームスペース内の表示可能なすべてのクラス (システム・ライブラリ・クラスを含む) の名前を書き込みます。%Dictionary.ClassDefinition:Summary() クエリによって返されたさまざまな列を使用して、望まないクラスをフィルタできます。
特定のクラス定義に関する詳細は、そのクラスの %Dictionary.ClassDefinitionOpens in a new tab オブジェクトを開き、そのプロパティを表示することで取得できます。%Dictionary.ClassDefinitionOpens in a new tab オブジェクトを格納するための ID は、そのクラス名です。
Set cdef = ##class(%Dictionary.ClassDefinition).%OpenId("Sample.Person")
Write cdef.Name,!
// get list of properties
Set count = cdef.Properties.Count()
For i = 1:1:count {
Write cdef.Properties.GetAt(i).Name,!
}
クラス名とそのパッケージ名から成る完全記述名を指定しない場合、%OpenId() への呼び出しが失敗することに注意してください。
クラス定義の修正
%Dictionary.ClassDefinitionOpens in a new tab オブジェクトを開き、任意の変更を行い、%Save() メソッドを使用してそれを保存することで、既存のクラス定義を修正できます。
新規の %Dictionary.ClassDefinitionOpens in a new tab オブジェクトを生成し、そのプロパティを入力して保存することで、新規のクラスを生成できます。%Dictionary.ClassDefinitionOpens in a new tab オブジェクトを生成するときには、%New() コマンドでクラスの名前を渡す必要があります。クラス (プロパティやメソッド) にメンバを追加するとき、("class_name.member_name" を含む文字列を %New() コマンドに渡して) 対応する定義クラスを作成し、オブジェクトを %Dictionary.ClassDefinitionOpens in a new tab オブジェクト内の該当コレクションに追加する必要があります。
例えば以下のようになります。
Set cdef = ##class(%Dictionary.ClassDefinition).%New("MyApp.MyClass")
If $SYSTEM.Status.IsError(cdef) {
Do $system.Status.DecomposeStatus(%objlasterror,.Err)
Write !, Err(Err)
}
Set cdef.Super = "%Persistent,%Populate"
// add a Name property
Set pdef = ##class(%Dictionary.PropertyDefinition).%New("MyClass:Name")
If $SYSTEM.Status.IsError(pdef) {
Do $system.Status.DecomposeStatus(%objlasterror,.Err)
Write !,Err(Err)
}
Do cdef.Properties.Insert(pdef)
Set pdef.Type="%String"
// save the class definition object
Do cdef.%Save()