搜索​​​​

清除过滤器
公告
Michael Lei · 四月 9, 2022

在 Docker 20.10.14+ 使用 InterSystems IRIS 容器

Docker 20.10.14(2022年3月23日发布)改变了赋予容器的Linux能力,其方式与InterSystems IRIS 2021.1(及以上)容器的Linux能力检查器不兼容。 在Linux上运行Docker 20.10.14的用户会发现,IRIS 2021.1+容器将无法启动,并且日志会错误地报告缺少所需的Linux能力。 比如说。 [ERROR] Required Linux capability cap_setuid is missing. [ERROR] Required Linux capability cap_dac_override is missing. [ERROR] Required Linux capability cap_fowner is missing. [ERROR] Required Linux capability cap_setgid is missing. [ERROR] Required Linux capability cap_kill is missing. [FATAL] Your IRIS container is missing one or more required Linux capabilities. 解决方案 遇到这个问题的用户需要调整传递给容器入口的命令行,以禁用对Linux功能的检查。 在命令行中,在docker run或docker start命令中的镜像后面添加--check-caps false。 例如: docker run containers.intersystems.com/intersystems/iris-community:2022.1.0.152.0 --check-caps false 如果你使用的是docker-compose,相应的改动如下: command: --check-caps false 能力检查是在启动IRIS进程之前检查常见的错误配置的一种方式。 禁用Linux能力检查对容器中运行的IRIS进程没有影响。 更多阅读 Docker 20.10.14 release notes Running InterSystems Products in Containers
公告
Tingting Jiang · 六月 21, 2022

InterSystems热招职位(4):Support Facilitator

我们正在招聘Support Facilitator,欢迎您的自荐、推荐。 请将简历投递至Belinda.Glasson@intersystems.com,愿您的加入给我们带来新的活力,我们也将为您提供广阔的发展空间!(由于岗位职能要求,职位说明以英文形式发布。) Location:Beijing Job Title:Support Facilitator Department:Product Support Reporting to:China Support Supervisor What We Do Matters Why are we here? To ensure that our customers have reliable access to the right information at the right time—information they can share and use to draw insights, leading to better decisions. Job Summary Ensure customer satisfaction by triaging support requests, facilitating rapid responses, managing the support queue, Service Level Agreements and backlog and assisting the China Support Supervisor with the coordination of projects. Key Responsibilities of the Role Provide immediate response to customer support inquiries via phone or iService (the TrakCare ticketing system) Ensure iService tickets contain sufficient information and detail for second line support to work with, according to the minimum datasets laid out Where possible, provide immediate resolution to support inquiries. Alternatively, triage the inquiry and determine the best person to pass it to Assist level 2 support staff and the Support Manager with the monitoring, maintenance, administration and processing of support queues and tickets Develop and maintain a set of Standard Operating Procedures for responding to common and/or repeatable inquiries Assist the Support Manager with adherence to Service Level Agreements Assist the Support Manager with the coordination and management of projects to deliver new functionality to existing customers Identify opportunities to act as a “multiplier” in order to drive efficiency Provide regular reports to management and customers as requested Acquire new skills by assuming additional responsibilities as requested. Additional responsibilities as determined by management. Experience and Qualifications Friendly and professional verbal and written communication skills demonstrated by prior customer service experience Good organizational skills with demonstrable attention to detail 1-2 years’ experience in a support or Project Management Office role or an administrative role in a similar organization Must be fluent in English Personal Specifications IT or health-based degree or 2 years’ related experience
公告
Tingting Jiang · 六月 21, 2022

InterSystems热门职位(1):Market Development Representative

InterSystems正在招聘Market Development Representative欢迎您的自荐、推荐。请将简历投递至:Belinda.Glasson@intersystems.com,愿您的加入给我们带来新的活力,我们也将为您提供广阔的发展空间! (由于岗位职能要求,招聘职位说明以英文形式发布。) Location:Beijing Job Title:Market Development Representative Department:Marketing Reporting to:Marketing Manager What We Do Matters Why are we here? To ensure that our customers have reliable access to the right information at the right time—information they can share and use to draw insights, leading to better decisions. Job Summary This role will suit someone who is energised by the opportunity to develop and grow enterprise software sales pipelines in Healthcare IT markets. As a Market Development Representative, you’ll be working with a smart, entrepreneurial team to shape and grow our local business. Your primary focus will be development of a high quality and growing pipeline of data platform prospects and accounts that you will nurture. You will play a pivotal role in helping the team to identify, break into, and grow named accounts. In many instances you will represent the front line of InterSystems technology engagement with significantly sized enterprise accounts and healthcare providers. Key Responsibilities of the Role Make first contact and nurture a prospect relationship into a marketing qualified lead Partner with sales and marketing to develop and conduct prospecting strategies and build and execute on named account strategies Build and execute outbound prospecting plans for targeted accounts including but not limited to emails, phone calls and industry focused event attendance Develop brand and technology champions externally across target contacts Follow up inbound enquiries and marketing-generated leads Represent and promote InterSystems at industry events Manage and be accountable for growing your pipeline using technology to engage with your prospects and to track and report on progress Provide feedback and recommendations on marketing efforts based on real front-line interactions Conduct industry research to uncover pain points, find potential sales opportunities, build account profiles Handle a variety of communication including, but not limited to, inbound calls, warm follow-ups, social media, and email campaigns Work with 3rd party outbound call partners to support the success of new campaigns and other lead generation programs if needed. Experience and Qualifications BA or BSc in business/economics, marketing or technical Five or more years' experience of business development/inside sales in B2B field Experience qualifying and selling software or other technology products over the phone Strong listening and solution selling skills Proven ability to collaborate with field sales representatives and marketing team to plan and achieve goals Excellent oral and written communication skills in Chinese and English Knowledge of standard computer application skills, such as Word, Excel, PowerPoint, and Automation/CRM. Goal oriented and self-motivated; approaches work with a passion and enthusiasm Experience requirement Development and execution of a territory plan and mutually agreed strategic account plans. Proven success and experience in leading complex enterprise sales with large implementation projects. Demonstrable experience with tender responses and bid management. Proven experience in managing senior client relationships. Ability to develop relationships with customers at all levels across the business. Able to develop and maintain internal stakeholder relationships. Discover, qualify and develop new Data Platform business opportunities. Define and execute market plans and campaigns – together with marketing. Build a pipeline of new activity for Data Platform within and outside the customer base. Maintain an in-depth understanding of the political and organisational structure of a targeted prospect. Act as the principal liaison between InterSystems and partner/ customer accounts. Personal Specifications COMMUNICATION AND INFLUENCE - Is articulate and asks good questions; gives clear, concise, and focused answers to questions; explains opinions and positions; uses empathy to persuade others; keeps key people informed; ability to communicate with diverse audiences. TEAMWORK - Ability to collaborate effectively with people of comparable talents and different strengths; handles conflict constructively; avoids being argumentative; willing to pitch in and do the mundane things that need to be done; treats people at all levels and all roles with respect. PASSION for technology and must be technically and Social Media Savvy.
文章
Jingwei Wang · 七月 14, 2022

InterSystems SQL 的使用 - 第三部分 - 表

