New post

Find

InterSystems Official
· Jan 27

IPM 0.10.5 版发布说明

IPM 0.10.5 版已于 2026 年 1 月 15 日发布。新版本包含大量改进和错误修复,请务必直接从GitHub 页面或社区注册中心查看!

主要变化如下

  • 重写了依赖关系解析,大大提高了性能,包括在非常复杂的情况下速度提高了 200 倍
  • 跟踪 IPM 安装、加载、更新和卸载的历史日志,可使用zpm "log "查看
  • 系统表达式(如${namespace} 和 $$$ 宏)现在可在 CPF 合并文件中进行评估,使初始配置更具灵活性
  • 模块.xml 中的 <Invoke> 将更直观地表现为始终检查 %Status 返回值,前提是且仅当方法签名声明返回 %Status。这意味着如果没有返回任何值、返回值不是 %Status 或不是 $$$OK,就会产生错误。

以下是完整的变更列表:

已添加

  • #938:为软件包命令添加了 -export-python-deps 标志
  • #462:用于版本库配置的 repo 命令现在支持使用 -password-stdin 标志的密码秘密输入终端模式。
  • #935:添加通用的 JFrog Artifactory tarball 资源处理器,用于将工件与软件包捆绑,并在安装时部署到最终位置。
  • #950:新增使用 list -pythonlist -pylist-installed -python 列出已安装 Python 软件包的支持。
  • #822:CPF 资源处理器现在支持 CPF 合并文件中的系统表达式和宏
  • #578:添加了记录和显示 IPM 安装、卸载、加载和更新历史的功能
  • #961:增加了在安装时使用 -create-lockfile 标志为模块创建锁定文件的功能。
  • #959:在 ORAS 仓库中,外部名称现在可以与 installupdate 的(默认)名称互换使用,即使用(默认)名称发布的模块可以使用其外部名称安装。
  • #951:如果提供 -force 标志,unpublish 命令将跳过用户确认提示。
  • #1018:不使用 -all 标志时,卸载时需要模块名称

已更改

  • #316:loadinstallupdate 命令中包含的所有参数(开发人员模式除外)都将传播给依赖程序
  • #885:始终同步加载依赖项,并让每个模块根据需要使用多线程编译来加载,而不是试图绕过 IRIS 编译器对项目加载进行多线程编译,从而导致锁争用。
  • #481:通过以下方法提高 BuildDependencyGraph 的性能:
    • 消除递归并使用迭代。
    • 取消深度优先搜索,采用纯广度优先搜索。
    • 通过折叠搜索表达式(减少交叉表达式),更好地缓存模块搜索结果。

已删除

  • #938:删除了 %Publish() 中对秘密标志 NewVersion 的处理

已修复

  • #943:当 load 命令与 GitHub 仓库 URL 一起使用时,会再次接受 branch 参数。
  • #701:修正了关于 search 命令的误导性帮助注释
  • #958:如果使用外部名称,更新命令不应提前失败
  • #970: 修复:解决 "生成 "命令 WebApp 处理中的错误
  • #965:在名称不带斜线的目录上进行文件复制(FileCopy)现在可以正常工作了
  • #937:发布包含 <WebApplication> 的模块不再出错
  • #957:改进了操作系统命令执行的错误信息。现在,当命令执行失败时,错误信息会包含完整命令及其返回代码。还修正了 Windows attrib 命令的参数分离,并删除了对丢失命令的误导性错误处理。
  • #789:修复在为 ORAS 软件包列出指定命名空间的模块时出现的错误。
  • #999、#1000:安装 IPM 时清除旧版本 IPM 中使用的陈旧映射
  • #1007:${ipmDir} 表达式现在可在 <Arg><Invoke> 中使用。
  • #1015:修复 * 作为版本要求和相交范围无法正常工作的依赖关系解析错误。
  • #1036:update 命令不再将开发者模式传播给依赖关系

已弃用

  • #828:用于 <Invoke> 操作的 CheckStatus 标志已被弃用。现在的默认行为是,如果且仅当方法签名返回 %Library.Status 时,始终检查该方法的状态。
  • #885:-synchronous 标志,因为同步加载依赖关系现在是默认行为。

安全性

  • urllib3 轮已更新至 2.6.3

如果您有任何问题、建议或要提出的 bug,请随时在此处或GitHub 页面上提出。(在 GitHub 上,问题和建议应放在讨论页面,而错误应放在问题页面)。

Discussion (0)1
Log in or sign up to continue
Article
· Jan 26 5m read

