Pesquisar

ダイジェスト
· 2025年2月28日

Résumé de la communauté des développeurs d'InterSystems, Février 2025

Bonjour, voici la newsletter de la communauté des développeurs de Février 2025.
Statistiques générales
✓ Nouvelles publications 19 publiées le Février :
 11 nouveaux articles
 7 nouvelles annonces
 1 nouvelle question
✓ Nouveaux membres 2 ayant rejoint le Février
✓ Publications 1,113 publiées depuis le début
✓ Membres 162 ayant rejoint depuis le début
Meilleures publications
Les meilleurs auteurs du mois
Articles
#InterSystems IRIS
Gérer correctement l'heure système de mon conteneur IRIS
Par Sylvain Guilbaud
Test des fonctionnalités FOREIGN SERVER et FOREIGN TABLE
Par Iryna Mykhailova
IRIS et Presto pour des requêtes SQL performantes et évolutives
Par Guillaume Rongier
IoP : Prise en charge de DTL pour les messages et JsonSchema
Par Guillaume Rongier
L'interopérabilité Python: mise à jour du support des opérations asynchrones
Par Guillaume Rongier
Importer un objet JSON avec une grande string
Par Iryna Mykhailova
Retour aux fondamentaux : pourquoi InterSystems ?
Par Sylvain Guilbaud
Vous rencontrez des problèmes avec votre instance IRIS après l'avoir installée sous Linux ? Filecheck à la rescousse !
Par Iryna Mykhailova
La puissance de Python intégré dans l'interopérabilité - un cas d'utilisation de MongoDB CDC
Par Sylvain Guilbaud
#Autre
Annonces
Questions
#InterSystems IRIS
Février, 2025Month at a GlanceInterSystems Developer Community
ダイジェスト
· 2025年2月28日

InterSystems Developer Community Digest, February 2025

Hello and welcome to the February 2025 Developer Community Newsletter.
General Stats
150 new posts published in February:
 44 new articles
 31 new announcements
 73 new questions
 2 new discussions
