記事
· 2023年3月13日 3m read

永続クラス定義のデータが格納されるグローバル変数名について

これは InterSystems FAQ サイトの記事です。

永続クラス定義では、データを格納するグローバル変数名を初回クラスコンパイル時に決定しています。
グローバル変数名は、コンパイル後に表示されるストレージ定義(Storage)で確認できます。

例)

Class Training.Person Extends %Persistent
{
Property Name As %String; Property Email As %String; Storage Default
{
<Data name="PersonDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
<Value name="3">
<Value>Email</Value>
</Value>
</Data>
<DataLocation>^Training.PersonD</DataLocation>
<DefaultData>PersonDefaultData</DefaultData>
<ExtentSize>0</ExtentSize>
<IdLocation>^Training.PersonD</IdLocation>
<IndexLocation>^Training.PersonI</IndexLocation>
<StreamLocation>^Training.PersonS</StreamLocation>

<Type>%Storage.Persistent</Type>
}

}

 

DataLocation:^パッケージ名.クラス名D
永続クラスのデータが登録されるグローバル変数です。

IndexLocation:^パッケージ名.クラス名I
インデックスが格納されるグローバル変数です。

StreamLocation:^パッケージ名.クラス名S
ストリームプロパティのデータが格納される変数です。

 

例外として、31文字以上のクラス名を指定した場合、グローバル変数名の文字数制限を超えてしまうため、ネームスペースで一意となる適当なグローバル変数名を使用します。

Class TestPackage.VeryLongLongLongLongName Extends %Persistent
{
Property Name As %String; Storage Default
{
<Data name="VeryLongLongLongLongNameDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
</Data>
<DataLocation>^TestPackage.VeryLongLon92A3D</DataLocation>
<DefaultData>VeryLongLongLongLongNameDefaultData</DefaultData>
<IdLocation>^TestPackage.VeryLongLon92A3D</IdLocation>
<IndexLocation>^TestPackage.VeryLongLon92A3I</IndexLocation>
<StreamLocation>^TestPackage.VeryLongLon92A3S</StreamLocation>

<Type>%Storage.Persistent</Type>
}
}

 

ストレージ定義未作成の場合、DEFAULTGLOBALパラメータを利用してグローバル変数名を指定することができます。
(指定したグローバル変数名の末尾にD、I、Sを付与した名称をストレージに定義します。)

Class TestPackage.VeryLongLongLongLongName Extends %Persistent
{
Property Name As %String;

Parameter DEFAULTGLOBAL = "^Test.LongName";

Storage Default
{
<Data name="VeryLongLongLongLongNameDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Name</Value>
</Value>
</Data>
<DataLocation>^Test.LongNameD</DataLocation>
<DefaultData>VeryLongLongLongLongNameDefaultData</DefaultData>
<IdLocation>^Test.LongNameD</IdLocation>
<IndexLocation>^Test.LongNameI</IndexLocation>
<StreamLocation>^Test.LongNameS</StreamLocation>

<Type>%Storage.Persistent</Type>
}

}

詳細は以下ドキュメントもご参照ください。

 

この他、2017.2以降からストレージに定義されるグローバル変数名をハッシュ化したグローバル変数名に変更できるパラメータ:USEREXTENTSETが、パフォーマンス向上のために追加されました。

ストレージ未作成時(クラス定義の初回コンパイル前)に設定することで、 ^EPgS.D8T6.1 のようなハッシュ化したグローバル変数名が設定されます。

Parameter USEEXTENTSET = 1;

 

USEEXTENTSETパラメータを使用する場合のストレージ定義について詳細は、関連トピックをご参照ください。

 


関連記事もご参照ください

ディスカッション (4)1
続けるにはログインするか新規登録を行ってください

クラス名が31文字を超える永続クラスをIRIS管理ポータルからクラスエクスポートしました。

一部リネームしたくて、エクスポートしたファイルを直接編集し、クラス名にパッケージ名を追加しました。

編集後、管理ポータルからクラスのインポート(元データはIRIS管理ポータルからエクスポートしたexport.xml)を行うと、グローバル名の31文字制限エラーが出力されますが、インポート対象のネームスペースにはクラスが取り込まれているようでした。(クラスは新規追加を想定)

ですが、ストレージ定義の部分で31文字制限にかかっているようで、一度VSCodeなどでインポートしたクラスを開いてストレージ定義をすべて消して保存(コンパイル)したらエラーが出なくなりました。

対応としてはこれで問題ないでしょうか。

@Yusuke Kojima さん、こんにちは。

一度VSCodeなどでインポートしたクラスを開いてストレージ定義をすべて消して保存(コンパイル)したらエラーが出なくなりました。

ストレージ定義を削除しコンパイルしたため、現在のクラス定義に合わせて新しいストレージ定義ができていると思われます。

変更前の永続クラス定義に合わせて作成されたデータ(グローバル変数)を今後使用しない状況(新規クラスとして利用する状況)であれば問題ありませんが、クラス定義変更前のデータ(グローバル変数)を修正後の新しいクラス定義でも使用したいなどありますか?

@Mihoko.Iijimaさん、ご返信ありがとうございます。 

クラス定義変更前のデータ(グローバル変数)を修正後の新しいクラス定義でも使用したいなどありますか?

簡単に背景をご説明しますと、永続クラスの定義の基となる標準規格のバージョンがあがり、一部の永続クラスの構造が変化してしまいました。

そのため、新バージョンクラスと旧バージョンクラスを別々に定義し(旧バージョンは名称変更はせず、現状のまま残しておきます)、導入時にはデータ移行プログラム(一度だけ実行するDTLを作成しようと思っています)で旧クラスから新クラスにデータコピーを検討しています。

旧バージョンから新バージョンへの切り替えも、ユーザーの任意のタイミングで実行できるよう、柔軟性を持たせた作りにする予定ですが、その部分はアイデアがあるためユーザーと相談中です。

新旧クラス定義を別々に定義しておいて、新クラスはストレージ定義を作り直しても大丈夫な環境なのですね。背景のご説明ありがとうございました!