Class Reference
IRIS for UNIX 2019.2
InterSystems: The power behind what matters   
Documentation  Search
  [%SYS] >  [%FOI] >  [Metadata] >  [Type]
Private  Storage   

persistent class %FOI.Metadata.Type extends %Library.Persistent

A Type Descriptor (TD) defines a complex type. A Type Descriptor can be defined by a user or derived from a class or class member definition (%Dictionary classes).

Each TD is identified by a namespace, name and category. The namespace is simply a logical grouping of types and it contains an arbitrary number of dot-delimited pieces. The name cannot contain any dots but both the nameSpace and the name can be delimited identifiers. The category is simply an additional name qualifier to prevent collisions.

The name and nameSpace of a TD derived from a class definition is based on the qualified name of the class, the nameSpace is equal to the full package name and the name is equal to the unqualified name of the class. The category for class TD's is "CLS".

TDs can also be derived from class members - indices, properties, and storage. The name of a TD derived from a class member is the same as the member name and the nameSpace is the fully qualified name of the class. In the case of storage TDs, there can be additional TDs derived from storage members. For submember derived TDs, the name is the name of the submember and the nameSpace is the name of the containing member. The level of submember nesting is not constrained by the Type Descriptor model and the naming convention is the same, nameSpace is the container name and name is the member name. This naming convention is completely consistent as a package can be viewed as the container of a class.

Since the nameSpace and name of TD derived from a class can be the same as the nameSpace and name of a class member, names are qualified by category. The category is based on the entity from which the TD is derived.

A Type Descriptor exists as an intermediate definition. The intermediate definition is a complete definition of the TD. From that intermediate definition some other descriptors can be derived. Those descriptors may exist in an optimized serial form and may not be a complete representation of the intermediate type. One such descriptor might be a compressed list serialization of only the storage descriptors of a particular class.

Primitive Types

Complex Types

Inventory

Parameters Properties Methods Queries Indices ForeignKeys Triggers
3 6 21 3


Summary

Properties
category descriptor name nameSpace qualifiedName
typeID

Methods
%AddToSaveSet %AddToSyncSet %BMEBuilt %CheckConstraints
%CheckConstraintsForExtent %ClassIsLatestVersion %ClassName %ComposeOid
%ConstructClone %Delete %DeleteExtent %DeleteId
%DispatchClassMethod %DispatchGetModified %DispatchGetProperty %DispatchMethod
%DispatchSetModified %DispatchSetMultidimProperty %DispatchSetProperty %Exists
%ExistsId %Extends %GUID %GUIDSet
%GetLock %GetParameter %GetSwizzleObject %Id
%InsertBatch %IsA %IsModified %IsNull
%KillExtent %KillExtentData %LoadFromMemory %LockExtent
%LockId %New %NormalizeObject %ObjectIsNull
%ObjectModified %Oid %OnBeforeAddToSync %OnDetermineClass
%Open %OpenId %OriginalNamespace %PackageName
%PhysicalAddress %PurgeIndices %Reload %RemoveFromSaveSet
%ResolveConcurrencyConflict %RollBack %Save %SaveDirect
%SaveIndices %SerializeObject %SetModified %SortBegin
%SortEnd %SyncObjectIn %SyncTransport %ToJSON
%UnlockExtent %UnlockId %ValidateIndices %ValidateObject
fieldToList getAddressDescriptor getClassDescriptor getConstraintDescriptor
getDescriptor getExtentDescriptor getExtentFieldDescriptor getFieldDescriptor
getIndexDescriptor getJSONType getMapDescriptor getMapDescriptorDirect
getMetadata getODBCTypeInfo getQualifiedName getType
getTypeClass getTypeDirect toCOS toXEP


Parameters

• parameter DEFAULTGLOBAL = "^ISC.FOI.MD";

If a persistent class uses %Storage.Persistent then the DEFAULTGLOBAL parameter is used as the default global root for the values of the storage keywords COUNTERLOCATION, DATALOCATION, IDLOCATION, INDEXLOCATION and STREAMLOCATION in the active storage definition. DEFAULTGLOBAL is only used to generate location keyword values that are not already defined. The location value is constructed by adding a location type to the end of DEFAULTGLOBAL. For example, if DEFAULTGLOBAL = "^GL.Account" the compiler will generate DATALOCATION = ^GL.AccountD.

If USEEXTENTSET is true, then DEFAULTGLOBAL is used as the default extent location.