377 new members joined in February
14,572 posts published all time
15,378 members joined all time
Top posts
Top authors of the month
Articles
#InterSystems IRIS
Correctly manage the system time of my IRIS container
By Sylvain Guilbaud
Run Your InterSystems Solution In Your Kubernetes Environment With Guaranteed Quality of Service
By Ariel Glikman
SQL Host Variables missing ?
By Robert Cemper
Monitoring InterSystems IRIS with Prometheus and Grafana
By Stav Bendarsky
REST Service in IRIS Production: When You Crave More Control Over Raw Data
By Aleksandr Kolesov
Generation of OpenAPI Specifications
By Alessandra Carena
Using DocDB in SQL, almost
By Dmitry Maslennikov
Streamlining Interoperability with Embedded Python in InterSystems IRIS
By Anila Kosaraju
IntegratedML Configuration and Application in InterSystems IRIS
By André Dienes Friedrich
IRIS %Status and Exceptions
By Ashok Kumar
IRIS %Status and Exceptions Part-2
By Ashok Kumar
Orchestrating a local LLM with IRIS Interoperability
By Chris Stewart
Using SQL Gateway with Python, Vector Search, and Interoperability in InterSystems Iris - Part 1 - SQL Gateway
By Julio Esquerdo
Using SQL Gateway with Python, Vector Search, and Interoperability in InterSystems Iris - Part 2 – Python and Vector Search
By Julio Esquerdo
Using SQL Gateway with Python, Vector Search, and Interoperability in InterSystems Iris - Part 3 – REST and Interoperability
By Julio Esquerdo
Getting Started Using Istio Service Mesh with Mirrored IRIS Environment in Kubernetes
By Ariel Glikman
A look at Dynamic SQL and Embedded SQL
By Andre Larsen Barbosa
Using REST API, Flask and IAM with InterSystems IRIS - Part 1 - REST API
By Julio Esquerdo
Using REST API, Flask and IAM with InterSystems IRIS - Part 2 – Flask App
By Julio Esquerdo
Using REST API, Flask and IAM with InterSystems IRIS - Part 3 – IAM
By Julio Esquerdo
Having trouble with your IRIS instance after installing it on Linux? Filecheck to the rescue!
By Luis Angel Pérez Ramos
Back to Basics: Why InterSystems?
By Daniel Cole
HTTP and HTTPS with REST API
By Julio Esquerdo
JWT Creation and Integration in InterSystems IRIS
By Ashok Kumar
Importing json object with a large string property
By Theo Stolker
OMOP Odyssey - Celebration (House of Hades)
By Ron Sweeney
REST API with Swagger in InterSystems IRIS
By Julio Esquerdo
Securing HL7 Interfaces with SSL/TLS (X.509) Certificates
By Eric Fortenberry
Keeping IRISTEMP Under Control: Stop It from Taking Over Your Storage!
By Mario Sanchez Macias
Modern and Easy-to-Use VSCode Plugin for InterSystems ObjectScript: Class Diagram Visualization with PlantUML
By Jinyao
Introducing UDP Adapter
By Corentin Blondeau
How Do You Display %Status Error in Terminal Or Let's Have a New Helpful Terminal Alias!
By Evgeny Shvarov
The Case for IRIS and JavaScript
By Rob Tweed
#InterSystems IRIS for Health
#Other
#Developer Community Official
#Health Connect
Announcements
#InterSystems IRIS
[Webinar] Configuring a Web Server for use with InterSystems IRIS
By Anastasia Dyubaylo
What's new with InterSystems Language Server 2.7
By Raj Singh
[Video] Make Upgrades Easier - Introducing the Upgrade Impact Checklist
By Anastasia Dyubaylo
[Video] Globals in Embedded Python for Dummies
By Anastasia Dyubaylo
[Video] FHIR Repository and FHIR SQL Builder
By Anastasia Dyubaylo
[Hebrew Webinar]: GenAI + RAG - Leveraging Intersystems IRIS as your Vector DB
By Ronnie Hershkovitz
Alert: SQL Queries Returning Wrong Results
By Daniel Palevski
Beta Testers Needed for our Upcoming InterSystems IRIS Developer Professional Certification Exam
By Celeste Canzano
[Video] FHIR Performance Benchmarking
By Anastasia Dyubaylo
Reminder: Seeking Exam Design Feedback for InterSystems ObjectScript Specialist Certification Exam
By Celeste Canzano
[Video] Coding InterSystems ObjectScript with Copilot
By Anastasia Dyubaylo
[Video] Unit Testing with IPM
By Anastasia Dyubaylo
InterSystems AI Programming Contest: Vector Search, GenAI and AI Agents
By Anastasia Dyubaylo
#Global Summit
#Developer Community Official
#Open Exchange
#InterSystems IRIS for Health
#Job Opportunity
#Other
#InterSystems Ideas Portal
#InterSystems Official
#Learning Portal
Questions
#InterSystems IRIS
How to use %ValidateObject with %Dynamic properties?
By Gabriel Santos
keep only the COS routine object (cache object script) to preserve the source routine.mac
By Robert Cemper
Connecting IRIS and VS Code on Windows 11 PRO
By Tulio Dantas
To configure VSCode as Studio for Intersystems
By Manoj R
Base64 decoding and storing it in a local path
By Vachan Rannore
Py fails in Win Terminal - fixed
By Robert Cemper
trying to put the SYSMGR global into a readable string
By JIM WHEELER
How to find all globals in routines?
By Anna Golitsyna
Error encountered while calling an API
By Anthony Decorte
How to check if the system user with the name "John" already exists in IRIS via SQL?
By Evgeny Shvarov
Error - SFTP connection with ssh key on a server that excludes the rsa-ssh algorithm
By Moussa SAMB
Track the global set location
By Ashok Kumar
Sorting, remove duplicate and count of Json file
By Sandeep
I don't know what I did wrong.
By Chiho Han
Visual Studio Code eating licenses
By Fabio Care
Where is InterSystems IRIS Download for Windows?
By Irina Yaroshevskaya
CRLF to LF
By Dmitrij Vladimirov
How to force stop a Live job
By Thembelani Mlalazi
ssldefs.ini file error [Matching SSL server config not found]
By Chiho Han
Change %Response.ContentLength
By omer
What causes a broker RESPONSE to have Transfer-Encoding:chunked?
By omer
Can the WebGateway Port changed from i.e. 57773 to 433?
By Ditmar Tybussek
How to append to a list in a for loop using ObjectScript
By Preedhi Garg
How to log index errors as warning
By Tommy Heyding
Disable Shared Memory in JDBC Driver URL
By Matheus Gomide
How to get IPM module name from source directory
By Pravin Barton
Cube Compilation Order in UCR: How to Manage Dependencies?
By David.Satorres6134
Apache server .../temp/ does not exist, limiting Gateway functionality
By Marcel den Ouden
Need to query the rule data from the tables in the InterSystems database
By Rick Rowbotham
How To Test REST API Methods without referring to a Web Server?
By Evgeny Shvarov
Problem sending Mail via smtp-mail.outlook.com / OAUTH2 as SMTP or JSON
By Ditmar Tybussek
Reading HTTP multipart/form messages from EnsLib.HTTP.GenericMessage object.
By Federico Sandrinelli
Management portal not working
By john smith
How to Get the Adapter State and Status of a Business Operation
By Bransen Smith
Open IRIS studio and management portal in Linux
By john smith
How to set XMLIGNORENULL for non %String property?
By Joe Fu
Can I find out which user created an Operation in Iris?
By Aaron Vail
file path in FTP outbound adapter
By Krishnaveni Kapu
how to convert %Stream.FileBinaryGzip into %Stream.Object?
By Dmitrij Vladimirov
Net Gateway How to instantiate a Class with a Constructor with a parameter
By Thembelani Mlalazi
How to create new special parameter?
By Gabriel Santos
#InterSystems IRIS for Health
Load ObjectScript external file and run code
By Phillip Wu
How to use DTL remove property for a repeating segment in for each loop for target using copy
By Mark OReilly
Process multiple messages by increasing pool size while maintaining order with keys
By Thomas Haig
WSGI/Flask app with iris container complains about flask not installed
By John McBride
Need Help to do a connection Between IRIS and SAP RFC
By Mariam Chaaban
Handling FHIR Responses in InterSystems – Transforming to SDA
By Ali Chaib
Transforming a FHIR Response to SDA – Handling Task Resource
By Ali Chaib
Flask, Iris Container and NGINX?
By John McBride
Objectscript get classs property error
By Phillip Wu
VS CODE Search Options
By RKumar
Intersystems Reports (Logi Reports) - Does it merge multiple PDFs?
By Suzy Green
SQL SYS.Database table not found
By Phillip Wu
Error message “Invalid CSRF token”
By Edmara Francisco
Converting Documents to PDF in IRIS
By Thembelani Mlalazi
Program read answers from a OS file
By Phillip Wu
Searching InterSystems FHIR Server for specific Encounter (based on peroid)
By Sebastian Thiele
#Ensemble
#Caché
#Other
#Health Connect
#HealthShare
#TrakCare
Discussions
February, 2025Month at a GlanceInterSystems Developer Community
記事
· 2025年2月28日 13m read