プロセスを一定間隔またはスケジュールで実行する方法

InterSystems IRIS、特にInteroperabilityを使い始めたころ、最初によく思っていた疑問の一つは「処理を一定間隔やスケジュールで実行するにはどうすればいいのか」でした。 このトピックでは、この問題に対処する2つのシンプルなクラスをご紹介します。 似たようなクラスがEnsLibに見当たらないことに、驚いています。 十分に検索しなかったのかもしれません。 いずれにせよ、このトピックでは複雑な作業を扱うつもりはなく、初心者向けの簡単なスニペットを少し紹介します。

Discussion (0)0
Log in or sign up to continue
Article
· Jan 26 6m read

分表(Sub-Table)安全

InterSystems IRIS 提供广泛的可配置安全选项,但许多开发人员主要使用角色和资源来保护整个表或例程。今天,我们将深入探讨。我们也可以分别确保单个列和行的安全,但这两种机制的操作方式截然不同。让我们从列开始。

列安全

为便于测试和演示,我们将保持表结构简洁明了。我们在 USER 名称空间中有一个名为 "Person "的表,其中包含 ID 列、出生日期列 (DOB)、名和姓。

Class User.Person Extends %Persistent
{
    Property FirstName As %String;
    Property LastName As %String;
    Property DOB As %Date;
    Property User As %String;
}

我们将创建一个名为 limited_access 的角色,它将实现一些列的安全性,但我们必须记住的第一件事是确保将 %DB_User 资源添加到该角色,以便用户可以访问数据库。完成这些后,我们就可以开始考虑列的问题了。我们将进入角色设置中的 SQL 表选项卡,确保选择了 USER 命名空间。然后单击 "添加表(Add Tables)"按钮右侧的 "添加列(Add Columns)"按钮。这将打开我们控制列权限的对话框。

该界面与添加表权限的界面非常相似。值得注意的是 "删除(DELETE  ) "选项不在其中,因为它不能在列级别进行控制。这是有道理的,因为我们无法删除表中记录的单个列。不过,我们可以保留对 SELECT、INSERT、UPDATE 和 REFERENCES 权限的控制。我们还可以使用 "授予管理员(Grant Admin)"复选框,允许具有该角色的用户将相同的权限委托给其他用户或角色。在今天的示例中,我们将授予该角色 ID、FirstName 和 LastName 列的所有权限。但是,我们将只为 DOB 列分配 SELECT 权限。完成这些更改后,我们将保存角色。这时你会发现,角色配置中该表的条目在权限列下显示了一个连字符 (-)。不过,它还包含一个 "编辑列(Edit Column )"选项。

如果我们点击右侧的 "编辑列(Edit Column)"链接,就可以查看为每一列单独定义的确切权限。

在这里,我们可以修改或撤销特定列的权限。如果选中 "添加列(Add Column) "复选框,添加列的初始配置表单将重新出现在下方,允许我们进一步添加。如果遇到角色中列出的表格似乎缺乏已定义的权限,则应单击 "编辑列(Edit Column)"链接,检查特定列的权限。

为了测试此配置,我们需要设置一个具有此角色的用户。我们将这个用户命名为 testuser。它将拥有我们的 limited_access 角色,我们还将授予它 %Developer 角色,以访问管理门户的 SQL 部分并执行一些查询。例如,请看下面的 SQL 查询。

INSERT INTO Person(DOB,FirstName,LastName) VALUES(%ODBCIN('1900-09-03'),'David','Hockenbroch')

如果我们以具有 %All 权限的超级用户身份登录并执行此查询,查询将会成功。但是,如果我们注销管理门户并以测试用户身份重新登录,则会出现错误。

查询失败的原因是用户没有权限插入 DOB 列。如果我们调整查询,省略受限列,查询就会成功。下面的查询对该用户仍然有效:

INSERT INTO Person(FirstName,LastName) VALUES('David','Hockenbroch')

同样,如果用户没有更新或选择列的权限,任何违反这些限制的查询都会失败。例如,如果我从列权限中完全删除了 DOB 列,就无法执行 SELECT * FROM Person 命令。相反,我必须使用 SELECT ID、FirstName、LastName FROM Person 命令。请注意,如果用户无法访问某些计算列,计算仍会正确执行。

如果我们稍微修改一下类的定义,就会引入一个全新的问题。假设我们决定修改类定义,在 DOB 属性中包含 Required 关键字。如果我们尝试运行上述查询,就会导致错误,而不是成功。