创建表 可以通过以下方式定义表: 通过DDL定义表 使用任意数据库管理工具执行DDL(使用ODBC,JDBC连接) MyApp.Person表可以使用DDL CREATE TABLE语句来定义,指定SQL schema.table名称。成功执行这个SQL语句会生成一个相应的持久化类,包名MyApp,类名Person。当使用DDL命令定义一个表时,你不需要指定USEEXTENTSET或创建一个位图范围索引。InterSystems SQL会自动应用这些设置,并将它们包含在预测的持久化类中。默认情况下,CREATE TABLE在相应的类定义中指定了Final类的关键字,表示它不能有子类。 CREATE TABLE MyApp.Person ( Name VARCHAR(50) NOT NULL, SSN VARCHAR(15) DEFAULT 'Unknown', DateOfBirth DATE, Sex VARCHAR(1) ) 使用Objectscript执行DDL 在ObjectScript中使用 Embedded SQL. 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, returing SQLCODE " RETURN SQLCODE_" "_%msg} } 这个方法试图创建一个Sample.Employee表(以及相应的Sample.Employee类)。如果成功,SQLCODE变量被设置为0;如果不成功,SQLCODE包含一个SQL错误代码,表明失败的原因。 像这样的DDL命令,最常见的失败原因是: SQLCODE -99(特权侵犯)。这个错误表明你没有权限执行所需的DDL命令。一般来说,这是因为应用程序没有确定谁是当前用户。你可以使用$SYSTEM.Security.Login()方法以编程方式完成这个任务。 DO $SYSTEM.Security.Login(username,password) 使用 Dynamic SQL. Class Sample.NewT { ClassMethod DefTable(user As %String, pws As %String) [Language = objectscript] { Do ##class(%SYSTEM.Security).Login(user,pws) 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 qStatus = 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} } } 批量执行DDL脚本文件 使用$SYSTEM.SQL.Schema.Run()方法从终端会话中交互式地导入InterSystems SQL DDL脚本文件 使用$SYSTEM.SQL.Schema.ImportDDL("IRIS")方法作为后台作业。这个方法可以导入和执行多个SQL命令,使你能够使用一个txt脚本文件来定义表和视图,并为它们填充数据。 针对特定供应商的%SYSTEM.SQL.Schema Load方法。特定供应商的SQL被转换为InterSystems的SQL并执行。错误和不支持的功能被记录在日志文件中。例如下面的Oracle示例。 SET $namespace = "MYNAMESPACE" DO $SYSTEM.SQL.Schema.LoadOracle() 通过持久化类定义表 当编译时,这个持久化类会自动投射到一个与类定义相对应的关系表中:每个类代表一个表;每个属性代表一个列,以此类推。这个定义在MyApp schema中创建了MyApp.Person持久化类和相应的SQL表Person。持久类的名称Person被用作SQL表的名称。要提供一个不同的SQL表名,你可以使用SqlTableName类的关键字。 Class MyApp.Person Extends %Persistent { Parameter USEEXTENTSET = 1; //USEEXTENTSET 类参数被定义并设置为1,这个参数将表的存储组织成一个更有效的globals集合。 Property Name As %String(MAXLEN=50) [Required]; Property SSN As %String(MAXLEN=15) [InitialExpression = "Unknown"]; Property DateOfBirth As %Date; Property Sex As %String(MAXLEN=1); Index BitmapExtent [Extent, Type = bitmap ] //位图范围索引为范围集中的所有ID创建一个索引。这种设置使得计数和其他操作更加有效。 } 使用持久化类定义在编译时可以创建的相应的表,但是这个表定义不能使用SQL DDL命令进行修改或删除(或者使用管理门户的Drop操作),这些命令会给你提示"'schema.name'类不启用DDL...")。你必须在表类定义中指定[DdlAllowed]以允许这些操作。 Class MyApp.Person Extends %Persistent [DdlAllowed] 根据现有的表(或表或视图)来定义和填充一个新的表。 你指定一个查询和一个新的表名。现有的表名和/或新的表名可以是限定的或非限定的。查询可以包含JOIN语法。查询可以提供列名别名,成为新表中的列名。 可以使用: CREATE TABLE AS SELECT命令 CREATE TABLE Sample.YoungPeople AS SELECT Name,Age FROM Sample.People WHERE Age < 21 $SYSTEM.SQL.Schema.QueryToTable()方法执行。 DO $SYSTEM.SQL.Schema.QueryToTable("SELECT Name,Age,AVG(Age) AS AvgInit FROM Sample.Person WHERE Age < 21","Sample.Youth",1,.errors) QueryToTable()复制了现有表的DDL定义,并将其指定为新表的名称。它复制查询中指定的字段的定义,包括数据类型、最大长度和最小值/最大值,但不复制字段的数据约束,如默认值、要求值或唯一值。它不会从一个字段复制引用到另一个表中。 如果查询指定SELECT *或SELECT %ID,原始表的RowID字段将被复制为数据类型为整数的非必填、非唯一的数据字段。QueryToTable()为新表生成了一个唯一的RowID字段。如果复制的RowID被命名为ID,生成的RowID被命名为ID1。 QueryToTable()为这个新表创建一个相应的持久化类。该持久化类被定义为DdlAllowed。新表的所有者是当前用户。 新表被定义为默认存储=YES和支持位图索引=YES,不管源表中的这些设置如何。为新表创建的唯一索引是IDKEY索引,没有生成位图范围索引。被复制的字段的索引定义不会被复制到新表中。 $SYSTEM.SQL.Schema.TableExists()方法可以用来确定一个表的名字是否已经存在。 RowID 在SQL中,每条记录都由一个唯一的整数值来标识,称为RowID。 在InterSystems SQL中,你不需要指定一个RowID字段。当你创建一个表并指定所需的数据字段时,会自动创建一个RowID字段。这个RowID在内部使用,但没有被映射到一个类属性。默认情况下,只有当一个持久化类被投射到一个SQL表时,它的存在才是可见的。在这个投射表中,会出现一个额外的RowID字段。 默认情况下,这个字段被命名为 "ID "并被分配到第1列,且这个字段是自增的,不会被重复使用。因此,如果记录被插入和删除,RowID值将是升序的数字序列,但可能不是数字连续的。且ALTER TABLE不能修改或删除RowID字段的定义。RowID计数器可以通过TRUNCATE TABLE命令被重置,但它不会被DELETE命令重置,即使DELETE命令删除了表中的所有记录。如果没有数据被插入到表中,或者TRUNCATE TABLE被用来删除所有表的数据,IdLocation存储关键字的global是未定义的。 默认情况下,InterSystems IRIS将这个字段命名为 "ID",然而这个字段名并不保留。RowID字段名在每次编译表的时候都会重新建立。如果用户定义了一个名为 "ID "的字段,当表被编译时,InterSystems IRIS将RowID命名为 "ID1"。例如,如果用户随后使用ALTER TABLE来定义一个名为 "ID1 "的字段,表的编译就会将RowID重命名为 "ID2",以此类推。在一个持久化的类定义中,你可以使用SqlRowIdName类关键字来直接指定这个类所投射的表的RowID字段名。由于这些原因,应该避免用名字来引用RowID字段。 InterSystems SQL提供了%ID伪列名(别名),它总是返回RowID值,不管分配给RowID的字段名是什么。(InterSystems TSQL提供了$IDENTITY伪列名,它也做同样的事情)。 默认情况下,使用CREATE TABLE定义的表使用$SEQUENCE执行ID分配,允许多个进程同时快速填充表。当$SEQUENCE被用来填充表时,一个RowID值的序列被分配给一个进程,然后按顺序分配它们。因为并发的进程使用他们自己分配的序列来分配RowID,所以不能假设由一个以上的进程插入的记录是按照插入的顺序进行的。 当使用CREATE TABLE创建一个表时,RowID默认是隐藏的。一个隐藏的字段不会被SELECT *显示,并且是PRIVATE。当你创建一个表的时候,你可以指定%PUBLICROWID关键字来使RowID不被隐藏并且是公开的。这个可选的%PUBLICROWID关键字可以在CREATE TABLE逗号分隔的表元素列表中的任何地方指定,但不能在ALTER TABLE中指定。 当创建一个投射为表的持久化类时,RowID默认不会被隐藏。它通过SELECT *显示,并且是公共的。你可以通过指定类的关键字SqlRowIdPrivate来定义一个RowID为隐藏和PRIVATE的持久化类。 作为外键引用的RowID必须是公共的。默认情况下,一个具有公共RowID的表不能被用作源表或目标表,例如使用 INSERT INTO Sample.DupTable SELECT * FROM Sample.SrcTable 将数据复制到一个重复的表。 你可以使用管理门户SQL界面来查看RowID是否被隐藏。 基于其他字段的RowID 通过定义一个投射表的持久化类,你可以将RowID定义为来自一个字段或一个字段组合的值。要做到这一点,用IdKey索引关键字指定一个索引。例如,通过PatientName字段的值指定索引定义 IdxId On PatientName [IdKey]; 或者通过PatientName和SSN字段的合并值指定索引定义 IdxId On (PatientName,SSN) [IdKey] 但是,基于字段的RowID比采取系统分配的连续正整数的RowId效率低。 在INSERT中:为构成RowId的字段或字段组合指定的值必须是唯一的。指定一个非唯一的值会产生一个SQLCODE -119 "UNIQUE或PRIMARY KEY约束在INSERT时唯一性检查失败"。 在UPDATE中:默认情况下,组成RowId的每个字段的值是不可修改的。试图修改这些字段之一的值会产生一个SQLCODE -107 "不能UPDATE RowID或基于字段的RowID"。 当一个RowID基于多个字段时,RowID的值是由||操作符连接的每个组成字段的值。例如,Ross,Betsy||123-45-6789。InterSystems IRIS试图确定基于多个字段的RowID的最大长度;如果它不能确定最大长度,RowID长度默认为512。 主键 InterSystems IRIS提供两种方法来唯一地识别表中的行:RowID和主键。 可选的主键是一个有意义的值,应用程序可以用它来唯一地识别表中的一行(例如在连接中)。一个主键可以是用户指定的数据字段,也可以是一个以上的数据字段的组合。主键值必须是唯一的,但不要求是整数值。RowID是一个内部使用的整数值,用于识别表中的一行。通常情况下,主键是一个由应用程序生成的值,而RowID是一个由InterSystems IRIS生成的唯一整数值。 系统会自动创建一个master map来访问使用RowID字段的数据行。如果你定义了一个主键字段,系统会自动创建并维护一个主键索引。 显然,有两个不同的字段和索引来识别行,这种双重性不一定是好事。你可以通过以下两种方式中的任何一种解决单一的行标识符和索引: 使用应用程序生成的主键值作为IDKEY。你可以通过在类定义中使用关键字PrimaryKey和IdKey来识别主键索引,当然,也可以从DDL中这样做。这使得主键索引成为表的主映射。因此,主键将被用作行的主要内部地址。如果主键由一个以上的字段组成,或者主键值不是整数,这可能会降低效率。 不要使用应用程序生成的主键值,而是使用应用程序内系统生成的RowID整数作为应用程序使用的主键(例如在连接中)。这样做的好处是,整数的RowID适合于更有效的处理,包括使用位图索引。 根据应用程序的性质,你可能希望解决一个单一的行标识符和索引,或者为应用程序生成的主键和系统生成的RowID设置单独的索引。 特殊字段:RowVersion字段 , 自增字段, 和 Serial 计数器字段 InterSystems SQL支持三种特殊用途的数据类型,用于自动递增计数器的值。这三种数据类型都是扩展%Library.BigInt数据类型类的子类。 %Library.RowVersion: 计算对所有RowVersion表的插入和更新的命名空间。只有包含ROWVERSION字段的表的插入和更新才会增加这个计数器。ROWVERSION值是唯一的,不可修改的。这个全命名空间的计数器从不重置。可以通过指定一个数据类型为ROWVERSION(%Library.RowVersion)的字段来创建一个RowVersion字段。你只能在每个表中指定一个ROWVERSION数据类型字段。试图创建一个有一个以上ROWVERSION字段的表会导致5320编译错误。RowVersion字段不应该被包含在唯一键或主键中。RowVersion字段不能成为IDKey索引的一部分。 %Library.Counter(也被称为SERIAL计数器字段)。计算插入到表中的次数。默认情况下,这个字段接收一个自动递增的整数。然而,用户可以为这个字段指定一个非零的整数值。用户可以指定一个重复的值。如果用户提供的值大于系统提供的最高值,自动递增计数器被设置为从用户指定的值开始递增。这个计数器通过TRUNCATE TABLE命令被重置为1。它不会被DELETE命令重置,即使DELETE命令删除了表中的所有记录。分片的表不能有SERIAL计数器字段。 %Library.AutoIncrement: 计算插入到表中的次数。默认情况下,这个字段接收一个自动递增的整数。然而,用户可以为这个字段指定一个非零的整数值。用户可以指定一个重复的值。指定一个用户值对自动递增计数器没有影响。 所有这三个字段和IDENTITY字段都返回AUTO_INCREMENT = YES,如下面的例子所示。 查看表定义 表信息 INFORMATION.SCHEMA.TABLES持久化类显示当前命名空间中所有表(和视图)的信息。包括模式和表名,表的所有者,以及是否可以插入新记录。TABLETYPE属性表明它是一个基础表还是一个视图。 SELECT Table_Type,Table_Schema,Table_Name,Owner FROM INFORMATION_SCHEMA.TABLES INFORMATION.SCHEMA.CONSTRAINTTABLEUSAGE持久化类为当前命名空间中的每个表定义的每个主键(显性或隐性)、外键或唯一约束。 INFORMATION.SCHEMA.KEYCOLUMNUSAGE为当前命名空间中的每个表的每个已定义的约束。 也可以使用管理门户SQL界面中的目录详情来查看表信息。 列信息 GetColumn 方法 SET stat = ##class(%SYSTEM.SQL.Schema).GetAllColumns("MyApp.Person",.byname,.bynum) IF stat=1 { SET i=1 WHILE $DATA(bynum(i)) { WRITE "name is ",bynum(i), "column is ", i, ! } }ELSE{ WRITE "GetAllColumns() cannot locate specified table"} 生成结果: name is ID col num is 1 name is Age col num is 2 name is Home col num is 3 name is Name col num is 4 SQL脚本 INFORMATION_SCHEMA.COLUMNS可以列出指定schema的所有列名: 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='MyApp' ​ 或者 ​ SELECT TOP 0 * FROM tablename. Constraints信息 INFORMATION.SCHEMA.TABLECONSTRAINTS持久化类列出了表名,约束类型和约束名称。约束类型包括UNIQUE, PRIMARY KEY, 和 FOREIGN KEY。 SELECT Table_Schema,Table_Name,Constraint_Type,Constraint_Name FROMINFORMATION_SCHEMA.TABLE_CONSTRAINTS INFORMATION.SCHEMA.CONSTRAINTCOLUMNUSAGE持久化类列出了表名、列名和约束名称。如果一个约束涉及到多个列,那么每一个列都会列出一个单独的项目。 SELECT Table_Schema,Table_Name,Column_Name,Constraint_Name FROMINFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE INFORMATION.SCHEMA. REFERENTIALCONSTRAINTS持久化类列出了外键约束,包括引用表(CONSTRAINT_SCHEMA, CONSTRAINT_TABLE_NAME),被引用表(UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_TABLE),外键名称(CONSTRAINT_NAME),以及UPDATE和DELETE参考动作(UPDATE_RULE,DELETE_RULE),值为NO ACTION,SET DEFAULT,SET NULL,或CASCADE。 SELECT Constraint_Table_Name,Unique_Constraint_Table,Constraint_Name,Update_Rule,Delete_Rule FROMINFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 连接外部表 在InterSystems SQL中,你也可以有 "外部表",即在SQL字典中定义的表,但存储在一个外部关系数据库中。外部表的作用就像它们是本地的InterSystems IRIS表一样:你可以对它们发出查询,执行INSERT、UPDATE和DELETE操作。 对外部数据库的访问是由InterSystems SQL Gateway提供的,它使用ODBC或JDBC提供透明的连接。
公告
Claire Zheng · 八月 1, 2023

