数据类型类的用途是用作对象类中的文本属性的类型。数据类型类提供以下功能:
它们通过提供SQL逻辑操作、客户端数据类型和转换信息来提供SQL、ODBC、ActiveX和Java互操作性。
它们为文字数据值提供验证,可以使用数据类型类参数对其进行扩展或自定义。
它们管理文字数据的存储(在磁盘上)、逻辑(在内存中)和显示格式的转换。
数据类型类在许多方面与其他类不同:
它们不能独立实例化或存储。
它们不能包含属性。
它们支持一组特定的方法(称为数据类型接口),如下所述。
由于了解一些内部细节很有用,因此本节简要讨论数据类型类的工作方式。
如前所述,数据类型类的用途是用作属性的类型,特别是在扩展核心对象类之一的类中。下面显示了一个具有三个特性的样例对象类。每个属性都使用一个数据类型类作为其类型。
Class Datatypes.Container Extends %RegisteredObject
{
Property P1 As %String;
Property P2 As %Integer;
Property P3 As %Boolean;
}
向类添加文本属性并编译该类时,caché会向该类添加属性方法。作为参考,让我们使用术语容器类来指代包含属性的类。属性方法控制容器类如何处理这些属性的数据。
该系统的工作方式如下:
在这里显示的示例中,当我们编译Datatypes.Container时,编译器使用%String、%Integer和%Boolean数据类型类的方法生成器。这些方法生成器为每个属性创建方法,并将这些方法添加到容器类。如上所述,这些方法称为属性方法。它们的名称以它们所应用的属性的名称开头。例如,对于P1属性,编译器生成诸如P1IsValid()、P1Normalize()、P1LogicalToDisplay()、P1ToDisplayToLogical()等方法。
请注意,属性方法在类定义中不可见。
许多属性方法将数据从一种格式转换为另一种格式,例如,当以人们可读的格式显示数据或通过ODBC访问数据时。
格式为:
类参数在与数据类型类一起使用时具有特殊行为。对于数据类型类,类参数用于提供一种基于数据类型自定义任何属性行为的方法。
例如,%Integer数据类型类有一个类参数MAXVAL,它指定%Integer类型的属性的最大有效值。如果使用属性NumKids定义类,如下所示:
Property NumKids As %Integer(MAXVAL=10);
这指定NumKids属性的%Integer类的MAXVAL参数将设置为10。
在内部,这是这样工作的:标准数据类型类的验证方法都实现为方法生成器,并使用它们的各种类参数来控制这些验证方法的生成。
在此示例中,此属性定义为NumKidsIsValidDT()方法生成内容,该方法测试NumKidsIsValidDT()的值是否超过10。如果不使用类参数,创建此功能将需要定义IntegerLessThanTen类。
若要定义数据类型类,请首先标识最接近你需要的现有数据类型类。创建此类的子类。在的子类中:
如果需要,还可以添加自己的类参数。
如果数据类型类不是基于现有的数据类型类,请确保将[ClassType=DataType]添加到类定义中。如果类基于另一个数据类型类,则不需要此声明。
根据需要,应该在数据类型类中定义以下部分或全部类方法:
ClassMethod IsValid(%val) As %Status
其中%val是要验证的值。如果值无效,此方法应返回错误状态,否则应返回$OK。
注意:Caché中的标准做法是不调用空值的验证逻辑。
ClassMethod Normalize(%val) As Type
翻译:
其中%val是要验证的值,Type是合适的类型类。
ClassMethod DisplayToLogical(%val) As Type
其中%val是要转换的值,Type是合适的类型类。
其他格式转换方法具有相同的形式。
请注意,ODBC值必须与数据类型类的 ODBC Type类关键字指定的ODBC类型一致。
如果数据类型类包括DISPLAYLIST和VALUELIST参数,则这些方法必须首先检查是否存在这些类参数,并包含处理这些列表的代码。其他方法的逻辑与此类似。
在大多数情况下,这些方法中的许多都是方法生成器。
例如:
ClassMethod LogicalToDate(%val As %MV.Date) As %Library.Date [ CodeMode = expression, ServerOnly = 1 ]
{
$s(%val="":"",1:%val+46385)
}
注意:请注意,数据格式和转换方法不能包含嵌入式SQL。如果需要在此逻辑中调用嵌入式SQL,则可以将嵌入式SQL放在单独的例程中,该方法可以调用此例程。
还可以向数据类型类添加实例方法,这些方法可以使用变量%val,该变量包含属性的当前值。编译器使用它们在使用数据类型类的任何类中生成关联的属性方法。
例如,考虑以下示例数据类型类:
Class Datatypes.MyDate Extends %Date
{
Method ToMyDate() As %String [ CodeMode = expression ]
{
$ZDate(%val,3)
}
}
假设我们有另一个类,如下所示:
Class Datatypes.Container Extends %Persistent
{
Property DOB As Datatypes.MyDate;
}
当我们编译这些类时,Caché会将实例方法DOBToMyDate()添加到容器类中。然后,当我们创建CONTAINER类的实例时,我们可以调用此方法。例如:
SAMPLES>set instance=##class(Datatypes.Container).%New()
SAMPLES>set instance.DOB=+$H
SAMPLES>write instance.DOBToMyDate()
30/10/2014