清除过滤器
文章
姚 鑫 · 四月 9, 2021
# 第二十一章 导入和导出SQL数据
在InterSystems IRIS®Data Platform Management Portal中,有用于导入和导出数据的工具:
- 从文本文件导入数据
- 将数据导出到文本文件
这些工具使用动态SQL,这意味着查询是在运行时准备和执行的。可以导入或导出的行的最大大小为3,641,144个字符。
还可以使用%SQL.Import.Mgr类导入数据,使用%SQL.Export.Mgr类导出数据。
# 从文本文件导入数据
可以将数据从文本文件导入到合适的InterSystems IRIS类中。执行此操作时,系统将在表中为该类创建并保存新行。该类必须已经存在并且必须编译。要将数据导入到此类中,请执行以下操作:
1. 从管理门户中选择系统资源管理器,然后选择SQL。使用页面顶部的切换选项选择一个命名空间;这将显示可用命名空间的列表。
2. 在页面顶部,单击向导下拉列表,然后选择数据导入。
3. 在向导的第一页上,从指定外部文件的位置开始。对于导入文件所在的位置,请单击要使用的服务器的名称。
4. 然后输入文件的完整路径和文件名。
5. 对于选择架构名称,单击要向其中导入数据的InterSystems IRIS包。
6. 对于选择表名,单击将包含新创建的对象的类。
7. 然后单击下一步。
8. 在向导的第二页上,单击将包含导入数据的列。
9. 然后单击下一步。
10. 在向导的第三页上,描述外部文件的格式。
- 有关用什么分隔符分隔您的列?,请单击与此文件中的分隔符对应的选项。
- 单击第一行是否包含列标题?如果文件的第一行不包含数据,则选中此复选框。
- 对于字符串引号,单击指示此文件用于开始和结束字符串数据的引号分隔符字符的选项。
- 对于日期格式,请单击指示此文件中日期格式的选项。
- 对于时间格式,请单击指示此文件中的时间格式的选项。
- 对于时间戳格式,请单击指示此文件中的时间戳格式的选项。
- 单击禁用验证?如果不希望向导在导入时验证数据,请选中此复选框。
- 使用%SortBegin/%SortEnd?如果不希望向导在导入期间重新生成索引,请选中此复选框。如果选中延迟索引生成,向导将在将导入的数据插入到表中之前为该类调用%SortBegin方法。导入完成后,向导将调用%SortEnd方法。不执行任何验证(与使用%NOCHECK的INSERT相同)。这是因为当使用%SortBegin/%SortEnd时,在SQL INSERT期间不能检查索引的唯一性。如果选中延迟索引构建,则假定导入的数据有效,不会检查其有效性。
- 或者,单击“预览数据”以查看向导将如何分析此文件中的数据。
11. 单击“下一步”。
12. 检查条目,然后单击Finish。向导将显示“数据导入结果”对话框。
13. 单击关闭。或者单击给定的链接以查看后台任务页面。
在任何一种情况下,向导都会启动一个后台任务来完成工作。
# 将数据导出到文本文件
可以将给定类的数据导出到文本文件。为此:
1. 从管理门户中选择系统资源管理器,然后选择SQL。使用页面顶部的切换选项选择一个命名空间;这将显示可用命名空间的列表。
2. 在页面顶部,单击向导下拉列表,然后选择数据导出。
3. 在向导的第一页上:
- 输入要创建以保存导出数据的文件的完整路径和文件名。
- 从下拉列表中,选择要从中导出数据的命名空间、方案名和表名。
- 或者,从Charset下拉列表中选择一个字符集;默认值为Device Default。
- 然后单击下一步。
4. 在向导的第二页上,选择要导出的列。然后单击下一步。
5. 在向导的第三页上,描述外部文件的格式。
- 有关用什么分隔符分隔的列?,请单击与此文件中的分隔符对应的选项。
- 单击导出列标题?如果要将列标题导出为文件的第一行,请选中此复选框。
- 对于字符串引号,单击一个选项以指示如何开始和结束此文件中的字符串数据。
- 对于日期格式,单击一个选项以指示要在此文件中使用的日期格式。
- (可选)单击“预览数据”以查看结果的外观。然后单击下一步。
6. 检查条目,然后单击Finish。该向导将显示“数据输出结果”对话框。
7. 单击关闭。或单击给定的链接以查看后台任务页面。
在任何一种情况下,向导都启动后台任务来完成工作。
文章
Jingwei Wang · 六月 23, 2024
低代码挑战
想象一下那个场景。您正在 Widgets Direct 愉快地工作,这是互联网上首屈一指的小部件和小部件配件零售商。您的老板有一些毁灭性的消息,一些客户可能对他们的小部件不太满意,我们需要一个帮助台应用程序来跟踪这些投诉。为了让事情变得有趣,他希望代码占用非常小,并挑战您使用 InterSystems IRIS 以少于 150 行代码交付应用程序。这可能吗?
免责声明:本文记录了一个非常基本的应用程序的构建,为了简洁起见,省略了安全性和错误处理等细节。该应用程序仅供参考,不得用于任何生产应用。本文使用IRIS 2023.1作为数据平台,并非所描述的所有功能在早期版本中都可用
第 1 步 - 定义数据模型
我们首先定义一个新的干净的命名空间 - 带有代码和数据数据库。虽然所有内容都可以位于 1 个数据库中,但将它们拆分以便于数据刷新。
我们的帮助台系统需要 3 个基本类:一个 Ticket 对象,它可以包含用于记录员工顾问 UserAccount 和客户联系人 UserAccount 之间交互的操作。让我们用一些基本属性来定义它们:
19 行代码,我们就有了完整的数据模型!我们将 2 个类设置为 Persistent,以便将它们保存到数据库中,并且还继承自 %JSON.Adapter,这使我们能够非常轻松地以 JSON 格式导入和导出对象。作为测试,我们在终端中设置第一个用户,保存它,然后验证 JSONExport 是否正常工作
这一切看起来都不错。老板给我们留下了一个 csv 文件,其中包含员工和客户的列表。我们可以编写一些代码来解析它并加载它,但是有更简单的方法吗?
第 2 步 - 加载数据
InterSystems IRIS 在 SQL 中提供了一个简单易用的 LOAD DATA 语句,可以轻松地从 CSV 文件加载数据,包括解析标题和重命名字段的选项。让我们用它来加载我们的用户表:
我们可以使用标题标签来提取这些数据并将其加载到数据库中,如下所示:
所有 300 行均已使用单个命令导入。这 4 行代码使我们的运行代码编写数量达到 23 行。我们可以使用基本的 SQL select 查询脚本来快速验证这些记录是否正确
现在我们有了起始数据,让我们构建一些基本的 API 来和前端连接。我们将把 API 构建可以接受 JSON 的 REST 服务。
第 3 步 - 构建 REST API
InterSystems IRIS 通过继承 %CSP.REST 类提供 REST 支持,因此我们将创建一个继承 %CSP.REST 的REST.Dispatch 类。该类由 2 个部分组成:一个 XData UrlMap,它将 URL 和 Call 映射到Method,通过 Url 调用Method。
我们的最小可行产品需要 4 项操作:检索员工或客户的用户列表、检索最后一张票、通过 ID 号检索单个票,最后创建新票。我们定义Call,然后定义Method。
GetUserList 是一个基本的嵌入式 SQL 游标,它直接以 JSON 形式输出数据。然后,我们可以使用 JSON 功能解析它,将其推送到 JSON 数组中并将其作为响应正文。我们将 Staff 变量从 URL 直接传递到方法中使用。
TicketSummary 几乎相同,但改为访问票证表
TicketSummary 是最简单的服务。我们通过 ID 获取对象,并使用内置的 %JSONExport 输出JSON。如果对象加载失败,我们会写出一个错误数据包
最后,我们的 UploadTicket 方法是最复杂的。我们必须从请求对象中读取有效票证数据,将其解析为 JSON,然后使用 %JSONImport 将其导入到 Ticket 的新实例。我们还从当前时间设置 OpenDate 和 OpenTime,而不是将日期作为输入。成功保存后,我们会显示新票证对象的 JSON 表示形式,或者如果对象保存失败,我们会返回错误。
通过这些服务,我们在总数中又添加了 60 行代码。我们现在这个应用程序总共有 89 行代码
现在,我们需要在“安全”>“应用程序”下创建一个 Web 应用程序。这应该设置为 REST 类型的应用程序,并且 Dispatch Classname 应设置为我们刚刚创建的 REST.Dispatch 类(注意,您需要向该应用程序授予适当的安全角色,以便它可以访问代码和数据)。保存后,现在可以从您定义的 URL 调用 REST 服务
我们可以调用UserList来检查
我们现在准备创建一些数据。让我们使用 REST 客户端将有效数据发送到票证创建服务。我们提供关键字、描述、顾问和联系人,然后返回我们创建的票证的 JSON,包括 OpenDate 和 TicketId
我们现在有了最小可行产品。使用我们选择的前端表单生成器,我们现在可以通过 REST 服务发送和接收票证信息。
第 4 步 - 互操作性要求
您现在仅用 89 行书面代码就构建了一个基本的票务应用程序。你的老板一定印象深刻吧?是的,但他有一些坏消息。你错过了一个要求。 Widgets Direct 在法语地区有一份特殊合同,所有用法语书写的门票必须交由 Bettie Francis 女士进行初步审核。幸运的是,您有一位同事关注了 Robert Luman 关于Python Natural Language Support 的优秀文章,并创建了一个可以接受文本示例并识别语言的 REST 服务。当文本为法语时,我们可以使用 InterSystems IRIS Interoperability 来调用此服务并自动将顾问更新为 Mme Francis 吗?
我们需要首先创建一些 Message 类,以便我们有一种方法来发送和接收我们的请求。我们需要一个包含票证 ID 和示例文本的请求,以及一个返回语言代码和描述的响应。这些将继承Ens.Request 和 Ens.Response
再写 6 行代码,我们就可以得到 95 个 LOC。我们现在需要创建我们的业务操作,它将请求发送到您同事的服务并检索答案。我们定义一个出站业务操作,其中包含服务器和 URL 的属性,并通过将它们包含在 SETTINGS 参数中来将它们公开给用户配置。如果服务器路径发生变化,这将使我们能够轻松更新请求。我们创建一个辅助方法来设置 HTTPRequest,然后使用它来调用服务并填充我们的响应
又增加了 27 行代码,代码数量就超过了 100 行,现在我们已经编写了 122 行代码。我们现在需要在 Ensemble 中设置此类。转到互操作性下的Production配置,然后按操作标题下的添加。使用类名称和显示名称设置您的业务操作
然后我们可以单击它进入“设置”,输入服务器名称和 URL 并启用该业务操作。
我们现在需要第二个业务操作,该业务操作获取票证 ID 并将顾问设置为提供的用户帐户 ID。我们需要消息和业务操作类,但在这种情况下,我们不会返回响应,业务操作将在没有反馈的情况下执行任务
另外 12 行代码使我们编写了 134 行代码。我们可以按照添加服务的相同方式将此业务操作添加到Production中,但在这种情况下,我们无需设置任何配置。
接下来,我们需要一个可以调用服务、评估响应并可以选择调用 French Advisor Operations 的路由器。我们转到互操作性>构建>业务流程并访问可视化规则生成器。我们首先设置请求和响应的上下文并添加一个调用项。我们将输入和输出设置为我们创建的消息类,然后使用请求生成器映射输入。确保未选中“异步”标志,我们希望在继续之前等待响应。
然后,我们添加一个“If”项来评估返回的语言代码。如果是“fr”,那么我们要调用 FrenchAdvisor 操作
Mme Francis 的用户 ID 为 11,因此我们设置 Call 对象以向 FrenchAdvisor 服务提供 AdvisorUpdate 消息,并使用请求构建器传递 TicketID 和 Advisor 参数的固定值 11
现在,我们可以通过单击“进程”标题下的“添加”,选择该类并为其指定一个 DisplayName“FrenchRouter”,将其添加到 Production 中。
现在我们的路由就位了。我们只需要一个服务来扫描新票并将其发送到路由器进行处理。我们基于 SQL 适配器定义一个 Service 类,如下所示(在我们的计数中添加另外 8 行代码):
然后,我们将其添加到Production中,就像我们对业务操作和业务流程对象所做的那样。我们需要对 SQL 适配器进行一些设置。我们通过 ODBC DSN 向本地数据库提供连接详细信息,以及基本 SQL 查询,服务将使用该查询来查询 CallInterval 设置中设置的计时器上的票证。此查询与键字段名称设置配对,该设置定义查询的唯一键,并防止重新发送已发送的记录
完成此业务操作后,我们现在有了完整的Production,它将扫描新票证,将文本传递到外部服务以解析语言,并可选择根据响应重置顾问程序。让我们试试这个吧!我们首先发送一个英语请求,该请求返回为 TicketId 70。我们稍等一下,然后通过 GetTicket REST 服务访问此记录,并且顾问与原始请求相比没有变化
让我们用法语文本重复一遍
当我们请求 71 票证时,我们的顾问已更改为弗朗西斯女士,正如我们所料!我们可以通过在 Visual Trace 中查找消息并验证操作是否按预期调用来在互操作性中检查这一点。
我们现在编写了 142 行代码,并且拥有一个 InterSystems IRIS 应用程序,该应用程序可以保存数据,使用 LOAD DATA 加载数据,提供用于查看和编辑数据的基本 REST API,以及基于调用提供决策支持的高级集成引擎到外部 REST 服务。当然,没有人能要求更多吗?
第 5 步 - 要求更多:分析
您的应用程序取得了巨大成功,数据源源不断地涌入。这些宝贵的数据需要专业知识才能访问,而 Widgets Direct 的管理人员希望获得一些见解。是否可以提供对数据的交互式访问?
使用 InterSystems IRIS Analytics,我们可以轻松快速地访问高级数据操作工具。我们首先需要在我们的内部 Web 应用程序上启用分析支持:
这使我们能够针对我们的命名空间使用分析部分。首先打开 Analytics>Architect。选择新建,然后填写表单以为工单类创建分析多维数据集。
接下来,我们可以使用 Visual Builder 设置维度和基本的向下钻取列表。该视图是拖放式的。还可以使用简单的可视化构建器创建列表,以自定义用户在询问数据点时看到的内容
一旦我们有了一些基本设置,我们就可以保存、编译和构建Cube。这将设置所有索引并启用多维数据集以在分析器中进行分析。打开分析器开始处理数据。在示例中,我们可以轻松地将顾问与按所服务的联系人过滤的年度和季度层次结构进行比较。单击单元格后,可以按下双筒望远镜图标来调用您创建的深入分析列表,以进行进一步分析和导出
结论
只需 142 行代码,我们就拥有了一个基本但功能齐全的现代后端应用程序,并提供支持工具以允许应用程序间通信和高级分析。这是一个过于简化的实现,只能用作在 IRIS 中构建数据库应用程序所需的基本框架的示例。正如本文开头提到的,此代码尚未准备好投入生产,在实际使用中,开发人员应参考 InterSystems IRIS 文档和最佳实践,以确保其代码稳健、安全和可扩展(这些都不适用于此代码库) )。快乐编码!该文章 作者 @Chris Stewart 来源于 https://community.intersystems.com/node/553856
文章
姚 鑫 · 六月 30, 2021
# 第二十三章 执行XSLT转换概述
XSLT(Extensible StyleSheet Language Transformations,可扩展样式表语言转换)是一种基于XML的语言,用于描述如何将给定的XML文档转换为另一个XML或其他“人类可读”的文档。可以使用`%XML.XSLT`和`%XML.XSLT2`包中的类来执行`XSLT 1.0`和`2.0`转换。
注意:使用的任何XML文档的XML声明都应该指明该文档的字符编码,并且文档应该按照声明的方式进行编码。如果未声明字符编码, IRIS将使用本书前面的“输入和输出的字符编码”中描述的默认值。如果这些默认值不正确,请修改XML声明,使其指定实际使用的字符集。
# 在IRIS中执行XSLT转换概述
IRIS提供两个XSLT处理器,每个处理器都有自己的API:
- `Xalan`处理器支持`XSLT 1.0`。`XML.XSLT`包为该处理器提供API。
- `Saxon`处理器支持`XSLT 2.0`。`%XML.XSLT2`程序包为该处理器提供API。
`XML.XSLT2` API通过到`XSLT 2.0`网关的连接向`Saxon`发送请求。网关允许多个连接。这意味着,例如,可以将两个独立的 IRIS进程连接到网关,每个进程都有自己的一组编译样式表,同时发送转换请求。
使用Saxon处理器,编译的样式表和`isc:Evaluate`缓存是特定于连接的;必须管理自己的连接才能利用这两个特性。如果打开连接并创建编译样式表或计算填充`isc:Evaluate`缓存的转换,则在该连接上计算的所有其他转换都将访问编译样式表和`isc:Evaluate`缓存条目。如果打开新连接,其他连接(及其编译的样式表和缓存)将被忽略。
这两个处理器的API相似,不同之处在于`%XML.XSLT2`中的方法使用另一个参数来指定要使用的网关连接。
要执行`XSLT`转换,请执行以下操作:
1. 如果使用的是`Saxon`处理器,请按照下一节所述配置`XSLT`网关服务器。或使用默认配置。
如果使用的是`Xalan`处理器,则不需要网关。
系统会在需要时自动启动网关。或者也可以手动启动它。
2. 如果使用的是`Saxon`处理器,则可以选择创建`%Net.Remote.Gateway`的实例,表示到`XSLT`网关的单个连接。
请注意,当使用`Saxon`处理器时,要利用已编译的样式表和`isc:Evaluate`缓存,这一步是必需的。
3. 可以选择创建已编译的样式表并将其加载到内存中。请参阅本章后面的“创建编译样式表”。如果使用的是`Saxon`处理器,请确保在创建编译后的样式表时指定网关参数。
如果打算重复使用同一样式表,则此步骤非常有用。然而,此步骤也会消耗内存。当不再需要编译的样式表时,请务必将其删除。
4. 调用适用API的转换方法之一。如果使用的是`Saxon`处理器,则在调用`Transform`方法时可以选择指定网关参数。
5. 可以选择调用其他转换方法。如果使用的是`Saxon`处理器,则在调用`Transform`方法时可以选择指定网关参数;这使能够使用相同的连接计算另一个转换。此转换将访问与此连接相关联的所有编译样式表和`isc:Evaluate`缓存条目。如果打开新连接,其他连接(及其编译的样式表和缓存)将被忽略。
Studio还提供了一个向导,可以使用该向导测试XSLT转换;本章稍后将对此进行介绍。
# 配置、启动和停止XSLT 2.0网关
当使用`Saxon`处理器(执行`XSLT 2.0`转换)时, IRIS使用`XSLT 2.0`网关(后者使用Java)。要配置此网关,请执行以下操作:
1. 在管理门户中,选择 System Administration > Configuration > Connectivity > XSLT 2.0 Gateway Server.
2. 选择Go。