第二届InterSystems Idea 创意马拉松

嗨,开发者们! 我们很高兴邀请您参加Idea-A-Thon创意马拉松,展示与 InterSystems 技术相关的好创意: 🎁第二届 InterSystems Idea-A-Thon创意马拉松🎁 在8 月 1 日至8 月 21 日期间,根据本次创意马拉松的主题发布创意,即可获得即可获得创意达成奖。 最重要的是,此次赛事InterSystems的员工和社区成员都可以参与! 主题 💡使用 InterSystems IRIS 快速、安全、绿色地运行解决方案💡 该主题基于2023 年 InterSystems 全球峰会期间@Jeffrey Fried的演示而来: InterSystems IRIS 最新动态、下一步计划 如果您的创意得到实施,将提高基于 InterSystems IRIS 的解决方案的速度和可靠性,并减少碳足迹——本次Idea-A-Thon创意马拉松就是为这些好创意而来。 您的创意需要有助于: 提高解决方案的性能 减少实施所需的硬件资源 减少开发、测试、实施、用户培训的工作日 以及与Idea-A-Thon创意马拉松主题相关的其他想法。 👉 要参加我们的Idea-A-Thon创意马拉松,请在InterSystems Ideas 门户上提交创意。 合格的参赛创意应符合以下要求: 用户在Idea-A-Thon创意马拉松期间提交,由通过InterSystems Ideas网站注册的用户创建(您可以通过InterSystems SSO登录); 不要成为其他已经存在的想法的一部分——只允许提交新创意; 不要描述InterSystems产品或服务的现有功能; 除标题外,还包含对创意的详细描述以及对为什么该创意适合 Idea-A-Thon 主题,阐释需清晰明了,包含3~5句话; 以英文发布; InterSystems 专家认为该创意有意义。 所有想法都将受到审核。我们可能会要求您更详细地阐释您的创意。 符合要求的创意将获得特殊的“创意马拉松(Idea-A-Thon)”状态标记。 谁可以参加? 我们邀请所有人加入我们的创意马拉松。欢迎InterSystems员工和社区成员参与并提交创意。 奖品 1. 参与奖——所有发布合格创意的参与者都会将获得奖励 🎁 无线充电鼠标垫 2. 专家奖 ——InterSystems 专家将评选出 3 个最佳创意。获胜者将获得: 第一名- 🎁 Apple Watch SE / Fairphone Fairbuds XL 耳机 第二名- 🎁 扬声器套装 JBL Pulse 5 / Apple AirPods Pro 第二代 / 乐高星球大战 R2-D2 第三名- 🎁 乐高保时捷 911 / Beeline 自行车 GPS 电脑 - Velo 2 3. 社区奖——得票最多的创意将获得: 🎁 乐高保时捷 911 / Beeline 自行车 GPS 电脑 - Velo 2 注:InterSystems员工只能获得参与奖。专家奖和社区奖只会颁发给社区非 InterSystems 成员。 参赛时间 ⚠️ 创意提交:8 月 1 日至 21 日 ✅ 创意投票:8 月 1 日至 27 日 🎉 公布获奖者:8 月 28 日 我们鼓励您在此期间登录创意门户上分享您的想法。注册会员可以对已发布的创意进行投票、发表评论。 注意:社区奖仅计入在开发者社区发表过至少一篇帖子的活跃社区用户的投票。 所以, 来 InterSystems Ideas 门户上发布您的创意吧,并随时关注您创意的状态更新: >>在此提交您的创意<< Important note: All prizes are subject to availability and shipping options. Some items may not be available for international shipping to specific countries, in this case, an equivalent alternative will be provided. We will let you know if a prize is not available and offer a possible replacement. Prizes cannot be delivered to residents of Crimea, Russia, Belarus, Iran, North Korea, Syria, or other US-embargoed countries. 重要提示:所有奖品均视供应情况和运输情况而定。有些奖品可能无法通过国际航运到特定国家,在这种情况下,我们将提供等效的替代方案。如果没有奖品,我们会通知您,并提供备选的替代奖品。奖品不能寄给克里米亚、俄罗斯、白俄罗斯、伊朗、朝鲜、叙利亚或其他美国禁运国家的居民。
公告
jieliang liu · 五月 15, 2022

[视频]使用Python连接到InterSystems IRIS

嗨,开发者们! 看看你如何用PyODBC和Native API在Python中开发并连接到InterSystems IRIS®数据平台。 ⏯ Using Python to Connect to InterSystems IRIS 欢迎大家来我们的 Bilibili主页观看更多视频!
公告
Claire Zheng · 二月 23, 2022

【投票时间】InterSystems 开发者竞赛:Python

投票时间到! 来为你最欣赏的应用投上一票吧! 【投票时间】InterSystems 开发者竞赛:Python 🔥 为你的最爱投票 🔥 如何投票?请看以下细节。 Experts nomination(专家提名) InterSystems experts:InterSystems经验丰富的专家评审团将选出最好的应用程序,在Experts nomination(专家提名)中提名奖项。 有请InterSystems专家: ⭐️ @Benjamin.DeBoe, Product Manager⭐️ @Raj.Singh5479, Product Manager ⭐️ @Robert.Kuszewski, Product Manager⭐️ @Stefan.Wittmann, Product Manager⭐️ @Thomas.Dyar, Product Specialist⭐️ @Aleksandar.Kovacevic, Sales Engineer⭐️ @Eduard.Lebedyuk, Sales Engineer⭐️ @Sergey.Lukyanchikov, Sales Engineer⭐️ @Guillaume.Rongier7183, Sales Engineer⭐️ @Alexander.Woodhead, Technical Specialist ⭐️ @Jon.Willeke, Distinguished Quality Development Engineer⭐️ @Evgeny.Shvarov, Developer Ecosystem Manager Community nomination(社区提名) 每一个用户来说,你投出的每一票的分数,是根据下面两类中最高的分数来计: 满足条件 奖项排名 第一名 第二名 第三名 在社区发布一篇帖子,并在Open Exchange中上传一个App 9 6 3 在社区发布了至少一篇帖子 或 在Open Exchange上传了一个App 6 4 2 在社区进行了任何有效贡献,如回帖、提问、发帖等 3 2 1 等级 奖项排名 第一名 第二名 第三名 Global Masters 的 VIP 级别 或 InterSystems 产品经理 15 10 5 Global Masters 的 Ambassador级别 12 8 4 Global Masters的Expert 级别或开发者社区版主 9 6 3 Global Masters的Specialist级别 6 4 2 Global Masters的Advocate级别,或 InterSystems员工 3 2 1 Blind vote! 每个应用获得的投票数将对所有人不可见。我们会每天在这个帖子(英文原帖)的评论区发布一次排行榜。 在 竞赛页面 ,各项目将按以下进行排名:发布得越早,排名越靠前。 P.S. 不要忘记订阅本文(请订阅英文原帖),点击铃铛图标,即可收到最新评论。 在参与投票前,您需要: 登录 Open Exchange – 使用开发者社区账号即可。 在社区内进行有效贡献 ——回答问题、发帖、在Open Exchange发布新应用等等都可以,然后你的账号才可以参与投票。点击查看本帖 ,了解如何更好地成为有效的社区贡献者! 投票期间,如果你改了主意,可以随时将票改投给其他项目。 来支持你喜欢的项目吧! 注意:在投票期间,参赛者可以继续修复bug,提升应用,所以投票者不要错过最新发布的版本哦~ 排名第一了,请同学们继续努力! Voting for the InterSystems Python Contest goes ahead! And here're the results at the moment: Expert Nomination, Top 3 django-iris by @Dmitry Maslennikov appmsw-sql2xlsx by @Sergey Mikhailenko blockchain - [ IRIS python ] by @davi massaru teixeira muta ➡️ Voting is here. Community Nomination, Top 3 IRIS-Database-and-Machine-Learning-Based-Approaches-for-Prediction-of-Spontaneous-Intracerebral-Hemo by @Fatian Wu appmsw-sql2xlsx by @Sergey Mikhailenko django-iris by @Dmitry Maslennikov ➡️ Voting is here.
文章
Jingwei Wang · 七月 21, 2022

