搜索​​​​

清除过滤器
问题
Johnny Wang · 七月 13, 2021

关于Ensemble中消息形成过程的问题

各位老师好! 如下两图,是HL7信息体,在形成消息之前,我们一般会先制定文档,包括消息题、消息段、阈值;但是最终在Ensemble中形成的消息是怎么一个过程? 制定好的消息文档可以转换成IRIS可以读取的格式,导入到IRIS中成为消息Schema结构。在处理消息时,可以配置接口应用我们指定的消息Schema结构去处理消息。更多细节可参见文档:HL7 Schemas and Available Tools | Routing HL7 Version 2 Messages in Productions | InterSystems IRIS for Health 2023.1
公告
Claire Zheng · 十二月 22, 2022

直播预告 | 卫生健康信息标准应用管理培训班 (第二期)

2022年12月24日-25日,卫生健康信息标准应用管理培训班 (第二期)将于线上举办,此次培训班由国家卫生健康委统计信息中心指导、由《中国卫生信息管理杂志》社、深圳市卫生健康信息协会主办,InterSystems协办。详细日程请点击此处了解。您可以通过以下方式参与: 报名观看(可申请学分) 视频号(可观看直播) 如需要回看,请扫描“可申请学分”的二维码观看
文章
Qiao Peng · 五月 25, 2022

如何通过Journal日志文件查询谁对特定数据做了什么操作

