Encontrar

Article
· Jul 31 1m read

Import CSV into CACHÉ

Here's a practical example of how to import data from a CSV file into InterSystems CACHÉ using ObjectScript
Assuming your CSV file is simple (e.g., comma-separated, with headers), you can use %Stream.FileCharacter to read it line by line and parse the data.

 

ClassMethod ImportCSV(filePath As %String) As %Status {
    Set stream = ##class(%Stream.FileCharacter).%New()
    Set sc = stream.LinkToFile(filePath)
    If 'sc Quit sc

    While 'stream.AtEnd {
        Set line = stream.ReadLine()
        Set fields = $ListFromString(line, ",")
        // Example: Save to a persistent class
        Set obj = ##class(MyApp.Data).%New()
        Set obj.Name = $List(fields,1)
        Set obj.Age = $List(fields,2)
        Set obj.Email = $List(fields,3)
        Do obj.%Save()
    }
    Quit $$$OK
}

Discussion (0)1
Log in or sign up to continue
Article
· Jul 31 2m read

Listando conexões dos itens da produção recursivamente

Se você trabalha com Produções, destacar as conexões entre Business Hosts é um recurso muito conveniente, permitindo aos desenvolvedores obter uma representação visual do fluxo de dados.

Esse recurso funciona por padrão com todos os Business Hosts do sistema. Se um usuário escreve seus próprios Business Services, Processes ou Operations, ele deve implementar o método OnGetConnections para que essa funcionalidade funcione com seus Business Hosts personalizados (ou usar as propriedades  Ens.DataType.ConfigNamepara as conexões).
Dito isso, o SMP mostra apenas a primeira camada de conexões do Business Host selecionado. Às vezes, precisamos obter conexões de conexões recursivamente para construir um grafo completo de fluxo de dados. Ou podemos precisar dessas informações de conexão para verificar quais sistemas downstream podem ser afetados por uma mudança upstream.Para fazer tudo isso, escrevi uma classe Utils.Connectionsque oferece o método GetConnectionsJSON Você pode passar um ID do Item ou Nome do Item, e ele retornará um objeto dinâmico contendo todas as conexões. Veja como funciona. Assumindo esta produção:


