第二章 IRIS 定义和编译类

本文介绍了InterSystemsIRIS数据平台中类的定义,包括类的基本结构、术语、类的种类、属性和方法的定义,以及继承机制。重点讨论了类的命名规范、选择超类、属性和方法的定义,并提到了编译器关键字的作用。此外,还涵盖了类的文档创建和编译过程。
摘要由CSDN通过智能技术生成

本章介绍使用InterSystems IRIS®数据平台定义和编译类的基础知识。

2.1 术语介绍

下面显示了一个简单的InterSystems IRIS类定义,其中包含一些典型元素:

Class Demo.MyClass Extends %RegisteredObject
{

Property Property1 As %String;

Property Property2 As %Numeric;

Method MyMethod() As %String
{
   set returnvalue=..Property1_..Property2
   quit returnvalue
}

}

注意以下几点:

  • 全名为 Demo.MyClass ,包名为 Demo ,短类名为 MyClass

  • 此类扩展了类 %RegisteredObject 。等价地,该类继承自 %RegisteredObject

    %RegisteredObject 是这个类的超类,或者这个类是 %RegisteredObject 的子类。InterSystems IRIS类可以有多个超类,正如本章稍后讨论的那样。

    类的超类决定了如何使用该类。

  • 此类定义了两个属性: Property1Property2 。属性 Property1 的类型为 %String ,而属性 Property2 的类型为 %Numeric

  • 此类定义了一个方法: MyMethod() ,它的返回值类型为 %String

此类是指InterSystems IRIS提供的几个系统类。这些类是 %RegisteredObject (其全名为 %Library.RegisteredObject ), %String%Library.String ), 和 %Numeric%Library.Numeric )。 %RegisteredObject 是InterSystems IRIS中的关键类,因为它定义了对象接口。它提供了用于创建和处理对象实例的方法。 %String%Numeric 是数据类型类。因此,相应的属性持有相应值(而不是其他类型的值)。

2.2 类的种类

InterSystems IRIS提供了一组大的类定义,您的类可以以下列常规方式使用这些定义:

  • 您可以使用InterSystems IRIS类作为类的超类。
  • 您可以将InterSystems IRIS类用作属性的值、方法的参数值、方法返回的值等。
  • 一些InterSystems IRIS类只提供特定的API。您通常不会以上述任一方式使用这些类。而是编写调用API方法的代码。

超类最常见的选择如下:

  • %RegisteredObject -此类以其最通用的形式表示对象接口。
  • %Persistent -此类表示持久对象。除了提供对象接口之外,此类还提供了将对象保存到数据库和从数据库读取对象的方法。
  • %SerialObject -此类表示可以嵌入(序列化在)另一个对象中的对象。
  • 前面任何类的子类。
  • 无-创建类时不需要指定超类。

属性的值、方法的参数值、方法返回的值等的最常见选择如下:

  • 对象类(上一列表中包含的类)
  • 数据类型类
  • 集合类
  • 流类

本书后面的章节讨论了这些类别的课程。

2.2.1 对象类

对象类指 %RegisteredObject 的任何子类。使用对象类,您可以创建类的实例,指定实例的属性,并调用实例的方法。后面一章将描述这些任务(并提供适用于所有对象类的信息)。

通用术语对象是指对象类的实例。

对象类有三个一般类别:

  • 临时对象类或注册对象类是 %RegisteredObject 的子类,而不是的 %Persistent%SerialObject (请参阅以下项目)。

    有关详细信息,请参阅“使用已注册对象”

  • 持久类是 %Persistent 的子类,它是 %RegisteredObject 的直接子类。 %Persistent 包括 %RegisteredObject 的行为,并添加了将对象保存到磁盘、重新打开等功能。

    有关详细信息,请参阅“持久对象简介”一章及其后续章节。

  • 串行类是 %SerialObject 的子类,它是 %RegisteredObject 直接子类。 %SerialObject 包括的 %RegisteredObject 行为,以作为另一个对象(通常是暂时对象或持久对象)中的属性包含。短语序列化对象指的是创建此字符串。

    有关详细信息,请参阅“定义和使用对象值属性”一章。

下图显示了这三个类之间的继承关系。这些框列出了类中定义的一些方法:

在这里插入图片描述

集合类和流类是具有特殊行为的对象类。

2.2.3 数据类型类

