Using Caché Objects
Defining Data Type Classes
[Home] [Back] [Next]
InterSystems: The power behind what matters   

This chapter describes how data type classes work and describes how to define them. It discusses the following topics:

Also see the chapter Defining and Using Literal Properties.”
When viewing this book online, use the preface of this book to quickly find other topics.
Overview of Data Type Classes
The purpose of a data type class is to be used as the type of a literal property in an object class. Data type classes provide the following features:
See the chapter Property Methods for information on how the compiler uses a data type class to generate code for a property.
Data type classes differ from other classes in a number of ways:
Because it is useful to be aware of some internal details, this section briefly discusses how data type classes work.
As noted previously, the purpose of a data type class is to be used as the type of a property, particularly within a class that extends one of the core object classes. The following shows an example object class that has three properties. Each property uses a data type class as its type.
Class Datatypes.Container Extends %RegisteredObject

Property P1 As %String;

Property P2 As %Integer;

Property P3 As %Boolean;

Property Methods
When you add literal properties to a class and compile the class, Caché adds property methods to that class. For reference, let us use the term container class to refer to the class that contains the properties. The property methods control how the container class handles the data for those properties. This system works as follows:
Note that the property methods are not visible in the class definition.
Data Formats
Many of the property methods translate data from one format to another, for example when displaying data in a human-readable format or when accessing data via ODBC. The formats are:
Parameters in Data Type Classes
Class parameters have a special behavior when used with data type classes. With data type classes, class parameters are used to provide a way to customize the behavior of any properties based on the data type.
For example, the %Integer data type class has a class parameter, MAXVAL, which specifies the maximum valid value for a property of type %Integer. If you define a class with the property NumKids as follows:
Property NumKids As %Integer(MAXVAL=10);
This specifies that the MAXVAL parameter for the %Integer class will be set to 10 for the NumKids property.
Internally, this works as follows: the validation methods for the standard data type classes are all implemented as method generators and use their various class parameters to control the generation of these validation methods. In this example, this property definition generates content for a NumKidsIsValid() method that tests whether the value of NumKids exceeds 10. Without the use of class parameters, creating this functionality would require the definition of an IntegerLessThanTen class.
Defining a Data Type Class
To easily define a data type class, first identify an existing data type class that is close to your needs. Create a subclass of this class. In your subclass:
If you do not base your data type class on an existing data type class, be sure to add [ ClassType=datatype ] to the class definition. This declaration is not needed if you do base your class on another data type class.
When defining a data type class, do not extend %Persistent, %RegisteredObject, or other object classes, as data type classes cannot contain properties.
Defining Class Methods in Data Type Classes
Depending on your needs, you should define some or all of the following class methods in your data type classes:
If the data type class includes the DISPLAYLIST and VALUELIST parameters, these methods must first check for the presence of these class parameters and include code to process these lists if present. The logic is similar for other methods.
In most cases, many of these methods are method generators. See Defining Method and Trigger Generators,” later in this book.
The following shows an example:
ClassMethod LogicalToDate(%val As %MV.Date) As %Library.Date [ CodeMode = expression, ServerOnly = 1 ]
Note that the data format and translation methods cannot include embedded SQL. If you need to call embedded SQL within this logic, then you can place the embedded SQL in a separate routine, and the method can call this routine.
Defining Instance Methods in Data Type Classes
You can also add instance methods to the data type class, and these methods can use the variable %val, which contains the current value of the property. The compiler uses these to generate the associated property methods in any class that uses the data type class. For example, consider the following example data type class:
Class Datatypes.MyDate Extends %Date

Method ToMyDate() As %String [ CodeMode = expression ]
Suppose that we have another class as follows:
Class Datatypes.Container Extends %Persistent

Property DOB As Datatypes.MyDate;

/// additional class members
When we compile these classes, Caché adds the instance method DOBToMyDate() to the container class. Then when we create an instance of the container class, we can invoke this method. For example:
SAMPLES>set instance=##class(Datatypes.Container).%New()
SAMPLES>set instance.DOB=+$H
SAMPLES>write instance.DOBToMyDate()

Send us comments on this page
Copyright © 1997-2019 InterSystems Corporation, Cambridge, MA