Proposal for ObjectScript naming conventions and coding guidelines

Introduction

What's in a name? That which we call a rose
By any other name would smell as sweet

William Shakespeare, "Romeo & Juliet"

In this article, we will describe a set of naming conventions for ObjectScript code.

Code naming conventions exist for several important reasons:

  1. Readability: Consistent names improve code clarity and comprehension. Following naming conventions makes it easier to identify and remember components.
  2. Maintainability: Properly named code elements ease the maintenance and updating of code and configuration items, reducing confusion and errors.
  3. Collaboration: in a team setting, having a common naming convention ensures that everyone is on the same page. It promotes smoother collaboration and reduces the likelihood of miscommunication.
  4. Debugging: clear and consistent names can help in quickly identifying and fixing issues. Descriptive names can indicate the purpose and scope of a code element, aiding in the debugging process.
  5. Documentation: following naming conventions can simplify the process of creating and maintaining documentation. Names that reflect their function or purpose make it easier to explain and understand the code. 

As IRIS developers and administrators, we are naming various types of objects, some of which have numerous instances. For example, interoperability production with dozens of configurations items and data transformation classes is not at all uncommon in real-world scenarios such as healthcare patient and appointment data routing.

The aim of this article is to compile bits from various sources of information in a consistent proposal for robust naming conventions. As the many names defined are used in ObjectScript code, it also describes some coding guidelines.

 