数据类型类是指ClassType关键字等于数据类型的任何类或此类的任何子类。这些类不是对象类(数据类型类不能定义属性,也不能创建类的实例)。数据类型类(更准确地说是数据类型生成器类)的目的是用作对象类的属性类型。

2.3 类成员的类型

InterSystems IRIS类定义可以包括以下项,都称为类成员:

  • 参数-一个参数定义一个常量值供该类使用。在大多数情况下,该值在编译时设置。
  • 方法-InterSystems IRIS支持两种类型的方法:实例方法和类方法。实例方法从类的特定实例调用,并执行与该实例相关的某些操作;这种类型的方法只在对象类中有用。类方法是一种无论其类的实例是否在内存中都可以调用的方法;这种类型的方法在其他语言中称为静态方法。
  • 属性-属性包含类实例的数据。属性仅在对象类中有用。以下小节提供了更多信息。
  • 类查询-类查询定义了类可以使用的SQL查询,并指定了用作查询容器的类。通常(但不一定),您在持久类中定义类查询,以对该类的存储数据执行查询。但是,您可以在任何类中定义类查询。
  • 仅与持久类相关的其他类型的类成员:
    • 存储定义
    • 索引
    • 外键
    • SQL触发器
  • XData块-XData块是类中定义的命名数据单元,通常由类中的方法使用。这些有许多可能的应用。
  • 投影-类投影提供了一种扩展类编译器行为的方法。

2.3.1 属性种类

形式上,有两种属性:特性和关系。

特性保存值。特性属性通常简称为属性。根据特性定义,它所包含的值可以是以下任意值:

  • 文本值,如“MyString”和1。包含文字值的属性基于数据类型类,也称为数据类型属性。请参阅“定义和使用文字属性”一章。
  • 流。流是InterSystems IRIS对象,它包含的值对于字符串来说太长。请参阅“使用流”一章。
  • 集合。InterSystems IRIS提供了将属性定义为列表或数组的功能。列表或数组项可以是文本值,也可以是对象。请参阅“使用集合”一章。
  • 其他类型的对象。请参阅“定义和使用对象值属性”一章。

关系保持对象之间的关联。关系属性被称为关系。仅在持久类中支持关系。请参阅“定义和使用关系”一章

2.4 定义类:基础知识

本节将更详细地讨论基本类定义。它讨论了以下主题:

  • 选择超类
  • 指定类关键字
  • 包含文件
  • 定义类参数
  • 定义属性
  • 定义方法

通常,您使用集成开发环境(IDE)来定义类。您还可以使用InterSystems IRIS类定义类或通过XML类定义文件以编程方式定义类。如果使用SQLDDL语句定义SQL表,系统将创建相应的类定义。

2.4.1 选择超类

当您定义一个类时,最早的设计决策之一是选择作为类基础的类。如果只有一个超类,请在类定义的开头包含Extendes,后跟超类名称。

Class Demo.MyClass Extends Superclass 
{

//...

}

如果有多个超类,请将它们指定为逗号分隔的列表,用括号括起来。

Class Demo.MyClass Extends (Superclass1, Superclass2, Superclass3) 
{

//...

}

创建类时不必指定超类。即使类不表示任何类型的对象,使用 %RegisteredObject 作为超类也是很常见的,因为这样做可以让类访问许多常用的宏,但您可以直接包含包含它们的include文件。

2.4.2 包括文件

如果类或其任何子类中没有扩展 %RegisteredObject 的类,可能需要包含以下包含文件:

  • %occStatus.inc ,它定义宏值中使用 %Status

  • %occMessages.inc ,它定义用于处理消息的宏。

有关这些包含文件定义的宏的详细信息,请参阅使用ObjectScript中的“使用系统提供的宏”。

如果类或其任何子类中扩展了 %RegisteredObject ,则这些宏将自动可用。

您还可以创建自己的包含文件,并根据需要将它们包含在类定义中。

要在类定义的开头包含包含文件,请使用以下格式的语法。请注意,必须省略包含文件的.inc扩展名:

Include MyMacros

例如:

Include %occInclude

Class Classname 
{
}

要在类定义的开头包含多个包含文件,请使用以下形式的语法:

Include (MyMacros, YourMacros) 

注意,此语法没有前导#符号(与例程中所需的语法相反)。此外,Include指令不区分大小写,因此可以改用Include。包含文件名区分大小写。

