大家好,
我在 OEX 上加载了一个新软件包,我也计划在本月参加比赛。
简而言之,它为您提供以下内容。
- 用于 InterSystems IRIS 的持久(表)类以保存记录历史的基类
- 这些类允许在touch时将持久类记录历史化到另一个持久类中。
- 这提供了任何记录的完整历史记录。
- 它允许记录回滚到特定版本。
- 它可以自动清除旧的历史记录。
请检查一下。
谢谢你们。
InterSystems ObjectScript 是一种脚本语言,可使用 InterSystems 数据平台的任何数据模型(对象、关系、键值、文档、全局变量/Global)处理数据,并在 InterSystems 数据平台上为服务器端应用程序开发业务逻辑。
文档。
大家好,
我在 OEX 上加载了一个新软件包,我也计划在本月参加比赛。
简而言之,它为您提供以下内容。
请检查一下。
谢谢你们。
简单来说,网络抓取、网络收获或网络数据提取是从网站收集大数据(非结构化)的自动化过程。用户可以根据需要提取特定站点上的所有数据或特定数据。收集的数据可以以结构化格式存储以供进一步分析。

就这么简单!
Beautiful Soup 是一个纯 Python 库,用于从网站中提取结构化数据。它允许您解析来自 HTML 和 XML 文件的数据。它充当辅助模块,并以与使用其他可用开发人员工具以网页交互的方式与 HTML 交互。
经过一段时间的学习和使用本文总结了一些使用VsCode开发的使用方法,本文偏向于应用但会对少量的我知晓的原理进行一部分解释。
参考教程链接:https://cn.community.intersystems.com/node/488611
VSCode下载:https://code.visualstudio.com/
1 优势:
2 劣势:
1官网安装Visual Studio Code编辑器
背景
作为集成平台厂商,在医院同其它系统联调的时候所做的事情中,多的不是开发代码而是查消息。我先演示一下目前我正在使用的IRIS查消息的方式:
例子1:
需要看【个人信息注册服务】
我只需要在框中输入【个人信息注册】回车
点击【查看消息】,显示的是消息里面的内容,如图所示:
点击【查看流程】,显示的是IRIS消息可视化的页面,如图所示:
例子2:
需要查询患者ID为【2874621】这患者在集成平台调用了哪些服务
我只需要选择下拉选择【患者ID】,然后输入【2874621】,回车
这个是我们以用户需求的角度直观的查询到指定的消息,IRIS也有这个功能—消息查看器,它是如何使用的呢?首先,我们得知道这条消息使用了哪些Production组件,其次我们需要了解这个消息使用的实体类的结构。比如同样查这个人的消息,我需要输入request.Body.PatientID=“2874621”,选择消息类。如果我需要查多个服务的我还需要多选消息类 …… 本文不是来介绍如何使用消息查看器的,各位大概知道就好。
程序分析与设计思路
原始消息查看器的使用
我们先使用IRIS自带的【消息查看器】查患者ID为【2874621】个人信息注册服务,如图所示:
前言
自接触IRIS以来在医院之中使用最多的是其作为一个ESB集成引擎来使用,作为医院的集成平台+数据中心中的一环。但是其也可以进行CRUD作为前后端分离项目的后端使用:
文章目录
前言
文章目录
一、开发技术和工具
二、开发路径和相关代码
1.数据库
2.准备工作
3.开发接口的相关步骤
4.成果展示
总结
本文章将以一个简单的页面展示IRIS的相关CRUD操作:
是的,我计划使用IRIS重构Production页面,先展示一下我开发完的成果吧:
呃の好像是一毛一样,哈哈
一、开发技术和工具
工欲善其事,比先利其器:
后端:HealthConnect+Global
前端:vue
使用IRIS的%CSP.REST开发的Rest API接口,前端使用vue简单的把接口相关内容展示,可以编辑、新增组件,控制production启动、停止、更新检测状态。
二、开发路径和相关代码
1.数据库
首先,我们找到Production的相关表,分别是:Ens_Config.Item 和 Ens_Config.Production 如图所示:
所以代码的思路很明确了对Ens_Config.Item进行新增、删除、修改、查询操作对Ens_Config.Production进行查询操作。
2.准备工作
在正式开发之前我们得先做一些准备工作:比如开放网关
Cache起源于没有SQL的1970时代,当时各种高级计算机语言才刚刚诞生,其中M语言较为独特,它的诞生就是为了在没有操作系统的机器上,进行数据存储。别忘了,Unix在1971年才发布。M语言别具一格地采用了Global多维数组,统一了复杂的内存操作和文件读写,使之成为了1970年代数据库的事实标准,特别是在医疗行业。而后Intersystems在1978年接过M语言的旗帜,在M语言上添加了SQL兼容层和ObjectScript层,前者顺应了时代的潮流,后者不仅为M语言提供了强大的OOP和各种便捷的语法糖,还让数据能以对象形式进行访问,让数据和代码更加紧密。
本文将简述多维数组、SQL、对象这3种数据操作方式,提供实例代码片段,并在运行效率、开发效率、管理效率、实用性方面讨论它们的优缺点。 为方便讨论,以学校与学生为例。对每种操作方法,都列举3种典型的用例,分别为,访问某特定ID的学生(即数据库ID索引)、访问某特定studentID的学生(即遍历唯一索引)、和访问某学校的所有人(即遍历非唯一索引)。
现假设学生表/对象定义如下:
Class Student Extends %Persistent
{
Property schoolId AS %String;
Property studentId As %String;
Property name As %String;
Index IdxOnSchoolId ON schoolId ;
Index IdxOnStudentId ON studentId [Unique];
Storage Default
{
<Data name="StudentDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>schoolId</Value>
</Value>
<Value name="3">
<Value>studentId</Value>
</Value>
<Value name="4">
<Value>name</Value>
</Value>
</Data>
<DataLocation>^StudentD</DataLocation>
<DefaultData>StudentDefaultData</DefaultData>
<IdLocation>^StudentD</IdLocation>
<IndexLocation>^StudentI</IndexLocation>
<StreamLocation>^StudentS</StreamLocation>
<Type>%Library.CacheStorage</Type>
}
}
s id = 1 // 已知id
s student = ^StudentD(id)
s name = $LIST(student, 4)
w name
s studentId = 1 // 已知studentId
s id = $ORDER(^StudentI("IdxOnStudentId",studentId,""))
s student = ^StudentD(id)
s name = $LIST(student, 4)
w name
s schoolId = 1 // 已知schoolId
s id=""
for {
s id = $ORDER(^StudentI("IdxOnSchoolId",schoolId,id))
q:id=""
s student = ^StudentD(id)
s name = $LIST(student, 4)
w name
}
$ORDER方法返回多维数组最末端下标的下一个值。用来遍历多维数组。
s id = 1 // 已知id
&sql(SELECT name INTO :name from Student where id=:id)
w name
s studentId = 1 // 已知studentId
&sql(SELECT name INTO :name from Student where studentId=:studentId)
w name
s schoolId = 1 // 已知schoolId
s query="SELECT name from Student where schoolId=?"
s statement=##class(%SQL.Statement).%New()
s sc=statement.%Prepare(query)
s rset=statement.%Execute(schoolId)
while (rset.%Next()) {
s name = rset.%Get("name")
w name,!
}
&sql()为嵌入式SQL语句,在INTO子句中赋值给变量,适合单行查询。&sql()也可以返回游标Cursor,以实现多多行查询,但效率比SQL.Statement低,不推荐使用。SQL.Statement类实现动态SQL语句,动态查询适合返回多行结果。
s id = 1 // 已知id
s student = ##class(Student).%OpenId(id)
s name = student.name
w name
s studentId = 1 // 已知studentId
s student = ##class(Student).IdxOnStudentIdOpen(studentId)
s name = student.name
w name
s schoolId = 1 // 已知schoolId
s id=""
for {
s id = $ORDER(^StudentI("IdxOnSchoolId",schoolId,id))
q:id=""
s student = ##class(Student).%OpenId(id)
s name = student.name
w name
}
%OpenId方法通过ID查找并返回对象。IndexOpen方法通过唯一索引值查找并返回对象。注意,非唯一索引没有类似方法。
这是一篇笔记:
说明
Restful是一种基于Http的网络应用程序的设计风格和开发方式,可以使用xml格式或者Json格式定义。
RESTFUL特点包括:
1、每一个URI代表1种资源;
2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
3、通过操作资源的表现形式来操作资源;
4、资源的表现形式是XML或者HTML;
5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
IRIS中实现
GET:
我需要在当前命名空间下创建一系列的只读类,并限制除_system之外的所有用户都只有读取权限,无法在studio中编译,请问我应该如何操作呢?
我的目的是可以在工程的项目分支中管理这些类,并通过发布方式持续升级这部分类文件。
但是这些类的内部逻辑有可能会需要维护人员能够知晓其中的功能和实现方式,所以不能通过MakeDeployed来解决这个问题
我现在知道可以通过设置database的读写属性来解决这个问题,但是这样就需要额外新建一个database并maping到当前命名空间下。采取这种方式处理时有一个重大的缺点,即在执行代码发布过程中,需要停库,并且停库时间可能会在半个小时左右,这个我无法接受。
Hi 社区的朋友们,大家好!
有时我们需要以编程方式自动将CSV数据从文件或者UR网址L导入到InterSystems IRIS。我们希望创建具有适当数据类型的类并导入数据。
我在Open Exchange上发布了一个模块csvgen,它正是这样做的。
如果你只需要将CSV文件导入IRIS,你可以这么做:
USER>do ##class(community.csvgen).Generate("/usr/data/titanic.csv",,"Data.Titanic")
Class name: Data.Titanic
Header: PassengerId INTEGER,Survived INTEGER,Pclass INTEGER,Name VARCHAR(250),Sex VARCHAR(250),Age INTEGER,SibSp INTEGER,Parch INTEGER,Ticket VARCHAR(250),Fare MONEY,Cabin VARCHAR(250),Embarked VARCHAR(250)
Records imported: 891
USER>或者你的CSV文件在互联网上, 例如GitHub上面的新冠疫情数据 你可以这样获得数据:
USER>d ##class(community.csvgen).GenerateFromURL("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_daily_reports/05-29-2020.csv",",","Data.Covid19")
Class name: Data.Covid19
Header: FIPS INTEGER,Admin2 VARCHAR(250),Province_State VARCHAR(250),Country_Region VARCHAR(250),Last_Update DATE,Lat MONEY,Long_ DOUBLE,Confirmed INTEGER,Deaths INTEGER,Recovered INTEGER,Active INTEGER,Combined_Key VARCHAR(250),Incidence_Rate DOUBLE,Case-Fatality_Ratio DOUBLE
Records imported: 3522
USER>嗨社区,
这篇文章公开介绍我的 iris-fhir-client 客户端应用。
iris-fhir-client 可以可以借助嵌入式 python 连接到任何开放的 FHIR 服务器 fhirpy 图书馆.
通过终端和使用 CSP Web 应用程序获取资源信息。
在这篇文章中,你可以访问InterSystems开发者社区中与学习InterSystems IRIS最相关主题的文章库。找到按机器学习、嵌入式Python、JSON、API和REST应用、管理和配置InterSystems环境、Docker和云、VSCode、SQL、分析/BI、全局、安全、DevOps、互操作性、Native API排列的顶级发表的文章。快来享受学习的乐趣吧!
机器学习是建立先进的数据分析和自动化人工活动的一种必要的技术,具有很好的效率。它可以创建认知模型,从现有的数据中学习,并根据其自我调整的算法进行预测、概率计算、分类、识别和 "非创造性 "的人类活动的自动化。
在所有情况下,InterSystems IRIS作为一个数据平台和环境来创建、执行、提供和使用这些机器学习模型。IRIS能够从SQL命令(IntegratedML)中使用ML,使用嵌入式Python和PMML(预测模型标记语言)来执行ML。你可以在以下文章中查看它的功能:
在Caché基础课程中,同学们同时学习了Caché开发和ObjectScript语法。为了帮助大家完成练习,我们提供了ObjectScript快速参考(俗称 "小抄")。
它不是所有ObjectScript的参考资料! 它是学生在课程中使用的ObjectScript命令和函数的列表,以及对象、集合等的常用语法。它还包含一些有用的宏。
我们正在为开发者社区提供一个pdf版本。
有时,有必要从主机操作系统的Shell(即你的ObjectScript程序所在的地方)执行命令,以启动程序、操作系统服务、安排crontasks以及其他活动。为此,该语言有一个叫做$ZF(-100). 的实用程序:
$ZF(-100,flags,program,args)
其中flags是你想执行的命令的类型。在我们的例子中,标志是"/ SHELL",用于在主机操作系统上执行shell命令。
Program是要执行的程序或服务的名称。
Args是传递给程序的执行参数。
一个例子是在提示符下打印一些内容,例如:
$ZF(-100,"/SHELL","echo","https://www.intersystems.com/")
如果你的程序依赖于改变当前目录,要运行该程序,在调用前使用以下命令:
Do ##class(%SYSTEM.Process).CurrentDirectory("/path/")ObjectScriptt至少有三种处理错误的方法(状态代码status codes、异常 exceptions, SQLCODE等)。大多数系统代码使用状态码,但由于一些原因,异常更容易处理。在处理遗留代码时,你要花一些时间在不同的技术之间进行转换。我经常使用这些片段作为参考。希望它们对其他人也是有用的。
假设有一个类 "X.Y.Z"
它的SQL表名称是什么?如何通过ObjectScript获取??
快速的搜素不能显示任何方法或属性。文档有点 "不对" 说 SQL 表名称是一样的. 至少应该是 'x_y.z'.
答案见英文社区:https://community.intersystems.com/post/getting-sql-table-name-given-cl…
我现在在使用object script。如果把代码从 objectscript转成 Java 我需要做些什么?
在前一篇文章中,我已经演示了一种简单的方法来记录数据的变化。在这个时候,我改变了负责记录审计数据的 "审计抽象类 "和记录审计日志的数据结构。
我已经将数据结构改为父子结构,其中将有两个表来记录 "交易 "和在该交易中改变的 "字段的值"。
看一下新的数据模型:
看看从 "审计类 "改变的代码吧:
下面的代码允许用户查看其实例的审计设置。通过运行类方法 "test "来运行该代码。:
class objectscript.checkAudit Extends %RegisteredObject
{
classmethod test() {
w "Checking for Auditing...",!
Set SYSOBJ = ##class(Security.System).%OpenId("SYSTEM")
If +SYSOBJ = 0 Set SYSOBJ = ##class(Security.System).%New()
i SYSOBJ.AuditEnabled {
w "Security Auditing is enabled for the following services",!
s rs=##class(%ResultSet).%New("Security.Events:ListAllSystem")
s sc=rs.Execute() If $$$ISERR(sc) Do DisplayError^%apiOBJ(sc) Quit
while rs.%Next() {
d:rs.Data("Enabled")="Yes" rs.%Print()
}
d rs.Close()
s rs=##class(%ResultSet).%New("Security.Events:ListAllUser")
s sc=rs.Execute() If $$$ISERR(sc) Do DisplayError^%apiOBJ(sc) Quit
while rs.%Next() {
d:rs.Data("Enabled")="Yes" rs.%Print()
}
d rs.Close()
}
}
}
这是 GitHub的链接: https://github.com/intersystems-community/code-snippets/blob/master/src/cls/objectscript/checkAudit.cls
这是一个在InterSystems IRIS中用python和objectscript建立的对比测试。
测试目的是比较在python和objectscript中从BP到BO来回发送一千条请求/消息的速度。
更多信息,请访问 https://github.com/LucasEnard/benchmark-python-objectscript。
重要提示 : 这里用的是python, graph objectscipt和objectscript从一个BP到一个BO来回发送1000条消息的时间,单位是秒。
字符串信息是由十个字符串变量组成。
对象信息由十个对象变量组成,每个对象都是它自己的int、float、str和List(str)。
| 消息字符串 | 1000条消息来回的时间 (秒) |
|---|---|
| Python BP | 1.8 |
| BPL | 1.8 |
| ObjectScript | 1.4 |
| 消息对象 | 1000条消息来回的时间 (秒) |
|---|---|
| Python BP | 3.2 |
| BPL | 2.1 |
| ObjectScript | 1.8 |
行中函数的时间是列中函数的x倍 :
| 消息字符串 | Python | BPL | ObjectScript |
|---|---|---|---|
| Python | 1 | 1 | 1.3 |
| BPL | 1 | 1 | 1.3 |
| ObjectScript | 0.76 | 0.76 | 1 |
例如,第一行告诉我们,Python字符串的时间是Objectscript图形字符串函数的1倍,是Objectscript字符串函数的1.3倍。
( 利用第一个表格,我们可以验证我们的结果 :
1.3 * 1.4 = 1.8
1.3是第一行最后一列表格中的x,1.4s是本节第一个表格中看到的objectscript中的字符串信息的时间,1.8s实际上是python中的字符串信息的时间,我们可以通过寻找本节第一个表格或通过前面所示的微积分找到。)
行中的函数有列中函数X倍的时间:
| Messages objects | Python | BPL | ObjectScript |
|---|---|---|---|
| Python | 1 | 1.5 | 1.8 |
| BPL | 0.66 | 1 | 1.2 |
| ObjectScript | 0.55 | 0.83 | 1 |
我今天遇到了一个有趣的ObjectScript用例,有一个通用的解决方案,我想与大家分享。
我有一个JSON数组(在本例中具体而言是一个来自Jira的问题数组),我想在几个字段上进行聚合--例如,类别、优先级和问题类型。然后,我想把聚合的数据编平化到一个简单的列表中,其中包含每个组的总数。当然,对于聚合来说,使用一个本地数组的形式是有意义的,即:
agg(category, priority, type) = total
这样,对于输入数组中的每一条记录,我可以只用:
Do $increment(agg(category, priority, type))但是一旦我做了聚合,我想把它变成一种更容易迭代的形式,比如一个整数下标的数组:
summary = n summary(1) = $listbuild(total1, category1, priority1, type1) ... summary(n) = $listbuild(totalN, categoryN, priorityN, typeN)
简单的方法是,用$Order嵌套三个For循环--比如说:
绕过ODBC使用ObjectScript访问远程系统
这是一个在 IRIS 2020.1 和 Caché 2018.1.3 上工作的代码示例
不会与新版本保持同步
也不会获得 InterSystems 提供的支持服务!
我们经常会遇到这样的情况,由于各种原因ODBC是访问一个远程系统的唯一选择。如果你只需要检查或改变表,这就足够了。但你不能直接执行一些命令或改变一些Global。
特别感谢@Anna Golitsyna 启发我发表此文。
这个例子提供了3种 SQLprocedure 方法来实现访问远程系统这个目的,如果其他的访问方式被阻止,通常是被一些防火墙阻止。
Object Script(六)
ObjectScript中的变量是没有类型的,也就是说,它们没有一个指定的数据类型,可以接受任何数据值。
ObjectScript支持以下几种类型的变量:
1. 本地变量 :只有创建它的进程可以访问的变量,当该进程终止时,改变量将自动删除。一个本地变量可以从任何命名空间访问。
示例:
SET str = "A string"
2. 进程私有的全局变量 : 只有创建它的进程可以访问的变量,并且在进程结束时不再存在。一个进程专用的全局变量可以从任何命名空间访问,因为它与命名空间无关。进程私有的全局变量对于临时存储大数据值特别有用。在许多情况下,它们可以替代Mgr/Temp目录的使用,在进程终止时提供自动清理。
示例:
SET ^||flintstones(1)="Fred"
SET ^||flintstones(2)="Wilma"
3. 全局变量 : 一个存储在InterSystems IRIS数据库中的持久性变量。一个全局变量可以从任何进程中访问,并且在创建它的进程终止后仍然存在。全局变量是针对个别命名空间的。
示例:
SET ^myglobal = "This is a global stored in the current namespace"
4. i%property实例变量
Object Script(五)
Property PropName as Classname(PARAM1=value,PARAM2=value) [ Keywords ] ;Property SSN As %String(PATTERN = "3N1""-""2N1""-""4N") [ Required ];
Studio创建:
将下段代码填写入建好的类中:
ClassMethod FindPatient(id As %String) As HIS.Patient{ Set patient= ##class(HIS.Patien).%OpenId(id) Quit patient}
Terminal 调用:
set p = ##class(HIS.Patient).FindPatient(1)
传入参数的类型分为普通参数,输出型参数和返回参数:
普通参数 (传值参数):
Method Calculate(count As %Integer, name, state As %String = "CA") {…}
输出型参数(引用) :
大家是不是经常遇到以下情况:
Hi, 社区!
想和大家分享一下俄罗斯论坛上的一个Debug方法。
假设我想对应用程序进行Debug,我想让它在某一行停止执行。
在代码中加入这一行:
l +d,-d
当我想在这一行中开始调试时,我在终端中屏蔽了d
USER> l +d
执行该应用程序。
应用程序在这一行停止,让我用Studio调试器连接到它。
为了释放锁,我在终端做了以下工作
USER> l -d
还有其他好的Debug 建议吗?
本月我们正式发布VS Code ObjectScript扩展的1.8.0版本,它包含以下增强功能和错误修复。
最大的更新是支持服务器端的项目文件,因为很多人会记得Studio。如果你在客户端工作,VS Code已经有很好的项目管理功能。你可以简单地使用一个文件夹作为一个项目,或者使用多个根目录的工作空间。但是如果你在服务器端工作,你可能会喜欢一些更好的工具管理能力,这就是这个功能的意义所在。更多内容,欢迎查阅文档的新项目章节。
完整的更新日志在这里。
如果您已经安装了ObjectScript扩展,VS Code会自动更新。如果您是一个新用户,请从这里开始。
我一直希望 VSCode 能够拥有熟悉的 Studio 外观。
值得庆幸的是,VSCode 易于定制,因此您可以为任何元素选择任何颜色。
这是我到目前为止得到的:
有很多方法可以使用Intersystems生成excel文件,其中一些是ZEN报告、IRIS报告(Logi报告或正式称为JReports),或者我们可以使用第三方Java库,可能性几乎是无限的。
但是,如果你想只用Caché ObjectScript创建一个简单的电子表格呢?(没有第三方应用程序)
在我的案例中,我需要生成包含大量原始数据的报告(财务人员喜欢这些数据),但是我的ZEN/IRIS失败了,给了我一个我想称之为 "零字节的文件",基本上说java的内存用完了,并导致报告服务器上的重载。
这可以用Office Open XML(OOXML)来完成。Office Open XML格式是由一个ZIP包内的一些XML文件组成的。因此,基本上我们需要生成这些XML文件,并将其压缩重命名为.xslx。就这么简单。
这些文件遵循一套简单的惯例,称为开放包装惯例。你需要声明各部分的内容类型,以及告诉消费应用程序应该从哪里开始。
为了创建一个简单的电子表格,我们至少需要5个文件。
要用程序编辑Production(界面),你可以使用互操作性API和SQL查询的组合。
从顶层了解你目前正在工作的命名空间和生产是很重要的。
// Object script
// The active namespace is stored in this variable
$$$NAMESPACE
// Print namespace
Write $$$NAMESPACE
# Python
import iris
# The active namespace is returned from this method
iris.utils._OriginalNamespace()
# Print namespace
print(iris.utils._OriginalNamespace())
>>> DEMONSTRATION
另外,知道你的Production名称是很重要的,你可以使用以下API获得名称空间中正在运行的Production。
// ObjectScript
USER>ZN "DEMONSTRATION"
// Get current or last run production
DEMONSTRATION>W ##class(Ens.Director).GetActiveProductionName()
>>> Hospital.HospitalProduction
# Python
import os
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
active_production = iris.cls('Ens.Director').GetActiveProductionName()
print(active_production)
>>> Hospital.HospitalProduction
你可以使用Objectscript或python来寻找Production中在运行的项目
SELECT Name FROM Ens_Config.Item Where Production = 'Hospital.HospitalProduction'
--
['From_Athena_Multi']
['From_Athena_Multi_Router']
['From_Cerner_ADT']
['From_Cerner_ADT_Router']
['From_Cerner_Orders']
['From_Cerner_Orders_Router']
['From_Dictaphone_Results']
['From_Dictaphone_Results_Router']
['From_Lab_Results']
['From_Lab_Results_Router']
['From_Radiology_Results']
['From_Radiology_Results_Router']
['HS.IHE.XDSb.DocumentSource.Operations']
['HS.IHE.XDSb.Repository.Operations']
['To_Cerner_Results']
['To_Dictaphone']
['To_Intellilab']
['To_Lab']
['To_Radiology']
--
SELECT Name, ClassName
FROM Ens_Config.Item
WHERE Production = 'Hospital.HospitalProduction'
AND Enabled = 1
--
Name ClassName
To_Radiology EnsLib.HL7.Operation.FileOperation
To_Lab EnsLib.HL7.Operation.FileOperation
To_Dictaphone EnsLib.HL7.Operation.FileOperation
From_Cerner_ADT EnsLib.HL7.Service.FileService
From_Cerner_ADT_Router EnsLib.HL7.MsgRouter.RoutingEngine
From_Radiology_Results_Router EnsLib.HL7.MsgRouter.RoutingEngine
From_Lab_Results_Router EnsLib.HL7.MsgRouter.RoutingEngine
From_Dictaphone_Results_Router EnsLib.HL7.MsgRouter.RoutingEngine
To_Intellilab EnsLib.HL7.Operation.FileOperation
To_Cerner_Results EnsLib.HL7.Operation.FileOperation
From_Cerner_Orders_Router EnsLib.HL7.MsgRouter.RoutingEngine
From_Athena_Multi_Router EnsLib.HL7.MsgRouter.RoutingEngine
HS.IHE.XDSb.DocumentSource.Operations HS.IHE.XDSb.DocumentSource.Operations
--
// ObjectScript
// Access to get all items in the active production
// Returns list of items
ClassMethod ListItemsInProduction()
{
Set productionName = ##class(Ens.Director).GetActiveProductionName()
Set items = []
&sql(Declare curr cursor FOR Select Name into :newId from Ens_Config.Item Where Production = :productionName)
&sql(OPEN curr)
For {
&sql(FETCH curr)
Quit:SQLCODE
Do items.%Push(newId)
}
&sql(CLOSE curr)
quit items
}
>>> zw ##class(ISC.SE.ProductionTools).ListItemsInProduction()
["From_Athena_Multi","From_Athena_Multi_Router","From_Cerner_ADT","From_Cerner_ADT_Router","From_Cerner_Orders","From_Cerner_Orders_Router","From_Dictaphone_Results","From_Dictaphone_Results_Router"
,"From_Lab_Results","From_Lab_Results_Router","From_Radiology_Results","From_Radiology_Results_Router","HS.IHE.XDSb.DocumentSource.Operations","HS.IHE.XDSb.Repository.Operations","To_Cerner_Results"
,"To_Dictaphone","To_Intellilab","To_Lab","To_Radiology"] ; <DYNAMIC ARRAY>
# Python
# Get Dataframe of active production items
import os
# Set environment variables
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
def getActiveProductionItems():
productionName = iris.cls('Ens.Director').GetActiveProductionName()
df = iris.sql.exec("SELECT Name FROM Ens_Config.Item Where Production = '{}'".format(productionName))
return df
production_items_df = getActiveProductionItems().dataframe()
# name
# 0 From_Athena_Multi
# 1 From_Athena_Multi_Router
# 2 From_Cerner_ADT
# 3 From_Cerner_ADT_Router
# 4 From_Cerner_Orders
# 5 From_Cerner_Orders_Router
# 6 From_Dictaphone_Results
# 7 From_Dictaphone_Results_Router
# 8 From_Lab_Results
# 9 From_Lab_Results_Router
# 10 From_Radiology_Results
# 11 From_Radiology_Results_Router
# 12 HS.IHE.XDSb.DocumentSource.Operations
# 13 HS.IHE.XDSb.Repository.Operations
# 14 To_Cerner_Results
# 15 To_Dictaphone
# 16 To_Intellilab
# 17 To_Lab
# 18 To_Radiology
// ObjectScript
set productionName = ##class(Ens.Director).GetActiveProductionName()
//create a new xml file service
set classname="EnsLib.XML.FileService" //class of this item
set name="NewService" //config name
set item=##class(Ens.Config.Item).%New(classname)
set item.Name=name
set item.Comment = "Test Service"
set item.PoolSize = "1"
set item.Enabled = 1
do item.%Save()
//
// open the production class
// set prod="Test.configtest" //production name set manually
// OR
set prod = productionName
set prodObj=##class(Ens.Config.Production).%OpenId(prod)
//save the new item
set tSC=prodObj.Items.Insert(item)
set tSC=prodObj.SaveToClass(item)
set tSC=prodObj.%Save()
// DELETE item from above
set tSC = prodObj.RemoveItem(item)
set tSC = prodObj.SaveToClass()
set tSC=prodObj.%Save()
# Python
import os
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
active_production = iris.cls('Ens.Director').GetActiveProductionName()
print("Current Production {}".format(active_production))
# Metadata about component
classname="EnsLib.XML.FileService" # class of this item
name="NewService" # config name
item=iris.cls('Ens.Config.Item')._New(classname) # Make new component
item.Name=name
item.Comment = "Test Service"
item.PoolSize = "1"
item.Enabled = 1
item._Save()
# open the production class
# prod="Test.configtest" # production name manually set
# OR use the active production from above
prod = active_production
prodObj=iris.cls('Ens.Config.Production')._OpenId(prod)
# save the production after we insert that item to it
tSC=prodObj.Items.Insert(item)
tSC=prodObj.SaveToClass(item)
tSC=prodObj._Save()
# DELETE item from above
tSC = prodObj.RemoveItem(item)
tSC = prodObj.SaveToClass()
tSC=prodObj._Save()
// ObjectScript
set productionName = ##class(Ens.Director).GetActiveProductionName()
set itemName = "My.Inbound.HL7"
// Required for Enable Item
Set componentName = productionName _ "||" _ itemName _ "|"
// Disable or enable
Set enable = 1 // or 0
Do ##class(Ens.Director).EnableConfigItem(componentName, enable, 1)
/// Enable or disable a ConfigItem in a Production. The Production may be running or not.
/// The pConfigItemName argument gives the name of the config item to be enabled or disabled
/// In the case of multiple matching items with the same config name, if any is already enabled then
/// the pEnable=1 option will do nothing and the pEnable=0 option will disable the running matching
/// production item, or if not running then the first matching enabled item that it finds.
///
/// See method Ens.Director.ParseConfigName() for full syntax of the ConfigItem name specification string.
ClassMethod EnableConfigItem(pConfigItemName As %String, pEnable As %Boolean = 1, pDoUpdate As %Boolean = 1)
# Python
import os
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
active_production = iris.cls('Ens.Director').GetActiveProductionName()
item_name = "My.Inbound.HL7"
componentName = active_production + "||" + item_name + "|"
enable = 1 # or 0
iris.cls('Ens.Director').EnableConfigItem(componentName, enable, 1)
// ObjectScript
/// This method returns the production status via the output parameters.
/// pProductionName: Returns the production name when the status is running, suspended or troubled.
/// pState: Outputs production status. The valid values are:
/// $$$eProductionStateRunning == 1
/// $$$eProductionStateStopped == 2
/// $$$eProductionStateSuspended == 3
/// $$$eProductionStateTroubled == 4
Set sc = ##class(Ens.Director).GetProductionStatus(.productionName, .productionState)
Write productionName, " -- ", productionState
import os
# Set namespace the hard way
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
# TEST 2 with output variables
productionName, productionState = iris.ref('productionName'), iris.ref('productionState')
status = iris.cls('Ens.Director').GetProductionStatus(productionName, productionState)
print("Status: {}".format(status))
# see .value
print("Production: {}".format(productionName.value))
# see .value
print("Production State: {}".format(productionState.value))
HI 开发者们,
我们在bilibili 发布了新的视频!
<iframe src="//player.bilibili.com/player.html?aid=637281555&bvid=BV1cb4y1p7RE&cid=550213579&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>
看看VS Code的InterSystems ObjectScript的调试器如何帮助你浏览和检查代码。了解如何为调试类方法和production组件编写启动配置,并获得VS Code调试器界面的概述--包括变量部分、观察窗格和调试控制台。
请欣赏并继续关注!