InterSystems SQL 的使用 - 第四部分 - 视图

视图为存储查询,提供了物理表的所有灵活性和安全权限。所有的视图都是可更新的或只读的。 注意:不能对只读的数据库中的数据创建视图。不能对存储在通过ODBC或JDBC网关连接的Informix表中的数据创建视图。这是因为InterSystems IRIS查询转换在FROM子句中使用子查询,而Informix不支持FROM子句的子查询。 创建视图 视图名称可以是合格的的或不合格的。一个没有限定的视图名称是一个简单的标识符。MyView。一个合格的视图名称由两个简单的标识符组成,一个schema名称和一个视图名称,用句号隔开, 例如MySchema.MyView。视图名和表名遵循相同的命名规则,并对未限定的名称执行相同的schema名称解析。同一模式中的视图和表不能有相同的名称。 你可以通过几种方式定义视图: 使用SQL CREATE VIEW命令(在DDL脚本中或通过JDBC或ODBC)。 CREATE VIEW MySchema.MyView (ViewCol1, ViewCol2, ViewCol3) AS SELECT TableCol1, TableCol2, TableCol3 FROM MyTable 使用管理门户的创建视图界面。 系统操作 -> SQL -> 操作 -> 创建视图 这将显示 "创建视图 "窗口,如图所示: schema:您可以决定将视图包含在现有schema中,或者创建一个新的schema。 视图名称:一个有效的视图名称。在同一模式中,你不能对表和视图使用相同的名称。 带检查选项:选项有READONLY、LOCAL、CASCADED。 授予视图的所有权限给_PUBLIC:如果选择了这个选项,这个选项会给所有用户执行这个视图的权限。默认是不给所有用户访问该视图的权限。 查看文本:你可以通过以下三种方式中的任何一种指定视图文本。 在 "查看文本 "区域键入一个SELECT语句。 使用查询生成器创建一个SELECT语句,然后按确定将此查询提供给视图文本区。 如果你在管理门户SQL界面左侧选择一个缓存查询名称(例如%sqlcq.USER.cls4),然后调用创建视图,这个缓存查询就会提供给视图文本区。注意,在视图文本区,你必须在保存视图文本之前用实际值替换变量引用(问号)。 使用Objectscript执行DDL ClassMethod CreateTable() As %String { &sql(CREATE VIEW Sample.VSrStaff AS SELECT Name AS Vname,Age AS Vage FROM Sample.Person WHERE Age>75) IF SQLCODE=0{ WRITE "Created a view"} ELSEIF SQLCODE=-201 { WRITE "View already exists" RETURN SQLCODE} ELSE { WRITE "Serious SQL Error, returing SQLCODE " RETURN SQLCODE_" "_%msg} } $SYSTEM.SQL.Schema.ViewExists()方法可以用来确定一个视图名称是否已经存在。 查看视图定义 视图信息 SELECT * FROM INFORMATION_SCHEMA.VIEWS 视图的依赖表 NFORMATION.SCHEMA.VIEWTABLEUSAGE持久化类显示当前命名空间中的所有视图和它们所依赖的表。 通过SQL脚本显示视图依赖表 SELECT View_Schema,View_Name, Table_Schema,Table_Name FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE 通过ObjectScript显示依赖表 SET statemt = ##class(%SQL.Statement).%New() SET cqStatus = statemt.%PrepareClassQuery("%Library.SQLCatalog","SQLViewDependsOn") IF cgStatus '= 1 { WRITE "PrepareClassQuery failed:" DO $System.Status.DisplayError(cgStatus) QUIT } SET rset = statemt.%Execute("vschema.vname") DO rset.%Display() 如果调用者没有视图所依赖的表的权限,该表及其模式将被列为NOT PRIVILEGED。这允许没有表权限的调用者确定视图所依赖的表的数量,但不能确定表的名称。 View ID: %VID InterSystems IRIS为视图或FROM子句返回的每条记录分配一个整数的视图ID(%VID)。与表的行ID号一样,这些视图的行ID号也是系统分配的、唯一的、非空的、非零的和不可修改的。这个%VID通常对用户来说是不可见的,只有在明确指定时才会返回。它作为数据类型INTEGER返回。因为%VID值是连续的整数,如果视图返回有序的数据,它们就更有意义;视图只有在与TOP子句配对时才能使用ORDER BY子句。 CREATE VIEW Sample.VSrStaff AS SELECT TOP ALL Name AS Vname,Age AS Vage FROM Sample.Person WHERE Age>75 ORDER BY Name 下面的例子返回VSrStaff视图定义的所有数据(使用SELECT *),并且还指定要返回每一行的视图ID。与表的行ID不同,视图的行ID在使用星号语法时不会显示;只有在SELECT中明确指定时才会显示。 SELECT *,%VID AS ViewID FROM Sample.VSrStaff %VID可以用来进一步限制SELECT从视图返回的行数,如下面的例子所示。 SELECT *,%VID AS ViewID FROM Sample.VSrStaff WHERE %VID BETWEEN 5 AND 10 因此,%VID可以用来代替TOP(或者作为TOP的补充)来限制查询返回的记录的数量。一般来说,TOP子句用于返回数据记录的一个小子集;%VID用于返回大部分或全部数据记录,将记录返回到小子集的中。这个功能可能很有用,特别是对于Oracle查询(%VID很容易映射到Oracle ROWNUM)。然而,用户应该意识到,与TOP相比,使用%VID有一些性能限制。 %VID不执行time-to-first-row的优化。TOP的优化是尽可能快地返回第一行数据。%VID的优化是为了尽可能快地返回完整的数据集。 如果查询指定了排序的结果,%VID不会执行有限的排序(这是由TOP执行的特殊优化)。查询首先对完整的数据集进行排序,然后使用%VID对返回的数据集进行限制。TOP是在排序前应用的,所以SELECT执行的是有限的排序,只涉及一个受限制的行子集。 为了保持对第一行的优化时间和有限的排序优化,你可以使用一个带有TOP和%VID组合的FROM子句子查询。 SELECT *,%VID AS SubQueryID FROM (SELECT TOP 10 Name,Age FROM Sample.Person WHERE Age > 75 ORDER BY Name) WHERE %VID > 4 不能对指定了%VID的查询进行并行执行,即使明确指定了%PARALLEL关键字。
公告
Claire Zheng · 九月 27, 2022

首届InterSystems Idea创意马拉松

社区成员们,大家好! 我们开心地宣布一种全新类型的比赛——寻找最聪明的创意比赛!欢迎了解: 💡 InterSystems Idea 创意马拉松 💡 在9月26日至10月16日期间提出一个与InterSystems产品和服务相关的想法,即可获得达成奖。 最重要的是,此次赛事InterSystems的员工和社区成员都可以参与! >> 点击提交你的想法吧! << 规则 InterSystems Idea创意马拉松是由InterSystems Ideas反馈门户组织的,在InterSystems Ideas反馈门户,您可以提交与我们的服务(文档、开发社区、全球大师等)相关的产品增强请求和想法,并投票选出您喜欢的。 在本次比赛中,我们邀请大家在这个门户网站上分享自己的想法,并为他人投票。 只需在 InterSystems Ideas网站 提交想法即可参赛。 合格的参赛创意应符合: 用户在Idea-A-Thon创意马拉松期间提交,由通过InterSystems Ideas网站注册的用户创建(您可以通过InterSystems SSO登录); 不要成为其他已经存在的想法的一部分——只允许新的想法; 不描述InterSystems产品或服务的现有功能; 除了标题之外,还要对观点的本质进行详细而清晰的解释; 以英文发帖; 被专家认为是有意义的。 所有符合条件的想法将在InterSystems ideas门户网站上拥有一个特殊的“Idea-A-Thon”状态,可以很容易地在Idea创意马拉松上找到。 谁可以参加? 我们邀请所有人加入我们的创意马拉松。欢迎InterSystems员工和社区成员参与并提交创意想法。 奖项 1. 参与奖 :每个发布合格想法的人都会将获得奖励: 🎁 InterSystems Branded T-Shirt 2. 专家奖:获胜者将由InterSystems专家团队选出,并将获得: 🎁 LEGO Star Wars™ R2-D2™ / BOSE Sleepbuds™ II / BOSE SoundLink Flex Bluetooth® speaker bundle 3. 社区奖:获得最多投票的创意,获奖者将获得: 🎁 LEGO Star Wars™ R2-D2™ / BOSE Sleepbuds™ II / BOSE SoundLink Flex Bluetooth® speaker bundle 重要提示:InterSystems的员工只能获得参与奖。专家奖和社区奖只能由非intersystems社区成员获得。 参赛时间 📝 9月26日 - 10月16日:创意发布、投票阶段 在此期间发布一个或几个创意。InterSystems Ideas网站的注册会员可以为发表的创意投票,这些投票将计入社区奖。 注意:越早发表你的创意,你就越有更多的时间去收集投票。 来参加吧! 来 InterSystems Ideas 发布你的创意拿大奖!时刻关注你的创意! 祝大家好运 👍 Important note: All prizes are subject to availability and shipping options. Some items may not be available to ship internationally to specific countries. Prizes cannot be delivered to residents of Crimea, Russia, Belarus, Iran, North Korea, Syria, or other US-embargoed countries. We will let you know if a prize is not available and offer a possible replacement. 重要提示:所有奖品均受可用性和运输选择。有些项目可能无法国际运输到特定国家。奖品不能发放给克里米亚、俄罗斯、白俄罗斯、伊朗、朝鲜、叙利亚或其他美国禁运国家的居民。如果没有奖品,我们将告知您,并提供可替代品。
公告
Claire Zheng · 十一月 17, 2022

