リテラル・プロパティの定義と使用
リテラル・プロパティは、あらゆるオブジェクト・クラスで定義できます。リテラル・プロパティは、リテラル値を保持し、データ型クラスに基づいています。ここでは、このようなプロパティを定義して使用する方法について説明します。
前述したように、トピックのいくつかは、他の種類のプロパティにも適用できます。
リテラル・プロパティの定義
リテラル・プロパティをクラス定義に追加するには、以下のいずれかのような要素をクラスに追加します。
Property PropName as Classname;
Property PropName as Classname [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) ;
以下はその説明です。
-
PropName は、プロパティの名前です。
-
Classname は、このプロパティが基づくクラスです。これを省略すると、Classname は %StringOpens in a new tab であると見なされます。このプロパティをリテラル・プロパティとして定義するには、Classname を省略するか、Classname をデータ型クラスの名前として指定します。"一般的なデータ型クラス" を参照してください。カスタムのデータ型クラスも使用できます。
-
Keywords はプロパティ・キーワードを表します。"コンパイラ・キーワードの概要" を参照してください。
-
PARAM1、PARAM2 などはプロパティ・パラメータです。使用可能なパラメータは、プロパティで使用されるクラスによって異なります。
プロパティ・パラメータを含める場合は、パラメータを括弧で囲み、プロパティ・キーワードの前に置きます。プロパティ・キーワードを含める場合、キーワードは角括弧で囲みます。
例
例えば、クラスでは %IntegerOpens in a new tab データ型クラスを使用して、Count プロパティを定義できます。
Property Count As %Integer;
%IntegerOpens in a new tab がデータ型クラスなので、Count はデータ型プロパティになります。
データ型パラメータを使用して、データ型プロパティの許容値を制限できます。例えば、タイプ %IntegerOpens in a new tab のプロパティには、MAXVAL パラメータを指定できます。
Property Count As %Integer(MAXVAL = 100);
データ型プロパティ値を空文字列に設定するには、以下の形式のコードを使用します。
Set object.Property = $C(0)
すべてのプロパティに照合タイプがあります。これにより、値を並べる方法 (先頭文字の大文字化が有効かどうかなど) が決まります。文字列の既定の照合タイプは、SQLUPPER です。照合の詳細は、"データ照合" を参照してください。
プロパティの初期値式の定義
既定では、新しいオブジェクトを作成したときに、それぞれのプロパティは NULL になります。その代わりに、特定のプロパティの初期値として使用するように、ObjectScript 式を指定できます。式はオブジェクトが作成されるときに評価されます。
プロパティの初期値式を指定するには、プロパティ定義に InitialExpression キーワードを含めます。
Property PropName as Classname [ InitialExpression=expression ] ;
この expression は ObjectScript 式です (この式には、別の言語を使用できない点に注意してください)。詳細は、"InitialExpression" を参照してください。
必須としてのプロパティの定義
このオプションは、永続クラスのプロパティにのみ適用されます。(このオプションはリテラル・プロパティだけでなく、任意の種類のプロパティに適用されます。)
既定では、新しいオブジェクトを保存するときに、InterSystems IRIS は、そのオブジェクトのプロパティが NULL 以外の値を持つことを必要としません。プロパティは、NULL 以外の値を必要とするように定義できます。そのためには、プロパティ定義に Required キーワードを含めます。
Property PropName as Classname [ Required ] ;
これにより、プロパティに NULL 値を持つオブジェクトを保存しようとすると、InterSystems IRIS は以下のエラーを発行するようになります。
ERROR #5659: Property required
Required キーワードは SQL アクセスを使用したこのクラスのデータの挿入または変更の方法にも影響を及ぼします。特に、レコードの挿入または更新をする際に値が欠落しているとエラーが発生します。
計算プロパティの定義
InterSystems IRIS では、計算プロパティを定義できます。計算プロパティの値は ObjectScript で計算されます (他のプロパティに基づく場合もあります)。一般的なフレーズの計算プロパティ (または計算フィールド) には、以下のバリエーションの両方が含まれます。
-
Always computed (常に計算) — このプロパティの値は、アクセスされるときに計算されます。インデックスを定義していない限り、データベースに格納されません。インデックスを定義していれば、そのインデックスが格納されます。
-
Triggered computed (トリガによって計算) — このプロパティの値は、トリガされたときに再計算されます (詳細は下記を参照)。
プロパティが永続クラスで定義される場合、その値はデータベースに保存されます。
どちらの場合も、オブジェクト・アクセスや SQL クエリを使用するかどうかに関係なく、再計算が実行されます。
プロパティ・キーワードは 6 つあります (SqlComputed、SqlComputeCode、SqlComputeOnChange、Transient、Calculated、ComputeLocalOnly)。これらはプロパティ計算の是非と、計算方法を制御します。SqlComputeCode を指定する代わりに、PropertyComputation メソッドに計算コードを記述できます。Property は計算プロパティの名前です。詳細は、"計算プロパティ値" を参照してください。
以下のテーブルに可能な組合せをまとめます。
SqlComputed は true (SqlComputeCode は定義済み) | SqlComputed は false | ||
---|---|---|---|
Calculated は true | Transient は true | プロパティは常に計算されます | プロパティは計算されません |
Calculated は true | Transient は false | プロパティは常に計算されます | プロパティは計算されません |
Calculated は false | Transient は true | プロパティは常に計算されます | プロパティは計算されません |
Calculated は false | Transient は false | プロパティはトリガによって計算されます (この場合、SqlComputeOnChange も指定できます) | プロパティは計算されません |
計算プロパティを定義するには、以下の手順を実行します。
-
プロパティ定義に SqlComputed キーワードを含めます。(つまり、SqlComputed キーワードを true に指定します。)
-
プロパティ定義に SqlComputeCode キーワードを含めます。このキーワードの値には、SqlComputeCode に記載された規則に従い、プロパティの値を設定する ObjectScript コードの行を中括弧で囲んで指定します。例えば以下のようにします。
Class Sample.Population Extends %Persistent { Property FirstName As %String; Property LastName As %String; Property FullName As %String [ SqlComputeCode = {set {*}={FirstName}_" "_{LastName}}, SqlComputed ]; // ... }
ObjectScript または Python などの他の言語を使用して PropertyComputation メソッドを指定し、プロパティの値を設定することもできます。例えば以下のようにします。
Class Sample.Population Extends %Persistent { Property FirstName As %String; Property LastName As %String; Property FullName As %String [ SqlComputed ]; // ... ClassMethod FullNameComputation(cols As %Library.PropertyHelper) As %String { return cols.getfield("FirstName")_" "_cols.getfield("LastName") } // ... }
Class Sample.Population Extends %Persistent { Property FirstName As %String; Property LastName As %String; Property FullName As %String [ SqlComputed ]; // ... ClassMethod FullNameComputation(cols As %Library.PropertyHelper) As %String [ Language = python ] { return cols.getfield("FirstName") + " " + cols.getfield("LastName") } // ... }
-
プロパティが常に計算されるようにするには、プロパティ定義で Calculated キーワードを true に指定します。
また、プロパティがトリガによって計算されるようにする場合は、Calculated および Transient キーワードをプロパティ定義に含めません。(つまり、必ず両方のキーワードを false にします。)
-
プロパティがトリガによって計算される場合は、必要に応じて SqlComputeOnChange を指定します。
このキーワードは 1 つ以上のプロパティを指定できます。これらのプロパティの値が変更されると、トリガされたプロパティは再計算されます。プロパティ名には、SqlFieldName で指定された名前 (後述) 以外を使用する必要があります。以下に例を示します (意図的に改行を入れてあります)。
Property messageId As %Integer [ SqlComputeCode = { set {*}=$Select({Status}="":0,1:$List($List($Extract({Status},3,$Length({Status}))))) }, SqlComputed, SqlComputeOnChange = Status ];
その他の例を示します (意図的に改行を入れてあります)。
Property Test2 As %String [ SqlComputeCode = { set {*}={Refprop1}_{Refprop2}}, SqlComputed, SqlComputeOnChange = (Refprop1, Refprop2) ];
SqlComputeOnChange の値には、値 %%INSERT または %%UPDATE も含めることができます。詳細は、"SqlComputeOnChange" を参照してください。
-
シャードまたはフェデレートされた環境で、計算フィールドに格納されたデータが、クエリの発行元のサーバからのみ返されるようにする場合は、追加で ComputeLocalOnly キーワードを指定できます。
このフィールドのインデックス付けを予定している場合は、非決定的コードではなく、決定的コードOpens in a new tabを使用します。非決定的コードは、古いインデックス・キー値を確実に削除することができないため、InterSystems IRIS は非決定的コードの結果に対するインデックスを保持できません。(決定的コードは、同じ引数を渡された場合はいつでも同じ値を返します。例えば、$h を返すコードは、$h が関数の制御外で変更されているため、非決定的です。)
"Calculated (プロパティ・キーワード)" も参照してください。後述する "計算プロパティの SQL プロジェクションの制御" も参照してください。
多次元プロパティの定義
多次元になるプロパティを定義できます。つまり、プロパティを多次元配列のように機能させるということです。これを行うには、プロパティ定義に MultiDimensional キーワードを含めます。
Property PropName as Classname [ MultiDimensional ] ;
このプロパティは、以下の点で他のプロパティとは異なります。
-
InterSystems IRIS は、このプロパティにプロパティ・メソッドを提供しません ("プロパティ・メソッドの使用とオーバーライド" を参照)。
-
オブジェクトを検証または保存するときに、無視されます。
-
アプリケーションにそれを明示的に保存するコードが含まれていない場合、ディスクに保存されません。
-
Java などのクライアントに公開することはできません。
-
SQL テーブルに格納できず、SQL テーブルでも公開されません。
多次元プロパティはあまり使用されませんが、オブジェクトの状態に関する情報を一時的に格納する場合に有用な方法を提供します。
また、"多次元プロパティの値の指定" も参照してください。
列挙プロパティの定義
数多くのプロパティが、VALUELIST パラメータと DISPLAYLIST パラメータをサポートしています。これらを使用して、列挙プロパティを定義します。
プロパティに有効な値のリストを指定するには、VALUELIST パラメータを使用します。VALUELIST のフォームは、区切り文字で区切った論理値のリストで、区切り文字が最初の文字になります。以下はその例です。
Property Color As %String(VALUELIST = ",red,green,blue");
この例で VALUELIST は、有効な値が red、green、blue であることを指定し、区切り文字としてコンマを使用します。同様に、
Property Color As %String(VALUELIST = " red green blue");
上の文は同じリストを指定しますが、区切り文字としてスペースを使用しています。
プロパティはリストの値に限定され、データ型の妥当性検証コードは、その値がリストにあるかどうかだけを調べます。リストがなければ、値は特に限定されません。
DISPLAYLIST は、リストがある場合、プロパティの LogicalToDisplay() メソッドで返される対応する表示値を表す追加リストです。
表示値を取得する方法の例は、"プロパティ・メソッドの使用法" を参照してください。
リテラル・プロパティの値の指定
リテラル・プロパティに値を指定するには、以下に示すように SET コマンド、OREF、およびドット構文を使用します。
SET oref.MyProp=value
oref は OREF、MyProp は対応するオブジェクトのプロパティです。value は、リテラル値に評価される ObjectScript 式です。以下に例を示します。
SET patient.LastName="Muggles"
SET patient.HomeAddress.City="Carver"
SET mrn=##class(MyApp.MyClass).GetNewMRN()
set patient.MRN=mrn
リテラル値は、プロパティ・タイプに対して有効な論理値にする必要があります。例えば、%BooleanOpens in a new tab に基づくプロパティには、1 または 0 を使用します。もう 1 つ例を挙げると、列挙プロパティの場合、値は、VALUELIST パラメータで指定された項目のいずれかにする必要があります。
多次元プロパティの値の指定
多次元プロパティについては、プロパティの添え字に応じて値を指定できます。以下に例を示します。
set oref.MyStateProp("temp1")=value1
set oref.MyStateProp("temp2")=value2
set oref.MyStateProp("temp3")=value3
多次元プロパティは、オブジェクトで使用するための一時的な情報を保持する際に役立ちます。このようなプロパティはディスクに保存されません。
プロパティ・メソッドの使用法
それぞれのプロパティは、生成されたクラス・メソッドのセットをクラスに追加します。これらのメソッドには、propnameIsValid()、propnameLogicalToDisplay()、propnameDisplayToLogical()、propnameLogicalToOdbc()、propnameOdbcToLogical() などが含まれます。propname はプロパティの名前です。これらのメソッドの一部は、%Property クラスから継承され、その他のメソッドはプロパティが基づくデータ型クラスから継承されます。メソッドの詳細とリストは、"データ型クラスの定義" を参照してください。
InterSystems IRIS はこれらのメソッドを内部的に使用し、ユーザもこれらを直接呼び出すことができます。どの場合も、引数はプロパティ値です。例えば、Sample.Person に論理値 M と F (および表示値 Male と Female) を持つ Gender という名前のプロパティがあるとします。次のように、指定されたレコードに対してこのプロパティの論理値と表示値を表示できます。
MYNAMESPACE>set p=##class(Sample.Person).%OpenId(1)
MYNAMESPACE>w p.Gender
M
MYNAMESPACE>w ##class(Sample.Person).GenderLogicalToDisplay(p.Gender)
Male
リテラル・プロパティの SQL プロジェクションの制御
永続クラスは、SQL テーブルとして投影されます。そのクラスでは、すべてのプロパティが SQL に投影されます。ただし、以下の例外を除きます。
-
Transient プロパティ (ただし、"計算プロパティの SQL プロジェクションの制御" を参照すること)
-
Calculated プロパティ (ただし、"計算プロパティの SQL プロジェクションの制御" を参照すること)
-
プライベート・プロパティ
-
多次元プロパティ
このセクションでは、リテラル・プロパティについて詳しく説明します。
フィールド名の指定
既定では、プロパティ (SQL に投影される場合) は、そのプロパティと同じ名前の SQL フィールドとして投影されます。別のフィールド名を指定する場合は、プロパティ・キーワード SqlFieldName を使用します (プロパティ名が SQL 予約語の場合にも、このキーワードを使用できます)。例えば、"Select" という名前の %StringOpens in a new tab プロパティがある場合、投影された名前を以下の構文で定義できます。
Property Select As %String [ SqlFieldName = SelectField ];
列番号の指定
システムでは、各フィールドに一意の列番号が自動的に割り当てられます。列番号の割り当てを制御するには、以下の例で示すように、プロパティ・キーワード SqlColumnNumber を指定します。
Property RGBValue As %String [ SqlColumnNumber = 3 ];
SqlColumnNumber に指定する値は 1 より大きい整数にする必要があります。SqlColumnNumber キーワードを引数なしに使用すると、InterSystems IRIS はテーブルで保持されていなくて固定位置を持たない列番号を割り当てます。
指定された SQL 列番号を持つプロパティがある場合、InterSystems IRIS は他のプロパティに列番号を割り当てます。割り当てられた列番号の開始値は、指定された SQL 列番号に続く最高値です。
SqlColumnNumber キーワードの値は継承されます。
データ型クラスとプロパティ・パラメータの影響
特定のプロパティで使用されるデータ型クラスは、SQL プロジェクションに影響を与えます。具体的には、データ型の SQL カテゴリ (SqlCategory キーワードで定義) により、プロパティを投影する方法を制御します。該当する場合は、プロパティ・パラメータも影響を与えます。
例えば、以下のようなプロパティ定義を考えてみます。
Property Name As %String(MAXLEN = 30);
このプロパティは、最大長が 30 文字の文字列フィールドとして投影されます。
計算プロパティの SQL プロジェクションの制御
InterSystems IRIS では、計算プロパティを定義できます。計算プロパティの値は ObjectScript で計算されます ("計算プロパティの定義" を参照してください)。以下のテーブルでは、どのバリエーションが SQL に投影されるかを示しています。
プロパティ定義 | SQL へのプロジェクション |
---|---|
プロパティは計算されず、一時的ではありません (既定) | プロパティは SQL に投影されます |
プロパティは計算されず、一時的です | プロパティは、SQL に投影されません |
プロパティは常に計算されます | プロパティは SQL に投影されます |
プロパティはトリガされる計算プロパティです | プロパティは SQL に投影されます |
このテーブルでは、Calculated、Transient、SqlComputed、および SqlComputeCode キーワードの効果のみを考慮します。また、SQL プロジェクションを禁止するような別のキーワードがプロパティに使用されていないことを想定しています。例えば、プロパティはプライベートでないことを想定しています。