Você obterá este JSON para o serviço in.REST service (##class(Utils.Connections).GetConnections("in.Rest")):

{
  "in.REST":[
    {
      "EnsLib.HL7.SequenceManager":[
        "Ens.Alert",
        {
          "Router":[
            "Ens.Alert"
          ]
        },
        "in.BO",
        "s3.BusinessOperation"
      ]
    }
  ]
}

Cada item possui um array de conexões. Se uma conexão tiver conexões próprias, será um objeto com um array dentro; caso contrário, será apenas uma string.

Também existem queries SQL para obter conexões para um item ou listar todas as conexões para todos os itens:

SELECT Utils.Connections_GetConnections(ID)
SELECT * FROM Utils.Connections_ListConnections()

Código no GitHub.

Discussion (0)1
Log in or sign up to continue
Announcement
· Jul 31

[Video] What Is InterSystems FHIR Server?

Hi, Community!

Are you building applications in a healthcare setting? See how InterSystems FHIR Server can help:

What Is InterSystems FHIR Server?

InterSystems Product Manager @Elijah Cotterrell explains how InterSystems FHIR Server helps you store, manage, and query healthcare data. In a brief demo, Elijah shows how you can:

  • Deploy a FHIR server.
  • Configure OAuth authentication.

You will also learn about two key tools—the Bulk FHIR Coordinator and FHIR SQL Builder—which allow you to scale your applications and perform analytics!

Discussion (0)1
Log in or sign up to continue
Article
· Jul 31 3m read

Avoiding SQL Injection in InterSystems IRIS: The Case for Secure Query Practices

SQL injection remains one of the most critical vulnerabilities in database-driven applications, allowing attackers to manipulate queries and potentially access or compromise sensitive data. In InterSystems IRIS, developers have access to both Dynamic SQL and Embedded SQL, each with distinct characteristics. Understanding how to use them securely is essential for preventing SQL injection.

The Problem: Dynamic SQL and SQL Injection

Dynamic SQL constructs queries as strings at runtime. While this offers flexibility, it also creates a vulnerability if user input is not handled correctly. For example:

Set query = "SELECT Name, Age FROM Patients WHERE Age > "_age
Set statement = ##class(%SQL.Statement).%New()
Set status = statement.%Prepare(query)

If age is user-provided, concatenating it directly into the query string exposes the application to injection. An attacker might supply a malicious value such as 0; DROP TABLE Patients, with disastrous results.

The Solution: Parameterised Queries

Parameterised queries are the best defence against SQL injection. Rather than concatenating inputs into the query, user values are bound as parameters. Here is a secure approach using Dynamic SQL:

Set query = "SELECT Name, Age FROM Patients WHERE Age > ?"
Set statement = ##class(%SQL.Statement).%New()
Set status = statement.%Prepare(query)
If status {
    Set result = statement.%Execute(age)
    While result.%Next() {
        Write "Name: ", result.Name, ", Age: ", result.Age, !
    }
}

Here, the ? placeholder ensures the age value is treated strictly as data rather than executable code, significantly reducing the risk of injection.

Embedded SQL: Built-in Safety

Embedded SQL integrates SQL directly into ObjectScript, inherently protecting against SQL injection. The host variable syntax (:variable) securely binds parameters at compile time:

&sql(SELECT Name, Age INTO :name, :age FROM Patients WHERE Age > :minAge)

With Embedded SQL, there is no mechanism to concatenate raw user input directly into the query, thereby preventing injection.

Comparing Embedded SQL and Dynamic SQL

Feature Embedded SQL Dynamic SQL
Security Safe from injection due to host variables Secure if parameterised; risky if not
Flexibility Limited (static queries only) Highly flexible for dynamic scenarios
Searchability Easy to locate in class definitions Harder to analyse; queries are in strings
Performance Compiled at class compile time Parsed and optimised at runtime

When to Use Dynamic SQL

Dynamic SQL is useful when query structures must be determined at runtime, for example when adding optional filters:

Set query = "SELECT Name, Age FROM Patients"
If includeGender {
    Set query = query_" WHERE Gender = ?"
}
Set statement = ##class(%SQL.Statement).%New()
Set status = statement.%Prepare(query)
If status {
    Set result = statement.%Execute("Male")
}

Always remember to use parameterisation (?) for these dynamically built queries to maintain security.

Conclusion

Dynamic SQL allows for flexible query building but demands responsible usage to avoid SQL injection risks. Parameterised queries address this risk effectively. Meanwhile, Embedded SQL comes with built-in safeguards, making it an excellent choice for static queries. By using these approaches appropriately, developers can build robust, secure applications with InterSystems IRIS.

Discussion (0)1
Log in or sign up to continue
Question
· Jul 31

Has anyone built a tool to generate a %Installer Manifest from an existing IRIS system?

Hi everyone,

I’m working with an existing InterSystems IRIS server that hosts several web applications and namespace-specific code and data. I’d like to reverse-engineer the current environment into a %Installer.Manifest file so I can store it in Git and manage its changes.

My goal is to:

  • Track the application setup and configuration in version control
  • Rebuild environments consistently (namespaces, CSP apps, security roles, etc.)
  • Possibly automate deployments later on

I understand that %Installer is declarative and wasn’t necessarily designed to reflect a running system. But before I start building a tool or writing scripts to extract pieces (like web apps, packages, globals, roles…), I wanted to ask:

Has anyone already built something like this — a generator, exporter, or script that helps create a %Installer manifest based on the current state of an IRIS instance?

Even partial tools, tips, or lessons learned would be greatly appreciated!

Thanks in advance,

Andre-Claude

1 Comment
Discussion (1)3
Log in or sign up to continue