Find

Article
· Oct 31 6m read

Nobody expects the Spanish Inquisidor!

¡Sí sí! ¡Adelante! No os habéis equivocado, estáis en vuestra querida Comunidad de Desarrolladores de InterSystems en español.

Os preguntaréis a qué viene el título de este artículo, pues muy sencillo, hoy estamos aquí reunidos para honrar al Inquisidor y elogiar la gran labor desempeñada por el mismo. 

Comunidad de Steam :: :: Nobody expects the Spanish Inquisition

Y bien, ¿quién o qué es el Inquisidor?

Perfecto, ahora que he captado vuestra atención, es momento de explicar que es el Inquisidor. El Inquisidor es una solución desarrollada con tecnología InterSystems para someter a inquisición los contratos públicos que diariamente son publicados en la plataforma https://contrataciondelestado.es/

Aunque la plataforma tiene un buscador habilitado para filtrar las licitaciones públicas este tenía varias limitaciones:

  • Es imposible realizar búsquedas por el título de la licitación.
  • La búsqueda por adjudicatarios depende de que conozcas la descripción exacta utilizada en el registro del mismo en el resultado de la licitación, la cual varía invariablemente de una a otra (me he encontrado a InterSystems escrito de 5 formas distintas).
  • Encontrar el organismo que ha publicado la licitación es digno de un libro de ¿Dónde está Wally en la Administración Pública?

Y ni qué decir tiene que es imposible sacar la más mínima estadística al respecto de las licitaciones.

¿Cómo funciona el Inquisidor?

Muy sencillo, la plataforma de contratación pública pone a disposición de la plebe, en una muestra de generosidad, descargas diarias de las licitaciones publicadas en la plataforma en formato XML de este estilo:

<entry>
        <id>https://contrataciondelestado.es/sindicacion/licitacionesPerfilContratante/13983936</id>
        <link href="https://contrataciondelestado.es/wps/poc?uri=deeplink:detalle_licitacion&amp;idEvl=Ag4n4m84LtCqb7rCcv76BA%3D%3D"/>
        <summary type="text">Id licitación: 2023/20; Órgano de Contratación: Parlamento de Andalucía; Importe: 99750 EUR; Estado: EV</summary>
        <title>Suministro de equipamiento para el trabajo de trabajo en movilidad del Parlamento de Andalucía.</title>
        <updated>2024-01-31T12:59:50.514+01:00</updated>
        <cac-place-ext:ContractFolderStatus>
            <cbc:ContractFolderID>2023/20</cbc:ContractFolderID>
            <cbc-place-ext:ContractFolderStatusCode listURI="https://contrataciondelestado.es/codice/cl/2.04/SyndicationContractFolderStatusCode-2.04.gc" languageID="es">EV</cbc-place-ext:ContractFolderStatusCode>
            <cac-place-ext:LocatedContractingParty>
                <cbc:ContractingPartyTypeCode listURI="http://contrataciondelestado.es/codice/cl/2.10/ContractingAuthorityCode-2.10.gc">2</cbc:ContractingPartyTypeCode>
                <cbc:ActivityCode listURI="http://contrataciondelestado.es/codice/cl/2.10/ContractingAuthorityActivityCode-2.10.gc">1</cbc:ActivityCode>
                <cbc:BuyerProfileURIID>https://contrataciondelestado.es/wps/poc?uri=deeplink:perfilContratante&amp;idBp=SI5CV24QS6s%3D</cbc:BuyerProfileURIID>
                <cac:Party>
                    <cbc:WebsiteURI>http://www.parlamentodeandalucia.es</cbc:WebsiteURI>
                    <cac:PartyIdentification>
                        <cbc:ID schemeName="DIR3">I00000175</cbc:ID>
                    </cac:PartyIdentification>
                    <cac:PartyIdentification>
                        <cbc:ID schemeName="NIF">S4133001J</cbc:ID>
                    </cac:PartyIdentification>
                    <cac:PartyIdentification>
                        <cbc:ID schemeName="ID_PLATAFORMA">20015840002647</cbc:ID>
                    </cac:PartyIdentification>

Tenéis acceso a los archivos desde esta URL.