%SYS.Journal.Record 类有一个查询(query), List, 可以列出Journal文件中记录的数据修改历史。例如,要查询谁对global节点^QP(1,2)做过修改,可以使用如下代码。它查询Journal文件(输入参数pFilePath)中的global节点(输入参数pSearchGlobal)的操作: ClassMethod SearchGlobal(pSearchGlobal = "^QP(1,2)", pFilePath = "C:\InterSystems\IRISHealth\mgr\journal\20220525.003") { Set tRS = ##class(%ResultSet).%New("%SYS.Journal.Record:List") Set tSC = tRS.Execute(pFilePath) While (tRS.Next()) { Set address = tRS.Data("Address") Set globalNode = tRS.Data("GlobalNode") Set newValue = tRS.Data("NewValue") Set type = tRS.Data("TypeName") Set processid = tRS.Data("ProcessID") Set time = tRS.Data("TimeStamp") Set globalRef = tRS.Data("GlobalReference") If globalNode=pSearchGlobal { W ! W time,! W processid,! W address,! W type," ",globalRef,"=",newValue,! } } }
问题
天恒 周 · 八月 6, 2022

cache题目

cache的题目资源,类似于Oracle的OCP试题那种,能反应出对基础概念的掌握。 回答您的问题: 1. 我们海外在招募考试平台测试者,您可以直接给certification@intersystems.com 发邮件申请,具体内容可以参考:https://community.intersystems.com/post/beta-testers-needed-our-upcoming-intersystems-iris-system-administration-specialist; 2. 我们国内也即将推出初中高级的培训认证体系,敬请关注。 这还有网上的一些体验题目:https://community.intersystems.com/sites/default/files/post-associated-docs/sysadmin_practice_questions_0.pdf 谢谢您的关注! 好的,感谢!
文章
姚 鑫 · 九月 16, 2022

第三十四章 在 Windows 上使用 IRIS(一)

# 第三十四章 在 Windows 上使用 IRIS(一) 在 `Microsoft Windows` 平台上管理 `IRIS` 数据平台实例非常简单。可以使用管理门户和 `IRIS` 启动器执行大多数任务。还可以从命令提示符控制 `IRIS` 实例。 本主题使用 `install-dir` 来指代 `IRIS` 安装目录——可以在安装指南的默认安装目录部分找到默认目录。 **注意:不要对 `IRIS IRIS.DAT` 数据库文件使用 `Windows` 文件压缩。 (通过右键单击 `Windows` 资源管理器中的文件或文件夹并选择属性,然后选择高级,然后压缩内容以节省磁盘空间来压缩文件;压缩后,文件夹名称或文件名在 `Windows` 资源管理器中呈现为蓝色。)如果压缩一个`IRIS.DAT` 文件,它所属的实例将无法启动,并出现误导性错误。** # 管理对 `IRIS` 实例的访问 ## `InterSystems` 服务 所有 `IRIS job`和进程都从 `InterSystems` 服务、 `IRIS Controller for ` 运行。 `InterSystems` 服务具有的权限由其关联的 `Windows` 用户帐户决定。当这是本地 `SYSTEM` 帐户时, `IRIS` 可以访问 `Windows` 系统上的所有文件和权限。为了维护一个更安全和限制性更强的环境,应该为服务选择一个仅具有所需权限和访问权限的 `Windows `帐户。 在正常安装和锁定安装中, `IRIS` 创建两个本地用户组来授予对实例的访问权限。当为 `InterSystems` 服务指定一个 `Windows` 用户帐户而不是默认的本地 `SYSTEM` 帐户时 `IRIS` 将该 `Windows` 用户帐户添加到每个组。这些组是: - `IRISServices`,它授予启动、停止和控制 `IRIS` 实例的权限。 - `IRIS_Instance_instancename`,授予对安装树的访问权限——`IRIS` 的安装目录及其所有子目录。 **注意:这些组可能不会授予 `IRIS` 执行某些操作所需的所有权限。要确保 `IRIS` 对安装树之外的所有实例、日志和日志文件具有所需的访问权限,请授予 `IRIS_Instance_instancename` 组对这些文件和包含它们的目录的完全访问权限。如有必要,还可以授予该组额外的权限。** 通常,在安装期间为 <instance-name> 选择 `IRIS` 控制器的 `Windows` 帐户,如安装指南的 `Windows` 用户帐户部分所述。 ## 限制对安装树的访问 默认情况下,任何经过身份验证的 `Windows` 用户都可以访问安装树,这可能是不可取的。以下命令为经过身份验证的用户删除 `Windows` 访问控制条目 (ACE): ```java icacls /remove "NT AUTHORITY\Authenticated Users" ``` 运行此命令后,只有管理员用户或 `IRIS_Instance_instancename` 组中的用户才能访问安装树。 **重要提示:如果不这样做,任何可以登录到主机 `Windows` 系统的用户都可以轻松地修改文件、更改设置或完全禁用 `IRIS` 实例。** 在某些情况下,除了 `IRIS` 控制器用于 ` ` 服务的帐户之外,可能还希望授予另一个 `Windows` 帐户访问安装树的权限。例如,这可能包括运行自动化任务的帐户,或直接登录到 `Windows` 服务器以访问 `IRIS` 的帐户(通过本地终端会话或调用自定义调用可执行文件)。可以通过将任何此类帐户添加到 `IRIS_Instance_instancename` 组来为其提供所需的访问权限。 # 更改 InterSystems 服务帐户 在命令行中输入以下内容以更改用于 `IRIS Controller for `的` Windows` 用户帐户: ```java \bin\IRISinstall.exe setserviceusername ``` 此命令将 `Windows` 用户帐户更改为指定的帐户。它还将用户添加到 `IRISServices` 和 `IRIS_Instance_instancename` 组,并在必要时创建这些组。运行此命令并重新启动 `IRIS` 实例后,该实例将在新指定的 `Windows` 用户帐户下运行。
文章
姚 鑫 · 三月 8, 2021

第五章 SQL定义表(三)

# 第五章 SQL定义表(三) # 使用DDL定义表 可以使用标准DDL命令在InterSystems SQL中定义表: InterSystems SQL中可用的DDL命令 - `ALTER`命令 `ALTER TABLE`,`ALTER VIEW` - `CREATE` 命令 `CREATE TABLE`,`CREATE VIEW`,`CREATE INDEX`,`CREATE TRIGGER` - `DROP` 命令 `DROP TABLE`,`DROP VIEW`,`DROP INDEX`,`DROP TRIGGER` 可以通过多种方式执行DDL命令,包括: - 使用动态SQL。 - 使用嵌入式SQL。 - 使用DDL脚本文件。 - 使用ODBC调用。 - 使用JDBC调用。 ## 在嵌入式SQL中使用DDL 在ObjectScript方法或例程中,可以使用嵌入式SQL来调用DDL命令。 例如,以下方法创建一个`Sample.Employee`表: ```java /// d ##class(PHA.TEST.SQL).CreateTable() ClassMethod CreateTable() As %String { &sql(CREATE TABLE Sample.Employee ( EMPNUM INT NOT NULL, NAMELAST CHAR (30) NOT NULL, NAMEFIRST CHAR (30) NOT NULL, STARTDATE TIMESTAMP, SALARY MONEY, ACCRUEDVACATION INT, ACCRUEDSICKLEAVE INT, CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM))) IF SQLCODE=0 {WRITE "Table created" RETURN "Success"} ELSEIF SQLCODE=-201 {WRITE "Table already exists" RETURN SQLCODE} ELSE {WRITE "Serious SQL Error, returning SQLCODE" RETURN SQLCODE_" "_%msg} } ``` ```java DHC-APP>d ##class(PHA.TEST.SQL).CreateTable() Table already exists ``` 调用此方法时,它将尝试创建`Sample.Employee`表(以及相应的`Sample.Employee`类)。如果成功,则将`SQLCODE`变量设置为0。如果失败,则`SQLCODE`包含指示错误原因的SQL错误代码。 这样的DDL命令失败的最常见原因是: - `SQLCODE -99`(违反权限):此错误表明没有执行所需DDL命令的权限。通常,这是因为应用程序尚未确定当前用户是谁。可以使用`$SYSTEM.Security.Login()`方法以编程方式执行此操作: ```java DHC-APP>w $SYSTEM.Security.Login("yx","123456") 0 ``` `SQLCODE -201`(表或视图名称不是唯一的):此错误表明正在尝试使用已经存在的表的名称创建新表。 ## 使用类方法执行DDL 在ObjectScript中,可以使用`Dynamic SQL%SQL.Statement`对象使用`Dynamic SQL`准备和执行DDL命令。 下面的示例定义了一个使用动态SQL创建表的类方法: ```java ClassMethod DefTable(user As %String,pwd As %String) As %Status [Language=objectscript] { DO ##class(%SYSTEM.Security).Login(user,pwd) SET myddl=2 SET myddl(1)="CREATE TABLE Sample.MyTest " SET myddl(2)="(NAME VARCHAR(30) NOT NULL,SSN VARCHAR(15) NOT NULL)" SET tStatement=##class(%SQL.Statement).%New() SET tStatus=tStatement.%Prepare(.myddl) IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT} SET rset=tStatement.%Execute() IF rset.%SQLCODE=0 {WRITE "Created a table"} ELSEIF rset.%SQLCODE=-201 {WRITE "table already exists"} ELSE {WRITE "Unexpected error SQLCODE=",rset.%SQLCODE} } ``` 与嵌入式SQL示例一样,如果当前没有用户登录,则此方法将失败。 ## 通过导入和执行DDL脚本定义表 可以使用`IRIS()`方法从终端会话中交互式地导入InterSystems SQL DDL脚本文件,也可以使用`DDLImport(“ IRIS”)`方法作为后台作业来导入InterSystems SQL DDL脚本文件。此方法可以导入和执行多个SQL命令,使可以使用txt脚本文件来定义表和视图,并用数据填充它们。 如果要将表从另一供应商的关系数据库迁移到InterSystems IRIS,则文本文件中可能包含一个或多个DDL脚本。 InterSystems IRIS提供了几种`%SYSTEM.SQL`方法来帮助将此类表加载到InterSystems IRIS中。可以使用通用的`DDLImport()`方法或特定供应商的`%SYSTEM.SQL`方法。供应商特定的SQL转换为InterSystems SQL并执行。错误和不支持的功能记录在日志文件中。 例如,从ObjectScript命令行加载一个Oracle DDL文件: 1. 使用InterSystems IRIS启动器菜单中的“终端”命令启动终端会话。 2. 切换到希望在其中加载表定义的名称空间: ```java SET $namespace = "MYNAMESPACE" ``` 3. 调用所需的DDL导入方法: ```java DO $SYSTEM.SQL.Oracle() ``` 并按照终端上显示的说明进行操作。 ![image](/sites/default/files/inline/images/1_23.png) # 定义分片表 创建分片表有三个要求。 1. 许可证密钥必须支持分片。使用管理门户,系统管理,许可,许可证密钥显示当前许可证或激活新许可证。 2. 必须在IRIS实例上启用分片。必须具有`%Admin_Secure`特权才能启用分片。使用“管理门户”,“系统管理”,“配置”,“系统配置”,“分片配置”来选择“启用分片”按钮。这使当前的InterSystems IRIS实例可以在分片群集中使用。选择“为任何角色启用此实例”或“仅对碎片主机角色启用此实例”。按确定。重新启动您的InterSystems IRIS实例。 3. 必须在IRIS实例上部署分片群集。此分片群集包含一个分片主名称空间。如果未为分片配置当前名称空间,则尝试定义分片表失败,并显示错误#9319:当前名称空间%1没有配置分片。 然后,可以在Shard Master命名空间中定义一个分片表,该表已定义为分片集群的一部分。可以使用`CREATE TABLE`通过指定分片键来定义分片表。或者,可以创建一个持久化类,该持久化类投影到分片表。 # 通过查询现有表定义表 可以使用`$SYSTEM.SQL.QueryToTable()`方法基于一个或多个现有表来定义和填充新表。指定一个查询和一个新的表名称。现有表名和/或新表名可以是合格的或不合格的。该查询可以包含`JOIN`语法。该查询可以提供列名别名,这些别名将成为新表中的列名。 1. `QueryToTable()`复制现有表的DDL定义,并为其指定指定的新表名。它复制查询中指定的字段的定义,包括数据类型,`maxlength`和`minval / maxval`。它不复制字段数据约束,例如默认值,必需值或唯一值。它不会将引用从字段复制到另一个表。 如果查询指定`SELECT *`或`SELECT%ID`,则将原始表的`RowID`字段复制为数据类型为整数的非必需,非唯一数据字段。 `QueryToTable()`为新表生成唯一的`RowID`字段。如果复制的`RowID`名为`ID`,则生成的`RowID`名为`ID1`。 `QueryToTable()`为此新表创建一个对应的持久化类。持久类定义为DdlAllowed。新表的所有者是当前用户。 不管源表中的这些设置如何,新表都将使用`Default Storage = YES`定义,并且`Supports Bitmap Indices = YES`。 为新表创建的唯一索引是`IDKEY`索引。没有位图范围索引生成。复制字段的索引定义不会复制到新表中。 2. `QueryToTable()`然后使用查询选择的字段中的数据填充新表。它将表格的“范围大小”设置为100,000。它估计`IDKEY`块计数。运行“音调表”以设置实际的“范围大小”和“块计数”,以及每个字段的“选择性”和“平均字段大小”值。 `QueryToTable()`既创建表定义,又用数据填充新表。如果只希望创建表定义,请在查询`WHERE`子句中指定一个不选择任何数据行的条件。例如,`WHERE Age < 20 AND Age > 20`. 下面的示例从S`ample.Person`复制`“名称”`和`“年龄”`字段,并创建一个AVG(Age)字段。这些字段定义用于创建名为`Sample.Youth`的新表。然后,该方法`where Age < 21`. 的那些记录的`Sample.Person`数据填充`Sample.Youth`。`AvgInit`字段包含创建表时所选记录的合计值。 ```java DO $SYSTEM.SQL.QueryToTable("SELECT Name,Age,AVG(Age) AS AvgInit FROM Sample.Person WHERE Age < 21","Sample.Youth",1,.errors) ``` ```java DHC-APP> DO $SYSTEM.SQL.QueryToTable("SELECT Name,Age,AVG(Age) AS AvgInit FROM Sample.Person WHERE Age < 21","Sample.Youth",1,.errors) Preparing query... Creating class... Compiling class... Copying data... ``` ![image](/sites/default/files/inline/images/2_13.png) # 外部表 在InterSystems SQL中,还可以具有“外部表”,这些表在SQL词典中定义但存储在外部关系数据库中。外部表的行为就像它们是本机InterSystems IRIS表一样:可以对它们发出查询并执行`INSERT`,`UPDATE`和`DELETE`操作。 InterSystems SQL网关提供对外部数据库的访问,该网关使用ODBC或JDBC提供透明的连接。 # List表 `INFORMATION.SCHEMA.TABLES`持久类显示有关当前名称空间中所有表(和视图)的信息。它提供了许多属性,包括模式和表名称,表的所有者以及是否可以插入新记录。 `TABLETYPE`属性指示它是基表还是视图。 以下示例返回当前名称空间中所有表和视图的表类型,架构名称,表名称和所有者: ```java SELECT Table_Type,Table_Schema,Table_Name,Owner FROM INFORMATION_SCHEMA.TABLES ``` ![image](/sites/default/files/inline/images/3_11.png) `INFORMATION.SCHEMA.CONSTRAINTTABLEUSAGE`持久类为为当前名称空间中的每个表定义的每个主键(显式或隐式),外键或唯一性约束显示一行。 `INFORMATION.SCHEMA.KEYCOLUMNUSAGE`为定义为当前名称空间中每个表的这些约束之一的一部分的每个字段显示一行。 # 列出列名和数字 可以通过以下四种方式列出指定表的所有列名(字段名): - `GetColumns()`方法。这列出了所有列名和列号,包括隐藏的列。 `ID(RowID)`字段可以隐藏也可以不隐藏。 `x__classname`列始终是隐藏的;除非使用`Final class`关键字定义了持久类,否则它将自动定义。 - 管理门户网站SQL界面(系统资源管理器,SQL)架构内容的“目录详细信息”选项卡。它列出了所有列名和列号(包括隐藏的列)以及其他信息,包括数据类型和指示列是否被隐藏的标志。 - `SELECT TOP 0 * FROM`表名。这将按列号顺序列出所有非隐藏的列名。请注意,由于隐藏的列可以按列号顺序出现在任何位置,因此您无法通过计算这些非隐藏的列名来确定列号。 - `INFORMATION.SCHEMA.COLUMNS`持久类为当前名称空间中每个表或视图中的每个非隐藏列列出一行。 `INFORMATION.SCHEMA.COLUMNS`提供了大量属性,用于列出表和视图列的特征。请注意,`ORDINALPOSITION`与列号不同,因为不计算隐藏字段。 `GetColumns()`方法同时计算隐藏字段和非隐藏字段。 下面的示例使用`INFORMATION.SCHEMA.COLUMNS`列出一些列属性: ```java SELECT TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT,IS_NULLABLE,UNIQUE_COLUMN,PRIMARY_KEY FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='Sample' ``` ![image](/sites/default/files/inline/images/4_7.png) ## GetColumns()方法 要以列号顺序列出表中的列名,可以使用`GetColumns()`方法,如下所示: ```java /// d ##class(PHA.TEST.SQL).GetColumn() ClassMethod GetColumn() { SET stat=##class(%SYSTEM.SQL).GetColumns("Sample.Person",.byname,.bynum) IF stat=1 { SET i=1 WHILE $DATA(bynum(i)) { WRITE "name is ",bynum(i)," col num is ",i,! SET i=i+1 } } ELSE { WRITE "GetColumns()无法找到指定的表" } } ``` `GetColumns()`列出所有已定义的列,包括隐藏的列。如果表引用了嵌入式`%SerialObject`类,则`GetColumns()`首先列出持久性类中的所有列,包括引用`%SerialObject`的属性,然后列出所有`%SerialObject`属性。在下面的`GetColumns()`结果中显示了这一点: ```java DHC-APP>d ##class(PHA.TEST.SQL).GetColumn() name is ID col num is 1 name is Age col num is 2 name is DOB col num is 3 name is FavoriteColors col num is 4 name is Home col num is 5 name is Name col num is 6 name is Office col num is 7 name is SSN col num is 8 name is Spouse col num is 9 name is x__classname col num is 10 name is Home_City col num is 11 name is Home_State col num is 12 name is Home_Street col num is 13 name is Home_Zip col num is 14 name is Office_City col num is 15 name is Office_State col num is 16 name is Office_Street col num is 17 name is Office_Zip col num is 18 ``` 还可以使用此方法确定指定列名的列号,如下所示: ```java /// d ##class(PHA.TEST.SQL).GetColumn1() ClassMethod GetColumn1() { SET stat=##class(%SYSTEM.SQL).GetColumns("Sample.Person",.byname) IF stat=1 { WRITE "Home_State is column number ",byname("Home_State"),! } ELSE { WRITE "GetColumns()无法找到指定的表" } } ``` ```java DHC-APP>d ##class(PHA.TEST.SQL).GetColumn1() Home_State is column number 12 ```
文章
Hao Ma · 一月 15, 2021

IAM实践指南——OAuth 2.0下的API保卫战(第一部分)

介绍 目前,诸多应用程序通过开放授权框架(OAuth)来安全、可靠、高效地访问各种服务中的资源。InterSystems IRIS目前已兼容OAuth 2.0框架。事实上社区有一篇关于OAuth 2.0和InterSystems IRIS的精彩文章,链接如下。 然而,随着API管理工具的出现,一些组织开始将其用作单点身份验证,从而防止未经授权的请求到达下游服务,并将授权/身份验证复杂性从服务本身分离出来。 您可能知道,InterSystems已经推出了自己的API管理工具,即InterSystems API Management (IAM),以IRIS Enterprise license(IRIS Community版本不含此功能)的形式提供。这里是社区另一篇介绍InterSystems AIM的精华帖。 这是三篇系列文章中的第一篇,该系列文章将展示如何在OAuth 2.0标准下使用IAM简单地为IRIS中的未经验证的服务添加安全性。 第一部分将介绍OAuth 2.0相关背景,以及IRIS和IAM的初始定义和配置,以帮助读者理解确保服务安全的整个过程。 本系列文章的后续部分还将介绍两种使用IAM保护服务的可能的场景。在第一种场景中,IAM只验证传入请求中的访问令牌,如果验证成功,则将请求转发到后端。在第二种场景中,IAM将生成一个访问令牌(充当授权服务器)并对其进行验证。 因此,第二篇将详细讨论和展示场景1中的配置步骤,第三篇将讨论和演示场景2中的配置以及一些最终要考虑的因素。 如果您想试用IAM,请联系InterSystems销售代表。 OAuth 2.0背景 每个OAuth 2.0授权流程基本上都由4个部分组成: 用户 客户端 授权服务器 资源所有者 简单起见,本文使用“资源所有者密码凭证”OAuth流(可以在IAM中使用任何OAuth流)。另外,本文将不指定任何使用范围。 注意:因为资源所有者密码凭证流直接处理用户凭证,所以应该只在客户端应用程序高度受信任时使用。在大多数情况下,客户端应为第一方应用程序。 通常,资源所有者密码凭证流遵循以下步骤: 用户在客户端应用程序中输入凭证(如用户名和密码) 客户端应用程序将用户凭证和自身的标识(如客户端ID和客户端密钥)一起发送到授权服务器。授权服务器验证用户凭证和客户端标识,并返回访问令牌 客户端使用令牌访问资源服务器上的资源 资源服务器首先验证收到的访问令牌,然后再将信息返回给客户端 考虑到这种情况,你可以在两种场景下使用IAM应对OAuth 2.0: IAM充当验证器,验证客户端应用程序提供的访问令牌,仅在访问令牌有效时才将请求转发给资源服务器;在这种情况下,访问令牌将由第三方授权服务器生成 IAM既充当授权服务器(向客户端提供访问令牌),又充当访问令牌验证器,在将请求重定向到资源服务器之前验证访问令牌。 IRIS和IAM初始定义和配置 本文中使用名为“/SampleService”的IRIS Web应用程序。从下面的截屏中可以看到,这是一个在IRIS中部署的未经身份验证的REST服务: 此外,在IAM端配置了一个名为“SampleIRISService”的服务,其包含一个路由,如以下截屏所示: 再者,在IAM中配置了一个名为“ClientApp”的客户端(初始没有任何凭据),用来识别谁在调用IAM中的API: 经上述配置,IAM将发送到以下URL的每个GET请求代理到IRIS: http://iamhost:8000/event 此时还没有使用身份验证。所以,如果将一个简单的GET请求(未进行身份验证)发送到URL: http://iamhost:8000/event/1 我们将获得期望的响应。 本文中,我们使用名为“PostMan”的应用程序发送请求并检查响应。在下面的PostMan截屏中,可以看到简单的GET请求及其响应。 请继续阅读本系列的第2篇,了解如何配置IAM来验证传入请求中的访问令牌。
公告
Michael Lei · 一月 9, 2022

2021 年英文社区Top 问题

a {color:#2a2e78;} 嘿,社区。 这里是2021年度开发社区问题摘要。 让我们来看看InterSystems开发人员提出的最受欢迎的问题。 统计 ✓ 2021年提出了980 个问题✓ 社区总共提出了5,699 问题 最多浏览问题 WINDOWS ODBC CACHE 驱动 by Fernando Zañartu 2,113 SOAP 错误 CONTENT-TYPE 返回 text/html 而不是 text/xml by Kurro Lopez 741 如何用xmlns 和 xsi:type 属性解析xml by water huang 733 ODBC 驱动 by Brian Bechard 667 VS Code中的意外Token错误 by David Hockenbroch 646 Log4j 脆弱性 by JOSE PALAU 597 如何在SQL查询中获得行编号? by Anderson Negreli 541 httpRequest POST 文件上传by Emanuel Lazar 527 Log4Shell Apache 影响 / Intersystems产品by Andy Stobirski 486 Intersystems Cache Studio 下载 by Joseph Lovato 461 如何在httpResponse对象中设置HTTP Response 状态编码 by Mike Yackanich 441 JSON解析空值null values in by Lucas Macori 398 如何快速简单从老的Dot Scoping转化为新的Parentleses Scoping? by Dominic Chui 397 从Caché 数据库到 IRIS数据库的转化. by Сергей Марушко 383 JSON Web Token令牌 授权与不记名令牌Tokensby Neil Thaiss 371 在另一个命名空间中调用类的方法 by Nigel Salm 371 超出License 限制? by yeung elijah 364 锁 /解锁 by Matjaz Murko 352 JWT/OAuth2.0 by M C 344 转化 ISO-8859-1 输入文件 by Michoel Reach 332 显示所有英文社区问题 » 显示所有中文社区问题 » 讨论最多的 Debugging功能不见了 by Anna Golitsyna 24 在 %SYS 命名空间外获得用户属性 by Evgenii Ermolaev 22 从 VS studio终端运行Python脚本 by Akshay Pandey 20 VS Code中的意外Token错误 by David Hockenbroch 20 JSON对象上的SQL 搜索索引. by Güvenal 20 锁 /解锁 by Matjaz Murko 19 IRIS - 原生 API 和 .NET Provider - 回归到 Cache .net Provider ?by Emanuel Lazar 18 &sql(.....) 不工作且返回SQLCODE -400 by prashanth ponugoti 18 修改 %Stream 内容 by Marlin Mixon 17 收到错误 #9406 by Rick Prichett 16 在VSCode转化 ObjectScript格式 by Julian Matthews 16 从Caché 数据库到 IRIS数据库的转化. by Сергей Марушко 15 Ensemble用SQL批量插入 by Jimmy Christian 14 #5003 没有实施by Gary Koester 14 动态 SQL 参数化 UPDATE vs INSERT的问题 by Jonathan Anglin 14 如何区分命名空间 Globals 和 Routines 数据库 ? by Muhammad Waseem 14 如何测试从虚拟文档到FLR的转化 by Werner Beukes 14 第一个REST 操作 - 定制Header by Scott Roth 14 vscode 新 routines 没有显示 by Paul Price 14 显示 %GlobalCharacterStream by Rochdi Badis 13 显示所有英文社区问题 » 显示所有中文社区问题 »
文章
Hao Ma · 十一月 14, 2022

ZPM介绍(1)

# ZPM介绍 有Developer听闻了InterSystems的包管理器ZPM, 希望我能介绍一下。正好刚刚看到一个开发者论坛的新闻:[ Open Exchange ZPM is now InterSystems Package Manager ](https://community.intersystems.com/post/zpm-now-intersystems-package-manager-ipm), 觉得更有必要了。 ## zpm是什么 简单说:zpm, 全称InterSystems ObjectScript Package Manager, 是一个包管理器, 开发者是Nikolay Soloviev和Dmitry Maslennikov。它先是在开发者社区里得到认可,以至于InterSystems开发者社区最近的一些比赛,要求参赛作品用zpm打包。然后就有了上面的链接的内容:InterSystems决定把它做为自己官方的打包工具, 将它改名字叫IPM(InterSystems Package Manager),同时保持它的开源状况不变。 这里我还是用zpm称呼它。两个原因。1. 操作的命令还是zpm, 所谓ipm,只是官方给的名字。2. ipm新的注册中心还不太了解,而且**到目前为止,IPM的注册中心还只对自己的雇员和付费用户开放**。本文的读者应该都还没来得及付费,所以暂时先放放,还是叫它zpm。 考虑到没有程序员背景的读者而对包管理器不熟悉,啰嗦两句。 ### 什么是包管理器 大多数开发工具都有自己的包管理器,Java开发使用MAVEN, Python用PIP, NodeJS使用npm, 它们细节有区别,功能大致是一致的,就是安装管理程序包,最基本的工作是: 1. 找到自己要的程序包。 简单的命令能让你在网上找到它,用名字找,或者其他方法搜索。 2. 安装包。 - 这里面最重要的是发现包之间的依赖。比如你要装一个软件包叫“包饺子”,作者在开发的时候使用了另一个软件叫“和面”,这个“和面”可能是作者自己写的,或者是网上其他人写的,注册在包管理器的。这时候作者在”包饺子“里声明,我依赖”和面“。 那么,当您去下载安装"包饺子“的时候,包管理器会自动的把”和面“也给你下载并安装上。 3. 管理包: 比如升级,删除等等。 ### ZPM的特点 没有zpm的时候,人们是怎么传递ObjectScript代码的? 大概是这样:发布者把代码从studio导出成一个XML;接受者拿到这个xml, 然后使用Studio或者iris管理门户把它导入到一个命名空间。 这里面有两个问题:1. 麻烦, 2. 没有打包各种类型文件的能力。通常一个项目,除非是只使用ObjectScript, 多数都用到各种文件:前端的css, html, javascript, 图片; 各种配置文件xml或者yaml, 其他语言的包 (iris支持嵌入式python,以及集成多种编程语言工作)等等。 ZPM是怎么工作的? 1. 作者把自己的数据放在一个公网地址上,比如github; 使用zpm生成一个配置文件(module.xml); 把module.xml发布到zpm的registry, 让别人能找到你的软件包。 2. 使用者在Registry搜寻并下载这个程序包,zpm命令自动把它导入到IRIS的一个命名空间。 为什么能自动导入到iris ? 这里有个ZPM和其他包管理器的很大的区别: **ZPM命令是在IRIS的terminal里执行的, 而不是操作系统上。** 还有一个特点:**zpm的设计假设大家开发代码使用的IDE是VSCode而不是Studio**,这非常关键。Studio上的开发是在服务端的开发,没有一个类应该存在哪个文件目录的概念。VSCode相反,你创建一个类:`Demo.Web.Test`, 那么默认的文件保存是在一个这样的目录下: `./src/Dome/Web/Test.cls` 不遵循这样的目录结构,您要额外做很多手工的调整才能使用zpm保存加载程序包。 这里还有很多问题, 我们后面详细说。 ## ZPM的下载安装 您可以从github上的InterSystems-Community用户的[zpm Repo](https://github.com/intersystems-community/zpm/wiki/01.-Getting-started)下载zpm-xxx.xml文件, 其中xxx是版本号, 当前(2022年10月)最新的版本是0.4.0。 把下载的xml文件导入到IRIS的**任何**命名空间。这样安装就成功了。 要下载安装软件的时候,您要先进入安装目标的命名空间(比如下面的USER),然后输入zpm, 也就进入了ZPM的操作界面: *ZPM Shell* ```sh USER>zpm ============================================================================= || Welcome to the Package Manager Shell (ZPM). || || Enter q/quit to exit the shell. Enter ?/help to view available commands || ============================================================================= zpm:USER> ``` 输入help, 您可以看到帮助文件。(帮助文件很长, 我只贴一小段。) ```sh zpm:USER>help -v Available commands: NOTE: [] around a parameter indicates it is optional arrange [flags] [] ■ Description: Rearranges the resources in a module manifest to follow the standard format # 此处省略许多行 ........ For more detail, run: help or help -v zpm:USER> ``` 接着, 我相信您一定想看看安装命令是怎么执行的,比如这样: ```sh zpm:USER>help install install [flags] [] ...此处省略若干行... ■ Examples ∙ install HS.JSON 1.x Installs the most recent 1.x version of HS.JSON available in any configured repository in the current namespace. zpm:USER>quit USER> ``` 好吧,让我们来下载一个最受欢迎的开发者应用“webTerminal”,了解最基本的zpm操作。 ## 最基本的ZPM操作 ### 搜索package 输入`zpm:USER>search`或者, 您可以使用`zpm:USER>search -r`,“-r"显示数据包所在的repo的位置。我没有贴在这里是因为显示的内容太宽了。在我的帖子的代码框里显示看上去有点乱。 ```sh zpm:USER>zpm:USER>search registry https://pm.community.intersystems.com: alwo-goselector 1.0.1 analytics-okr 1.0.0 ...此处省略许多行... zpm-shields 1.0.1 zpmhub 0.3.1 zpmshow 1.0.3 zpm:USER> ``` 除了search, 还有个find命令。 它可以使用*,但无法忽略大小写。 ```sh zpm:USER>find *Webt* registry https://pm.community.intersystems.com: zpm:USER>find *webt* registry https://pm.community.intersystems.com: webterminal 4.9.6 zpm:USER> ``` ### 安装package ```sh zpm:USER>install webterminal ...(省略若干行)... WebTerminal package successfully mapped into all namespaces. [USER|webterminal] Compile SUCCESS [USER|webterminal] Activate START [USER|webterminal] Configure START [USER|webterminal] Configure SUCCESS [USER|webterminal] Activate SUCCESS zpm:USER> ``` **到这里, 我来再次总结一下ZPM的最基本的功能:原本您想要使用一个其他开发者使用的程序,您要把它从某处,比如一个帖子,InterSystems的OpenExchange网站,或者一个github的主页上下载程序(XML文件),然后导入到IRIS执行。有了ZPM, 你可以在IRIS的terminal里通过ZPM命令,直接获得这个程序并执行。前提是:作者的程序是用ZPM打包并放在ZPM注册中心。** 来先了解一下ZMP的注册中心 ## 注册中心(Registry) 默认安装下, zpm的注册中心是这样的 ```sh zpm:USER>repo -list registry Source: https://pm.community.intersystems.com Enabled? Yes Available? Yes Use for Snapshots? Yes Use for Prereleases? Yes Is Read-Only? No Deployment Enabled? No zpm:USER> ``` 这也是当前zpm唯一的一个注册中心(配置私服会在后面介绍), 组册的软件包是最近一些年社区开发者写的各种工具和示例代码。说一下它的当前状况: - 当前能下载到278个软件包。 - 所有的包都放在了github。 - 包都很新。 这么说吧,release能到2.0的都是凤毛麟角 这里有个让人意外的事。我安装完webterminal并开始使用的时候,浏览器跳出这个提示。 “Welcome to WebTerminal! ...New update is available. ”。这说明这个registry并没有给出最新的webterminal版本。 我有点好奇,去看了一下webterminal的github page, 发现WebTerminal当前的版本是4.9.5。而zpm registry上下载的版本是4.9.2, 发行于2019年。 webterminal是一个前台工具,作者理所当然的的在代码里做了版本更新的检查并提醒了用户。而对于纯后台的ObjectScript语言的代码, 我估计大多数程序员都做不到这一点。 那么如果要保证其他人看到的是新版的软件, 就要求软件的作者,除了更新自己Github上的代码,还要把新版本及时更新在zpm的注册中心上。 文章太长了, 先贴一部分,后面会介绍 - 软件的发布 - 定义软件包的依赖 - 配置私服 *to be continued* 期待
文章
Qiao Peng · 十二月 2, 2022

通过智能数据编织应对数据挑战

1.数据的价值 数据的核心价值是帮助我们决策。 我们无时无刻不在决策,大到战略决策——为一家新医院选址,还有战术决策——鉴别产品的目标市场或抵押贷款审批,更频繁的是操作决策——决定患者的手术方案或患者药物的调整。 这些决策要求不同的决策速度,传统的数据中心已经能较好地帮助我们做战略决策、战术决策,甚至一些操作决策。但新的业务需求要求我们的决策速度越来越快,甚至借助机器学习自动为我们做出即时的决策,例如批准还是拒绝一笔信用卡交易或基于算法自动交易。 无论是人工决策还是基于机器学习的自动决策,决策的依据是数据。数据的速度和质量决定了决策的速度和质量。要支持决策,需要数据具有如下特征: (1)完整 :关联且具有完整上下文; (2)干净 :数据质量没有问题; (3)及时 :在决策点上没有延迟。 传统数据中心很难在及时性上满足要求。 2.数据挑战 数字化浪潮下,我们面临更大的数据挑战: 数据规模:数据量已经完全超出了人工处理能力。 数据源多样性:数据源不再仅是数据库,流式引擎的消息、物联网、对象存储......它们还带来了越来越多模型种类的数据。 更多的数据孤岛:更多的系统和应用被建设,进一步增加了数据孤岛现象。 跨部门的数据不一致:统计口径和统计时间的差异,造成财务部门统计的数据,总是和业务部门统计的数据对不上。 数据服务对象变化:现在业务分析师、运营数据消费者、数据工程师、数据科学家和普通人群都是服务对象。 部署需求的多样性:传统本地部署、云部署、混合部署...... 而由于技术、法律、经济性等原因,传统的数据集中保存无以为继...... 数据库、数据仓库、数据湖,这些传统的数据管理技术应对这些需求和挑战,越来越力不从心。数据库能保持数据的热度(良好的数据存取速度),但支持的模型类型和数据来源有限;数据仓库要统一数据质量与格式(Schema on Write),缺乏灵活性;数据湖可以“以原始形态保存一切数据” (Schema on Read),但各种数据进入这样一个湖,全都变成了无法直接分析利用的冷数据! 应对之道 – 数据编织和智能数据编织 数据编织是正在兴起的数据管理技术以应对数据挑战,Gartner将其定为2022年12大战略技术趋势之首。 那什么是数据编织? Gartner将数据编织定义为一种设计概念,可作为数据和连接流程的集成层(结构)。通过对现有、可发现和可推理的元数据资产进行持续分析,数据编织能够在所有环境(包括混合云和多云平台)中设计、部署和利用可重复使用的集成数据。 智能数据编织(Smart Data Fabric)则更进一步,在结构中直接嵌入各种分析能力,包括数据探索、商业智能、自然语言处理和机器学习,使企业可以更快、更容易地获得全新洞察,为智能预测和规范性服务及应用提供动力。 Gartner的这个名词解释还是有些抽象,如何理解它?为何数据编织/智能数据编织是解决上述挑战的利器? 如何利用现有的产品真实实现智能数据编织的落地? InterSystems提供的智能数据编织解决方案 今天,智能数据编织(Smart Data Fabric)正被用于许多行业的实际生产中,为各种企业级、关键任务创新提供动力,包括场景规划和决策支持、法规遵从、实时可见性和警报等,作为全球领先的数据技术提供商,为应对当前数据挑战,特别通过InterSystems IRIS新一代数据平台提供智能数据编织解决方案,整合了许多关键特性和能力,以满足客户实施智能数据编织进行数字化转型的需求,该方案在解决数据挑战的同时,允许现有的遗留应用和数据保持原位,最大限度地利用以前的技术投资,包括现有的数据湖和数据仓库,而不需要“撕裂和替换”任何现有技术。 InterSystems IRIS数据编织解决方案把智能数据编织分为3个阶段: 数据互联互通阶段:有能力实时、双向打通各种数据源,将数据源有机编织在一起。 数据集成阶段:对数据本身进行编织,为多模型数据提供高性能存取和转换、加入数据安全控制、建立数据谱系、抽象为干净和统一的语义层供数据用户使用。 智能利用阶段:对建立了统一语义的数据提供紧贴数据的智能利用能力,例如商业智能分析、自然语言分析、机器学习,并使这些智能增强数据编织本身。 InterSystems IRIS数据平台在单一技术栈内提供智能数据编织的这些能力:互联互通、数据集成、自助服务、智能分析和多云 。 传统数据利用的是多级瀑布模式:数据从数据库到数据湖,再到数据中心,数据大批量、高延时地在异构数据平台间移动和拷贝。这是影响数据时效性、一致性的主要原因。所以InterSystems智能数据编织第一就要解决这个问题,而解决之道就是互联互通和数据集成。 1.互联互通 因为数据源和数据模型的多样性,传统的ETL在能力和时效性上都已不能满足需求,需要更完整的互联互通能力。长期以来,InterSystems是互操作技术的领导者,它提供各种适配器实时接入各种数据源,例如流式处理引擎Kafka,并对遗留系统进行现代化,即便有很多遗留系统作为数据源,依然可以通过它将其数据模型多态化和数据服务现代化。 2.数据集成 数据集成(Integration)不追求将数据放在一起,而是要建立数据间的准确关联,建立具有连续上下文的全息数据,甚至丰富数据。InterSystems提供: (1)多模型 面对多元数据,Gartner表示,要想成功利用数据编织,企业必须确保数据编织能够动态地(通过元数据驱动设计)支持不同数据交付风格的组合,以支持特定的用例。 InterSystems的多模型数据建模和保存能力,让不同的数据以最适合的模型进行操作,它支持原生的对象、表、键值对和JSON文档。 (2)多语言 如何操作多模型的数据?每个数据用户都有熟悉或适合其用途的语言来使用数据,例如很多场景下,SQL是最简单的使用数据的语言。InterSystems让用户可以用SQL操作一切数据,哪怕它是以键值对建模和保存的。 (3)数据转换 不同的数据用户希望得到不同结构的数据。InterSystems提供图形化的高效数据转换工具,为用户构建干净的、单一可信的数据。 3.自助服务 如何发现、探索、推理数据编织平台中的数据?需要借助统一的语义和自助的服务能力。 (1)统一语义 为了数据完整性,无论是数据仓库还是数据湖,都将数据中心化存储。这造成了很多数据障碍:数据的时效性低、数据的质量参差不齐、数据需求严重依赖IT去清洗关联等等。 InterSystems的自适应分析是一个统一的、抽象的语义层,通过建立虚拟/逻辑数据分析立方体,用户可以使用SQL或BI工具访问这个语义层,而自适应分析自动使用SQL访问后台的多InterSystems IRIS数据平台实例获得数据和分析结果,不需要将数据集中保存到一起。 数据无需集中,因此无需ETL,没有数据抽取拷贝的时间成本开销,提供高时效性的数据;而抽象语义层将多数据源的数据建立逻辑关联,向用户提供干净、完整的语义上下文。 (2)行业语义级的数据编织 医疗健康行业面临相较其它行业更复杂的行业数据,在现实业务中要应对不同的语义表达。编织不同语义的数据源,将数据抽象为非标准语义,这会为后面的数据价值利用增加障碍。 FHIR建立统一行业语义的行业数据内容标准、利用标准行业术语和标识符、定义统一的传输标准、并逐步建立隐私和安全标准,让使用行业语义编织数据成为可能。 InterSystems支持所有FHIR的交互范式,提供FHIR服务器和FHIR资源仓库,并通过FHIR SQL构建器,建立基于SQL的FHIR数据访问能力,用最简单的数据操作支持BI/AI。通过FHIR来搭建具有统一行业语义和生态的数据编织平台。 (3)自助服务 长久以来,由于数据源和数据本身的复杂性,专业IT用户把持着数据的使用,商业用户极度依赖于专业用户才能获取、分析和利用数据。 借助统一语义层和对标准的支持,InterSystems让商业用户使用自己熟悉的工具和语言,例如SQL、BI工具和API来探索数据、操作数据和分析数据。 4.智能分析 为数据编织增加智能, InterSystems提供开放的智能分析能力。包括嵌入平台的机器学习、自然语言分析、商业智能特性,对第三方工具和生态的支持,以及对标准的支持——MDX、UIMA、PMML...... InterSystems提供全SQL操作方式的自动化机器学习,并允许使用第三方的自动化机器学习后台,如DataRobot,从而避免学习不同的API,用最简单的SQL就可以获得丰富的机器学习能力: 5.多云 数据编织平台要能支持所有主要的开发和部署环境,使开发人员和运营团队能够在他们选择的环境中工作。并与现有的基础设施和最佳技术无缝集成,支持最广泛的客户环境和应用要求。 公共云、私有云、本地、混合、裸机和虚拟机环境,InterSystems支持所有部署选项,且都只需要一个API,而不需要对你的应用程序进行修改。 6.单一技术栈而不建议不同产品和技术的堆砌与粘合 这一点至关重要。从整个数字化、信息化行业来看,信息部门尤其是最终用户的人员配置是远远不足的,从信息化部/科技部到我们的服务厂商,大部分从业人员工作负载基本都处在一个饱和甚至过饱和的状态,同时,IT从业人员由于薪酬激励的原因,大部分的中高端IT人才集中在少数行业或者少数头部厂商。针对这种情况,在数智底座的技术选择上,应该采取“少就是多”的策略,选择尽可能少的技术和产品种类,或者说一体化的技术架构,用一套技术体系来支持多种业务应用的实现,从而降低管理和学习成本。 另外一个原因,比如传统闭源厂商,很多软件产品都是收购或者是不同团队部门研发的,不同软件之间也需要集成或者胶水(参考文章:统一技术的高效数据架构能帮助客户节约大量成本)成本也是极其昂贵的。如果是选择开源技术栈,除了集成以外,还要考虑更多的比如技术路线的生命周期持久度,比如今天选择的技术会不会很快就过时了,技术支持如何延续?此外开源技术人员的成本普遍高于传统软件,人员流动也比较强,这也是企业选型必须考虑的问题。 总结 InterSystems的智能数据编织解决方案通过对数据源、数据的编织,避免多级瀑布式的大规模、高延迟的数据拷贝。构建抽象的统一语义层,并借助行业标准语义,建立基于标准的数据编织平台,为用户提供简单易用的数据探索和利用能力。利用全面的智能分析能力提升数据质量和数据价值,并降低数据利用的难度。多云的架构确保了对最广泛的客户环境和应用要求的支持,为数智底座的实施部署铺平了道路。
文章
YuHao Wan · 十一月 1, 2022

Caché实现SM3密码杂凑算法

### 0. 算法概述 SM3密码杂凑算法是中国国家密码管理局2010年公布的中国商用密码杂凑算法标准。该算法于2012年发布为密码行业标准(GM/T 0004-2012),2016年发布为国家密码杂凑算法标准(GB/T 32905-2016)。 SM3适用于商用密码应用中的数字签名和验证,是在[SHA-256]基础上改进实现的一种算法,其安全性和SHA-256相当。SM3和MD5的迭代过程类似,也采用Merkle-Damgard结构。消息分组长度为512位,摘要值长度为256位。 整个算法的执行过程可以概括成四个步骤:**消息填充、消息扩展、迭代压缩、输出结果**。 ### 1. 消息填充 SM3的消息扩展步骤是以512位的数据分组作为输入的。因此,我们需要在一开始就把数据长度填充至512位的倍数。具体步骤如下: 1、先填充一个“1”,后面加上k个“0”。其中k是满足(n+1+k) mod 512 = 448的最小正整数。 2、追加64位的数据长度。 ![消息填充](https://gitee.com/wanyuhao/intersystems/raw/master/%E5%9B%BD%E5%AF%86%E7%AE%97%E6%B3%95SM3,SM4/images/SM3-01.png) ### 2. 消息分组扩展 将填充后的消息m′按512比特进行分组:m′ = B(0)B(1)...B(n−1) 其中n=(l+k+65)/512。 SM3的迭代压缩步骤没有直接使用数据分组进行运算,而是使用这个步骤产生的132个消息字。(一个消息字的长度为32位/4个字节/8个16进制数字)概括来说,先将一个512位数据分组划分为16个消息字,并且作为生成的132个消息字的前16个。再用这16个消息字递推生成剩余的116个消息字。 ![消息分组](https://gitee.com/wanyuhao/intersystems/raw/master/%E5%9B%BD%E5%AF%86%E7%AE%97%E6%B3%95SM3,SM4/images/SM3-02.png) ### 3. 迭代压缩 SM3使用消息扩展得到的消息字进行迭代运算。 ![迭代运算](https://gitee.com/wanyuhao/intersystems/raw/master/%E5%9B%BD%E5%AF%86%E7%AE%97%E6%B3%95SM3,SM4/images/SM3-03.png) 初值IV被放在A、B、C、D、E、F、G、H八个32位变量中,整个算法中最核心、也最复杂的地方就在于**压缩函数**。压缩函数将这八个变量进行64轮相同的计算。 ![压缩函数](https://gitee.com/wanyuhao/intersystems/raw/master/%E5%9B%BD%E5%AF%86%E7%AE%97%E6%B3%95SM3,SM4/images/SM3-04.png) ### 4. 输出结果 将得到的A、B、C、D、E、F、G、H八个变量拼接输出,就是SM3算法的输出。 ![杂凑值输出](https://gitee.com/wanyuhao/intersystems/raw/master/%E5%9B%BD%E5%AF%86%E7%AE%97%E6%B3%95SM3,SM4/images/SM3-05.png) ### 5. 附录 ![符号](https://gitee.com/wanyuhao/intersystems/raw/master/%E5%9B%BD%E5%AF%86%E7%AE%97%E6%B3%95SM3,SM4/images/SM3-07.png) ![常数与函数](https://gitee.com/wanyuhao/intersystems/raw/master/%E5%9B%BD%E5%AF%86%E7%AE%97%E6%B3%95SM3,SM4/images/SM3-06.png) ### 6. Caché实现 ``` /// SM3密码杂凑算法是中国国家密码管理局2010年公布的中国商用密码杂凑算法标准 /// 该算法于2012年发布为密码行业标准(GM/T 0004-2012),2016年发布为国家密码杂凑算法标准(GB/T 32905-2016)。 /// 对长度为l(l < 2^64)比特的消息m,SM3杂凑算法经过填充和迭代压缩,生成杂凑值,杂凑值长度为256比特。 Class Utility.SM3 Extends %RegisteredObject { /// Creator: wyh /// CreatDate: 2022-11-01 /// Description:SM3加密 /// Input: msg:原文 /// Output: 16进制密文 /// Debug: w ##class(Utility.SM3).Hashsm3("{""appId"":""60C90F3B796B41878B8D9C393E2B6329"",""nonceStr"":""1234567890"",""timestamp"":""60C90F3B796B41878B8D9C393E2B6329"",""version"":""V2.0.0""}F2D8D966CD3D47788449C19D5EF2081B") ClassMethod Hashsm3(msg) { #; 初始值IV =7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e s V(0) = "01110011100000000001011001101111 01001001000101001011001010111001 00010111001001000100001011010111 11011010100010100000011000000000 10101001011011110011000010111100 00010110001100010011100010101010 11100011100011011110111001001101 10110000111110110000111001001110" #; 1. 消息填充 s m = ..s2m(msg) #; 2. 消息分组 #; 将填充后的消息m′按512比特进行分组:m′ = B(0)B(1)...B(n−1) #; 其中n=(l+k+65)/512。 s n = $l(m)/512 f i = 0 : 1 : n-1 d .s B(i) = $e(m, 512 * i + 1, 512 * (i + 1)) #; 3. 迭代压缩 #; 对m′按下列方式迭代: #; FOR i=0 TO n-1 #; V(i+1) = CF(V(i),B(i)) #; ENDFOR #; 其中CF是压缩函数,V(0)为256比特初始值IV,B(i)为填充后的消息分组,迭代压缩的结果为V(n)。 .s V(i+1) = ..CF(V(i) ,B(i)) #; 4. 杂凑输出 #; ABCDEFGH = V(n) #; 输出256比特的杂凑值y = ABCDEFGH。 s rtn = "" f i = 1 : 1 : 8 d .s bit = $p(V(n), " ", i) .s num = ..bs2n(bit) .s hex = $ZHEX(num) .i $l(hex) < 8 d ..f j = 1 : 1 : 8 - $l(hex) d ...s hex = "0" _ hex .s rtn = rtn _ hex s rtn = $zcvt(rtn, "L") return rtn } /// 1. 消息填充 /// 将填充后的消息m′按512比特进行分组:m′ = B(0)B(1)...B(n−1) /// 其中n=(l+k+65)/512 ClassMethod s2m(msg) { s len = $l(msg) s r = "" f i = 1 : 1 : len d .s num = $ascii($e(msg, i)) .s bs = ..n2bs(num) .s r = r _ bs s rtn = r s rtn = rtn _ "1" s k = 512 - (64 + ($l(r) + 1)) # 512 f i = 1 : 1 : k d .s rtn = rtn _ "0" s lenbs = ..n2bs($l(r)) s t = 64 - $l(lenbs) f i = 1 : 1 : t d .s rtn = rtn _ "0" s rtn = rtn _ lenbs return rtn } /// 3. 迭代压缩 /// 令A,B,C,D,E,F,G,H为字寄存器,SS1,SS2,TT1,TT2为中间变量,压缩函数V(i+1) = CF(V(i),B(i)), 0
文章
Michael Lei · 六月 26, 2022

以程序化的方式检查审计设置

下面的代码允许用户查看其实例的审计设置。通过运行类方法 "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
问题
li wang · 四月 23, 2022

浏览器地址中输入HealtConnect发布的webService地址报CSP应用程序错误

各位老师,你们好 我在浏览器地址中输入HealtConnect发布的webService地址报 CSP应用程序错误,并记录了此错误,不过该地址还是能正常访问。 我想知道怎么解决这种报错问题,谢谢! 以下图片为HealthConnect的版本,以及具体出现的错误 建议联系我们WRC团队support@intersystems.com 或者电话:4006019890或者对应的客户经理,谢谢! 应该是没开启SOAP测试页能力。搜一下三级等保文章,里面有介绍 https://cn.community.intersystems.com/smartsearch?search=InterSystems+数据平台与三级等保+-+第一篇
文章
姚 鑫 · 五月 2, 2021

第一章 简介global

# 第一章 简介global InterSystems IRIS®的核心功能之一是其多维存储引擎。此功能允许应用程序以紧凑、高效的多维稀疏数组存储数据。这些数组称为全局数组。 本章介绍: - 什么是全局变量(`globals` ),以及可以对其执行的操作。 - 全局变量的逻辑和物理结构,包括在分布式数据库体系结构中使用全局变量。 - 如何使用全局变量在应用程序中存储和检索数据。 - 如何使用全局变量。 # 特点 全局变量提供了一种在持久的多维数组中存储数据的易于使用的方法。 例如,可以使用名为`^Settings`的全局变量将值`“Red”`与键`“Color”`相关联: ```java SET ^Settings("Color")="Red" ``` 可以利用全局变量的多维特性来定义更复杂的结构: ```java SET ^Settings("Auto1","Properties","Color") = "Red" SET ^Settings("Auto1","Properties","Model") = "SUV" SET ^Settings("Auto2","Owner") = "Mo" SET ^Settings("Auto2","Properties","Color") = "Green" ``` 全局变量具有以下功能: - 简单易用-全局变量和其他编程语言变量一样易于使用。 - 多维-可以使用任意数量的下标指定全局内节点的地址。 例如,在 `^Settings("Auto2","Properties","Color")`中,下标`Color`是全局设置中的第三级节点。 下标可以是整数、数字或字符串值,并且不需要是连续的。 - 稀疏-用于寻址全局节点的下标高度压缩,不需要连续的值。 - 高效-全局变量上的操作(插入、更新、删除、遍历和检索)都经过高度优化,可实现最高性能和并发性。还有用于特殊操作(如批量插入数据)的其他命令。有一组特殊的全局变量是为临时数据结构设计的(例如,用于对记录进行排序)。 - 可靠-InterSystems IRIS数据库提供了许多机制来确保存储在全局数据库中的数据的可靠性,包括逻辑级和物理级日志记录。执行数据库备份操作时,将备份存储在全局数据库中的数据。 - 分布式IRIS提供了多种方法来控制存储在全局数据库中的数据的物理位置。可以定义用于存储全局的物理数据库,或将全局的部分分布到多个数据库中。使用InterSystems IRIS的分布式数据库功能,可以在数据库和应用程序服务器系统网络中共享全局数据。此外,通过镜像技术,存储在一个系统上的全局数据库中的数据可以自动复制到另一个系统上。 - **并发-全局支持多个进程之间的并发访问。在单个节点(数组元素)中设置和检索值始终是原子的:不需要锁定即可保证可靠的并发访问。此外,InterSystems IRIS支持一组强大的锁定操作,可用于为涉及多个节点的更复杂情况提供并发性。使用对象或SQL访问时,会自动处理此并发。** - **事务性-InterSystems IRIS提供定义事务边界的命令;可以启动、提交或回滚事务。在回滚的情况下,事务内对全局变量所做的所有修改都将被撤消;数据库的内容将恢复到事务前的状态。通过将各种InterSystems IRIS锁定操作与事务结合使用,可以使用全局变量执行传统的`ACID`事务。(`ACID`事务提供原子性、一致性、隔离性和持久性。)。使用对象或SQL访问时,事务会自动处理。** 注意:本文档中描述的全局变量不应与另一种类型的InterSystems IRIS数组变量混淆:进程私有全局变量。进程私有全局变量不是持久的;它们仅在创建它们程序期间持续。进程私有全局变量也不是并发的;它们只能由创建它们的进程访问。进程专用全局可以通过其多字符名称前缀:`^||`或`^|"^"|`轻松地与全局区分开来。 # 例如 一个简单的例子就可以展示全局变量的易用性和性能。下面的程序示例创建一个`10,000`个节点的数组(如果存在,则首先将其删除)并将其存储在数据库中。可以尝试这样做,以了解全局变量的性能: ```java /// w ##class(PHA.TEST.Global).GlobalSimple() ClassMethod GlobalSimple() { Set start = $ZH // get current time Kill ^Test.Global For i = 1:1:10000 { Set ^Test.Global(i) = i } Set elap = $ZH - start // get elapsed time Write "Time (seconds): ",elap q "" } ``` ```java DHC-APP> w ##class(PHA.TEST.Global).GlobalSimple() Time (seconds): .00307 ``` 我们还可以看到迭代和读取数组中的值需要多长时间(确保首先运行上面的示例来构建数组): -读取持久数组- ```java /// w ##class(PHA.TEST.Global).ReadGlobalSimple() ClassMethod ReadGlobalSimple() { Set start = $ZH // get current time Set total = 0 Set count = 0 // get key and value for first node Set i = $Order(^Test.Global(""),1,data) While (i '= "") { Set count = count + 1 Set total = total + data // get key and value for next node Set i = $Order(^Test.Global(i),1,data) } Set elap = $ZH - start // get elapsed time Write "Nodes: ",count,! Write "Total: ",total,! Write "Time (seconds): ",elap,! q "" } ``` ```java DHC-APP>w ##class(PHA.TEST.Global).ReadGlobalSimple() Nodes: 10000 Total: 50005000 Time (seconds): .001879 ``` # 在应用程序中使用 在InterSystems IRIS应用程序中,全局变量有多种使用方式,包括: - 作为对象和SQL引擎共享的底层存储机制。 - 作为用于为对象和SQL数据提供各种索引(包括位图索引)的机制。 - 作为用于执行不适合进程存储器的某些操作的工作空间。例如,当没有预先存在的索引可用于排序数据时,SQL引擎使用临时全局变量对数据进行排序。 - 用于在对象或SQL访问方面难以表达或效率低下的持久性对象或SQL表上执行专用操作。例如,可以定义一个方法(或存储过程或Web方法)来对表中保存的数据执行专门的分析。通过使用方法,这样的操作是完全封装的;调用者只需调用该方法。 - 实现特定于应用程序的自定义存储结构。许多应用程序需要存储难以用关系表示的数据。使用全局变量,可以定义自定义结构,并通过对象方法将其提供给外部客户端。 - 用于InterSystems IRIS系统使用的各种特殊用途的数据结构,例如配置数据、类定义、错误消息和可执行代码。 全局变量不受关系模型的限制。 它们提供了开发针对特定应用程序优化的定制结构的自由。 对于许多应用程序来说,明智地使用全局变量可能是提供性能的秘密武器,而这种性能是关系应用程序开发人员梦寐以求的。 无论应用程序是否直接使用全局变量,了解它们的操作都是有用的。 理解全局及其功能将帮助设计更高效的应用程序,并为确定应用程序的最佳部署配置提供帮助。
公告
Claire Zheng · 三月 7, 2021

如何更好地成为社区贡献者/活跃用户?

亲爱的开发者, 最近我们收到很多类似“如何成为一个活跃(Active)、有贡献值的成员”的问题。 条件很简单! 1. 回答问题 我们有许多未得到回答的问题, 以及 还没有收到有效回答的问题. 非常欢迎您在这些问题上共享您的见解和回答,帮助其他社区成员成长! 2. 撰写文章,发布帖子 撰写您使用InterSystems技术的经验和心得:解决方案、开发心得、解决bug的小技巧、部署等等。 这里是一些 帖子示例 ,这些帖子都对我们的社区建设很有帮助。 除了中文社区外,我们还有英语社区、日语社区、葡语社区等等,我们也欢迎您将这些社区里的文章翻译成中文进行发布! 3. 在Open Exchange提交应用程序 通过Github、Gitlab或任何其他公共存储库,在Open Exchange上共享您的库、解决方案和工具。 如果您对社区有什么问题和建议,欢迎跟帖回复、畅所欲言!我们欢迎大家共同建设社区,使这个社区对中国使用InterSystems技术的开发者们越来越有用! 请新注册的同学们阅读这篇文章,多问问题发帖子/有效评论; 或者多回答问题,中英文都可以: https://cn.community.intersystems.com/?filter=questions; https://community.intersystems.com/?filter=questions