The location types are:
LocationType
COUNTERLOCATIONC
DATALOCATIOND
IDLOCATIOND
INDEXLOCATIONI
STREAMLOCATIONS
• parameter TYPECATDEFAULT = "CLS";
• parameter USEEXTENTSET = 1;

If a persistent class uses %Storage.Persistent then the USEEXTENTSET parameter is used to specify the global naming strategy used by the default storage class (%Storage.Persistent). If TRUE, then global names are generated for each index that is not already allocated a LOCATION in the active storage definition.

If the storage definition specifies EXTENTLOCATION then that value is used as the base reference for all globals assigned to indices that do not have an explicit LOCATION assigned.

The global name generator for USEEXTENTSET = TRUE honors the package prefix defined in the Package Definition. If none is defined then the package prefix is generated using a based-62 encoded integer produced from CRC32 of the package name. The specific class identifier is generated from the unqualified class name using the same hash (class->crc32->base62) to form EXTENTLOCATION. Specific index suffixes are produced using a generated offset that is local to the first persistent class with an enumerated extent in which the index appears (either defined or inherited).

There are several factors that influence the generation of EXTENTLOCATION:

  1. If the EXTENTLOCATION keyword is defined then its value is used,
  2. If the DEFAULTGLOBAL class parameter is defined then its value is used,
  3. otherwise, the value is generated as two dot delimited segments. The first segment is either the defined package prefix retrieved from the package definition global or, if none is defined, a hash of the package name. The second segment is generated by a hash of the unqualified class name. The hash used is a base 62 encoded CRC32 of the value. For example, Sample.Person produces ^EW3K.wPC9 if no package prefix is defined.
The EXTENTLOCATION value is used as the base for specific globals allocated to indices. Each index is assigned an offset that is incremented from 1 by 1, offset = 1 is reserved for the IDKEY index.

EXTENTLOCATION is specific to each class. When a persistent class extends another persistent class, forming a subextent, then the subclass's EXTENTLOCATION is specific to that subclass. The index location for any inherited index is already defined specifically in the super class so the subclass's EXTENTLOCATION will only be used as the base for any index that originates in the subclass. For example, Sample.Employee extends Sample.Person. The EXTENTLOCATION generated for Sample.Person is ^EW3K.wPC9 and the EXTENTLOCATION for Sample.Employee is ^EW3K.D1Ex. Since Sample.Employee inherits several indices from Sample.Person, the global name assigned to each of those indices is already defined and inherited by Sample.Employee. However, any index defined in Sample.Employee and not inherited from Sample.Person will be assigned a global name based on Sample.Employee's EXTENTLOCATION, not on Sample.Person's EXTENTLOCATION. In other words, the EXTENTLOCATION storage keyword is not inherited.

The following tables show the indices and locations for Sample.Person and Sample.Employee. Notice the last index in the Sample.Employee table:
Class = Sample.Person
IndexLocation
IDKEY^EW3K.wPC9.1
$Person^EW3K.wPC9.2
NameIDX^EW3K.wPC9.3
SSNKey^EW3K.wPC9.4
ZipCode^EW3K.wPC9.5
Class = Sample.Employee extends Sample.Person
IndexLocation
IDKEY^EW3K.wPC9.1
$Person^EW3K.wPC9.2
NameIDX^EW3K.wPC9.3
SSNKey^EW3K.wPC9.4
ZipCode^EW3K.wPC9.5
$Employee^EW3K.D1Ex.2

Any generated global index locations and EXTENTLOCATION are updated back into the active storage definition after the class is compiled.

If USEEXTENTSET is FALSE, then global names are generated using the package-hash.class-hashSuffix strategy. For example, ^Sample.PersonD and ^Sample.PersonI("SSNKey") are globals used by Sample.Person and specific index structures are all stored in ^Sample.PersonI with the index name used as the first subscript.



Properties

• property category as %String(MAXLEN=3,VALUELIST=",CLS,CON,EXT,FLD,IDX,SDF,ADR,MAP,UDT");

CategoryMember Type
CLSClass
EXTExtent
IDXIndex
SDFStorage
ADRStorage Address
MAPStorage Map
UDTUser Defined Type

• property descriptor as %Library.DynamicAbstractObject;
• property name as %String(MAXLEN=220);
• property nameSpace as %String(MAXLEN=220);
• property qualifiedName as %String(MAXLEN=220) [ Calculated ];
• property typeID as %Integer;

Methods