El Inquisidor se conecta diariamente a la URL que descarga el fichero y lo mapea a su propia base de datos, extrayendo los datos más útiles de la misma, como es la descripción, el importe, fechas de publicación así como el ganador de la misma y el importe en el caso de estar adjudicadas.

Esta información puede ser consultada desde una aplicación de Angular desarrollada para tal efecto:

¿Que nos aporta InterSystems IRIS al Inquisidor?

Hasta ahora las funcionalidades presentadas no pueden ser más sencillas y podrían implementarse con cualquier tecnología, pero gracias a IRIS, no tenemos que contentarnos con esa funcionalidades básicas. Veamos cómo IRIS impulsa y mejora a nuestro Inquisidor.

Almacenamiento columnar para estadísticas

Actualmente la plataforma almacena 874534 licitaciones entre publicadas y adjudicadas (y creciendo). La explotación estadística de las mismas se podría ver afectada por el número de registros, pero gracias al almacenamiento de tipo columnar sobre la columna de importes de adjudicación el tiempo de búsqueda y de agregaciones se reduce dramáticamente.

Property Ganador As %String(MAXLEN = 200);
Property GanadorNIF As %String(MAXLEN = 200);
Property ImporteGanador As %Numeric(STORAGEDEFAULT = "columnar");
Property ImporteGanadorSinImpuestos As %Numeric(STORAGEDEFAULT = "columnar");

De tal forma que podremos buscar agilmente y con absoluta inmediatez los importes de adjudicaciones agregadas tanto por empresas ganadoras, organismo contratante y años de publicación.

Indexación de textos con %iFind

Las búsquedas por campos de texto pueden ser una auténtica tortura, al implicar consultas que hagan uso de "LIKE" así como de carácteres especiales "%" o "?" que pueden ralentizar la obtención de resultados ad aeternum. Esto no es un problema trabajando con IRIS gracias a la indexación con %iFind (más información aquí).

Index IndexTitulo On (Titulo) As %iFind.Index.Basic(INDEXOPTION = 0, LANGUAGE = "es");

Este tipo de índices permite indexar campos de texto que aceleran de forma dramática las búsquedas sobre los mismos ahorrando tiempos de procesamiento y sobre todo y lo más importante, no agotando nuestra paciencia.

Aquí podemos ver un ejemplo de búsqueda de adjudicaciones de contratos para la adquisición de embutidos y la cual ha tardado menos de 1 segundo:

Vectorización de títulos de licitaciones

En ocasiones es posible que no estemos totalmente seguros de la descripción usada para el título de las licitaciones, por ello hemos aprovechado las capacidades de almacenamiento vectorial de la base de datos para la vectorización de los títulos y permitir búsquedas basadas en proximidad vectorial, obteniendo resultados que se aproximen a la búsqueda realizada.

Property TituloVectorizado As %Vector(DATATYPE = "DECIMAL", LEN = 384);

Conclusiones

Como veis, lo que a priori puede ser una aplicación básica, gracias a InterSystems IRIS puede ser mejorada y optimizada al máximo haciendo uso de las múltiples funcionalidades y capacidades incluidas.

¿Cuellos de botellas o problemas de rendimiento en tus aplicaciones? ¡Echa un vistazo a InterSystems IRIS!

Asociado a este artículo tenéis la aplicación subida a GitHub. La aplicación hace uso de la versión Community de InterSystems IRIS, por lo que podréis hacer uso de la misma de forma gratuita, con la única limitación del tamaño de la base de datos.

Actualmente disponemos de una versión pública a la que podréis acceder (previa solicitud dejando un comentario en este artículo).

1 Comment
Discussion (1)2
Log in or sign up to continue
Article
· Oct 31 20m read

使用 Docker 运行 InterSystems IRIS 的分步指南 - 第 1 部分:从基础知识到自定义 Dockerfile

