Python からのデータベース・メソッドおよび関数の呼び出し
ここでは、ObjectScript クラス・メソッドおよび関数を Python アプリケーションから直接呼び出すことを可能にするクラス iris.IRIS のメソッドを説明します。詳細および例は、以下のセクションを参照してください。
-
Python からのクラス・メソッドの呼び出し — ObjectScript クラス・メソッドを呼び出す方法を示します。
-
Python からの関数とプロシージャの呼び出し — 関数とプロシージャを呼び出す方法を示します。
-
引数の参照渡し — IRISReference クラスを使用して引数を渡す方法を示します。
Python からのクラス・メソッドの呼び出し
classMethodValue() メソッドと classMethodVoid() メソッドは、ほとんどの目的に使用できますが、特定の返りタイプが必要な場合は、classMethodBoolean()、classMethodBytes()、classMethodDecimal()、classMethodFloat()、classMethodIRISList()、classMethodInteger()、classMethodObject()、および classMethodString() の IRIS.classMethodValue() 型キャスト・メソッドも使用できます。
これらのメソッドはすべて、class_name および method_name の文字列引数に加え、0 個以上のメソッド引数を取ります。
以下の例のコードでは、User.NativeTest という名前の ObjectScript テスト・クラスからいくつかのデータ型のクラス・メソッドを呼び出します (このセクションの最後に示す “ObjectScript クラス User.NativeTest” を参照)。
この例のコードでは、サポートされている各データ型のクラス・メソッドを ObjectScript テスト・クラス User.NativeTest から呼び出します (この例の直後に表示されています)。変数 irispy はクラス iris.IRIS の以前に定義されたインスタンスで、現在サーバに接続されていると想定します (“Python での接続の作成” を参照)。
className = 'User.NativeTest'
comment = ".cmBoolean() tests whether arguments 2 and 3 are equal: "
boolVal = irispy.classMethodBoolean(className,'cmBoolean',2,3)
print(className + comment + str(boolVal))
comment = ".cmBytes returns integer arguments 72,105,33 as a byte array (string value 'Hi!'): "
byteVal = irispy.classMethodBytes(className,'cmBytes',72,105,33) #ASCI 'Hi!'
print(className + comment + str(byteVal))
comment = ".cmString() concatenates 'Hello' with argument string 'World': "
stringVal = irispy.classMethodString(className,'cmString','World')
print(className + comment + stringVal)
comment = ".cmLong() returns the sum of arguments 7+8: "
longVal = irispy.classMethodInteger(className,'cmLong',7,8)
print(className + comment + str(longVal))
comment = ".cmDouble() multiplies argument 4.5 by 1.5: "
doubleVal = irispy.classMethodFloat(className,'cmDouble',4.5)
print(className + comment + str(doubleVal))
comment = ".cmList() returns a $LIST containing arguments 'The answer is ' and 42: "
listVal = irispy.classMethodIRISList(className,"cmList","The answer is ",42);
print(className + comment+listVal.get(1)+str(listVal.get(2)))
comment = ".cmVoid assigns argument value 75 to global node ^cmGlobal: "
try:
irispy.kill('cmGlobal') # delete ^cmGlobal if it exists
irispy.classMethodVoid(className,'cmVoid',75)
nodeVal = irispy.get('cmGlobal'); #get current value of ^cmGlobal
except:
nodeVal = 'FAIL'
print(className + comment + str(nodeVal))
この例では、classMethodValue() (決まった形式のない値を返します)、classMethodDecimal() (主に高精度への対応において classMethodFloat() とは異なります)、および classMethodObject() (“Python からのデータベース・オブジェクトの制御” で説明しています) は省略されています。
前の例を実行するには、この ObjectScript クラスがコンパイルされ、サーバで使用可能である必要があります。
Class User.NativeTest Extends %Persistent
{
ClassMethod cmBoolean(cm1 As %Integer, cm2 As %Integer) As %Boolean
{
Quit (cm1=cm2)
}
ClassMethod cmBytes(cm1 As %Integer, cm2 As %Integer, cm3 As %Integer) As %Binary
{
Quit $CHAR(cm1,cm2,cm3)
}
ClassMethod cmString(cm1 As %String) As %String
{
Quit "Hello "_cm1
}
ClassMethod cmLong(cm1 As %Integer, cm2 As %Integer) As %Integer
{
Quit cm1+cm2
}
ClassMethod cmDouble(cm1 As %Double) As %Double
{
Quit cm1 * 1.5
}
ClassMethod cmVoid(cm1 As %Integer)
{
Set ^cmGlobal=cm1
Quit
}
ClassMethod cmList(cm1 As %String, cm2 As %Integer)
{
Set list = $LISTBUILD(cm1,cm2)
Quit list
}
}
ターミナルからこれらのメソッドを呼び出すことで、それらをテストできます。例を以下に示します。
USER>write ##class(User.NativeTest).cmString("World")
Hello World
Python からの関数とプロシージャの呼び出し
以前のインターシステムズ・データベース・プラットフォームでは、コードは、オブジェクト指向のクラスおよびメソッドではなく、関数とプロシージャが含まれるモジュールで構成されていました ("ObjectScript の使用法" の “呼び出し可能なユーザ定義コードモジュール” を参照)。以前のコード・ベースには関数が必要なことが多いですが、新しいコードでは可能であればオブジェクト指向のメソッド呼び出しを使用してください。
function() メソッドと procedure() メソッドは、ほとんどの目的に使用できますが、特定の返りタイプが必要な場合は、functionBoolean()、functionBytes()、functionDecimal()、functionFloat()、functionIRISList()、functionObject()、functionInteger()、および functionString() の IRIS.function() 型キャスト・メソッドも使用できます。
これらのメソッドは、functionLabel および routineName の string 引数に加え、0 個以上の関数引数を取ります。これは、bool、bytes、bytearray、Decimal、float、int、str、IRISList のいずれかとなります。
以下の例のコードでは、NativeRoutine (この例の直後に示されています) という名前の ObjectScript テスト・ルーチンから関数が呼び出されます。
これらのメソッドは、ユーザ定義ルーチンで関数を呼び出すように設計されています。ObjectScript システム関数 ($ 文字で開始。"ObjectScript リファレンス" の “ObjectScript 関数” を参照) を Python コードから直接呼び出すことはできません。ただし、システム関数を呼び出してその結果を返す ObjectScript ラッパ関数を記述することで、間接的にシステム関数を呼び出すことができます。例えば、fnList() 関数 (このセクションの最後にある "ObjectScript Routine NativeRoutine.mac" を参照) は $LISTBUILD を呼び出します。
この例のコードでは、サポートされている各データ型の関数を ObjectScript ルーチン NativeRoutine から呼び出します (この例の直後に示されているファイル NativeRoutine.mac)。irispy はクラス iris.IRIS の既存のインスタンスで、現在サーバに接続されていると想定します (“Python での接続の作成” を参照)。
routineName = 'NativeRoutine'
comment = ".fnBoolean() tests whether arguments 2 and 3 are equal: "
boolVal = irispy.functionBoolean('fnBoolean',routineName,2,3)
print(routineName + comment + str(boolVal))
comment = ".fnBytes returns integer arguments 72,105,33 as a byte array (string value 'Hi!'): "
byteVal = irispy.functionBytes('fnBytes',routineName,72,105,33) #ASCI 'Hi!'
print(routineName + comment + str(byteVal))
comment = ".fnString() concatenates 'Hello' with argument string 'World': "
stringVal = irispy.functionString("fnString",routineName,"World")
print(routineName + comment + stringVal)
comment = ".fnLong() returns the sum of arguments 7+8: "
longVal = irispy.functionInteger('fnLong',routineName,7,8)
print(routineName + comment + str(longVal))
comment = ".fnDouble() multiplies argument 4.5 by 1.5: "
doubleVal = irispy.functionFloat('fnDouble',routineName,4.5)
print(routineName + comment + str(doubleVal))
comment = ".fnList() returns a $LIST containing arguments 'The answer is ' and 42: "
listVal = irispy.functionIRISList("fnList",routineName,"The answer is ",42);
print(routineName + comment + listVal.get(1)+str(listVal.get(2)));
comment = ".fnProcedure() assigns argument value 66 to global node ^fnGlobal: "
try:
irispy.kill('fnGlobal') # delete ^fnGlobal if it exists
irispy.procedure('fnProcedure',routineName,66)
nodeVal = irispy.get('fnGlobal') # get current value of node ^fnGlobal
except:
nodeVal = 'FAIL'
print(routineName + comment + str(nodeVal))
この例では、function() (決まった形式のない値を返します)、functionDecimal() (主に高精度への対応において functionFloat() とは異なります)、および functionObject() (“Python からのデータベース・オブジェクトの制御” で説明している classMethodObject() メソッドと機能的に同じです) は省略されています。
前の例を実行するには、この ObjectScript ルーチンがコンパイルされ、サーバで使用可能である必要があります。
fnBoolean(fn1,fn2) public {
quit (fn1=fn2)
}
fnBytes(fn1,fn2,fn3) public {
quit $CHAR(fn1,fn2,fn3)
}
fnString(fn1) public {
quit "Hello "_fn1
}
fnLong(fn1,fn2) public {
quit fn1+fn2
}
fnDouble(fn1) public {
quit fn1 * 1.5
}
fnProcedure(fn1) public {
set ^fnGlobal=fn1
quit
}
fnList(fn1,fn2) public {
set list = $LISTBUILD(fn1,fn2)
quit list
}
ターミナルからこれらの関数を呼び出すことで、それらをテストできます。例を以下に示します。
USER>write $$fnString^NativeRoutine("World")
Hello World
引数の参照渡し
InterSystems クラス・ライブラリのほとんどのクラスでは、メソッドが %StatusOpens in a new tab 値のみを返す呼び出し規則を使用します。実際の結果は、参照によって渡される引数で返されます。Native SDK では、メソッドと関数の両方で参照渡しがサポートされます。これには、以下のように引数の値をクラス IRISReference のインスタンスに割り当て、そのインスタンスを引数として渡します。
ref_object = iris.IRISReference(None); // set inital value to None
irispy.classMethodObject("%SomeClass","SomeMethod",ref_object);
returned_value = ref_object.getValue; // get the method result
以下の例では、標準のクラス・ライブラリ・メソッドが呼び出されます。
この例は、%SYS.DatabaseQuery.GetDatabaseFreeSpace()Opens in a new tab を呼び出して、iristemp データベースで利用可能な空き容量の量 (MB 単位) を取得します。
dir = "C:/InterSystems/IRIS/mgr/iristemp" # directory to be tested
value = "error"
status = 0
freeMB = iris.IRISReference(None) # set inital value to 0
print("Variable freeMB is type"+str(type(freeMB)) + ", value=" + str(freeMB.getValue()))
try:
print("Calling %SYS.DatabaseQuery.GetDatabaseFreeSpace()... ")
status = irispy.classMethodObject("%SYS.DatabaseQuery","GetDatabaseFreeSpace",dir,freeMB)
value = freeMB.getValue()
except:
print("Call to class method GetDatabaseFreeSpace() returned error:")
print("(status=" + str(status) + ") Free space in " + dir + " = " + str(value) + "MB\n")
出力 :
Variable freeMB is type<class 'iris.IRISReference'>, value=None
Calling %SYS.DatabaseQuery.GetDatabaseFreeSpace()...
(status=1) Free space in C:/InterSystems/IRIS/mgr/iristemp = 10MB