Skip to main content
InterSystems IRIS Data Platform 2024.3
AskMe (beta)
Loading icon

Defining Data Type Classes

This topic describes how data type classes work and describes how to define them.

Introduction

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:

  • They provide for SQL and client interoperability by providing SQL logical operation, client data type, and translation information.

  • They provide validation for literal data values, which you can extend or customize by using data type class parameters.

  • They manage the translation of literal data for its stored (on disk), logical (in memory), and display formats.

Data type classes define a specific set of methods (typically method generators) that the compiler uses to define the behavior of the properties. Data type classes are not object classes (that is, they do not inherit from %RegisteredObjectOpens in a new tab).

When a class has properties, the class automatically possesses a set of methods for accessing and working with property values. These are called property methods and their names are based on the property names. For example, if a class contains a string property called Name, the class includes methods called NameDisplayToLogical(), NameGet(), NameGetStored(), NameIsValid(), NameLogicalToDisplay(), NameLogicalToOdbc(), NameNormalize(), and NameSet(). InterSystems IRIS uses the property methods internally to access and work with property values. You can also call these methods directly; see Using Property Methods.

Parameters in Data Type Classes

A data type class can include class parameters that define default behavior, and this default behavior can be overridden for specific properties based on that data type class. For example, the %IntegerOpens in a new tab data type class has a class parameter, MAXVAL, which specifies the maximum valid value for a property of type %IntegerOpens in a new tab. If you define a class with the property NumKids as follows:

Property NumKids As %Integer(MAXVAL=10);

This specifies that the NumKids property cannot exceed 10.

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 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:

  • Specify suitable values for the keywords SqlCategory, ClientDataType, and OdbcType.

  • Override any class parameters as needed. For example, you might override the MAXLEN parameter so that there is no length limit for the property.

    If needed, add your own class parameters as well.

  • Override the methods of the data type class as needed. In your implementations, refer to the parameters of this class as needed.

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.

Note:

When defining a data type class, do not extend %PersistentOpens in a new tab, %RegisteredObjectOpens in a new tab, 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:

  • IsValid() — performs validation of data for the property, using property parameters if appropriate. As noted earlier, the %ValidateObject() instance method of any object class invokes the IsValid() method for each property. This method has the following signature:

    ClassMethod IsValid(%val) As %Status 
    

    Where %val is the value to be validated. This method should return an error status if the value is invalid and should otherwise return $$$OK.

    Note:

    It is standard practice in InterSystems IRIS not to invoke validation logic for null values.

  • Normalize() — converts the data for the property into a standard form or format. The %NormalizeObject() instance method of any object class invokes the Normalize() method for each property. This method has the following signature:

    ClassMethod Normalize(%val) As Type 
    

    Where %val is the value to be validated and Type is a suitable type class.

  • DisplayToLogical() — converts a display value into a logical value. (For information on formats, see Data Formats.) This method has the following signature:

    ClassMethod DisplayToLogical(%val) As Type 
    

    Where %val is the value to be converted and Type is a suitable type class.

    The other format conversion methods have the same general form.

  • LogicalToDisplay() — converts a logical value to a display value.

  • LogicalToOdbc() — converts a logical value into an ODBC value.

    Note that the ODBC value must be consistent with the ODBC type specified by the OdbcType class keyword of the data type class.

  • LogicalToStorage() — converts a logical value into a storage value.

  • LogicalToXSD() — converts a logical value into the appropriate SOAP-encoded value.

  • OdbcToLogical() — converts an ODBC value into a logical value.

  • StorageToLogical() — converts a database storage value into a logical value.

  • XSDToLogical() — converts a SOAP-encoded value into a logical value.

When implementing these methods, note the following requirements:

  • Each method must be a class method.

  • Each method must accept an argument: the value to check for validity, to normalize, to convert, and so on.

  • 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 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.

  • These methods are used within a procedure block and thus cannot use NEW to provide a new scope for a variable, other than a percent variable.

In most cases, it is best to define these methods as method generators.

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 additional 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 ]
{
$ZDate(%val,4)
}
}

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, InterSystems IRIS 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:

TESTNAMESPACE>set instance=##class(Datatypes.Container).%New()
 
TESTNAMESPACE>set instance.DOB=+$H
 
TESTNAMESPACE>write instance.DOBToMyDate()
30/10/2024

See Also

FeedbackOpens in a new tab