目录

  1. 本文目的
  2. 什么是容器,它们为什么对 IRIS 有意义
     2.1 容器和镜像简介
     2.2 为什么容器对开发者很有用
     2.3 为什么 IRIS 可以很好地与 Docker 配合使用
  3. 先决条件
  4. 安装 InterSystems IRIS 镜像
     4.1 使用 Docker Hub
     4.2 拉取镜像
  5. 运行 InterSystems IRIS 镜像
     5.1 启动 IRIS 容器
     5.2 检查容器状态
     5.3 在容器终端执行代码
     5.4 访问 IRIS 管理门户
     5.5 将容器连接到 VS Code
     5.6 停止或移除容器
     5.7 使用绑定挂载设置特定密码
     5.8 使用持久化 %SYS 卷
      5.8.1 可以使用持久化 %SYS 存储什么
      5.8.2 如何启用持久化 %SYS
  6. 使用 Docker Compose
     6.1 Docker Compose 示例
     6.2 运行 Docker Compose
  7. 使用 Dockerfile 运行自定义源代码
     7.1 Dockerfile 示例
     7.2 Docker Compose 示例
     7.3 了解层、镜像标记和构建与 运行时
     7.4 源代码和初始化脚本
     7.5 使用 Dockerfile 构建镜像
     7.6 在容器化 IRIS 终端中运行指令
  8. 结语和未来计划

1 new Comment
Discussion (1)3
Log in or sign up to continue
Announcement
· Oct 30

[Video] A Day in the Life of a Developer - Data Platforms Roundup

Hey Community,

Enjoy the new video on InterSystems Developers YouTube:

⏯ A Day in the Life of a Developer - Data Platforms Roundup @ Ready 2025

Explore full-stack development with InterSystems IRIS and Python, using only VS Code and mainstream technologies for object-relational mapping and UI development. Learn how to build modern, efficient applications with familiar tools and frameworks.

Presenters:
🗣 @Stefan Wittmann, Product Manager at InterSystems
🗣 @Raj Singh, Product Manager, Developer Experience at InterSystems

Curious how it works? Watch the video and subscribe for more insights!

Discussion (0)1
Log in or sign up to continue
Question
· Oct 30

Pulling/pushing HL7 from/to a API

Hello,
I am currently facing the task of retrieving or sending HL7 messages from a web API. Since we only send HL7 messages via internal sockets, web APIs are relatively new to me.
The following is my plan for the new interface:
I have created a new custom business service that periodically sends requests to a business process. In this business process, the HTTP request (HTTP.GenericMessage) is then created from scratch. The special feature is the "Authorisation" header field, where a signature is inserted, which consists of a base64-encoded hash value. The request is then sent to the API via a business operation (EnsLib.HTTP.GenericOperation). The whole thing is also secured via TLS.
If you remove the TLS encryption, I even get a response from the API (a negative one). As soon as I add a SSL/TLS configuration, I get the following error message:

Have I made any major mistakes? What could I improve and what does this error message mean?

Regards

Robert

4 Comments
Discussion (4)3
Log in or sign up to continue
Article
· Oct 30 4m read

Testando Inconsistências de Metadados no InterSystems IRIS Usando o Banco de Dados DATATYPE_SAMPLE

Ao usar SQL padrão ou a camada de objetos no InterSystems IRIS, a consistência dos metadados é geralmente mantida por meio de validação integrada e imposição de tipo. No entanto, sistemas legados que ignoram essas camadas—acessando globals diretamente—podem introduzir inconsistências sutis e graves.

Compreender como os drivers se comportam nesses casos extremos é crucial para diagnosticar problemas de dados legados e garantir a confiabilidade da aplicação.

O banco de dados DATATYPE_SAMPLE foi projetado para ajudar a analisar cenários de erro onde os valores das colunas não estão em conformidade com os tipos de dados ou restrições definidas nos metadados. O objetivo é avaliar como o InterSystems IRIS e seus drivers (JDBC, ODBC, .NET) e diferentes ferramentas se comportam quando tais inconsistências ocorrem. Nesta publicação, focarei no driver JDBC.


Qual é o Problema?

Algumas aplicações legadas escrevem diretamente em globals. Se um modelo relacional (criado via CREATE TABLEou definido manualmente usando um mapeamento de global) for usado para expor esses dados, o mapeamento define que os valores subjacentes estão em conformidade com os metadados declarados para cada coluna.