系统将显示XSLT网关服务器页面。
左侧区域显示配置详细信息,右侧区域显示最近的活动。

3. 在左侧区域中,可以选择指定以下设置:
- Port Number -`XSLT 2.0`网关独占使用的TCP端口号。此端口号不得与服务器上的任何其他本地TCP端口冲突。
默认值为 IRIS SuperServer端口号加`3000`。如果此数字大于`65535`,则系统使用`54773`。
- Java Version - 使用的Java版本。
- Log File - 日志文件的路径名。如果忽略此设置,则不执行日志记录。如果指定了文件名但忽略了目录,则将日志文件写入系统管理器的目录。
- Java Home Directory -包含Java bin目录的目录路径。如果服务器上没有默认Java,或者如果想使用不同的Java,请指定此选项。
要查看默认Java,请在服务器上的Shell中执行以下命令:
```
java -version
```
- JVM Arguments - Java虚拟机要使用的任何其他参数。
此区域还显示`JAVA_HOME`环境变量的当前值。
请注意,在网关运行时,不能编辑这些值中的任何一个。
4. 如果已进行更改,请选择保存以保存更改。或选择重置以。
5. (可选)选择测试以测试更改。
在此页面上,还可以执行以下操作:
- 启动网关。要执行此操作,请选择右侧区域中的Start。
请注意, IRIS会在需要时自动启动网关。不需要手动启动网关。
- 关闭网关。要执行此操作,请选择右侧区域中的Stop(停止)。
# 重用XSLT网关服务器连接(XSLT 2.0)
如果使用的是`Saxon`处理器,InterSystems IRIS将使用之前配置的`XSLT 2.0`网关。为了与此网关通信,InterSystems IRIS在内部创建一个`XSLT`网关连接(`%Net.Remote.Gateway`的实例)。默认情况下,系统创建一个连接,将其用于转换,然后丢弃该连接。打开新连接会产生开销,因此为多个转换维护一个连接可提供最佳性能。此外,必须维护自己的连接,以便利用已编译的样式表和`isc:Evaluate`缓存。
要重用XSLT网关连接,请执行以下操作:
1. 调用`%XML.XSLT2.Transformer`的`StartGateway()`方法:
```
set status=##class(%XML.XSLT2.Transformer).StartGateway(.gateway)
```
此方法启动XSLT 2.0网关(如果它尚未运行),并返回`%Net.Remote.Gateway`的实例作为输出。请注意,该方法还返回状态。
在`%Net.Remote.Gateway`实例表示与网关的连接。
`StartGateway()`有一个可选的第二个参数`useSharedMemory`。如果此参数为真(缺省值),则与`localhost`或`127.0.0.1`的连接将使用共享内存(如果可能)。要强制连接仅使用`TCP/IP`,请将此参数设置为False。
2. 检查上一步返回的状态:
```java
if $$$ISERR(status) {
quit
}
```
3. 创建任何已编译的样式表。执行此操作时,请将网关参数指定为`%Net.Remote.GatewayInstance`的实例在步骤1中创建。
4. 根据需要调用`%XML.XSLT2.Transformer`的`Transform`方法(`TransformFile()`、`TransformFileWithCompiledXSL()`、`TransformStream()`和`TransformStreamWithCompiledXSL()`)。执行此操作时,请将网关参数指定为在步骤1中创建的`%Net.Remote.Gateway`的实例。
5. 如果不再需要给定的编译样式表,请在调用`%XML.XSLT2.CompiledStyleSheet`的`ReleaseFromServer()`方法:
```java
Set status=##class(%XML.XSLT2.CompiledStyleSheet).ReleaseFromServer(compiledStyleSheet,,gateway)
```
重要提示:当不再需要已编译的样式表时,请务必使用此方法。
6. 当不再需要XSLT网关连接时,调用`%XML.XSLT2.Transformer`的`StopGateway()`方法,并将网关连接作为参数传递:
```java
set status=##class(%XML.XSLT2.Transformer).StopGateway(gateway)
```
此方法丢弃连接并重置当前设备。它不会停止`XSLT 2.0`网关。
重要提示:当不再需要连接时,请务必使用此方法。
有关示例,请参见XSLT2中的`Example10()`方法。`Samples`命名空间中的`Examples`。
# 排除XSLT 2.0网关服务器连接故障
当XSLT 2.0网关打开时,InterSystems IRIS和网关服务器之间的连接可能会变得无效。例如,如果出现网络错误或在InterSystems IRIS连接到网关服务器后重新启动网关服务器,则连接可能无法正常关闭。因此,可能会遇到错误。
可以通过连续调用XSLT网关连接对象的`%LostConnectionCleanup()`方法和`%reconnect`方法,尝试将InterSystems IRIS重新连接到网关服务器。
如果希望在断开连接时自动重新连接到网关服务器,请将网关连接对象的`AttemptReconnect`属性设置为true。
# 创建编译的样式表
如果打算重复使用同一样式表,则可能需要编译该样式表以提高速度。请注意,此步骤会消耗内存。当不再需要编译的样式表时,请务必将其删除。
要创建编译的样式表,请执行以下操作:
- 如果使用的是`Xalan`处理器(对于`XSLT 1.0`),请使用`%XML.XSLT.CompiledStyleSheet`的以下类方法之一:
- `CreateFromFile()`
- `CreateFromStream()`
- 如果使用的是`Saxon`处理器(用于`XSLT 2.0`),请在使用`%XML.XSLT2.CompiledStyleSheet`的以下类方法之一:
- `CreateFromFile()`
- `CreateFromStream()`
另请注意,将需要创建一个XSLT网关连接;请参阅“重用XSLT网关服务器连接(`XSLT 2.0`)”。
对于所有这些方法,完整的参数列表按顺序如下:
1. source - 样式表。
对于`CreateFromFile()`,此参数是文件名。对于`CreateFromStream()`,此参数是一个流。
2. compiledStyleSheet - 编译后的样式表,作为输出参数返回。
这是样式表类(`%XML.XSLT.CompiledStyleSheet`或`%XL.XSLT2.CompiledStyleSheet`,视情况而定)的实例。
3. errorHandler - 编译样式表时使用的可选自定义错误处理程序。
对于这两个类中的方法,这是`%XML.XSLT.ErrorHandler`实例。
4. (仅适用于`%XML.XSLT2.CompiledStyleSheet`)网关-`%Net.Remote.Gateway`的实例
```
//将tXSL设置为等于适当流的OREF
Set tSC=##class(%XML.XSLT.CompiledStyleSheet).CreateFromStream(tXSL,.tCompiledStyleSheet)
If $$$ISERR(tSC) Quit
```
文章
Michael Lei · 八月 26, 2021
# SAM - 设置和添加非 IRIS 目标指标的技巧和提示
SAM(系统警报和监视)以“功能齐全”的 docker-compose 容器集的形式提供,只要启动就可以开始以默认的仪表板监视 IRIS 实例。 使用初始配置就可以很好地了解 SAM 功能并开始对 IRIS 系统进行基本监视。 但是,当开始监视多个系统并收集大量指标数据时,需要更改一些默认设置。 为了从 SAM 获取更多价值,您还会想要添加来自其他数据源(目标)的指标。 以下技巧将帮助您在生产环境中部署 SAM,从多个目标收集指标并将这些指标组合到您自己的仪表板和图表中。 此外,您还将看到一些可能有助于探索 SAM 容器和应用程序的命令。
> *注意:*我应该指出,其中一些技巧和提示可能不是最佳做法;这更像是一个日志,记录了我第一次如何配置 SAM 来监视相同系统上的多个服务器和非 IRIS 目标的基准。 如果您有建议,请在评论中指教 ;) 所以,记住本帖可能会随着时间的推移而有所变化,让我们开始吧;
---
在下面的技巧中,有重启 docker 以及启动和停止 SAM 的操作。 请通读这些技巧,确定哪些适合您,然后按照下面的相同顺序执行。
## 1. 确保有足够的空间用于 SAM 数据库
默认情况下,docker 容器将文件存储在根 (/) 文件系统。 SAM 不需要很多 CPU 或内存资源;但是,指标收集将占用空间。
> 指标需要的存储容量“视情况而定”。 虽然在开始监视之前可能无法明确数据库大小,但大致上,在抓取周期为 15 秒的情况下,监视 10 个 IRIS 虚拟机以及操作系统指标大约消耗 50GB 存储。
策略包括:增加监视实例的根存储,或更改数据库的卷位置。 我使用了以下命令来更改运行 docker 的虚拟机上的 docker 目录。 也许是杀鸡用了牛刀,但很管用。
- 停止 docker 并将 docker 文件复制到空间充足的文件系统(本例中为 /data/docker/data)。 见下面的示例:
```other
[root@mysamserver lib]# sudo systemctl stop docker
[root@mysamserver lib]# pwd
/var/lib
[root@mysamserver lib]# cp -rp docker /data/docker/data
[root@mysamserver lib]#
[root@mysamserver lib]# rm -rf docker
```
- 在 docker 配置文件中更新卷路径。 注意此文件还有一个网络设置“bip”(请参见注释:...)
```swift
cat /etc/docker/daemon.json
{
"data-root": "/data/docker/data",
"bip": "192.168.0.1/24"
}
```
- 重启 docker
```swift
sudo systemctl daemon-reload
sudo systemctl restart docker
systemctl status docker.service
```
## 2. 设置 SAM
我假定您已在测试系统上设置 SAM,并熟悉它的基本操作:添加集群和实例,以及查看系统指标。 建议您花 20 分钟时间查看我在虚拟全球峰会 2020 上的展示,以了解安装步骤的概述,以及添加多个目标的运行指标时 SAM 的外观。 要观看此会议,请使用以下链接(您需要使用您的电子邮件注册):
[DEV007 系统警报和监视](https://intersystems.6connex.com/event/virtual-summit/en-us/contents/434680/share?rid=Lobby&nid=804450)
登录到 SAM 门户并配置一些 IRIS 实例。 这会填充配置文件并提供向导。
`http://mysamserver:8080/api/sam/app/index.csp#/`
> 注意:如果要添加多个实例,或者希望用脚本执行此步骤,可以通过 API 添加实例。 请参见文档。
## 3. 升级到生产许可证
SAM 随附了一个 IRIS 社区版许可证。 有几个限制,包括 IRIS.DAT 限制为 10GB。 10GB 不足以长时间从多个目标收集数据。 请联系您的 InterSystems 联系人以获取生产许可证。 在没有编辑器的情况下,在精简的容器中更新许可证可能很棘手,我只是在 IRIS 容器上登录一个交互式会话,然后使用以下命令更新许可证密钥:
- 打开 shell,切换目录至 mgr 文件夹(iris.key 文件的默认位置)
```swift
docker exec -it sam_iris_1 bash
cd /dur/iconfig/mgr
```
- 使用 unix“here 文档”更新密钥。 在“>”后面粘贴密钥文本。 在密钥文本后面,输入“>EOF”以提交命令。 然后输入“exit”退出 shell。
```other
cat
[ConfigFile]
FileType=InterSystems License Rev-A.1
LicenseID=999999
[License]
LicenseCapacity=InterSystems IRIS 2020.2 Server for SAM:etc etc, the key you were sent by your InterSystems contact.
>EOF
exit
```
- 然后使用提供的 docker-compose shell 脚本停止再启动 SAM:
```swift
./stop.sh
./start.sh
```
- 可以通过访问系统管理门户或登录到 iris 实例并检查 messages.log 来检查许可证是否一切正常。
```shell
docker exec -it sam_iris_1 bash
cd /dur/iconfig/mgr
cat messages.log
```
## 4. 在目标上安装其他 prometheus 导出程序
例如,prometheus 节点导出程序可显示各种硬件和内核相关的指标。
[节点导出程序文档](https://prometheus.io/docs/guides/node-exporter/)
通过请求(抓取)实例端点的指标,测试节点导出程序是否正常工作:
```swift
curl my_target_server_name:9100/metrics
```
您应该看到类似下面的信息:
```swift
mylaptop:~ mo$ my_target_server_name:9100/metrics | more
HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 4.8862e-05
go_gc_duration_seconds{quantile="0.25"} 7.5898e-05
go_gc_duration_seconds{quantile="0.5"} 9.2974e-05
go_gc_duration_seconds{quantile="0.75"} 0.000130664
go_gc_duration_seconds{quantile="1"} 0.000358762
go_gc_duration_seconds_sum 303.291715258
go_gc_duration_seconds_count 2.572586e+06
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 9
:
: many many metrics will be displayed
```
注意您可以对您的 IRIS 实例执行同样操作:
```swift
mylaptop:~ mo$ curl my_target_server_name:52776/api/monitor/metrics | more
iris_cpu_pct{id="AUXWD"} 0
iris_cpu_pct{id="CSPDMN"} 0
iris_cpu_pct{id="CSPSRV"} 0
iris_cpu_pct{id="ECPCliR"} 0
iris_cpu_pct{id="ECPCliW"} 0
iris_cpu_pct{id="ECPSrvR"} 0
iris_cpu_pct{id="ECPSrvW"} 0
:
: many many metrics will be displayed
```
## 5. 编辑配置文件以添加对新目标的抓取
例如,前一个技巧中的 node-exporter 实例。 配置文件将位于 SAM 的安装位置。 如下所示,可以看到 grafana 和 prometheus `yml` 配置文件。
```plaintext
[root@mysamserver sam-1.0.0.115-unix]# ls
config docker-compose.yml readme.txt start.sh stop.sh
[root@mysamserver sam-1.0.0.115-unix]# tree -x config
config
├── alertmanager
│ └── isc_alertmanager.yml
├── grafana
│ ├── dashboard.json
│ ├── dashboard-provider.yml
│ ├── datasource.yml
│ └── grafana.ini
├── nginx
│ └── nginx.conf
└── prometheus
├── isc_alert_rules.yml
└── isc_prometheus.yml
4 directories, 8 files
```
## 5.1 添加目标到 prometheus
以下示例是使用 SAM 中的配置 GUI 屏幕创建的 `isc_prometheus.yml` 文件。 该文件包含两个集群。 一个集群监视 sam 实例本身,另一个集群监视五个 IRIS 实例。
```yaml
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
global:
evaluation_interval: 15s
scrape_interval: 15s
remote_read:
- url: http://iris:52773/api/sam/private/db/read
remote_write:
- url: http://iris:52773/api/sam/private/db/write
rule_files:
- ./isc_alert_rules.yml
scrape_configs:
- job_name: SAM
metrics_path: /api/monitor/metrics
scheme: http
static_configs:
- labels:
cluster: "1"
targets:
- mysaminstance.mycompany.com:8080
- labels:
cluster: "2"
targets:
- myiristarget1:52776
- myiristarget2:52776
- myiristarget3:52776
- myiristarget4:52776
- myiristarget5:52776
```
- 要添加对其他运行 node-exporter 的目标的抓取,请将以下内容添加到 `isc_prometheus.yml` 文件的底部。 注意 API `metrics_path` 与 IRIS 不同。
```yaml
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
global:
evaluation_interval: 15s
scrape_interval: 15s
remote_read:
- url: http://iris:52773/api/sam/private/db/read
remote_write:
- url: http://iris:52773/api/sam/private/db/write
rule_files:
- ./isc_alert_rules.yml
scrape_configs:
- job_name: SAM
metrics_path: /api/monitor/metrics
scheme: http
static_configs:
- labels:
cluster: "1"
targets:
- iscsydsam.iscinternal.com:8080
- labels:
cluster: "2"
targets:
- myiristarget1:52776
- myiristarget2:52776
- myiristarget3:52776
- myiristarget4:52776
- myiristarget5:52776
- job_name: node_shard1
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget1:9100
- job_name: node_shard2
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget2:9100
- job_name: node_shard3
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget3:9100
- job_name: node_shard4
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget4:9100
- job_name: node_shard5
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget5:9100
```
- 然后使用提供的 docker-compose shell 脚本停止再启动 SAM:
```swift
./stop.sh
./start.sh
```
SAM 现在从您通过 GUI 添加的 IRIS 实例以及相同实例上的 node-exporter 中收集指标。
# 6. 增加 Prometheus 收集指标的天数
在 SAM 的第一版中,您可以在 GUI 中更改收集指标的天数。 但是,我在显示所有指标时遇到一个问题。 在我弄清楚发生了什么之前,我更改了 Prometheus 中的保留天数,否则 SAM 将收集数据,但是您在 Grafana 的 Prometheus 查询中看不到指标。
在文件 `docker-compose.yml` 中用来安装 SAM 的层,更改 Prometheus 启动时设置的保留天数,例如在 `prometheus` 部分中,更新 `storage.tsdb.retention.time` 参数以匹配所需的保留天数:
```swift
prometheus:
command:
- --web.enable-lifecycle
- --config.file=/config/isc_prometheus.yml
- --storage.tsdb.retention.time=30d
```
> 注意:在 SAM 的第一版中,最长保留天数为 30 天。 然后使用提供的 docker-compose shell 脚本停止再启动 SAM:
```swift
./stop.sh
./start.sh
```
## 7. 创建您自己的仪表板
您可以向现有仪表板添加面板,也可以创建新的仪表板以满足您的监视需求。 这是一个很大的主题,所以留到下一个帖子再说。 不过,这里先帮助您上手。
在 SAM 屏幕上使用 `View in Grafana`(在 Grafana 中查看)按钮切换到 Grafana。

打开 Grafana 后,可以创建或编辑仪表板;

网上有许多查询导出程序(如 node-exporter)的示例。
> 当可以显示 IRIS 系统指标(SAM 中的默认设置)、IRIS 应用程序指标(您需要将这些指标构建到应用程序中)以及其他指标(如 node-exporter 或由供应商创建的任何数量的指标)时,真正强大的功能才体现出来。 例如,[使用 SAM 和 cAdvisor 监视 Docker 容器](https://community.intersystems.com/post/monitor-docker-containers-using-sam-and-cadvisor)
文章
Michael Lei · 七月 4, 2021
大家好, 在本文中,我比较了 Gartner 最新DBMS 魔力象限中的主要领先数据库产品的功能。 请见按现有功能数量排序的列表。 1. InterSystems IRIS 2020.3 - 60 个功能 (https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls) 2. Oracle Database 21c - 54 个功能 (https://docs.oracle.com/en/database/oracle/oracle-database/index.html) 3. Microsoft SQL Server - 45 个功能 (https://docs.microsoft.com/en-us/sql/sql-server/?view=sql-server-ver15) 4. AWS Aurora - PostgreSQL - 34 个功能 (https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html) 我只比较了功能,未进行任何性能比较(关于此内容,请参见性能测试:https://cn.community.intersystems.com/post/intersystems-iris%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%EF%BC%9A%E6%95%B0%E6%8D%AE%E6%8E%A5%E6%94%B6%E9%80%9F%E5%BA%A6%E6%B5%8B%E8%AF%95)。 我使用了上面的产品官方文档链接。 请见比较表格: <colgroup><col style="width:245pt" width="327"><col style="width:88pt" width="118"><col style="width:122pt" width="162"><col style="width:150pt" width="200"><col style="width:146pt" width="195"></colgroup>
功能
InterSystemsIRIS 2020.3
OracleDatabase 21c
MicrosoftSQL Server 2020
AWS Aurora -PostgreSQL
故障转移集群
有
有
有
有
镜像/数据复制
有
有
有
有
分布式缓存/内存中支持
有
有
有
有
备份/恢复 - 增量和完整
有
有
有
有
纵向缩放
有
有
有
有
针对 Insert、Update 和 Delete 进行横向缩放
有
有
无
无
针对 Select 进行横向缩放
有
有
有
有
分片集群
有
有
无
有
云支持和云管理器
有
有
有
有
Kubernetes 支持和 Kubernetes 管理器
有
有
有
有
Docker 支持
有
有
有
无
AWS 托管
有
有
有
有
Azure 托管
有
有
有
无
Google Cloud 托管
有
有
有
无
托管云
有
有
有
有
内部部署支持
有
有
有
无
多模型 - OO
有
无
无
无
多模型 - 文档 - JSON
有
有
有
有
多模型 - XML
有
有
有
有
多模型 - 键/值
有
无
无
无
多模型 - SQL
有
有
有
有
多模型 - 空间
无
有
有
有
多模型 - 图表
无
有
有
无
多模型 - OLAP 多维数据集
有
有
有
无
GIS 平台
无
有
无
无
本机 OO 编程语言
有
有
无
无
Java、.Net、Python、C/C++ 和 PHP 支持
有
有
有
有
Node.js 支持
有
有
有
有
ODBC/JDBC 支持
有
有
有
有
后端应用程序开发
有
有
无
无
前端应用程序开发
有
有
无
无
低代码 Web 应用程序开发
无
有
有
无
数据库应用程序开发
有
有
有
有
OData 支持
无
有
有
无
REST 服务
有
有
有
有
SOAP 服务
有
无
无
无
终端工具
有
有
有
有
IDE 支持
有
有
有
有
Web 管理/IDE 支持
有
有
有
有
嵌入 NLP
有
无
无
无
嵌入 AutoML
有
无
无
无
R/机器学习支持
有
有
有
有
PMML
有
无
无
无
业务报表服务器/开发
有
有
有
无
自主 AI 操作
无
有
无
无
非结构化文本注释/类似 Apache UIMA
有
有
无
无
Spark 支持
有
有
有
有
BI 工具
有
无
有
无
MDX 支持
有
有
有
无
互操作性连接器
有
无
无
无
BPEL/集成编排/工作流
有
无
无
无
ETL - 提取、转换和加载数据
有
无
无
无
IoT/MQTT 支持
有
无
无
无
EDI 支持
有
无
无
无
ESB
有
无
无
无
CDC - 变更数据捕获
有
有
有
有
RBAC 模型
有
有
有
有
LDAP 支持
有
有
有
有
双因素授权/身份验证支持
有
有
有
有
加密
有
有
有
有
标记
有
有
有
无
审计和跟踪
有
有
有
有
SAM
有
有
有
有
多操作系统支持
有
有
有
有
SAML/Oauth/OpenID 支持
有
有
有
有
性能调整 IDE/包
无
有
无
无
特权用户访问管理
无
有
无
无
API 管理
有
无
无
无
功能总数
61
54
45
34
文章
Michael Lei · 九月 15, 2022
Spring Boot 是最常用来创建 REST API 和微服务的 Java 框架。 它可用于部署 Web 应用程序、可执行 Web 应用程序或桌面自包含应用程序,其中应用程序和其他依赖项打包在一起。 Spring Boot 允许执行许多功能,请参见:
注:要了解有关 SpringBoot 的信息,请参见官方网站 - https://spring.io/quickstart
要创建具有一个或多个微服务的 Web api 应用程序,可以使用 Spring IDE for Eclipse/VSCode,并使用向导配置上述将在应用程序中使用的技术,请参见:
.png)
您可以选择技术并创建项目。 所有技术都将通过 maven 导入。 它就像一个可视化的 zpm。
所创建的项目有一个类用于为应用程序提供支持,其中包含所有所需内容(Web 和应用程序服务器,以及所有依赖项、微服务概念)。
此项目的完整源代码在以下 open exchange 项目中: https://openexchange.intersystems.com/package/springboot-iris-crud。
首先要配置 IRIS JDBC 驱动程序和 IRIS Hibernate 支持,为此,请将 jar 文件复制到 resources 文件夹,请参见:
.png)
打开 pom.xml 以配置这些 jar 文件的依赖项,请参见:
<dependency>
<groupId>com.intersystems</groupId>
<artifactId>intersystems-jdbc</artifactId>
<version>3.2.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/intersystems-jdbc-3.2.0.jar</systemPath>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-iris</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/hibernate-iris-1.0.0.jar</systemPath>
</dependency>
现在可以在 application.properties 中配置与 IRIS 数据库的连接,请参见:
spring.datasource.username=_SYSTEM
spring.datasource.url=jdbc:IRIS://iris:1972/USER
spring.datasource.password=SYS
spring.jpa.properties.hibernate.default_schema=dc_Sample
#spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.intersystems.jdbc.IRISDriver
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.database-platform=org.hibernate.dialect.InterSystemsIRISDialect
spring.datasource.sql-script-encoding=utf-8
server.tomcat.relaxed-query-chars=|,{,},[,]
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=true
下一步是创建一个映射到 IRIS 表的持久化 Java 类,请参见:
package community.intersystems.springboot.app.model;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.fasterxml.jackson.annotation.JsonFormat;
@Entity
@Table(name = "Product")
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
private Double height;
private Double width;
private Double weight;
@Column(name="releasedate")
@Temporal(TemporalType.DATE)
@JsonFormat(pattern = "dd/MM/yyyy")
private Date releaseDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
public Double getWidth() {
return width;
}
public void setWidth(Double width) {
this.width = width;
}
public Double getWeight() {
return weight;
}
public void setWeight(Double weight) {
this.weight = weight;
}
public Date getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}
}
最后一步是创建一个仓库接口,以将您的持久化类作为 REST 服务公开(以 HATEOAS 模式),您无需执行 crud 操作,只需编写以下代码:
package community.intersystems.springboot.app.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import community.intersystems.springboot.app.model.Product;
public interface ProductRepository extends JpaRepository<Product, Long> {
}
现在,将您的应用程序作为 Spring Boot 应用程序运行:
.png)
等待内部服务器启动,然后打开 localhost:8080。 Spring boot 将打开一个 API REST HAL 浏览器。 请参见以下图像记录:

更多详细信息,请参见我的应用程序示例。 我将所有内容一起打包成一个 Docker 项目,其中包含 2 个服务:IRIS 和 SpringBoot。
HATEOAS 模式非常适合 api url、路径和导航,更多详细信息,请自行百度。
祝使用愉快!
文章
Hao Ma · 十一月 22, 2022
命名规范,英文叫"name convention", 是对写代码取名字的一些”共识“。也就是说, 你可以不遵守,但大家都选择了遵守,照者一个规范来。为什么呢?因为有社区,大家要共享代码, 你不照着规矩来, 别人会鄙视你, 懒的用你的代码。
ObjectScript以前没什么社区,大家各写各的, 使用ObjectScript的大公司也没谁把自己的代码拿出来共享。因此,个人开发者基本就是参考官方InterSystems的命名规范。举个例子, 比如以下的代码:
```java
Class Ens.Util.ResponseBodyMethods
{
property NoFailWhileDisconnected as %Boolean;
property FirstName as %String;
parameter SETTINGS = "ReplyCodeActions";
method OnKeepalive(pAdapterStatus As %Status) as %String
{
return "okay"
}
}
```
我来简单总结一下:
- **包名和类名**:Pascal格式,也就是首字母大写。其中%开头的是官方独占,
- **Property名字**:首字母大写
- **method Name**:同上。但出入参用的是驼峰格式,也就是第一个单词小写,后面单词大写开头。
- **Parameter Name**:常量。
官方的代码都是这个规范吗? 大体上是,但也有例外, 比如%xsd包,包名类名全小写, 像这样: %xsd.string。这个从Caché年代就这样,我是不明白为什么这个包这么特殊。
到了IRIS上,更多瞎写了, 比如这个: [%SYSTEM.external.SQL](https://docs.intersystems.com/iris20222/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=%25SYSTEM.external.SQL)。不光是它,我发现很多和“external“相关的包名,都开始用小写了,写在代码里是这样的: %system.external.help(), %system.dotnet.SQL.addPath()。后面一个为什么SQL大小,dotnet小写,我也是没想明白。
然后,重要的来了。
InterSystems Developer Community贴出了这样的[community代码命名规范](https://community.intersystems.com/post/objectscript-package-manager-naming-convention)。它是怎么被推广的呢? 通过zpm,也就是社区里的代码ObjectScript的包管理工具。曾经一度你要参加社区的代码比赛,就必须使用zpm打包,而zpm对使用这个代码规范有硬要求,所以这个convention得到了一定程度的接受,能看到越来越多的开发者这么写代码了。
原文上面有链接,这里说最重要的:
**package名字全小写,class名字用首字母大写**。比如class会定义成:
```java
class company.project.subpackage.TheClass{
...
}
```
这基本上是借鉴Java。作者也说了:*The approach borrowed from the naming convention for java classes.* 作者还做了个解释:全小写的Package名字避免了和class或者interface的名字冲突。这句话我不是很明白。
我觉得网友只所以接受它,纯粹就是java和python用惯了,烦大写的类名。 如果都是c++, c#的程序员,估计这个命名规范还得有得吵。
我这里只说了包名类名, 其他的method, property, 变量的命名什么的,还包括github上repo起名字的规范, 有兴趣去原文看看吧。
我是挺喜欢这个规范的。
唯一有点不满意的是:Java中定义Package name 和class name不是连着写在一起的,比如下面:
```java
package org.springframework.asm;
public abstract class AnnotationVisitor {
...
}
```
所以你很少能看到包名和类名连写在一起的情况,所以小写的小写, 大写的大写,都不挨着。而ObjectScript的类定义一定要写全了, 上面的定义如果在ObjectScript里就是:
```java
public class org.springframework.asm.AnnotationVisitor {
...
}
```
因此这样的写法会有个视觉上的大小写的落差。
我属于没事找事的。
结论: 社区有了命名规范,矮骡子们纷纷表示支持。
按这个convention,Tony老师如果去写一个示例代码贡献给社区的话,可能是这样的
```java
class com.dhc.tony.demo.xml.TestUtils
{
property noFailWhileDisconnected as %Boolean;
property firstname as %String;
parameter SETTINGS = "ReplyCodeActions";
method onKeepalive(pAdapterStatus As %Status) as %String
{
return "okay"
}
}
```
我们目前还都是首字母大写的驼峰 之后是要统一改用zpm的命名规范吗。。。
文章
Louis Lu · 十月 8, 2024
挑战
在使用FHIR进行开发的过程中,我们会面对海量的FHIR规范中定义的数据结构,具体来说在FHIR规范中定义了超过150个资源、700多个资源内元素。每个定义里都包括了对自身结构的描述以及数据约束、数据绑定值集等。对于一个开发人员要记住这些内容非常困难。
同时FHIR数据,特别是Json格式的FHIR数据是典型的“有向图”结构,它的资源中嵌套元素定义、集合以及复杂的资源间“关系”,在这些复杂结构的数据间导航并操作,非常困难。
解决方案
在InterSystems IRIS for Health 2024.1之前,我们会将FHIR数据以Json文档的方式载入 %DynamicAbstractObject,例如下面的代码
set dynObject1 = ##class(%DynamicObject).%New()
set dynObject1.SomeNumber = 42
set dynObject1.SomeString = "a string"
set dynObject1.SomeArray = ##class(%DynamicArray).%New()
set dynObject1.SomeArray."0" = "an array element"
set dynObject1.SomeArray."1" = 123
set dynObject2 = {"SomeNumber":42,"SomeString":"a string"}
set dynObject2.SomeArray = ["an array element",123]
write "object 1: "_dynObject1.%ToJSON(),!,"object 2: "_dynObject2.%ToJSON()
可以看到这样的处理有下面不方便的地方:
只能使用自己的方式解析、导航FHIR结构
不能从IDE中获取提示信息
没有数据类型安全
没有上下文敏感的文档
没有调试debug的支持
在InterSystems IRIS for Health 2024.1版本之后,引入了FHIR 对象模型。
FHIR 对象模型概览
在 HS.FHIRModel.R4 包下,每一个FHIR R4资源都对应一个ObjectScript类。比如 HS.FHIRModel.R4.AllergyIntolerance类对应于 AllergyIntolerance 资源。这些类通过为资源和组成元素提供一个共享的、可预测的数据结构和方法框架,简化了开发过程。
这样的结构,在VS Code环境下,会给出很好的提示
下面具体举例如何使用FHIR 对象模型:
1. 获取数据
按索引获取有序序列中的值
Set patientName = patient.name.get(0)
获取嵌套定义中的值
Set patientIdValue = patient.identifier.get(0).get(“value”)
Set patientCity = patient.address.get(0).city
在获取数据前判断键key是否存在
If patient.name.get(0).contains("family") {
Set familyName = patient.name.get(0).get(“family”)
}
2. 更新数据
添加新的键值对
Do patient.name.get(0).put("use","official")
更新存在的值
Do observation.put("status","final")
3. 添加对象的引用
Set claim = ##class(HS.FHIRModel.R4.Claim).%New()
Do claim.IncludeType()
Do claim.type.IncludeCoding()
4. 导航对象
Set contactItr = patient.contact.get(0).telecom.iterator()
While contactItr.hasNext() {
Set contact = contactItr.next().value
if contact.system = "phone" {
Write !, contact.value
}
}
5 读取JSON格式 FHIR 数据
Set rType = dao.resourceType
Set cls = $CLASSMETHOD("I4H.FhirR4."_rType,"fromDao",dao)
6. 将FHIR 数据输出为 JSON 格式
Set newDao = cls.toDao()
转为字符串
Set payload = cls.toString()
7. 创建新的 FHIR 元素
Do claim.IncludeType()
Do claim.type.IncludeCoding()
Set coding = ..MakeCoding("http://terminology.hl7.org/CodeSystem/claim-type","institutional")
Do claim.type.coding.add(coding)
8. “图” 结构查询引擎
Set key = "system"
Set value = "email"
Set query = "$[*]?(@."_key_"=='"_value_"')"
Set email = doctor.telecom.apply(query)
更多资料
FHIR Object Model 在线文档:https://docs.intersystems.com/irisforhealth20242/csp/docbook/DocBook.UI.Page.cls?KEY=HXFHIR_data#HXFHIR_data_classes
下面是一个完整的创建患者资源的例子
ClassMethod MakeCoding(system As %String, code As %String, display As %String = "") As HS.FHIRModel.R4.Coding
{
Set rec = ##class(HS.FHIRModel.R4.Coding).%New()
Set rec.system = system
Set rec.code = code
If (display'="") Set rec.display = display
Return rec
}
// Create a Patient using FHIR Object Model classes from R4 and then post
// this patient on the FHIR server
ClassMethod CreatePatient(ident As %String) As %Status
{
#dim patient As HS.FHIRModel.R4.Patient
Set patient = ##class(HS.FHIRModel.R4.Patient).%New()
Do patient.IncludeName()
Set name = patient.name.MakeEntry()
Set firstName = "John"
Do name.IncludeGiven()
Do name.given.add(firstName)
Set name.family = "Doe"
Do patient.name.add(name)
If patient.name.get(0).contains("family") {
Set fName = patient.name.get(0).get("family")
}
Do patient.name.get(0).put("use","official")
Set patient.gender = "male"
Set patient.birthDate = "1985-05-15"
Do patient.IncludeAddress()
Set addr = patient.address.MakeEntry()
Do addr.IncludeLine()
Set line1 = "123 Main Street"
Do addr.line.add(line1)
Set addr.city = "Boston"
Set addr.state = "MA"
Set addr.postalCode = "02111"
Do patient.address.add(addr)
Set address = ##class(HS.FHIRModel.R4.Address).%New()
Do patient.put("address", address)
Do patient.IncludeContact()
Set contact = patient.contact.MakeEntry()
Do contact.IncludeTelecom()
Set telecom = contact.telecom.MakeEntry()
Set telecom.system = "phone"
Set telecom.value = "555-555-5555"
Set telecom.use = "mobile"
Do contact.telecom.add(telecom)
Do patient.contact.add(contact)
Set contactItr = patient.contact.get(0).telecom.iterator()
While contactItr.hasNext() {
Set contact = contactItr.next().value
if contact.system = "phone" {
Write !, contact.value
}
}
Do patient.IncludeIdentifier()
Set id = patient.identifier.MakeEntry()
Set coding = ..MakeCoding("http://terminology.hl7.org/CodeSystem/v2-0203", "MR")
Set id.type = coding
Set id.value = ident
Do patient.identifier.add(id)
Set patientJSON = patient.toDao()
Set service = ##class(HS.FHIRServer.Service).EnsureInstance(1)
Do service.interactions.Add(patientJSON)
Return $$$OK
}
文章
姚 鑫 · 七月 28, 2021
# 第三十三章 类关键字 - SoapBodyUse
指定此类中定义的任何`web method`的编码。此关键字仅适用于`web服务`和`web客户端`类。
# 用法
要指定此类的`web method`的输入和输出所使用的编码,请使用以下语法:
```java
Class MyApp.MyClass [ SoapBodyUse = soapbodyuse ] { //class members }
```
其中`soapbodyuse`是下列之一:
- `literal` 文字(默认)—默认情况下,此类中的`web method`使用文字数据。也就是说,`SOAP`消息的``中的`XML`与`WSDL`中给出的模式完全匹配。
- `encoded` 编码—默认情况下,此类中的`web method`使用`SOAP`编码的数据。也就是说,`SOAP`消息的``中的`XML`使用了适合所使用的`SOAP`版本的`SOAP`编码,如以下规范所要求的:
- `SOAP 1.1` (https://www.w3.org/TR/2000/NOTE-SOAP-20000508/Opens in a new window)
- `SOAP 1.2` (https://www.w3.org/TR/soap12-part2/Opens in a new window)
重要提示:对于手动创建的`web服务`,该关键字的默认值通常是合适的。当使用`SOAP`向导从WSDL生成`web`客户端或服务时,InterSystems IRIS会将此关键字设置为适合该`WSDL`;如果修改该值,web客户端或服务可能不再工作。
# 详解
此关键字指定此类中定义的任何`web method`使用的默认编码。它还控制这个类的`ELEMENTQUALIFIED`和`XMLELEMENT`参数的默认值,这将在本主题的一个小节中讨论。
可以通过使用`SoapBodyUse`方法关键字或`SoapBodyUse`查询关键字,为单个方法重写此关键字。
# 对子类的影响
此关键字不是继承的。
# 默认
默认值为文字。(`SOAP`标准V1.1指定`web method`应该使用`SOAP`编码。但是,大多数`SOAP`客户端(包括`.NET`)都使用文字样式。)
# WSDL的关系
`SoapBodyUse`关键字指定了`WSDL`的``部分中``元素的`Use`属性的值。例如,如果`SoapBodyUse`是字面意思,则`WSDL`可能如下所示:
```xml
...
文章
Louis Lu · 四月 9, 2022
此文章也是对问题 在不重建的情况下插入索引Inserting an index without reconstruction 的一种解释
在使用SQL语言对 InterSystems IRIS 中的表进行查询时,有时候会发现返回的结果与实际有出入,特别是使用count() 函数,或者select 查询时,返回的结果少于实际应返回的值。这种情况往往是由于数据表格的索引值出了问题。
索引出问题的主要原因可能是:
表中先有数据,后创建的索引定义,并且定义之后没有重新生成索引。
对保存数据的global直接操作。如果是使用对象或者sql的方式操作数据,相应的索引都会自动更新,但是如果直接对global操作,则不会自动更新索引。
对保存索引的global直接操作。
要解决或者要检查是不是索引引发的问题,可以使用%ValidateIndices()函数,它有两种方式使用
$SYSTEM.OBJ.ValidateIndices(classname,idxList,autoCorrect,lockOption,multiProcess)
或者
##class(classname).%ValidateIndices(idxList,autoCorrect,lockOption,multiProcess)
两种使用方法最大的差别是:$SYSTEM.OBJ.ValidateIndices()方法会同时检查继承于该表的子表的索引,而##class(classname).%ValidateIndices()不检查子表的索引。
函数参数: idxList, ""代表检查所有索引,或者设定检查的索引项。默认为检查所有索引。 autoCorrect, 是否自动纠正错误。默认为0,不自动纠正。 lockOption, 执行过程中执行的锁的操作,0 - 完全不进行锁定 1 - 在检查每一行时进行共享锁定 2 - 对整个表进行独占锁定。默认=1 multiProcess, 在允许的情况下使用多进程执行。$SYSTEM.OBJ.ValidateIndices() 默认为 0,##class(classname).%ValidateIndices() 默认为 1.
例子:
Do $SYSTEM.OBJ.ValidateIndices("Sample.Company",$lb("NameIdx"),1,1)
Do ##class(Sample.Company).%ValidateIndices()
公告
Claire Zheng · 八月 26, 2022
欢迎了解2022年7月社区的最新动态!
最近我们进行了很多有趣的提升,以优化你在InterSystems开发者社区的体验:
📌 社交网络通知功能
📌 改进了订阅设置
📌 全新的“关于我们”页面
📌 更友好的“会员”页面
我们来详细看看这些改进!
通知
从现在开始,你会在你页面右上角(靠近头像照片)看到新的通知,点击小铃铛,你就可以看到所有最新的通知,点击即可获得更详细的信息:
点击“查看全部”即可抵达“通知”页面,在那里你可以看到所有通知信息。
在此页面中,您可以“将所有内容标记为已读(Mark all as read)”或通过链接进入生成通知的页面。并管理订阅设置。
订阅
我们改进了订阅页面,希望你们会觉得这个页面变得更加友好
您可以选择从开发者社区接收哪些通知,无论您是通过电子邮件还是通过网站接收。你可以在你账户的“订阅”部分找到它。
关于我们
我们 已经提到 过,我们创建了一些全新的“关于我们”页面。但是这些按钮太可爱了,值得我再提一次🥰
你可以在顶部菜单的About部分找到它——> 关于我们:
会员
另一个我们已经调整的是“会员”页,希望可以让你感到更便利。我们添加了一个新的“最新活动”列。您可以通过单击任何列的名称对其进行排序。
暂时就这些吧!希望您赞成我们所有的改进!
下次见!
文章
Chang Liu · 九月 22, 2022
1,准备
本次安装环境:Kylin-Server-10-SP2-Release-Build09-20210524-x86_64.iso
安装系统适配的对应版本:HealthConnect-2021.1.2.338.0-lnxubuntux64.tar.gz;ISCAgent-2021.1.2.338.0-lnxubuntux64.tar.gz
系统语言选择:English(必要)
2,安装HealthConnect+webgateway
2.1 新建所需用户组
groupadd iscagent
2.2 解压文件
2.3 安装
本次安装,使用root用户及root用户组安装,超级端口改为51773
3,安装ISCAgent
3.1安装说明
ISCAgent是healthconnect的镜像服务,若是单机使用,则不需要安装。
3.2 解压文件
3.3 安装
3.3 加入服务
3.3.1 新建文件
在/etc/systemd/system 下创建文件,ISCAgent.service,内容如下:
[Unit]
Description=InterSystems Agent
After=syslog.target network-online.target
[Service]
Environment=LD_LIBRARY_PATH=/usr/local/etc/irissys
Environment=COMLIB=/usr/local/etc/irissys
ExecStart=/usr/local/etc/irissys/ISCAgent
Type=forking PIDFile=/var/run/ISCAgent.pid KillMode=process
[Install]
WantedBy=multi-user.target
其中,/usr/local/etc/irissys为ISCAgent服务安装默认目录。
3.3.2 修改文件属性
chmod 755 ISCAgent.service3.3.3 重新启动systemctl
systemctl daemon-reload
3.3.4 启动服务
systemctl start ISCAgent.service
3.3.5 查看服务状态
systemctl status ISCAgent.service
如下:
4, 防火墙配置
firewall-cmd --zone=public --add-port=51773/tcp --permanent
firewall-cmd --zone=public --add-port=52773/tcp --permanent
firewall-cmd --zone=public --add-port=2188/tcp --permanent (--permanent永久生效,没有此参数重启后失效) 重载生效: firewall-cmd --reload
5,镜像配置
5.1 主机配置
创建镜像
5.2 备机配置
加入故障转移
hc为HealthConnect的安装实例名称
6 安装过程中出现的问题
6.1 描述
添加虚拟ip失败:
6.2 问题解决
发现virtualIP.sh中部分代码在中文系统中执行时有问题,则将系统换成英文系统则可以解决这个问题。
The End
可以,很实用 找了好久,国产系统适配先行者 很棒的分享! 友友写的真好 优秀 非常不错,总结到位 真的很不错 加精了!
文章
Michael Lei · 六月 8, 2023
嗨社区!
我们已经到了#GlobalSummit23 的尾声——最后一天!这是我们的一天——程序员的一天。今天的主题演讲都致力于开发人员、他们的成长、抱负和创新。
更有趣的是,在主题演讲中,@Dean.Andrews2971谈到了开发者社区等话题。你现在可以在Youtube上观看这部分,或者晚些有更新的版本:
午餐后,出席全球峰会的所有主持人齐聚一堂,参加名为“如何充分利用 InterSystems 开发人员生态系统”的会议。今年参加的人比去年多了很多!
@Dean.Andrews2971 谈到了社区、全球大师、开放交流、创意门户的新闻和功能,以及人们如何从中受益。
然后是任何想说几句话的人的开放季节😊
@Dmitry.Maslennikov 英文社区
@José.Pereira 葡语社区
@Muhammad.Waseem 英文社区
西语社区的@Francisco.López1549
法文社区的@Lorenzo Scalese
DC 英文社区的@Scott Roth
这是所有在场主持人的照片(从左到右):@José.Pereira、@Muhammad.Waseem、@Djeniffer.Greffin7753、@Scott.Roth、@Dean.Andrews2971、@John.Murray、@Irène.Mykhailova ,@Lorenzo.Scalese,@Francisco.López1549。
多么好的一群人!
我希望在场的每个人都喜欢这 45 分钟。
会议结束后,几乎是最后的冰淇淋和咖啡时间了!但在我看见@Guillaume.Rongier7183完成他关于他最喜欢的主题 Python 的演讲之前。
我们联系了@Dmitry.Maslennikov、@Murray.Oldfield 以及在上述会议期间加入的我们的新社区成员 - @Vladimir.Babarykin。
在最后的告别之后,我真的从 Caelestinus 抓住了@Vita.Tsareva
以上就是全部内容,希望您喜欢我的全球峰会进展情况的故事。
在评论中分享您对全球峰会的看法。您认为 2024 年全球峰会的举办地点是什么?这是一个有趣的话题😀到时候见!
文章
Jingwei Wang · 七月 7, 2023
本篇文章主要介绍互联互通套件的一些基础问题:
基于互联互通套件通过互联互通成熟的测评的实施工作量
电子病历共享文档部分:需要客户将业务系统数据灌入CCH套件SQL模型中
服务部分:在平台做消息改造,或者直接做业务系统接口改造
基于互联互通套件通过电子病例五级+互联互通成熟度测评四级需要的最低人员配备和项目总耗时
需要了医院现有业务系统和人员配备,做进一步评估及分析
目标只是通过互联互通成熟度测评需不需要FHIR
不需要,如果只是过测评,只需要互联互通套件基础版就够了
BI相关功能如何实现
可以使用DeepSee,基于Cubes做数据分析及钻取
如何使用Java进行快速开发
可以使用PEX,支持Java开发,但是如果使用Production,推荐使用内置开发语言ObjectScript,学习成本更低,未来开发新特性能力更强大
有没有自带的ETL工具
InterSystems 互联互通套件中没有ETL工具,但是支持所有ETL工具的连接
发送失败消息是否有记录
所有错误消息都能够在平台监控到,且可以进行转发或者重发
有没有按照单个服务流程进行整个业务流程的修改和查看
平台内所有服务都可以按照类别区分,也可以按照服务查看业务流程,但是没有按照单个服务修改整个业务流程的界面
公告
Claire Zheng · 五月 20, 2024
为推动《“十四五”全民健康信息化规划》全面实施,充分发挥国家医疗健康信息互联互通标准化成熟度评测工作对区域医疗信息交换促进作用,为医疗数据合规高效流通使用奠定坚实基础。《中国卫生信息管理杂志》社主办、深圳市卫生健康信息协会协办、InterSystems中国承办的区域信息互联互通新发展研讨会于5月11日在深圳举办。
国家卫生健康委统计信息中心胡建平副主任线上参会并致辞、广东省卫生健康委员会事务中心傅承主副主任、深圳市卫生健康信息协会林德南会长参加会议并致辞。胡建平副主任在视频致辞中强调了医疗健康信息互联互通标准化成熟度测评对区域全民健康信息化和智慧医院建设起到的重要作用,总结了互联互通标准化成熟度测评主要开展的四方面工作,指出下一步工作要从网络通、应用通、数据通等三个维度持续发力,通过叠加区块链等信息技术,实现互联互通从1.0阶段向2.0阶段跃迁,赋能卫生健康事业高质量发展。
查看精彩内容回放:欢迎扫描下图中的二维码或点击此处(如果您已报名过此次会议,使用报名时的手机号码即可登录查看,如首次登录,需填写报名信息后查看)