Using Caché Objects
Using the %Dictionary Classes
[Back] [Next]

This appendix discusses the class definition classes, a set of persistent classes that provide object and SQL access to all class definitions. This appendix discusses the following topics:

When viewing this book online, use the preface of this book to quickly find other topics.
Introduction to Class Definition Classes
The class definition classes provide object and SQL access to the Caché unified dictionary. Using these classes, you can programmatically examine class definitions, modify class definitions, create new classes, and even write programs that automatically generate documentation. These classes are contained within the %Dictionary package.
There is an older set of class definition classes defined within the %Library package. These are maintained for compatibility with existing applications. New code should make use of the classes within the %Dictionary package. Make sure that you specify the correct package name when using these classes or you may inadvertently use the wrong class.
There are two parallel sets of class definition classes: those that represent defined classes and those that represent compiled classes.
A defined class definition represents the definition of a specific class. It includes only information defined by that class; it does not include information inherited from superclasses. In addition to providing information about classes in the dictionary, these classes can be used to programmatically alter or create new class definitions.
A compiled class definition includes all of the class members that are inherited from superclasses. A compiled class definition object can only be instantiated from a class that has been compiled. You cannot save a compiled class definition.
This appendix discusses defined class definitions exclusively, though the operation of the compiled class definitions is similar.
The family of class definition classes that represent defined classes includes:
Class Description
%Dictionary.ClassDefinition Represents a class definition. Contains class keywords as well as collections containing class member definitions.
%Dictionary.ForeignKeyDefinition Represents a foreign key definition within a class.
%Dictionary.IndexDefinition Represents an index definition within a class.
%Dictionary.MethodDefinition Represents a method definition within a class.
%Dictionary.ParameterDefinition Represents a parameter definition within a class.
%Dictionary.PropertyDefinition Represents a property definition within a class.
%Dictionary.QueryDefinition Represents a query definition within a class.
%Dictionary.TriggerDefinition Represents an SQL trigger definition within a class.
To reiterate, the content of an uncompiled class definition (as an instance of the %Dictionary.ClassDefinition) is not necessarily the same as the content of a compiled class definition (as an instance of %Dictionary.CompiledClass).  The %Dictionary.ClassDefinition class provides an API to inspect or change the definition of the class — it does not ever represent the compiled class with inheritance resolved; %Dictionary.CompiledClass, on the other hand, does represent the compiled class with inheritance resolved.
For example, if you are trying to determine the value of a particular keyword in a class definition, use the keywordnameIsDefined() method from %Dictionary.ClassDefinition (such as OdbcTypeIsDefined() or ServerOnlyIsDefined()). If this boolean method returns false, then the keyword is not explicitly defined for the class. If you check the value of the keyword for the class definition, it will be the default value. However, after compilation (which includes inheritance resolution), the value of the keyword is determined by inheritance and may differ from the value as defined.
Browsing Class Definitions
You can use the SQL pages of the Management Portal to browse the class definition classes.
Similarly, you can programmatically browse through the class definitions using the same techniques you would use to browse any other kind of data: you can use the %ResultSet object to iterate over sets of classes and you can instantiate persistent objects that represent specific class definitions.
For example, from within a Caché process, you can get a list of all classes defined within the dictionary for the current namespace by using the %Dictionary.ClassDefinition:Summary() query:
 Set result = ##class(%ResultSet).%New("%Dictionary.ClassDefinition:Summary")
 Do result.Execute()
 While (result.Next()) {
     Write result.Data("Name"),!
You can just as easily invoke this query from an ActiveX or Java client using the client ResultSet object.
This %Dictionary.ClassDefinition:ClassInfo() query will return all of the classes visible from the current namespace (including classes in the system library). You can filter out unwanted classes using the various columns returned by the %Dictionary.ClassDefinition:Summary() query.
You can get detailed information about a specific class definition by opening a %Dictionary.ClassDefinition object for the class and observing its properties. The ID used to store %Dictionary.ClassDefinition objects is the class name:
 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,!
You can also do this easily from an ActiveX or Java client. Note that you must fully qualify class names with their package name or the call to %OpenId() will fail.
Altering Class Definitions
You can modify an existing class definition by opening a %Dictionary.ClassDefinition object, making the desired changes, and saving it using the %Save() method.
You can create a new class by creating a new %Dictionary.ClassDefinition object, filling in its properties and saving it. When you create %Dictionary.ClassDefinition object, you must pass the name of the class via the %New() command. When you want to add a member to the class (such as a property or method), you must create the corresponding definition class (passing its %New() command a string containing "class_name.member_name") and add the object to the appropriate collection within the %Dictionary.ClassDefinition object.
For example:
 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()