• method %ToJSON(destination As %Stream.Object) as %String
• classmethod fieldToList(field As %Library.DynamicObject) as %List
• classmethod getAddressDescriptor(nameSpace, addressName, refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getClassDescriptor(className, refresh As %Integer = 0) as %List
Complex Types

Avro supports six kinds of complex types: records, enums, arrays, maps, unions and fixed.

Records

Records use the type name "record" and support these attributes:

namea JSON string providing the name of the record (required).
namespaceJSON string that qualifies the name;
docJSON string providing documentation to the user of this schema (optional).
aliasesa JSON array of strings, providing alternate names for this record (optional).
fieldsa JSON array, listing fields (required). Each field is a JSON object with the following attributes:
namea JSON string providing the name of the field (required)
doca JSON string describing this field for users (optional).
typeA JSON object defining a schema, or a JSON string naming a record definition (required).
default

A default value for this field, used when reading instances that lack this field (optional). Permitted values depend on the field's schema type, according to the table below. Default values for union fields correspond to the first schema in the union. Default values for bytes and fixed fields are JSON strings, where Unicode code points 0-255 are mapped to unsigned 8-bit byte values 0-255.

avro typejson typeexample
nullnullnull
booleanbooleantrue
int,longinteger1
float,doublenumber1.1
bytesstring"\u00FF"
stringstring"foo"
recordobject{"a": 1}
enumstring"FOO"
arrayarray[1]
mapobject{"a": 1}
fixedstring"\u00ff"
order

specifies how this field impacts sort ordering of this record (optional). Valid values are "ascending" (the default), "descending", or "ignore". For more details on how this is used, see the the sort order section below.

aliasesa JSON array of strings, providing alternate names for this field (optional).
For example, a linked-list of 64-bit values may be defined with:

{ 
  "type": "record",
  "name": "LongList",
  "aliases": ["LinkedLongs"],                      // old name for this
  "fields" : [
    {"name": "value", "type": "long"},             // each element has a long
    {"name": "next", "type": ["null", "LongList"]} // optional next element
  ]
}

• classmethod getConstraintDescriptor(nameSpace, constraintName, refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getDescriptor(nameSpace, name, category, refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getExtentDescriptor(className As %String(MAXLEN=220), refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getExtentFieldDescriptor(nameSpace As %String(MAXLEN=220), fieldName As %String(MAXLEN=220), refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getFieldDescriptor(nameSpace As %String(MAXLEN=220), fieldName As %String(MAXLEN=220), refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getIndexDescriptor(nameSpace, indexName, refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getJSONType(class) as %String
• classmethod getMapDescriptor(nameSpace, mapName, refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getMapDescriptorDirect(nameSpace, addressName, mapName, refresh As %Integer = 0) as %Library.DynamicAbstractObject
• classmethod getMetadata(qualifiedName, format, refresh As %Integer = 0) as %RawString
• classmethod getODBCTypeInfo(field As %Library.DynamicAbstractObject) as %Library.String
• classmethod getQualifiedName(nameSpace, name, category) as %String
• classmethod getType(name As %String(MAXLEN=220), refresh As %Boolean = 0) as %FOI.Metadata.Type

This is the primary interface for retrieving a type. The name is the fully qualified name of the type to retrieve. If the type is not currently defined then the category extracted from the name is used to determine if a type generator exists. If a type generator does exist then the type is generated from the relevant metadata repository.

If the refresh value is TRUE then the type is generated even if it does exist and an appropriate generator is found.

This method throws an exception is an error is encountered during the retrieval of the type.

• classmethod getTypeClass(className) as %Library.DynamicAbstractObject
Return the datatype of any class
• classmethod getTypeDirect(nameSpace, name, category, refresh As %Boolean = 0) as %FOI.Metadata.Type
• method toCOS(refresh As %Integer = 0) as %String
COS Client metadata I think we should have an extent - the metadata describing the physical structure/logical structure and binding between them - and also an extentType - for enumerated and embedded.
• method toXEP(refresh As %Integer = 0) as %List
XEP metadata is for persistent classes only. embedded types - the utility simply provides the embedded type class name. I think we should have an extent - the metadata describing the physical structure/logical structure and binding between them - and also an extentType - for enumerated and embedded.

Indices

•index (IDK on typeID) [IdKey];
•index (PK on nameSpace,name,category) [PrimaryKey];
•index (fiMD on qualifiedName) [Data = descriptor];


Copyright (c) 2019 by InterSystems Corporation. Cambridge, Massachusetts, U.S.A. All rights reserved. Confidential property of InterSystems Corporation.