创意社区新闻摘要 | InterSystems Ideas News!

Hi 开发者社区的成员们,大家好! 欢迎关注我们第一期 InterSystems Ideas News! 最重要的消息是我们第一次非常成功的 创意马拉松。我们收到了75个有趣的新想法。 以下是创意社区(Ideas Portal)一些数据: ✓ 上月,我们收到了42条新创意✓ 上月,我们迎来了147位新用户✓ 迄今为止,我们共收到142 条新创意✓ 迄今为止,共有 273 位用户加入我们 以下是评选出来的当月最佳创意的前5名: IRIS and ZPM(Open Exchange) integration Move users, roles, resources, user tasks, Mappings (etc) to a seperate Database, other than %SYS, so these items can be mirrored RPMShare - Database solution for remote patient monitoring (RPM) datasets of high density vitals Create front-end package based on CSS and JS to be used in NodeJS and Angular projects PM platform 这里是上个月发布的所有想法的列表 目前就这些啦! 访问我们的 InterSystems Ideas portal(创意社区),提出你的观点,为你认同的创意投票! 下期见!
公告
jieliang liu · 九月 2, 2021

InterSystems公司合作伙伴名录已经推出!

开发者们好! 我们很高兴地宣布推出InterSystems公司的合作伙伴名录! 这里是寻找基于InterSystems产品的商业服务 和 解决方案 的地方。 为什么选择InterSystems合作伙伴目录? 每天,我们都会收到类似这样的问题: 是否有任何基于InterSystems技术的ERP解决方案? 我住在瑞典,我怎样才能得到InterSystems的培训? InterSystems在法国是否有任何实施伙伴? 无论我们的客户是在寻找建立解决方案的帮助,还是在寻找可信赖的咨询来源,还是在寻找实施项目的帮助,或者是寻找一些额外的培训,他们都可以通过合作伙伴名录来与适合他们的公司建立关系。 如果你的公司是InterSystems的合作伙伴,并且提供: 与InterSystems技术有关的实施、咨询或培训服务, 和使用InterSystems产品构建的解决方案。 我们欢迎你加入合作伙伴目录. 欢迎访问并与你的同事分享!
文章
Michael Lei · 五月 20, 2022

InterSystems IRIS REST API应用程序模式