Compiler items

In this part, we’ll describe guidelines for naming:

  • packages
  • classes, includes and routines
  • class members: parameters, properties, methods and XData blocks
  • local variables and method parameters 

Packages

 Package names use only lower-case letters and decimal digits. The first character must be a lower-case letter.

 The root package has at least one component, and it identifies the source entity, organization or group.

 Examples:

  • dc
  • myorg
  • acme 

Packages under root denote the purpose of the classes. They may have subpackages denoting a finer purpose or domain, and use lower case letters, except for application domains that are spelled in upper case letters. 

The following root subpackage names are reserved 

Compiler item purpose

Package

CSP page

csp

Data models and transfer objects (classes _not_ extending %Persistent)

model

Data type

type

Include resources: macros, constants, …

inc

Interoperability component - business adapter

interop.ba

Interoperability component - business service

interop.bs

Interoperability component - business process

interop.bp

Interoperability component - business operation

interop.bo

Interoperability component - message

interop.msg

Interoperability component - data transform

interop.dt

Persistent entity (classes extending %Persistent)

entity

REST API

api

Routines

rou

Scheduled tasks

tas

Service

service

SOAP Web Service

ws

Utility class

lib

Classes and other elements

Class names use upper camel case, must start with an uppercase letter and use letters and decimal digits. Avoid starting with "%".

Routine names should be all uppercase. Avoid starting with "%".

Item purpose

 Class name pattern

Examples of fully qualified class names

CSP page

<name>

myorg.csp.app.LogonForm

Data models and transfer objects (classes _not_ extending %Persistent)

<name>

myhospital.model.Patient

Data types

<name>

acme.type.FusionReactorType

myhospital.type.patient.MRN

Include resources: macros, constants, …

<name>

myorg.inc.Errors

Interoperability component - inbound business adapter

<name>InboundAdapter

myorg.interop.ba.hl7.UNCPathFileInboundAdapter

Interoperability component - outbound business adapter

<name>OutboundAdapter

acme.interop.ba.CustomTCPOutboundAdapter

Interoperability component - duplex business adapter

<name>DuplexAdapter

myorg.interop.ba.CustomTCPDuplexAdapter

Interoperability component - business service

<name>Service

myhosp.interop.bs.FileService

Interoperability component - business process

<name>Process

myhosp.interop.bp.AppointmentCancelProcess

Interoperability component - business operation

<name>Operation

myhosp.interop.bo.WISH.PatientOperation

Interoperability component - request message (extends Ens.Request)

<verb>[<resource>]Request

myorg.interop.msg.patient.GetRequest

myorg.interop.msg.patient.GetEncountersRequest
myorg.interop.msg.patient.Response

Interoperability component - response message (extends Ens.Response)

[<name>]Response

myorg.interop.msg.patient.Response

myhospital.interop.msg.invoicing.BillInsuranceResponse

Interoperability component - other message (extends Ens.MessageBody)

<name>