另请参见使用ObjectScript中的#include参考部分。

2.4.3 指定类关键字

在某些情况下,需要控制类编译器生成的代码的细节。例如,对于持久类,如果不想(或不能)使用默认表名,则可以指定SQL表名。例如,您可以将一个类标记为final,这样就不能创建它的子类。为此,类定义支持一组特定的关键字。如果需要指定类关键字,请将它们包含在超类后面的方括号中,如下所示:

Class Demo.MyClass Extends Demo.MySuperclass [ Keyword1, Keyword2, ...]
{

//...

}

例如,可用的类关键字包括Abstract和Final。有关介绍,请参阅本章后面的“编译器关键字”。InterSystems IRIS还为每种类成员提供特定的关键字。

2.4.4 定义类参数

类参数为给定类的所有对象定义一个常量值。要向类定义中添加类参数,请向类中添加如下元素之一:

Parameter PARAMNAME as Type;
Parameter PARAMNAME as Type = value;
Parameter PARAMNAME as Type [ Keywords ] = value;

关键字表示任何参数关键字。有关关键字的介绍,请参阅本章后面的“编译器关键字”。对于参数关键字;请参阅“类定义参考”中的“参数关键字”。这些是可选的。

2.4.5 定义属性

对象类可以包含属性。

要向类定义中添加属性,请向类中添加以下元素之一:

Property PropName as Classname;
Property PropName as Classname [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) ;

PropName是属性的名称,Classname是可选的类名(如果省略此项,则假定该属性的类型为%String)。

关键字表示任何属性关键字。有关关键字的介绍,请参阅本章后面的“编译器关键字”。对于属性关键字;请参阅类定义参考中的“属性关键字”。这些是可选的

根据属性使用的类,您还可以指定属性参数,如第三和第四个变体所示。

请注意,属性参数(如果包含)包含在括号中,并位于任何属性关键字之前。还要注意,属性关键字(如果包含)括在方括号中。

2.4.6 定义方法

您可以在InterSystems IRIS类中定义两种方法:类方法和实例方法。

要向类定义中添加类方法,请向类中添加如下元素:

ClassMethod MethodName(arguments) as Classname [ Keywords]
{
//method implementation
}

MethodName是方法的名称,arguments是逗号分隔的参数列表。类名是一个可选类名,表示此方法返回的值类型(如果有)。如果方法不返回值,则省略As Classname部分。

关键字表示任何方法关键字。有关关键字的介绍,请参阅本章后面的“编译器关键字”。有关方法关键字,请参阅类定义参考中的“方法关键字”。这些是可选的。

要添加实例方法,请使用与method而不是ClassMethod相同的语法:

Method MethodName(arguments) as Classname [ Keywords]
{
//method implementation
}

实例方法仅在对象类中相关。

2.5 命名惯例

类和类成员遵循特定的命名约定。这些将在本节中详细介绍。

2.5.1 类和类成员名称规则

本节介绍类和成员名称的规则,例如最大长度、允许的字符等。完整的类名包括其包名称,如下一节所述。

每个标识符在其上下文中必须是唯一的(即,两个类不能具有相同的名称)。InterSystems IRIS对包、类和成员名称有以下限制:

  • 每个包名称最多可包含189个唯一字符。
  • 每个类名最多可以有60个唯一字符。
  • 每个方法和属性名称最多可以有180个唯一字符。有关详细信息,请参阅“类成员名称”一节。
  • 属性名称和属性索引的组合长度不得超过180个字符
  • 每个成员的全名(包括非限定成员名、类名、包名和任何分隔符)必须少于220个字符。
  • 每个名称都可以包含Unicode字符。

标识符保留大小写:必须完全匹配名称的大小写;同时,两个类的名称不能仅大小写不同。例如,出于唯一性的目的,标识符“id1”和“ID1”被认为是相同的。

标识符必须以字母字符开头,尽管在第一个位置之后可能包含数字字符。标识符不能包含空格或标点符号,但可能包含“.”字符的包名除外。

某些标识符以“%”字符开头;这标识系统项。例如,InterSystems IRIS库提供的许多方法和包都以“%”字符开头。

成员名称可以用分隔符分隔,这允许它们包含不允许的字符。要创建分隔的成员名称,请在名称的第一个字符和最后一个字符之间使用双引号。例如:

Property "My Property" As %String;

