本附录讨论了类定义类,这是一组持久类,它们提供对所有类定义的对象和SQL访问。
类定义类提供对Caché统一字典的对象和SQL访问。使用这些类,可以以编程方式检查类定义,修改类定义,创建新类,甚至编写自动生成文档的程序。这些类包含在%Dictionary包中。
注意:%Library软件包中定义了一组较旧的类定义类。保留这些内容是为了与现有应用程序兼容。新代码应使用%Dictionary包中的类。使用这些类时,请确保指定正确的程序包名称,否则可能会无意中使用错误的类。
有两组平行的类定义类:代表定义的类和代表编译的类。
定义的类定义表示特定类的定义。它仅包含该类定义的信息;它不包括从父类继承的信息。除了提供有关字典中类的信息之外,这些类还可用于以编程方式更改或创建新的类定义。
编译的类定义包含从父类继承的所有类成员。只能从已编译的类实例化已编译的类定义对象。无法保存已编译的类定义。
尽管已编译的类定义的操作类似,但本附录仅讨论定义的类定义。
代表已定义类的类定义类家族包括:
类 | 描述 |
---|---|
%Dictionary.ClassDefinition | 表示一个类定义。包含类关键字以及包含类成员定义的集合。 |
%Dictionary.ForeignKeyDefinition | 表示类中的外键定义。 |
%Dictionary.IndexDefinition | 表示类中的索引定义。 |
%Dictionary.MethodDefinition | 表示类中的方法定义。 |
%Dictionary.ParameterDefinition | 表示类中的参数定义。 |
%Dictionary.PropertyDefinition | 表示类中的属性定义。 |
%Dictionary.QueryDefinition | 表示类中的查询定义。 |
%Dictionary.TriggerDefinition | 表示类中的SQL触发器定义。 |
重申一下,未编译的类定义的内容(作为%Dictionary.ClassDefinition的实例)不一定与已编译的类定义的内容(作为%Dictionary.CompiledClass的实例)相同。%Dictionary.ClassDefinition类提供了一个API来检查或更改类的定义-它永远不会代表已解决继承问题的已编译类;另一方面,%Dictionary.CompiledClass确实表示已解决继承的已编译类。
例如,如果尝试确定类定义中特定关键字的值,请使用%Dictionary.ClassDefinition中的keywordnameIsDefined()方法(例如OdbcTypeIsDefined()或ServerOnlyIsDefined())。如果此布尔方法返回false,则未为该类显式定义关键字。如果检查用于类定义的关键字的值,它将是默认值。但是,编译后(包括继承解析),关键字的值由继承确定,并且可能与定义的值不同。
可以使用Management Portal 的SQL页面浏览类定义类。
同样,可以使用与浏览任何其他类型的数据相同的技术,以编程方式浏览类定义:可以使用%ResultSet对象遍历类集,并且可以实例化表示特定类定义的持久对象。
例如,在Caché流程中,可以使用%Dictionary.ClassDefinition:Summary()查询来获取当前名称空间的词典中定义的所有类的列表:
/// d ##class(PHA.OP.MOB.Test).TestDiction()
ClassMethod TestDiction()
{
Set result = ##class(%ResultSet).%New("%Dictionary.ClassDefinition:Summary")
Do result.Execute()
While (result.Next()) {
i $p(result.Data("Name"),".",1) = "PHA" d
.Write result.Data("Name"),!
}
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestDiction()
PHA.CACHE.SOAP.Method
PHA.CACHE.SOAP.WeatherWebServiceSoap
PHA.CACHE.SOAP.WeatherWebServiceSoap.getSupportCity
PHA.CACHE.SOAP.WeatherWebServiceSoap.getSupportDataSet
PHA.CACHE.SOAP.WeatherWebServiceSoap.getSupportProvince
PHA.CACHE.SOAP.WeatherWebServiceSoap.getWeatherbyCityName
PHA.CACHE.SOAP.WeatherWebServiceSoap.getWeatherbyCityNamePro
PHA.CACHETEST.MaYuqiang
PHA.COM.Array
PHA.COM.Base
PHA.COM.Method
PHA.COM.MOB.Base
PHA.COM.MOB.Data
PHA.COM.MOB.Filter
PHA.COM.MOB.Utils
PHA.COM.Object
PHA.COM.Order
PHA.COM.Util
PHA.COM.WebSocket
PHA.COM.XML
PHA.COM.YX.WebSocket
可以使用客户端ResultSet对象轻松地从ActiveX或Java客户端调用此查询。
此%Dictionary.ClassDefinition:ClassInfo()查询将返回从当前名称空间可见的所有类(包括系统库中的类)。可以使用%Dictionary.ClassDefinition:Summary()使用变量过滤返回想要的结果
通过为该类打开%Dictionary.ClassDefinition对象并观察其属性,可以获得有关特定类定义的详细信息。用于存储%Dictionary.ClassDefinition对象的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,!
}
通过为该类打开%Dictionary.ClassDefinition对象并观察其属性,可以获得有关特定类定义的详细信息。用于存储%Dictionary.ClassDefinition对象的ID是类名:
/// d ##class(PHA.OP.MOB.Test).TestClassInfo()
ClassMethod TestClassInfo()
{
Set cdef = ##class(%Dictionary.ClassDefinition).%OpenId("PHA.DEC.MOB.Business")
Write cdef.Name,!
// get list of properties
Set count = cdef.Properties.Count()
For i = 1:1:count {
Write cdef.Properties.GetAt(i).Name,!
}
// get list of properties
Set count = cdef.Methods.Count()
For i = 1:1:count {
Write cdef.Methods.GetAt(i).Name,!
}
}
DHC-APP>d ##class(PHA.OP.MOB.Test).TestClassInfo()
PHA.DEC.MOB.Business
CompBox
DetailReceiveChcek
DetailWardDisp
Distribute
Execute
ExecuteAllDisp
GetAllDispFlag
GetAllDispFlagByBox
GetAllDispOutBox
GetAllExeInfo
GetAllSeqNo
GetBoxInfo
也可以从ActiveX或Java客户端轻松完成此操作。请注意,必须使用其程序包名称完全限定类名称,否则对%OpenId()的调用将失败。
可以通过打开%Dictionary.ClassDefinition对象,进行所需的更改,然后使用%Save()方法保存它来修改现有的类定义。
可以通过创建新的%Dictionary.ClassDefinition对象,填充其属性并保存来创建新类。创建%Dictionary.ClassDefinition对象时,必须通过%New()命令传递类的名称。向类中添加成员(例如属性或方法)时,必须创建相应的定义类(通过其%New()命令传递包含“ class_name.member_name”的字符串),然后将该对象添加到适当的对象中。 %Dictionary.ClassDefinition对象内的集合。
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()