Quando essa suposição é quebrada, diferentes tipos de problemas podem ocorrer:

  1. Falha de Acesso (Access Failure): Um valor não pode ser lido de forma alguma, e uma exceção é lançada quando o driver tenta acessá-lo.
  2. Corrupção Silenciosa (Silent Corruption): O valor é lido com sucesso, mas não corresponde aos metadados esperados.
  3. Mutação Não Detectada (Undetected Mutation): O valor é lido e parece válido, mas foi silenciosamente alterado pelo driver para se ajustar aos metadados, tornando a inconsistência difícil de detectar.

Simulando o Comportamento

Para demonstrar esses cenários, criei o banco de dados DATATYPE_SAMPLEdisponível no InterSystems Open Exchange:
🔗 Package page
🔗 GitHub repo

A tabela usada para a demonstração:

CREATE TABLE SQLUser.Employee (
   ID              BIGINT          NOT NULL AUTO_INCREMENT,
   Age             INTEGER,
   Company         BIGINT,
   DOB             DATE,
   FavoriteColors  VARCHAR(4096),
   Name            VARCHAR(50)     NOT NULL,
   Notes           LONGVARCHAR,
   Picture         LONGVARBINARY,
   SSN             VARCHAR(50)     NOT NULL,
   Salary          INTEGER,
   Spouse          BIGINT,
   Title           VARCHAR(50),
   Home_City       VARCHAR(80),
   Home_State      VARCHAR(2),
   Home_Street     VARCHAR(80),
   Home_Zip        VARCHAR(5),
   Office_City     VARCHAR(80),
   Office_State    VARCHAR(2),
   Office_Street   VARCHAR(80),
   Office_Zip      VARCHAR(5)
);

Exemplo 1: Falha de Acesso

Para simular uma inconsistência, injetei valores inválidos na coluna DOB(Date of Birth / Tipo de Dado DATE) usando acesso direto ao global. Especificamente, as linhas com chaves primárias 101, 180, 181, 182, 183, 184 e 185 foram preenchidas com valores que não representam datas válidas.

Os valores agora se parecem com isto:
 
Como você pode ver, uma string foi anexada ao final de um valor $H (Horolog). De acordo com os metadados da tabela, esta coluna deveria conter uma data—mas o valor armazenado claramente não é uma.

Então, o que acontece quando você tenta ler esses dados? Bem, isso depende da ferramenta que você está usando. Testei algumas ferramentas diferentes para comparar como elas lidam com esse tipo de inconsistência.

1) SquirrelSQL (SQuirreL SQL Client Home Page)


Quando o SquirrelSQL tenta acessar os dados, ocorre um erro. Ele tenta ler todas as linhas e colunas, e qualquer célula que contenha dados inválidos é simplesmente marcada como "ERROR". Infelizmente, não consegui encontrar quaisquer detalhes ou mensagens de erro adicionais explicando a causa.

  

2) SQLWorkbench/J (SQL Workbench/J -  Home)

O SQL Workbench/J para de processar o conjunto de resultados assim que encontra a primeira célula inválida. Ele exibe uma mensagem de erro como "Invalid date" (Data inválida), mas infelizmente, não fornece nenhuma informação sobre qual linha causou o problema.

 
3) DBVisualizer (dbvis) &  DBeaver (dbeaver)

O DBVisualizer e o DBeaver se comportam de forma semelhante. Ambas as ferramentas continuam lendo o conjunto de resultados e fornecem mensagens de erro detalhadas para cada célula afetada. Isso torna fácil identificar a linha correspondente que causou o problema.

   

4) SQL DATA LENS (SQL Data Lens - a powerful tool for InterSystems IRIS and Caché)

Com o lançamento mais recente do SQL DATA LENS, você obtém informações detalhadas sobre o erro, a linha afetada e o valor real do banco de dados. Conforme mostrado na captura de tela, o valor interno para a primeira linha na coluna DOB é "39146<Ruined>", que não pode ser convertido em um DATE válido.

O SQL DATA LENS também permite configurar se o processamento do resultado deve parar na primeira célula errônea ou continuar a leitura para recuperar todos os dados disponíveis.
 

A próxima parte deste artigo mostrará detalhes sobre:

Corrupção Silenciosa: O valor é lido com sucesso, mas não corresponde aos metadados esperados.

Mutação Não Detectada: O valor é lido e parece válido, mas foi silenciosamente alterado pelo driver para se ajustar aos metadados, tornando a inconsistência difícil de detectar.



Andreas

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