有关系统标识符的更多详细信息,请参阅“服务器端编程方向指南”中的附录“标识符规则和指南”。

2.5.2 类名称

每个类都有一个唯一标识它的名称。完整的类名由两部分组成:包名和类名:类名后跟名称中的最后一个“.”字符。类名在其包中必须是唯一的;包名称在InterSystems IRIS命名空间中必须是唯一的。有关软件包的详细信息,请参阅“软件包”一章

因为持久类自动投影为SQL表,所以类定义必须指定不是SQL保留字的表名;如果持久类的名称是SQL保留字,则类定义还必须为其SQLTableName关键字指定有效的非保留字值。

2.5.3 类成员名称

每个类成员(如属性或方法)的名称必须在其类中唯一,且最大长度为180个字符。此外,持久性的成员不能使用SQL保留字作为其标识符。但是,它可以使用该成员的SQLName或SQLFieldName关键字定义别名(视情况而定)。

重要:

InterSystems强烈建议不要给两个成员起相同的名字。这可能会产生意想不到的结果。

2.6 继承

InterSystems IRIS类可以继承现有的类。如果一个类从另一个类继承,则继承类被称为子类,而它派生的一个或多个类则被称为超类。

下面显示了使用两个超类的示例类定义:

Class User.MySubclass Extends (%Library.Persistent, %Library.Populate)
{
}

除了类从其超类继承方法外,属性还从系统属性行为类继承其他方法,如果是数据类型属性,则从数据类型类继承。

例如,如果定义了一个名为 Person 的类:

Class MyApp.Person Extends %Library.Persistent
{
Property Name As %String;
Property DOB As %Date;
}

从中派生一个新类 Employee

Class MyApp.Employee Extends Person
{
Property Salary As %Integer;
Property Department As %String;
}

此定义将 Employee 类建立为 Person 类的子类。除了自己的类参数、属性和方法之外, Employee 类还包括 Person 类中的所有这些元素。

2.6.1 子类的使用

您可以在任何可能使用其超类的地方使用子类。例如,使用上面定义的 EmployeePerson 类,可以打开 Employees 对象并将其称为 Person

 Set x = ##class(MyApp.Person).%OpenId(id)
 Write x.Name

我们还可以访问员工特定的属性或方法:

 Write x.Salary // displays the Salary property (only available in Employee instances)

2.6.2 主要超类

子类扩展的最左边的超类称为其主超类。类继承其主超类的所有成员,包括适用的类关键字、属性、方法、查询、索引、类参数,以及继承的属性和继承方法的参数和关键字。除了标记为Final的项之外,子类可以覆盖(但不能删除)其继承成员的特征。

有关多重继承的更多详细信息,请参阅下一节。

2.6.3 多重继承

通过多重继承,类可以从多个超类继承其行为和类类型。要建立多重继承,请在括号内列出多个超类。最左边的超类是主超类。

例如,如果类 X 继承自类 ABC ,则其定义包括:

Class X Extends (A, B, C) 
{
}