本文向你推荐一些使用IRIS创建REST API应用程序的模式。 注:所有源代码在https://github.com/yurimarx/movie 类模式到REST应用 首先,请看我对创建IRIS API应用程序所需类的建议: IRISRESTApplication: CSP.REST 类会作为中央控制者来控制业务服务处理的所有REST请求和响应. BusinessService: 具有业务主题的类实现。它可以使用一个或多个持久化域类来持久化和查询业务主题要求的数据。 Persistent Domain: 管理SQL表的持久化类. 环境准备 VSCode; Docker Desktop; InterSystems ObjectScript Extension Pack. 示例应用的类图 我将创建一个电影目录应用程序来演示文章中建议的模式: Note: 感谢IRIS API 模版应用 https://openexchange.intersystems.com/package/iris-rest-api-template . 这是本教程的基础. 搭建样本应用 1. 在你的文件系统中创建一个movie文件夹。在一个新的VSCode窗口中打开这个文件夹。 2. 在movie 文件夹中创建 Dockerfile 文件来在Docker container实例中运行IRIS社区版. 内容: Docker file content ARG IMAGE=intersystemsdc/iris-community:2020.3.0.221.0-zpm ARG IMAGE=intersystemsdc/iris-community:2020.4.0.524.0-zpm ARG IMAGE=intersystemsdc/iris-community FROM $IMAGE USER root WORKDIR /opt/irisapp RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp USER ${ISC_PACKAGE_MGRUSER} COPY src src COPY module.xml module.xml COPY iris.script /tmp/iris.script RUN iris start IRIS \ && iris session IRIS < /tmp/iris.script \ && iris stop IRIS quietly 3. 在movie 文件夹中创建 docker-compose.yml 文件来让你同时运行你的docker 和其他实例 (不在本例子中, 但是从docker-compose而不是 dockerfile运行是很好的习惯。内容: Docker composer content version: '3.6' services: iris: build: context: . dockerfile: Dockerfile restart: always ports: - 51773 - 1972:1972 - 52773:52773 - 53773 volumes: - ./:/irisdev/app 4. 在movie文件夹中创建iris.script文件,在运行IRIS之前做一些操作。这个文件对于做应用程序所需的自定义终端操作非常重要,比如禁用密码过期。内容: iris.script content ;do $System.OBJ.LoadDir("/opt/irisapp/src","ck",,1) zn "%SYS" Do ##class(Security.Users).UnExpireUserPasswords("*") zn "USER" zpm "load /opt/irisapp/ -v":1:1 halt 5. 在movie文件夹中创建module.xml文件,使用ZPM安装和运行你的应用程序。这个文件对于应用程序的端点配置和安装swagger-ui(用于使用swagger文件运行和测试你的API的web应用程序)非常重要。内容: Module.xml content <?xml version="1.0" encoding="UTF-8"?> <Export generator="Cache" version="25"> <Document name="movie.ZPM"> <Module> <Name>movie</Name> <Version>1.0.0</Version> <Packaging>module</Packaging> <SourcesRoot>src</SourcesRoot> <Resource Name="dc.movie.PKG"/> <Dependencies> <ModuleReference> <Name>swagger-ui</Name> <Version>1.*.*</Version> </ModuleReference> </Dependencies> <CSPApplication Url="/movie-api" DispatchClass="dc.movie.MovieRESTApp" MatchRoles=":{$dbrole}" PasswordAuthEnabled="1" UnauthenticatedEnabled="0" Recurse="1" UseCookies="2" CookiePath="/movie-api" /> </Module> </Document> </Export> You can see CSPApplication tag, used to run the application API in the /movie-api URI and enable or disable password to consume the API. 6. 在movie文件夹中创建LICENSE文件,设置你的应用程序的许可证。内容: LICENSE content MIT License Copyright (c) 2019 InterSystems Developer Community Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 7. 在movie文件夹中创建README.md文件,用markdown语言向用户记录你的应用程序。: ## movie-rest-application This is a sample of a REST API application built with ObjectScript in InterSystems IRIS. 8. 在movie文件夹内创建.vscode文件夹。在.vscode文件夹中创建settings.json文件,以配置VSCode和你的IRIS实例之间的服务器连接。内容: Settings content { "files.associations": { "Dockerfile*": "dockerfile", "iris.script": "objectscript" }, "objectscript.conn" :{ "ns": "USER", "username": "_SYSTEM", "password": "SYS", "docker-compose": { "service": "iris", "internalPort": 52773 }, "active": true }, "sqltools.connections": [ { "namespace": "USER", "connectionMethod": "Server and Port", "showSystem": false, "previewLimit": 50, "server": "localhost", "port": 32770, "askForPassword": false, "driver": "InterSystems IRIS", "name": "objectscript-docker", "username": "_SYSTEM", "password": "SYS" } ] } 9. 在movie文件夹内创建src文件夹,放置你的源代码文件夹和文件。 10. 在src文件夹内创建dc文件夹。当你建立项目到InterSystems开发者社区时,这是个传统,否则就没有必要。 11. 在dc文件夹内创建movie文件夹。这个文件夹将是你的objectscript类的文件夹。 12. 在 src\dc\movie 文件夹中创建我们的第一个类,MovieRESTApp.cls 文件。这个文件将是IRISRESTApplication类。内容: MovieRESTApp content Class dc.movie.MovieRESTApp Extends %CSP.REST { Parameter CHARSET = "utf-8"; Parameter CONVERTINPUTSTREAM = 1; Parameter CONTENTTYPE = "application/json"; Parameter Version = "1.0.0"; Parameter HandleCorsRequest = 1; XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <!-- Server Info --> <Route Url="/" Method="GET" Call="GetInfo" Cors="true"/> <!-- Swagger specs --> <Route Url="/_spec" Method="GET" Call="SwaggerSpec" /> </Routes> } ClassMethod %ProcessResult(pStatus As %Status = {$$$OK}, pResult As %DynamicObject = "") As %Status [ Internal ] { #dim %response As %CSP.Response SET tSC = $$$OK IF $$$ISERR(pStatus) { SET %response.Status = 500 SET tSC = ..StatusToJSON(pStatus, .tJSON) IF $isobject(tJSON) { SET pResult = tJSON } ELSE { SET pResult = { "errors": [ { "error": "Unknown error parsing status code" } ] } } } ELSEIF pStatus=1 { IF '$isobject(pResult){ SET pResult = { } } } ELSE { SET %response.Status = pStatus SET error = $PIECE(pStatus, " ", 2, *) SET pResult = { "error": (error) } } IF pResult.%Extends("%Library.DynamicAbstractObject") { WRITE pResult.%ToJSON() } ELSEIF pResult.%Extends("%JSON.Adaptor") { DO pResult.%JSONExport() } ELSEIF pResult.%Extends("%Stream.Object") { DO pResult.OutputToDevice() } QUIT tSC } ClassMethod SwaggerSpec() As %Status { Set tSC = ##class(%REST.API).GetWebRESTApplication($NAMESPACE, %request.Application, .swagger) Do swagger.info.%Remove("x-ISC_Namespace") Set swagger.basePath = "/movie-api" Set swagger.info.title = "Movie API" Set swagger.info.version = "1.0" Set swagger.host = "localhost:52773" Return ..%ProcessResult($$$OK, swagger) } } 注1:该类扩展了CSP.REST,以作为REST Endpoint使用。 注2:参数chaset是用来对请求和响应进行UTF-8编码的。 注3:CONVERTINPUTSTREAM用于强制要求的内容为UTF-8,如果没有这个参数,你可能会遇到特殊拉丁字母的问题。 注4:CONTENTTYPE用于使用JSON而不是XML声明内容。 注5:HandleCorsRequest = 1是必要的,它允许你从不同于IRIS服务器的其他服务器上消费API。 注意 6: Routes用于声明每个类方法的API URI。 注7:CSP.REST类的SwaggerSpec允许你生成API swagger(API网络文档)内容。 现在你有以下的文件夹和文件: 13. 打开VSCode终端 (menu Terminal > New Terminal) 并键入: docker-compose up -d --build 这样就建立一个docker示例并运行。 14. 用Swagger-UI测试API。打开浏览器键入: http://localhost:52773/swagger-ui/index.html. 注意地址栏。 在VSCode和 IRIS 之间建立联系 1. 点击ObjectScript 栏 ( VSCode footer) 2. 在顶部选择Toogle 链接: 3. 在ObjectScript Explorer里检查链接状态 (你能看到文件夹和创建的类): Movie 目录应用的持久化类 在这个部分我们会创立持久化域的类来存储和查询业务数据.查看DBeaver图: 1. 在src\dc\movie 目录内创建文件folder模型. 2. 在model目录内创建Actor.cls 文件. 写以下内容: Class dc.movie.model.Actor Extends (%Persistent, %JSON.Adaptor) { Parameter %JSONREFERENCE = "ID"; Property actorId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ]; Property name As %VarString(MAXLEN = 120); Property dob As %Date; Property genre As %Integer(VALUELIST = ",1,2"); } 3. 在model 目录内创建 Movie.cls 文件,写内容: Class dc.movie.model.Movie Extends (%Persistent, %JSON.Adaptor) { Parameter %JSONREFERENCE = "ID"; Property movieId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ]; Property name As %VarString(MAXLEN = 120); Property releaseDate As %Date; Property duration As %Integer; Property imdb As %String(MAXLEN = 300); Property movieCategory As dc.movie.model.MovieCategory; ForeignKey MovieCategoryFK(movieCategory) References dc.movie.model.MovieCategory(); } 4. 在model 目录内创建MovieCategory.cls 文件. 写下如下内容: Class dc.movie.model.MovieCategory Extends (%Persistent, %JSON.Adaptor) { Parameter %JSONREFERENCE = "ID"; Property movieCategoryId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ]; Property name As %VarString(MAXLEN = 120); } 5. 在model 目录内创建Casting.cls 文件. 写下如下内容: Class dc.movie.model.Casting Extends (%Persistent, %JSON.Adaptor) { Parameter %JSONREFERENCE = "ID"; Property castingId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ]; Property movie As dc.movie.model.Movie; ForeignKey MovieFK(movie) References dc.movie.model.Movie(); Property actor As dc.movie.model.Actor; ForeignKey ActorFK(actor) References dc.movie.model.Actor(); Property characterName As %String(MAXLEN = 100); Index CastingIndex On (movie, actor) [ Unique ]; } 查看创建的文件: 注1: 参数 %JSONREFERENCE = "ID" 允许在JSON回复内返回ID 值. 注2: 属性actorId 作为 %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ] 和一些其他的类似的属性被用来返回class+id 到 JSON响应中去. 注3: (VALUELIST = "1,2") 设置可能的值到1或者 2。 注4: 外健 MovieFK(movie) 参考 dc.movie.model.Movie() 和类似的用来创建SQL 外键参照. 注5: 在 (movie, actor) [ Unique ]上建立索引CastingIndex和类似的用来不允许在合并On (movie 和 actor)时重复值 注6: 我使用 Camel Case 做属性名称因为这是JSON属性命名的最佳实践. 业务服务类到Classes to the Movie Catalog Application 在本节中,我们将创建具有业务逻辑的类(做持久性、查询和计算的方法)。 1. 在src/dc/movie中创建服务文件夹。 2. 在服务文件夹中创建CrudUtilService.cls文件。写下内容: CrudUtilService content Class dc.movie.service.CrudUtilService Extends %CSP.REST { Parameter CHARSET = "utf-8"; Parameter CONVERTINPUTSTREAM = 1; Parameter CONTENTTYPE = "application/json"; Parameter Version = "1.0.0"; Parameter HandleCorsRequest = 1; /// Return all the records ClassMethod GetAll(DomainClass As %Persistent) As %Status { #dim tSC As %Status = $$$OK Set rset = DomainClass.ExtentFunc() Set %response.ContentType = ..#CONTENTTYPEJSON Set %response.Headers("Access-Control-Allow-Origin")="*" Write "[" if rset.%Next() { Set actor = DomainClass.%OpenId(rset.ID) Do actor.%JSONExport() } While rset.%Next() { Write "," Set actor = DomainClass.%OpenId(rset.ID) Do actor.%JSONExport() } Write "]" Quit tSC } /// Return one record ClassMethod GetOne(DomainClass As %Persistent, id As %Integer) As %Status { #dim tSC As %Status = $$$OK #dim e As %Exception.AbstractException #; Set the response header to plain text Set %response.ContentType = ..#CONTENTTYPEJSON Set %response.Headers("Access-Control-Allow-Origin")="*" Set domain = DomainClass.%OpenId(id) If '$IsObject(domain) Quit ..Http404() Do domain.%JSONExport() Quit tSC } /// Creates a new record ClassMethod Create(DomainClass As %Persistent) As %Status { #dim tSC As %Status = $$$OK #dim e As %Exception.AbstractException Set domain = DomainClass.%New() Set data = {}.%FromJSON(%request.Content) $$$TOE(tSC, domain.%JSONImport(data)) $$$TOE(tSC, domain.%Save()) Write domain.%JSONExport() Set %response.Status = 204 Set %response.ContentType = ..#CONTENTTYPEJSON Set %response.Headers("Access-Control-Allow-Origin")="*" Quit tSC } /// Update a record with id ClassMethod Update(DomainClass As %Persistent, id As %Integer) As %Status { #dim tSC As %Status = $$$OK #dim e As %Exception.AbstractException Set domain = DomainClass.%OpenId(id) If '$IsObject(domain) Return ..Http404() Set data = {}.%FromJSON(%request.Content) $$$TOE(tSC, domain.%JSONImport(data)) $$$TOE(tSC, domain.%Save()) Write domain.%JSONExport() Set %response.Status = 200 Set %response.ContentType = ..#CONTENTTYPEJSON Set %response.Headers("Access-Control-Allow-Origin")="*" Quit tSC } /// Delete a record with id ClassMethod Delete(DomainClass As %Persistent, id As %Integer) As %Status { #dim tSC As %Status = $$$OK #dim e As %Exception.AbstractException Set domain = DomainClass.%OpenId(id) If '$IsObject(domain) Return ..Http404() $$$TOE(tSC, domain.%DeleteId(id)) Set %response.Status = 200 Set %response.ContentType = ..#CONTENTTYPEJSON Set %response.Headers("Access-Control-Allow-Origin")="*" Quit tSC } } 3. 在服务文件夹中创建MovieService.cls文件。编写内容: MovieService content Class dc.movie.service.MovieService Extends %CSP.REST { ClassMethod GetAll() As %Status { Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.Movie).%New()) } ClassMethod GetOne(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.Movie).%New(), id) } ClassMethod Create() As %Status { Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.Movie).%New()) } ClassMethod Update(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.Movie).%New(), id) } ClassMethod Delete(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.Movie).%New(), id) } /// Return casting from the movie ClassMethod GetMovieCasting(id As %Integer) As %Status { #dim tSC As %Status = $$$OK Set qry = "SELECT actor->name AS actorName, characterName, movie->name AS movieName FROM dc_movie_model.Casting WHERE movie = ?" Set tStatement = ##class(%SQL.Statement).%New() Set qStatus = tStatement.%Prepare(qry) If tSC'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT} Set rset = tStatement.%Execute(id) Set %response.ContentType = ..#CONTENTTYPEJSON Set %response.Headers("Access-Control-Allow-Origin")="*" Set result = [] While rset.%Next() { Set item = {} Set item.actorName = rset.actorName Set item.movieName = rset.movieName Set item.characterName = rset.characterName Do result.%Push(item) } Write result.%ToJSON() Quit tSC } } 4. 在服务文件夹中创建MovieCategoryService.cls文件。编写内容: MovieCategoryService content Class dc.movie.service.MovieCategoryService { ClassMethod GetAll() As %Status { Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.MovieCategory).%New()) } ClassMethod GetOne(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.MovieCategory).%New(), id) } ClassMethod Create() As %Status { Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.MovieCategory).%New()) } ClassMethod Update(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.MovieCategory).%New(), id) } ClassMethod Delete(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.MovieCategory).%New(), id) } } 5. 在服务文件夹中创建ActorService.cls文件。编写内容: ActorService content Class dc.movie.service.ActorService { ClassMethod GetAll() As %Status { Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.Actor).%New()) } ClassMethod GetOne(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.Actor).%New(), id) } ClassMethod Create() As %Status { Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.Actor).%New()) } ClassMethod Update(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.Actor).%New(), id) } ClassMethod Delete(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.Actor).%New(), id) } } 6. 在服务文件夹中创建CastingService.cls文件。编写内容: CastingService content Class dc.movie.service.CastingService { ClassMethod GetAll() As %Status { Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.Casting).%New()) } ClassMethod GetOne(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.Casting).%New(), id) } ClassMethod Create() As %Status { Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.Casting).%New()) } ClassMethod Update(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.Casting).%New(), id) } ClassMethod Delete(id As %Integer) As %Status { Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.Casting).%New(), id) } } 7. 更新MovieRESTApp.cls文件,创建所有新服务类方法的路径。编写内容: MovieRESTApp updated content Class dc.movie.MovieRESTApp Extends %CSP.REST { Parameter CHARSET = "utf-8"; Parameter CONVERTINPUTSTREAM = 1; Parameter CONTENTTYPE = "application/json"; Parameter Version = "1.0.0"; Parameter HandleCorsRequest = 1; XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <!-- Server Info --> <Route Url="/" Method="GET" Call="GetInfo" Cors="true"/> <!-- Swagger specs --> <Route Url="/_spec" Method="GET" Call="SwaggerSpec" /> <!-- List all movies --> <Route Url="/movies" Method="GET" Call="GetAllMovies" /> <!-- Get a movie --> <Route Url="/movies/:id" Method="GET" Call="GetMovie" /> <!-- Get the movie casting --> <Route Url="/movies/casting/:id" Method="GET" Call="GetMovieCasting" /> <!-- Create new movie --> <Route Url="/movies" Method="POST" Call="CreateMovie" /> <!-- Update a movie --> <Route Url="/movies/:id" Method="PUT" Call="UpdateMovie" /> <!-- Delete a movie --> <Route Url="/movies/:id" Method="DELETE" Call="DeleteMovie" /> <!-- List all movie categories --> <Route Url="/categories" Method="GET" Call="GetAllMovieCategories" /> <!-- Get a movie category --> <Route Url="/categories/:id" Method="GET" Call="GetMovieCategory" /> <!-- Create new movie category --> <Route Url="/categories" Method="POST" Call="CreateMovieCategory" /> <!-- Update a movie category --> <Route Url="/categories/:id" Method="PUT" Call="UpdateMovieCategory" /> <!-- Delete a movie category --> <Route Url="/categories/:id" Method="DELETE" Call="DeleteMovieCategory" /> <!-- List all actors --> <Route Url="/actors" Method="GET" Call="GetAllActors" /> <!-- Get a actor --> <Route Url="/actors/:id" Method="GET" Call="GetActor" /> <!-- Create new actor --> <Route Url="/actors" Method="POST" Call="CreateActor" /> <!-- Update a actor --> <Route Url="/actors/:id" Method="PUT" Call="UpdateActor" /> <!-- Delete a actor --> <Route Url="/actors/:id" Method="DELETE" Call="DeleteActor" /> <!-- List all castings --> <Route Url="/castings" Method="GET" Call="GetAllCastings" /> <!-- Get a actor --> <Route Url="/castings/:id" Method="GET" Call="GetCasting" /> <!-- Create new actor --> <Route Url="/castings" Method="POST" Call="CreateCasting" /> <!-- Update a actor --> <Route Url="/castings/:id" Method="PUT" Call="UpdateCasting" /> <!-- Delete a actor --> <Route Url="/castings/:id" Method="DELETE" Call="DeleteCasting" /> </Routes> } /// List movies ClassMethod GetAllMovies() As %Status { Return ##class(dc.movie.service.MovieService).GetAll() } /// Get movie casting ClassMethod GetMovieCasting(id As %Integer) As %Status { Return ##class(dc.movie.service.MovieService).GetMovieCasting(id) } /// Get a movie ClassMethod GetMovie(id As %Integer) As %Status { Return ##class(dc.movie.service.MovieService).GetOne(id) } // Create a new movie ClassMethod CreateMovie() As %Status { Return ##class(dc.movie.service.MovieService).Create() } // Update a movie ClassMethod UpdateMovie(id As %Integer) As %Status { Return ##class(dc.movie.service.MovieService).Update(id) } // Delete a movie ClassMethod DeleteMovie(id As %Integer) As %Status { Return ##class(dc.movie.service.MovieService).Delete(id) } /// List movies categories ClassMethod GetAllMovieCategories() As %Status { Return ##class(dc.movie.service.MovieCategoryService).GetAll() } /// Get a movie category ClassMethod GetMovieCategory(id As %Integer) As %Status { Return ##class(dc.movie.service.MovieCategoryService).GetOne(id) } // Create a new movie category ClassMethod CreateMovieCategory() As %Status { Return ##class(dc.movie.service.MovieCategoryService).Create() } // Update a movie category ClassMethod UpdateMovieCategory(id As %Integer) As %Status { Return ##class(dc.movie.service.MovieCategoryService).Update(id) } // Delete a movie category ClassMethod DeleteMovieCategory(id As %Integer) As %Status { Return ##class(dc.movie.service.MovieCategoryService).Delete(id) } /// List actors ClassMethod GetAllActors() As %Status { Return ##class(dc.movie.service.TestActorService).GetAll() } /// Get an actor ClassMethod GetActor(id As %Integer) As %Status { Return ##class(dc.movie.service.ActorService).GetOne(id) } // Create a new actor ClassMethod CreateActor() As %Status { Return ##class(dc.movie.service.ActorService).Create() } // Update an actor ClassMethod UpdateActor(id As %Integer) As %Status { Return ##class(dc.movie.service.ActorService).Update(id) } // Delete an actor ClassMethod DeleteActor(id As %Integer) As %Status { Return ##class(dc.movie.service.ActorService).Delete(id) } /// List castings ClassMethod GetAllCastings() As %Status { Return ##class(dc.movie.service.CastingService).GetAll() } /// Get a casting ClassMethod GetCasting(id As %Integer) As %Status { Return ##class(dc.movie.service.CastingService).GetOne(id) } // Create a new casting item ClassMethod CreateCasting() As %Status { Return ##class(dc.movie.service.CastingService).Create() } // Update a casting ClassMethod UpdateCasting(id As %Integer) As %Status { Return ##class(dc.movie.service.CastingService).Update(id) } // Delete a casting ClassMethod DeleteCasting(id As %Integer) As %Status { Return ##class(dc.movie.service.CastingService).Delete(id) } /// General information ClassMethod GetInfo() As %Status { SET version = ..#Version SET fmt=##class(%SYS.NLS.Format).%New("ptbw") SET info = { "Service": "Movie API", "version": (version), "Developer": "Yuri Gomes", "Status": "Ok", "Date": ($ZDATETIME($HOROLOG)) } Set %response.ContentType = ..#CONTENTTYPEJSON Set %response.Headers("Access-Control-Allow-Origin")="*" Write info.%ToJSON() Quit $$$OK } ClassMethod %ProcessResult(pStatus As %Status = {$$$OK}, pResult As %DynamicObject = "") As %Status [ Internal ] { #dim %response As %CSP.Response SET tSC = $$$OK IF $$$ISERR(pStatus) { SET %response.Status = 500 SET tSC = ..StatusToJSON(pStatus, .tJSON) IF $isobject(tJSON) { SET pResult = tJSON } ELSE { SET pResult = { "errors": [ { "error": "Unknown error parsing status code" } ] } } } ELSEIF pStatus=1 { IF '$isobject(pResult){ SET pResult = { } } } ELSE { SET %response.Status = pStatus SET error = $PIECE(pStatus, " ", 2, *) SET pResult = { "error": (error) } } IF pResult.%Extends("%Library.DynamicAbstractObject") { WRITE pResult.%ToJSON() } ELSEIF pResult.%Extends("%JSON.Adaptor") { DO pResult.%JSONExport() } ELSEIF pResult.%Extends("%Stream.Object") { DO pResult.OutputToDevice() } QUIT tSC } ClassMethod SwaggerSpec() As %Status { Set tSC = ##class(%REST.API).GetWebRESTApplication($NAMESPACE, %request.Application, .swagger) Do swagger.info.%Remove("x-ISC_Namespace") Set swagger.basePath = "/movie-api" Set swagger.info.title = "Movie API" Set swagger.info.version = "1.0" Set swagger.host = "localhost:52773" Return ..%ProcessResult($$$OK, swagger) } } 8. 最终项目的文件和文件夹是: 9. 访问 http://localhost:52773/swagger-ui/index.html测试你的新方法 注 1: REST路径是以/id为复数的业务主题,当我们需要将id传递给Camel 和Case的情况下,将路径传递到. 注 2: 我们使用动词GET进行查询,POST用于新记录,PUT用于更新记录,DELETE用于删除记录。 注 3: 在<Route Url="/movies/casting/:id" Method="GET" Call="GetMovieCasting" /> 我使用/casting表示第二个目的(获得Movie和Casting)。这个方法运行ToJSON(),因为它是一个动态数组([])和动态项目({})。 注 4: 我创建了 CrudUtilService ,遵循 "避免重复 "的原则,做通用CRUD方法的小工具。 谢谢观赏!
公告
Michael Lei · 八月 17, 2023