在建立列权限时,您必须牢记这一点:如果您拒绝给予用户某一列的 INSERT 权限,而该列又不是通过计算代码、初始表达式或类似方法自动分配的,那么该用户将根本无法插入任何记录!

行级安全

现在,我们将探讨行级安全性。我们的目标是确保只有创建行的用户才能访问该行。

行级安全性的功能与列级安全性截然不同。我们不能通过管理门户( Management Portal)配置它。相反,我们必须修改我们的类定义。首先,我们应该添加一个属性:

Property Creator As %String [ SqlComputeCode = {set {*} = $USERNAME}, SqlComputed, SqlComputeOnChange = %%INSERT];

这是一个 SQL 计算属性,在插入记录时会自动将其值设置为当前用户名。我们将为每个用户插入一条记录。然后,我们应该观察以下记录:

接下来,我们需要覆盖类定义中的 ROWLEVELSECURITY 参数。将其设置为 1 将自动引导 IRIS 将读者列表存储在名为 %READERLIST 的属性中。不过,在我们的例子中,由于我们创建了一个属性来存储有权访问该行的用户名,因此我们将用该列的名称(Creator)覆盖该参数。请记住,由于行级安全性可以通过角色或用户名来处理,因此如果需要,我们可以使用包含角色名称的列来代替。

如果此时我们试图从表中选择任何数据,查询将返回空值。出现这种情况是因为我们在现有表中添加了行级安全性,而行级安全性依赖于在用于安全性的字段上建立索引。现在我们必须重建表的索引。我们将通过管理门户完成这项工作。在 SQL 区域,我们将选择左侧的表,然后单击操作,最后单击重建表的索引。

现在有了适当的索引,当用户从表中选择时,他们将只看到自己的行。必须认识到,这一限制甚至适用于超级用户!在 IRIS 的大多数安全环境中,拥有 %All 角色的用户几乎可以访问所有内容,但行级别的安全是一个明显的例外。即使我们以超级用户身份运行 DELETE * FROM Person 查询,也只能删除超级用户有权访问的记录。

我们可以用另一种方法实现同样的结果。这次,我们将 ROWLEVELSECURITY 参数设置为 1,但在类中添加一个 %SecurityPolicy 方法。

ClassMethod %SecurityPolicy(Creator) As %String [ SqlProc ]
{
    return Creator
}

该方法被定义为返回字符串并使用 SqlProc 关键字的类方法。它可以接受任意数量的参数,但这些参数必须是类本身的列名,而且参数的名称必须与列名精确匹配。在本例中,由于我们处理的列名为 "Creator",因此方法参数也必须名为 "Creator"。我们只需返回该列的值即可实现我们的目标。只要最终返回的是用户名或角色名,该方法就可以根据需要变得复杂。如有必要,它也可以返回以逗号分隔的名称列表。

当 ROWLEVELSECURITY 参数设置为 1 时,%READERLIST 属性将用于存储谁有权访问该行。如果希望在查询中查看该列表,可以执行类似下面的操作。

SELECT %READERLIST, * FROM Person

除表安全性外,还执行行级安全性。除非用户同时拥有表和行的权限,否则无法访问、更新或删除行。重要的是,行级安全仅在使用 SQL 时适用,而不是在使用对象访问或直接操作全局时。如果以绕过此安全层的方式访问数据,请务必谨慎!

认真使用这两个强大的工具,可以大大提高数据安全性!

Discussion (0)1
Log in or sign up to continue
Discussion (0)0
Log in or sign up to continue
Discussion
· Jan 26

Global Masters Chat: Resolutions 2026

Hi Community! 👋

As 2026 gets underway, we’d love to hear what you’re focusing on this year.

This discussion is a space to share your resolutions, goals, and focus areas for 2026 - technical, professional or community-related.

These don’t have to be traditional New Year’s resolutions. Think of them as intentions or priorities you’d like to work on this year.

💬 What you can share

  • Skills or technologies you want to learn
  • Projects you want to start or continue
  • Things you want to improve at work
  • Events or activities you want to take part in
  • Anything you’re excited to focus on in 2026

✍️ How to participate

  • Leave a comment with your resolutions or focus areas for 2026
  • Share as much or as little as you like
  • Feel free to reply to others, exchange ideas, or offer support

Let’s inspire each other and make 2026 a great year for the community.

And at the end of 2026, let’s check who kept their resolutions — and applaud!

Looking forward to reading your resolutions 👇

7 new Comments
Discussion (7)6
Log in or sign up to continue