myhospital.interop.msg.patient.PatientUpdatedEvent

myorg.interop.msg.document.Container

Interoperability component - data transform

[<source-applicaton>]<source-format>To[<target-application>]<target-format>

myorg.interop.dt.ULTRAGENDASIUToAppointmentUpdate

Persistent entities (classes extending %Persistent)

<name>

myorg.entity.Document

REST APIs - generated classes (lowercase letters)

impl
spec

disp

myhospital.api.terminology.impl
myhospital.api.terminology.spec

myhospital.api.terminology.disp

Routines

<name>

myhosp.rou.PHUTL001

Scheduled tasks

<name>Task

myhospital.task.CancelAppointmentsTask

Service

<name>Service

service

SOAP Web Services

<name>WS

acme.ws.accounting.SupplierWS

Utility classes

<name>

myorg.lib.xml.Utils

Class members

Class members names use  upper camel case, must start with an uppercase letter (avoid using '%'), and use letters and decimal digits.

Member

Convention

Example

Parameter

Upper camel case or all uppercase

MRNCODESYSTEM
DocTypeCategory

Properties

Upper camel case

BirthDate
DeathDate

Method

Upper camel case. Favor a <verb><object> pattern

FetchPatient
ProcessMessage
UpdatePractitionerRoles

Xdata

Upper camel case

HL7Mappings

Local variables & method parameters

Local variable names and method parameters use lower camel case and start with a lower-case letter.

Some examples: request, response, patientId, mrn

Instance (i%..., r%...) and process (%...) variables follow the same convention.

 

Coding guidelines

Block syntax

A block statement, or compound statement, lets you group any number of statements (including 0) into one statement.

ObjectScript currently supports two syntaxes for blocks:

  • Curly brace block syntax
  • Dot block syntax

Curly brace block syntax

It is similar to that in C, Java, C#, … making the following short example look very familiar to most programmers:

if a=0 {
   write "foo",!
   write "bar",!
}

Dot block syntax 

This is the original MUMPS block syntax. It is supported for backward compatibility with (very) old code. Its use is strongly discouraged, as it can get quite confusing, especially when combined with the short version of commands and the lack of reserved words, as in the following (intentionally a little mischievous) example: 

j=1:1:d d
 . r i
 . i '$test b
 . i i'="" d
 .. s d=$p(l," ",1) 41)
 .. s w=$p(l," ",2)
 .. w d,?10,$e(^title(d),1,80),!

Post-conditionals

This is an implementation in ObjectScript of the concept of guarded command, as defined by Dijkstra (1975).

It is a conditionally executed statement, where a boolean expression "guards" the execution of the statement. 

<command>:<condition> <command arguments>

 It is functionally equilavent to

if <condition> <command> <command arguments>

Although the concept is well defined, the syntax is not common, so when should it be used instead of an if statement?

  • execution flow control: quit, continue, throw
  • default value assignment: set

some examples:

quit on error, continue on condition

quit:$$$ISERR(sc)

#Dim a as %Integer
while a > 0 {

continue:a=5

}

throw on condition

#Dim obj as %RegisteredObject
throw:'$isobject(obj) ##class(%Exception.General).%New("object not found")
 

Assign default value

#Dim obj as Foo

set:'$isobject(obj) obj = ##class(Foo).%New()

Use return instead of quit for return values

In new code, use return instead of quit, as quit can be used both for exiting current execution context and return a value.

'quit' has two different meanings :

  • when use with no argument, it exits current execution context (e.g. loop)
  • when use with an argument, it exits current routine/method and returns value

 

'return' is an addition to ObjectScript meant to improve code readability, as it implements only the second meaning.

Command arguments

The use of a comma-separated list of command arguments should be avoided, as for some commands, it gets confusing.

For example,

if a=0,b=1 {
...
}

 

It is much less readable (to the 'modern' reader) than

if (a=0)&&(b=1) {
...
}
 

Ternary operator - expressional 'if' 