InterSystems 支持的平台更新 Q3-2023

我们经常收到有关 InterSystems IRIS 数据平台支持的平台和框架列表最近和即将发生的更改的问题。此更新旨在分享最近的变化以及我们对即将发生的变化的当前最佳知识,但预测未来是一件棘手的事情,这不应被视为承诺的路线图。 话虽如此,接下来是更新…… IRIS 生产环境操作系统和 CPU 架构 红帽Linux企业版RHEL 近期变动 RHEL 9.2 和 RHEL 8.8 于 2023 年 5 月发布。红帽计划为这些版本提供 4 年支持。 InterSystems 已通过我们称为“次要操作系统版本认证”的新流程完成了对 RHEL 9.2 和 RHEL 8.8 上的 IRIS 的额外测试,该流程旨在提供额外的安全性,确保次要操作系统更新不会破坏任何明显的功能。 RHEL 8.8 和 9.2 都成功通过了我们的测试。 随着 RHEL 9.2 的发布,红帽终止了对 RHEL 9.1 的公开支持。这与 Red Hat 自 RHEL 8.3 以来一直使用的“奇/偶”支持周期一致。 即将发生的变化 RHEL 9.3 计划于今年晚些时候推出。这将是 Red Hat 的短期支持版本,因此 InterSystems 不会执行次要操作系统认证或推荐将其用于生产部署。 之前的更新 IRIS 2022.1.2 添加了对RHEL 9.0的支持。 9.0 是一个主要操作系统版本,将 Linux 内核更新到 5.14、OpenSSL 更新到 3.0 以及 Python 3.9 IRIS 2022.2.0 删除了对 RHEL 7.x 的支持。早期版本的 IRIS 仍支持 RHEL 7.9。 进一步阅读: RHEL 发布页面 Ubuntu 近期变动 Ubuntu 分别于 2 月和 3 月发布了 22.04.2 LTS 和 20.04.6 LTS。 InterSystems 已通过次要操作系统版本认证,在 22.04.02 LTS 上完成了对 IRIS 的额外测试。 即将发生的变化 Ubuntu 的下一个主要更新是 24.04,预计将于 2024 年 4 月发布 之前的更新 IRIS 2022.1.1 添加了对Ubuntu 22.04 的支持。 22.04 是一个主要操作系统版本,将 Linux 内核更新到 5.15、OpenSSL 更新到 3.0.2 以及 Python 3.10.6 IRIS 2022.2.0 删除了对 Ubuntu 18.04 的支持。早期版本的 IRIS 仍支持 Ubuntu 18.04。 IRIS 2022.1.1 及更高版本容器基于 Ubuntu 22.04。 进一步阅读: Ubuntu 发布页面 SUSE Linux 即将发生的变化 SUSE Linux Enterprise Server 15 SP5 于 2023 年 6 月 20 日发布。SP5 包括 Linux Kernel 5.14.21、OpenSSL 3.0.8 和 Python 3.11。我们目前正在致力于次要操作系统认证。 之前的更新 IRIS 2022.3.0 添加了对SUSE Linux Enterprise Server 15 SP4的支持。 15 SP4 是一个主要操作系统版本,将 Linux 内核更新到 5.14、OpenSSL 更新到 3.0 以及 Python 3.9 SUSE 对 Linux Enterprise Server 15 SP3 的一般支持已于 2022 年 12 月 31 日结束,但扩展安全支持将持续到 2025 年 12 月。 延伸阅读: SUSE 生命周期 甲骨文Linux 即将发生的变化 Oracle 与 RHEL 9.2 几乎同时发布了 Oracle Linux 9.2,这让我们感到惊讶。我们目前正在开始次要操作系统认证。 之前的更新 IRIS 2022.3.0 增加了对Oracle Linux 9的支持。 Oracle Linux 9 是跟踪 RHEL 9 的主要操作系统版本,因此它也将 Linux 内核更新到 5.14、OpenSSL 更新到 3.0 以及 Python 3.9 进一步阅读: Oracle Linux 支持政策 微软Windows 即将发生的变化 Windows Server 2012 将于 2023 年 10 月结束扩展支持。如果您仍在该平台上运行,那么现在是计划迁移的时候了。 IRIS 2023.2+ 将不适用于Windows Server 2012。 之前的更新 自 IRIS 2022.1 中添加 Windows Server 2022 以来,我们没有对支持的 Windows 版本列表进行任何更改 延伸阅读: 微软生命周期 AIX 即将发生的变化 InterSystems 正在与 IBM 密切合作,增加对 OpenSSL 3.0 的支持。这不会包含在 IRIS 2023.2.0 中,因为 IBM 需要在进一步的 TL 版本中针对该功能。好消息是,IBM 正在寻求针对 AIX 7.2 和 7.3 发布 OpenSSL 3.0,而且时间看起来应该与 IRIS 2023.3 一致。 之前的更新 自 IRIS 2022.1 中添加 AIX 7.3 并删除 7.1 以来,我们没有对支持的 AIX 版本列表进行任何更改 延伸阅读: AIX 生命周期 容器Container 即将发生的变化 IRIS 容器将仅标记年份和版本,例如“2023.2”,而不是我们过去使用的完整版本号。这样,您的应用程序就可以默认获取您版本的最新维护版本。 我们还为最新的扩展维护和持续分发 IRIS 版本添加了“latest-em”和“latest-cd”标签。这些对于演示、示例和开发环境很有用。 我们还将开始使用“-preview”标记预览容器,以便清楚哪个容器是最新的 GA 版本。 之前的更新 我们现在正在发布 IRIS 容器的多架构清单。这意味着拉取标记为2022.3.0.606.0的 IRIS 容器将为您的计算机的 CPU 架构(Intel/AMD 或 ARM)下载正确的容器。 IRIS 开发环境操作系统和 CPU 架构 苹果系统 近期变动 我们在 IRIS 2023.1 中添加了对 MacOS 13 的支持 即将发生的变化 Apple 预计 MacOS 14 将于 9 月发布 GA,随后可能会在 IRIS 2024.1 中提供 IRIS 支持 CentOS 自 IRIS 2023.3 起,我们将取消对 CentOS/CentOS Stream 的支持。 红帽多年来一直在运行开发人员计划,该计划使开发人员能够获得非生产环境的免费许可证。鼓励当前使用 CentOS 的开发人员通过此计划切换到 RHEL。 CentOS Stream 现在是 RHEL 的“上游”,这意味着它具有 RHEL 中尚未包含的错误和功能。它还每天更新,这可能会给在平台上构建的开发人员带来问题(更不用说我们自己的测试人员了)。 自从我们在 IRIS 2022.1 中添加了对 CentOS 8-Stream 的支持并删除了对 CentOS 7.9 的支持以来,我们没有对受支持的 CentOS 版本列表进行任何更改 InterSystems组件 InterSystems Kubernetes 运营管理器 (IKO) IKO 3.6 于上周发布。 Caché & Ensemble 生产操作系统和 CPU 架构 之前的更新 Cache 2018.1.7 增加对 Windows 11 的支持 InterSystems 支持的平台文档 InterSystems 支持的平台文档是有关受支持技术的权威源信息。 IRIS 2023.1 支持的服务器平台 IRIS 2022.1 支持的服务器平台 IRIS 2021.1 支持的服务器平台 Caché & Ensemble 2018.1.7 支持的服务器平台 以上是全部。再次提醒大家,如果您还想了解更多信息,请告诉我们。
公告
Michael Lei · 九月 13, 2023