类编译器的默认继承顺序是从左到右,这意味着超类之间成员定义的差异将以最左边的超类为优先(在本例中, A 取代 BCB 取代 C

具体来说,对于类 X ,类参数值、属性和方法的值从类 A (列出的第一个超类)继承,然后从类 B 继承,最后从类 C 继承。 X 还从 B 继承了A没有定义的任何类成员,以及从 C 继承了 AB 都没有定义的所有类成员。如果类 B 有一个与已从 A 继承的成员同名的类成员,则 X 使用来自 A 的值;类似地,如果 C 有一个与从 AB 继承的成员同名的成员,则优先顺序为 ABC

因为从左到右继承是默认继承,所以不需要指定此继承;因此,前面的示例类定义等同于以下内容:

Class X Extends (A, B, C) [ Inheritance = left ]
{
}

要在超类之间指定从右到左的继承,请使用值为right的继承关键字:

Class X Extends (A, B, C) [ Inheritance = right ]
{
}

对于从右到左的继承,如果多个超类具有相同名称的成员,则右侧的超类优先。

注:

即使有从右到左的继承,最左边的超类(有时称为第一超类)仍然是主超类。这意味着该子类只继承其最左边的超类的类关键字值——这些值没有覆盖。

例如,在类 X 从类 ABC 继承并具有从右到左继承的情况下,如果从类 A 继承的成员与从类 B 继承的成员之间存在冲突,则来自类 B 的成员重写(替换)先前继承的成员; C 类成员相对于 A 类和 B 类成员也是如此。类 X 的类关键字完全来自类 A (这就是为什么用从左到右继承的顺序来扩展类 AB 与用从右到左继承的顺序扩展类 BA 不同的原因;关键字是从任一定义中最左边的超类继承的,这使得两种情况不同。)

2.6.4 其他

另请参阅“使用注册对象”一章中的“%ClassName()和最特定类型类(MSTC)”

2.7 编译器关键字

如“定义类:基础知识”中所示,可以在类定义或类成员的定义中包含关键字。这些关键字也称为类属性,通常会影响编译器。本节介绍一些常见的关键字,并讨论InterSystems IRIS如何呈现它们。

以下示例显示了包含一些常用关键字的类定义:

/// This sample persistent class represents a person.
Class MyApp.Person Extends %Persistent [ SqlTableName = MyAppPerson ]
{

/// Define a unique index for the SSN property.
Index SSNKey On SSN [ Unique ];

/// Name of the person.
Property Name As %String [ Required ];

/// Person's Social Security number.
Property SSN As %String(PATTERN = "3N1""-""2N1""-""4N") [ Required ];

}

此示例显示以下关键字:

  • 对于类定义,Extendes关键字指定该类从中继承的超类。

    请注意,当您以其他方式查看类时,Extendes关键字具有不同的名称;请参阅下一节。

  • 对于类定义,如果不使用默认名称,SqlTableName关键字将确定关联表的名称。这个关键字只对持久类有意义,这将在本书后面介绍。

  • 对于索引定义,Unique关键字使InterSystems IRIS对索引所基于的属性(本例中为SSN)强制执行唯一性。

  • 对于这两个属性,Required关键字会导致InterSystems IRIS要求属性的非空值。

PATTERN不是关键字,而是属性参数;请注意,PATTERN包含在括号中,而不是方括号中。

本书后面的章节讨论了许多附加的关键词,但并非全部。除了与存储相关的关键字(通常没有文档记录),您可以在“类定义参考”中找到有关关键字的详细信息。参考信息演示了在通常的编辑模式下查看类时适用的语法。

2.8 创建类文档

InterSystems IRIS提供了一个名为InterSystems Class Reference的网页,该网页显示InterSystems提供的类以及您创建的类的自动生成的参考信息。非正式地,类参考称为Documatic,因为它是由类 %CSP.Documatic 生成的。

本节介绍类参考,并说明如何创建自己的文档以及如何包含HTML标记。

2.8.1 类参考

类参考的目的是向其他程序员宣传可以使用类的哪些部分以及如何使用它们。以下是一个示例:
在这里插入图片描述

此参考信息显示了类成员的定义,但不显示它们的实际实现。例如,它显示方法签名,但不显示其内部定义。它包括元素之间的链接,以便您可以快速遵循代码的逻辑。还有一个搜索选项。

2.8.2 创建要包含在类参考中的文档

要创建要包含在类参考中的文档,请在类定义中创建注释,特别是以///开头的注释。如果在类声明之前添加此类注释,则注释将显示在该类页面的顶部。如果在给定的类成员之前添加此类注释,则注释将显示在为该类成员生成的信息之后。一旦编译了类,就可以在下次打开类参考文档时查看其生成的类文档。如果未添加任何类参考注释,则添加到类或包的项将适当地显示在类或包内容列表中,但没有任何说明性文本。

可以通过修改类定义来扩展任何现有的类参考注释。类参考注释的语法规则是严格的:

  • 描述类或类成员的所有类参考注释必须出现在它们描述的项声明之前的连续块中。

  • 注释块中的每一行必须以三个斜线开头:///

    提示:

    请注意,默认情况下,演示文稿组合了所有///行的文本,并将结果视为单个段落。您可以插入HTML换行符( < br >)。或者您可以使用HTML格式(如<p>和</p>),如小节所述。

  • 三个斜线必须从行中的第一个(最左侧)位置开始。

  • 类参考注释中不允许有空行。

  • 类参考注释的最后一行和它们描述的项的声明之间不允许有空行。

  • 类参考注释的长度(所有行合并)必须小于字符串长度限制(非常长)。请参阅服务器端编程方向指南中的“字符串长度限制”。

类参考注释允许纯文本,加上任何标准HTML元素和少量专用元素。

2.8.3 在类文档中使用HTML标记

您可以在类中的注释中使用HTML标记。在标记中,尽可能严格遵守HTML标准,例如XHTML,这样任何浏览器都可以显示结果。请注意,%CSP.Documatic 会生成一个完整的HTML页面,并且该类文档包含在该页面的<body>元素中。因此,不要在标记中包含HTML标记<HTML>、<body>、<head>或<meta>;这些标记都将被忽略。此外,类名显示为<h1>标题,因此如果使用标题,请使用<h2>和更低的标题。因为搜索引擎喜欢只有一个<h1>的HTML页面,所以如果在标记中包含<h1>,则该标题将转换为<h2>。

除了标准HTML之外,还可以使用以下标记:<CLASS>、<METHOD>、<PROPERTY>、<PARAMETER>、<QUERY>和<EXAMPLE>。(与标准HTML标记一样,这些标记的名称不区分大小写。)这里描述了最常用的标记。详细信息请参阅 %CSP.Documatic 的文档。

<CLASS>

用于标记类名。如果类存在,则内容将显示为指向类文档的链接。例如:

/// This uses the <CLASS>MyApp.MyClass</CLASS> class.

<EXAMPLE>

用于标记编程示例。此标记会影响文本的外观。请注意,在示例中,每一行///都成为一个单独的行(与通常的情况相反,行被合并为一个段落)。例如:

/// <EXAMPLE>
/// set o=..%New()
/// set o.MyProperty=42
/// set o.OtherProp="abc"
/// do o.WriteSummary()
/// </EXAMPLE>

<METHOD>

用于标记方法名称。如果该方法存在,则内容将显示为该方法文档的链接。例如:

/// This is identical to the <METHOD>Unique</METHOD> method.

<PROPERTY>

用于标记属性名称。如果该属性存在,则内容将显示为指向该属性文档的链接。例如:

/// This uses the value of the <PROPERTY>State</PROPERTY> property.

以下是使用HTML标记的多行描述:

/// The <METHOD>Factorial</METHOD> method returns the factorial
/// of the value specified by <VAR>x</VAR>.

2.9 编译类

InterSystems IRIS类定义由类编译器编译成应用程序例程。类在编译之前不能在应用程序中使用。

类编译器与其他编程语言(如Java)的编译器有两个显著的不同之处:首先,编译结果放在共享存储库(数据库)中,而不是文件系统中。其次,它自动为持久类提供支持。

具体来说,类编译器执行以下操作:

  1. 它生成一个依赖项列表-必须首先编译的类。根据使用的编译选项,还将编译自上次编译以来已修改的任何依赖项。
  2. 它解决了继承问题-它确定从超类继承哪些方法、属性和其他类成员。它将此继承信息存储到类字典中以供以后参考。
  3. 对于持久类和串行类,它确定在数据库中存储对象所需的存储结构,并创建类的SQL表示所需的必要运行时信息。
  4. 它执行类定义(或继承)的任何方法生成器。
  5. 它创建一个或多个例程,其中包含类的运行时代码。类编译器根据语言(ObjectScript和Basic)对方法进行分组,并生成单独的例程,每个例程包含一种语言或另一种语言的方法。
  6. 它将所有生成的例程编译为可执行代码。
  7. 它创建一个类描述符。这是一种特殊的数据结构(存储为例程),其中包含支持类所需的所有运行时调度信息(属性的名称、方法的位置等)。

2.9.1 调用类编译器

您可以使用IDE(如其他地方所述)编译类,也可以在终端中编译它们。在后一种情况下,使用 %SYSTEM.OBJCompile() 方法:

 Do $System.OBJ.Compile("MyApp.MyClass")

2.9.2 类编译器注释

2.9.2.1 编译顺序

编译类时,如果正在编译的类包含有关依赖关系的信息,则系统还会重新编译其他类。例如,系统编译类的任何子类。在某些情况下,您可能需要控制类的编译顺序。为此,请使用System、DependsOn和CompileAfter关键字。有关详细信息,请参阅类定义参考。

要查找编译给定类时编译器将重新编译的类,请使用 $SYSTEM.OBJ.GetDependencies() 方法。例如:

TESTNAMESPACE>d $system.OBJ.GetDependencies("Sample.Address",.included)
 
TESTNAMESPACE>zw included
included("Sample.Address")=""
included("Sample.Customer")=""
included("Sample.Employee")=""
included("Sample.Person")=""
included("Sample.Vendor")=""

该方法的签名如下:

classmethod GetDependencies(ByRef class As %String, Output included As %String, qspec As %String) as %Status
  • class 是单个类名(如示例中所示)、逗号分隔的类名列表或多维类名数组。(如果是多维数组,请确保通过引用传递此参数。)它还可以包含通配符。
  • included 是一个多维数组,其中包含在编译类时将编译的类的名称。
  • qspec 是一个编译器标志和限定符的字符串。请参阅下一小节。如果忽略此项,该方法将考虑当前编译器标志和限定符。
2.9.2.2 查看类编译器标志和限定符

Compile() 方法还允许您提供影响结果的标志和限定符。 Compile() 方法的解释中描述了它们在参数列表中的位置。

要查看适用的标志,请执行以下命令:

 Do $System.OBJ.ShowFlags()

这将产生以下输出:

See $system.OBJ.ShowQualifiers() for comprehensive list of qualifiers as flags have been superseded
by qualifiers
 
    b - Include sub classes.
    c - Compile. Compile the class definition(s) after loading.
    d - Display. This flag is set by default.
    e - Delete extent.
    h - Show hidden classes.
    i - Validate XML export format against schema on Load.
    k - Keep source.  When this flag is set, source code of
        generated routines will be kept.
    p - Percent.  Include classes with names of the form %*.
    r - Recursive.  Compile all the classes that are dependency predecessors.
    s - Process system messages or application messages.
    u - Update only.  Skip compilation of classes that are already up-to-date.
    y - Include classes that are related to the current class in the way that
        they either reference to or are referenced by the current class in SQL usage.
 
These flags are deprecated a, f, g, l, n, o, q, v
Default flags for this namespace
You may change the default flags with the SetFlags(flags,system) classmethod.

要查看限定符的完整列表及其描述、类型和任何相关值,请执行以下命令:

 Do $System.OBJ.ShowQualifiers()

限定符信息以类似于以下格式之一的格式显示:

            Name: /checkschema
    Description: Validate imported XML files against the schema definition.
           Type: logical
           Flag: i
  Default Value: 1

           Name: /checksysutd
    Description: Check system classes for up-to-dateness
           Type: logical
  Default Value: 0

           Name: /checkuptodate
    Description: Skip classes or expanded classes that are up-to-date.
           Type: enum
           Flag: ll
      Enum List: none,all,expandedonly,0,1
  Default Value: expandedonly
  Present Value: all
  Negated Value: none

虽然许多选项可以通过标志或限定符指定,但InterSystems建议使用限定符,因为它们是较新的机制。有关更多信息,请参阅标志和限定符。

2.9.2.3 编译包含位图索引的类

编译包含位图索引的类时,如果没有为该类定义位图范围索引,则类编译器将生成位图范围索引。向生产系统上的类添加位图索引时需要特别小心。有关详细信息,请参阅"SQL优化指南"-“定义和构建索引”一章中的“生成位图范围索引”一节。

2.9.2.4 内存中存在类的现有实例时进行编译

如果在正在编译的类的实例打开时调用编译器,则不会出现错误。已经打开的实例继续使用其现有代码。如果编译后打开了另一个实例,它将使用新编译的代码。

2.10 将类置于部署模式

在将某些类发送给客户之前,您可能希望将它们置于部署模式;此过程隐藏源代码。

对于包含不希望客户看到的方法定义的任何类定义,请编译这些类,然后使用 $SYSTEM.OBJ.MakeClassDeployed() 。例如:

 d $system.OBJ.MakeClassDeployed("MyApp.MyClass")

有关另一种方法,请参阅将编译代码添加到客户数据库一文。

2.10.1 关于部署模式

当类处于部署模式时,其方法和触发器定义已被删除。(请注意,如果该类是数据类型类,则会保留其方法定义,因为缓存的查询可能在运行时需要它们。)

不能导出或编译处于部署模式的类,但可以编译其子类(如果它们不处于部署模式)。

无法反转或撤消类的部署。但是,如果以前将定义保存到磁盘,则可以通过使用管理门户从文件中导入定义来替换该类。(如果您不小心将一个类过早地置于部署模式,这很有用。)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值