永続クラス定義のデータが格納されるグローバル変数名について
これは InterSystems FAQ サイトの記事です。
永続クラス定義では、データを格納するグローバル変数名を初回クラスコンパイル時に決定しています。
グローバル変数名は、コンパイル後に表示されるストレージ定義(Storage)で確認できます。
例)
{
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文字以上のクラス名を指定した場合、グローバル変数名の文字数制限を超えてしまうため、ネームスペースで一意となる適当なグローバル変数名を使用します。
{
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を付与した名称をストレージに定義します。)
{
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 のようなハッシュ化したグローバル変数名が設定されます。
USEEXTENTSETパラメータを使用する場合のストレージ定義について詳細は、関連トピックをご参照ください。
関連記事もご参照ください
Comments
クラス名が31文字を超える永続クラスをIRIS管理ポータルからクラスエクスポートしました。
一部リネームしたくて、エクスポートしたファイルを直接編集し、クラス名にパッケージ名を追加しました。
編集後、管理ポータルからクラスのインポート(元データはIRIS管理ポータルからエクスポートしたexport.xml)を行うと、グローバル名の31文字制限エラーが出力されますが、インポート対象のネームスペースにはクラスが取り込まれているようでした。(クラスは新規追加を想定)
ですが、ストレージ定義の部分で31文字制限にかかっているようで、一度VSCodeなどでインポートしたクラスを開いてストレージ定義をすべて消して保存(コンパイル)したらエラーが出なくなりました。
対応としてはこれで問題ないでしょうか。
@Yusuke Kojima さん、こんにちは。
一度VSCodeなどでインポートしたクラスを開いてストレージ定義をすべて消して保存(コンパイル)したらエラーが出なくなりました。
ストレージ定義を削除しコンパイルしたため、現在のクラス定義に合わせて新しいストレージ定義ができていると思われます。
変更前の永続クラス定義に合わせて作成されたデータ(グローバル変数)を今後使用しない状況(新規クラスとして利用する状況)であれば問題ありませんが、クラス定義変更前のデータ(グローバル変数)を修正後の新しいクラス定義でも使用したいなどありますか?
@Mihoko.Iijimaさん、ご返信ありがとうございます。
クラス定義変更前のデータ(グローバル変数)を修正後の新しいクラス定義でも使用したいなどありますか?
簡単に背景をご説明しますと、永続クラスの定義の基となる標準規格のバージョンがあがり、一部の永続クラスの構造が変化してしまいました。
そのため、新バージョンクラスと旧バージョンクラスを別々に定義し(旧バージョンは名称変更はせず、現状のまま残しておきます)、導入時にはデータ移行プログラム(一度だけ実行するDTLを作成しようと思っています)で旧クラスから新クラスにデータコピーを検討しています。
旧バージョンから新バージョンへの切り替えも、ユーザーの任意のタイミングで実行できるよう、柔軟性を持たせた作りにする予定ですが、その部分はアイデアがあるためユーザーと相談中です。
新旧クラス定義を別々に定義しておいて、新クラスはストレージ定義を作り直しても大丈夫な環境なのですね。背景のご説明ありがとうございました!