InterSystems 参加 麻省理工大学2023年度HackMIT

InterSystems 团队本周末将前往麻省理工学院最大的黑客马拉松,届时我们将为黑客们带来一项技术挑战。我们为黑客们提供在他们的项目中使用 IntegratedML 或 InterSystems Supply Chain Orchestrator 的机会,以便争夺一些非常酷的奖品! 如果您在波士顿并且有兴趣成为活动中的 InterSystems 导师,请给我们写信。 我们期待看到新的创意项目!请继续关注 9 月 18 日公布的获奖者名单。 了解有关本次黑客马拉松的更多信息,请访问HackMIT 官方网站。
文章
Louis Lu · 三月 12, 2021

第 1 天:使用 InterSystems Object 和 SQL 进行开发

原文在这里。 原作者YURI MARX GOME 我正在参加 Joel Solon 讲授的“使用 InterSystems Objects 和 SQL 进行开发”课程。 课程非常好,我将在这里分享一些从培训中总结的提示。 第 1 天的提示: 1. InterSystems IRIS 统一了:InterSystems IRIS Database (Caché)、IRIS Interoperability (Ensemble)、IRIS Business Intelligence (DeepSee) 和 IRIS Text Analytics (iKnow)。 2. IRIS 为多模型:对象、关系、文档和多维。 3. 互操作性:从 Java、.NET 和其他语言(如 ObjectScript)进行原生访问;ODBC 和 JDBC 数据访问,SOAP/REST 服务访问;数据路由、转换和工作流驱动消息;支持 ESB 的 SOA 架构。 4. IRIS 是事务和分析的结合。 5. IRIS 使用 ECP(用户量的分布式缓存)和Sharding进行水平数据量扩展。 6. 使用 Cloud Manager 在公共或私有容器中部署。 7. 3 种待开发 IDE 选项:VSCode(最受欢迎)、Studio(仅限 Windows)、Atelier(已弃用)。 8. 适用于 CLI 命令的终端工具。 9. 基于浏览器的管理门户。 10. IRIS 支持多平台(UNIX,Linux,Windows),并为 Linux 提供了 Docker 选项。 11. 提供年度版本 20##.1(EM - 扩展维护)和季度版本(CD - 连续交付)。 12. IRIS 区分大小写,推荐采用驼峰表示法。 13. 类是方法和属性的容器。 14. 方法执行特定任务,不允许方法重载(类中具有两个同名方法)。 15. 有 2 种类型的方法:ClassMethod(与对象实例不关联的操作)和 Method(与对象实例相关联的操作)。 16. 使用 ##class() 运行类方法并创建实例(利用 %New 或 %OpenId)以执行 Methods。 17. 方法参数的默认类型为 %String。 18. 符号 ... 表示变量参数。 示例:Method Sample(a As %String, b... as %String) as %Status。 19. 将参数作为方法调用方传递时: 如果使用 . 则作为引用传递; 参数是可选的,您可以使用 $data() 借助调用方传递的参数进行测试。 20. string 是变量的默认类型。 21. ObjectScript 支持动态类型。 22. 在 ObjectScript 中,0 为 false,其他值为 true。 23. 软件包允许您将类整理到文件夹中。 24. 如果在类或方法中使用导入,则不需要将限定名称引用到类。 25. 持久类(存储在磁盘中)扩展 %Persistent。 26. 持久类具有保持类特性/值的属性。 27. 每个持久类都有一个唯一的不可变 ID 编号。 PS 1:我用 40,000 积分兑换了这个为期 5 天的课程(价值 2800 美元) (https://globalmasters.intersystems.com/rewards/34/reward_redemptions/new) PS 2:Joel Solon 是一位出色的讲师(提供了优秀的 IRIS 认证提示) PS 3:课程材料非常好,课程资源、工具和支持都很棒。 明天我会发布第 2 天的总结。