The $select function can be used as ternary if operator:

$select(<boolean expression>:<true value>,1:<false value>)

 

 Switch/case 

Either

  • $case() when switch intent is to select a value
  • if elseif elseif … when switch intent is to select behaviour


Command keywords

Command keywords are not case-sensitive, and most commands come in two variants, fully named and shorthand.

  • Favor the use of full command keywords, except for the most common ones like 'set' and 'do'
  • Use all lowercase for command keywords
  • Avoid using legacy goto <label> command for flow control

 

Function names

As commands, function names are not case-sensitive and most functions come in two variants, fully named and shorthand.

  • Favor the use of full function names instead of shorthand, e.g. use $extract() instead of $e
  • Use all lowercase for intrinsic function names
  • Use upper camel case for extrinsic function names

Method parameters and return values

  • group optional parameters at the end
  • if the method is a function that returns a data type or OREF, and returns a %Status, the %Status is returned as the last parameter
 

Interoperability production items

Interoperability productions can easily count a sizeable of business hosts. A consistent naming scheme helps a lot with readability across the various actors reading the names: developers, administrators and support staff.

Business services

Propose

Name pattern

Examples

Receive messages from an application

<format>From<application>

SIUFromULTRAGENDA

Receive deferred responses

<application>Response

DOCSHIFTERResponse

REST or SOAP API

<name>Service

TerminologyService

Business processes

Purpose

Name pattern

Examples

Process requests

Orchestration

<name>Process

AppointmentCancelProcess

DocumentProcess

Route messages

<format>Router

ADTRouter
SIURouter

Business operations

Purpose

Name pattern

Examples

Send messages to an application or application component. Optionally use suffixes to denote application subcomponents or environments

<format>To<application>[_<component>]

SIUToWISH
ADTToSOFTALMO_PROD
ADTToSOFTALMO_TEST

HL7ToArchive

Query external system and return responses

<name>Operation

ULTRAGENDAAPIOperation

Duplex operation

<name>Duplex

 

Business duplexes

Classes extending Ens.BusinessDuplex are use

<name>Duplex

 

 

Some examples

Class method

/// <p>Purges all message bodies associated with sessionId and if purgeHeaders is set, purge headers too.</p>
/// <p><b>purged</b> returns the total count of items successfully purged, and the count by class name in the first subscript.</p>
/// <p>Stops and returns error status if any error occurs during purge.</p>
ClassMethod PurgeSessionMessageBodies(sessionId As %Integer, Output purged As %Integer, purgeHeaders As %Boolean = 0, noLock As %Boolean = 1) As %Status
{
  #Dim sc as %Status
  #Dim ex as %Exception.AbstractException
  #Dim stmt as %SQL.Statement
  #Dim rs as %SQL.StatementResult
  s sc = $$$OK
  try {    
    s stmt = ##class(%SQL.Statement).%New()
    s rs = stmt.%ExecDirect(,"select"_$select(noLock:" %NOLOCK",1:"")_" ID as HeaderId,MessageBodyClassName as BodyClass,MessageBodyId as BodyId from Ens.MessageHeader where SessionId=?",sessionId)
    while rs.%Next() {
      if ($length(rs.BodyClass) > 1) && $$$ISOK($classmethod(rs.BodyClass,"%DeleteId",rs.BodyId)) {
        d $increment(purged)
        d $increment(purged(rs.BodyClass))
      }
      if purgeHeaders {
        $$$TOE(sc,##class(Ens.MessageHeader).%DeleteId(rs.HeaderId))
        d $increment(purged)
        d $increment(purged("Ens.MessageHeader"))     
      }
    }
  }
  catch (ex) {
    s sc = ex.AsStatus()
  }
  return sc
}

Outbound adapter

/// HL7 file outbound adapter, using <class>ks.lib.file.ba.UNCOutboundAdapter</class>
/// This adapter also adds expression parsing to <method>CreateFilename</method> : see <method>ks.lib.hl7.Utils.ParseExpressions</method>
Class ks.interop.hl7.ba.FileOutboundAdapter Extends ks.interop.file.ba.UNCOutboundAdapter
{
// keeping parameter names as in superclass for clarity
Method CreateFilename(ByRef pFileName As %String, ByRef pSpec As %String, ByRef pIsVMS As %Boolean, ByRef pDirectory As %String, ByRef pLocal As %Boolean) As %String
{
	#Dim sc as %Status
	#Dim ex as %Exception.AbstractException
	s sc = $$$OK
	try {
  	  if $isobject(..BusinessHost.%RequestHeader) &&
	     $classmethod(..BusinessHost.%RequestHeader.MessageBodyClassName,"%Extends","EnsLib.HL7.Message") {
	    s msg = ##class(EnsLib.HL7.Message).%OpenId(..BusinessHost.%RequestHeader.MessageBodyId)
	    if $isobject(msg) {		  
	  	  s pSpec = ##class(ks.lib.hl7.Utils).ParseExpressions(msg,pSpec,.sc)
		  $$$TRACE("spec after HL7 expressions parsing : "_pSpec)
	    }
	  } 
	}
	catch (ex) {
	  // do nothing, fall back to ##super
	}	
	return ##super(.pFileName,.pSpec,.pIsVMS,.pDirectory,.pLocal)
}

}
/// A string datatype definition which extends <class>%Library.String</class> with additional regex pattern validation. <br />
Class ks.lib.type.RegExString Extends %String
{

/// Set PATTERN to empty and final, as it is not relevant on
/// this type, but is inherited from <class>%Library.String</class>
Parameter PATTERN [ Final ];
/// Set VALUELIST to empty and final, as it is not relevant on
/// this type, but is inherited from <class>%Library.String</class>
Parameter VALUELIST [ Final ];
/// Set DISPLAYLIST to empty and final, as it is not relevant on
/// this type, but is inherited from <class>%Library.String</class>
Parameter DISPLAYLIST [ Final ];
/// Set a valid regex pattern for value validation
Parameter REGEX As STRING;
/// The XMLPATTERN to regex by default. Can be overridden.
Parameter XMLPATTERN = {..#REGEX};
ClassMethod IsValid(%val As %Library.RawString) As %Status [ ServerOnly = 0 ]
{
    #Dim sc as %Status = $$$OK
    #Dim ex as %Exception.AbstractException
    try {
         $$$TOE(sc,##class(%String).IsValid(%val))
         if (..#REGEX '= "") {
            if '$match(%val, ..#REGEX) {
                s sc = $$$ERROR($$$DTPattern, %val, ..#REGEX)
            }
         }       
    }
    catch (ex) {
      s sc = ex.AsStatus()
    }
    q sc
}

}
Class myhosp.interop.dt.ADTNToFHIR Extends Ens.DataTransform
{

Parameter TARGETFHIRVERSION = "R4";
ClassMethod Transform(source As EnsLib.HL7.Message, ByRef target As Ens.StreamContainer, aux) As %Status
{
    #Dim sc as %Status = $$$OK
    #Dim ex as %Exception.AbstractException
    #Dim sda as %Stream.TmpCharacter
    #Dim fhir as HS.FHIR.DTL.Util.API.Transform.SDA3ToFHIR
    #Dim schema as HS.FHIRServer.Schema
    #Dim stream as %Stream.Object
    #Dim patientId as myhosp.type.WISH.MRN
    #Dim encounterId as myhosp.type.WISH.NADM
    #Dim exportType as %String
    try {
        s schema = ##class(HS.FHIRServer.Schema).LoadSchema(..#TARGETFHIRVERSION)
        if '$isobject(schema) throw ##class(%Exception.General).%New("FHIR Schema "_..#TARGETFHIRVERSION_" not found")

        s patientId = source.GetValueAt("PID:3.1")
        s encounterId = source.GetValueAt("PV1:19.1")

        $$$TOE(sc,##class(HS.Gateway.HL7.HL7ToSDA3).GetSDA(source,.sda,0))        
        s fhir = ##class(HS.FHIR.DTL.Util.API.Transform.SDA3ToFHIR).TransformStream(sda,"HS.SDA3.Container",..#TARGETFHIRVERSION,patientId,encounterId)  
        s stream = ##class(%Stream.GlobalCharacter).%New() 
        s stream.%Location = "^MyHosp.FHIR.Stream"
        s exportType = $select($data(aux):$select($isobject(aux):$select(aux.RuleActionUserData="":aux.RuleUserData,1:aux.RuleActionUserData),1:aux),1:"")
        if exportType="JSON" {
          s str = fhir.bundle.%ToJSON(stream)
        } else {
          d ##class(HS.FHIRServer.Util.JSONToXML).JSONToXML(fhir.bundle, .stream, schema)
        }
        s target = ##class(Ens.StreamContainer).%New(stream)
    } catch (ex) {
      s sc = ex.AsStatus()
    }
    return sc
}

}
2 Comments
ディスカッション (2)4
続けるにはログインするか新規登録を行ってください
記事
· 2025年2月28日 1m read

Évitez d'utiliser un package nommé « code » avec des méthodes Python intégrées utilisant [Language = python]

Bonjour,

Comme il m'a fallu un certain temps pour comprendre d'où venait le problème, je voudrais partager cette expérience, afin que vous ne tombiez pas dans le même piège.

Je viens de remarquer que si vous nommez votre package "code" (tout en minuscules), dans une classe utilisant du python intégré en utilisant [Language = python], vous aurez l'erreur suivante :

 <THROW> *%Exception.PythonException <PYTHON EXCEPTION> 246 <class 'ModuleNotFoundError'>: No module named 'code.basics'; 'code' is not a package

Class code.basics Extends %RegisteredObject
{

ClassMethod Welcome() As %Status [ Language = python ]
{
print('Welcome!')
return True
}
}
IRISAPP>w ##class(code.basics).Welcome()

W ##CLASS(code.basics).Welcome()
^
<THROW> *%Exception.PythonException <PYTHON EXCEPTION> 246 <class 'ModuleNotFoundError'>: No module named 'code.basics'; 'code' is not a package

Cela fonctionne bien avec "Code" :

Class Code.basics Extends %RegisteredObject
{

ClassMethod Welcome() As %Status [ Language = python ]
{
print('Welcome!')
return True
}
}
IRISAPP>w ##class(Code.basics).Welcome()
Welcome!
1
ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
記事
· 2025年2月28日 1m read

Avoid to use package named "code" with embedded python methods using [Language = python]

Hello,

as it took me some time to figure out what's wrong, I would like to share this experience, so that you do not fall into the same trap.

I've just noticed that if you name your package "code" (all lowercase), in a class using some embedded python using [Language = python], you'll face the <THROW> *%Exception.PythonException <PYTHON EXCEPTION> 246 <class 'ModuleNotFoundError'>: No module named 'code.basics'; 'code' is not a package

Class code.basics Extends %RegisteredObject
{

ClassMethod Welcome() As %Status [ Language = python ]
{
print('Welcome!')
return True
}
}
IRISAPP>w ##class(code.basics).Welcome()

W ##CLASS(code.basics).Welcome()
^
<THROW> *%Exception.PythonException <PYTHON EXCEPTION> 246 <class 'ModuleNotFoundError'>: No module named 'code.basics'; 'code' is not a package

It works well with "Code" :

Class Code.basics Extends %RegisteredObject
{

ClassMethod Welcome() As %Status [ Language = python ]
{
print('Welcome!')
return True
}
}
IRISAPP>w ##class(Code.basics).Welcome()
Welcome!
1
2 Comments
ディスカッション (2)3
続けるにはログインするか新規登録を行ってください