#InterSystems IRIS for Health

0 Abonnés · 382 Publications

InterSystems IRIS for Health™ est la première et la seule plateforme de données au monde conçue spécifiquement pour le développement rapide d'applications de santé afin de gérer les données les plus critiques du monde. Elle comprend de puissantes fonctionnalités prêtes à l'emploi : traitement et analyse des transactions, modèle de données de santé extensible, développement de solutions basé sur FHIR, prise en charge des normes d'interopérabilité de santé, etc. Toutes ces fonctionnalités permettent aux développeurs de créer rapidement de la valeur et des applications révolutionnaires. En savoir plus.

Annonce Irène Mykhailova · Juin 20, 2022

InterSystems et la communauté des développeurs autour de ZPM ont travaillé ensemble pour faire passer ZPM au niveau supérieur, en l'intégrant à IRIS et en en faisant un outil capable non seulement de gérer du code tiers, mais également des éléments clés des produits InterSystems. Vous pouvez en entendre beaucoup plus sur ce sujet lors du Global Summit 2022, et assister à un laboratoire d'expérience pour vous familiariser. 

0
0 40
Article Guillaume Rongier · Juin 15, 2022 17m read

Introduction

Nous sommes à l'ère de l'économie multiplateforme et les API sont la "colle " de ce scénario numérique. Étant donné leur importance, les développeurs les considèrent comme un service ou un produit à consommer. Par conséquent, l'expérience d'utilisation est un facteur crucial de leur succès.

Afin d'améliorer cette expérience, des normes de spécification telles que la spécification OpenAPI (OAS) sont de plus en plus adoptées dans le développement des API RESTFul.

IRIS ApiPub - qu'est-ce que c'est ?

IRIS ApiPub est un projet de type code source ouvert Open Source dont l'objectif principal est de publier automatiquement les API RESTful créées avec la technologie Intersystems IRIS, de la manière la plus simple et la plus rapide possible en utilisant la norme Open Specification API (OAS) standard, version 3.0.

Il permet à l'utilisateur de se concentrer sur la mise en œuvre et les règles métier (méthodes Web) de l'API, en abstrayant et en automatisant les autres aspects liés à la documentation, l'exposition, l'exécution et la surveillance des services.

Ce projet comprend également un exemple complet de mise en œuvre (apiPub.samples.api) de la Swagger Petstore, qui est l'échantillon officiel de swagger.

Testez-le avec vos services SOAP actuels

Si vous avez déjà publié des services SOAP, vous pouvez les tester en utilisant Rest/JSON avec OAS 3.0.

Lors de la publication de méthodes avec des types complexes, la classe de l'objet doit être une sous-classe de %XML.Adapter. De cette manière, les services SOAP précédemment installés sont rendus automatiquement compatibles.

Surveillez vos API avec IRIS Analytics

Activez la surveillance des API pour gérer et suivre tous vos Appels Rest. Vous pouvez également configurer vos propres indicateurs.

Installation

  1. Effectuez un clone/git pull depuis le dépôt dans le répertoire local.
$ git clone https://github.com/devecchijr/apiPub.git
  1. Ouvrez le terminal dans ce répertoire et exécutez la commande suivante :
$ docker-compose up -d
  1. Exécutez le conteneur IRIS avec le projet :
$ docker-compose up -d

Test de l'application

Ouvrez l'URL http://localhost:52773/swagger-ui/index.html de swagger

Essayez d'exécuter une opération à l'aide de l'API Petstore, par exemple en effectuant un postage d'un nouveau pet.

Consultez la table de bord du moniteur apiPub. Essayez d'explorer le domaine petStore pour explorer et analyser les messages.

Modifiez ou créez des méthodes dans la classe apiPub.samples.api et revenez à la documentation générée. Notez que toutes les modifications sont automatiquement reflétées dans la documentation OAS ou dans les schémas.

Publiez votre API selon la norme OAS 3.0 en seulement 3 étapes :

Étape 1

Définissez la classe d'implémentation de votre API et balises les méthodes avec l'attribut [WebMethod]

Cette étape n'est pas nécessaire si vous disposez déjà d'une mise en œuvre de WebServices.

Étape 2

Créez une sous-classe de apiPub.core.service et définissez sa propriété DispatchClass comme la classe Implementation créée précédemment. Incluez également le chemin de la documentation OAS 3.0. Si vous le souhaitez, pointez vers la classe apiPub.samples.api (PetStore).

Étape 3

Créez une application Web et définissez la classe de répartition comme la classe de service créée ci-dessus.

Utilisation de Swagger

Avec iris-web-swagger-ui vous pouvez exposer votre spécification de service. Il vous suffit de pointer vers le chemin de la documentation et... VOILÁ!!

Définition de l'en-tête de la spécification OAS

Il existe deux façons de définir l'en-tête OAS 3.0 :

La première consiste à créer un bloc JSON XDATA nommé apiPub dans la classe d'implémentation. Cette méthode autorise plus d'une balise et la modélisation est compatible avec la norme OAS 3.0. Les propriétés qui peuvent être personnalisées sont info, tags et servers.

XData apiPub [ MimeType = application/json ]
{
    {
        "info" : {
            "description" : "Il s'agit d'un exemple de serveur Petstore.  Vous pouvez en savoir plus sur Swagger à l'adresse suivante\n[http://swagger.io](http://swagger.io) or on\n[irc.freenode.net, #swagger](http://swagger.io/irc/).\n",
            "version" : "1.0.0",
            "title" : "IRIS Petstore (Dev First)",
            "termsOfService" : "http://swagger.io/terms/",
            "contact" : {
            "email" : "apiteam@swagger.io"
            },
            "license" : {
            "name" : "Apache 2.0",
            "url" : "http://www.apache.org/licenses/LICENSE-2.0.html"
            }
        },
        "tags" : [ {
            "name" : "pet",
            "description" : "Tout sur vos Pets",
            "externalDocs" : {
            "description" : "Pour en savoir plus",
            "url" : "http://swagger.io"
            }
        }, {
            "name" : "store",
            "description" : "Accès aux commandes du Petstore"
        }, {
            "name" : "user",
            "description" : "Opérations sur l'utilisateur",
            "externalDocs" : {
            "description" : "En savoir plus sur notre magasin",
            "url" : "http://swagger.io"
            }
        } ]
    }
}

La seconde méthode consiste à définir des paramètres dans la classe d'implémentation, comme dans l'exemple suivant :

Parameter SERVICENAME = "My Service";

Parameter SERVICEURL = "http://localhost:52776/apipub";

Parameter TITLE As %String = "REST aux API SOAP";

Parameter DESCRIPTION As %String = "API pour le proxy des services Web SOAP via REST";

Parameter TERMSOFSERVICE As %String = "http://www.intersystems.com/terms-of-service/";

Parameter CONTACTNAME As %String = "John Doe";

Parameter CONTACTURL As %String = "https://www.intersystems.com/who-we-are/contact-us/";

Parameter CONTACTEMAIL As %String = "support@intersystems.com";

Parameter LICENSENAME As %String = "Copyright InterSystems Corporation, tous droits réservés.";

Parameter LICENSEURL As %String = "http://docs.intersystems.com/latest/csp/docbook/copyright.pdf";

Parameter VERSION As %String = "1.0.0";

Parameter TAGNAME As %String = "Services";

Parameter TAGDESCRIPTION As %String = "Services d'héritage";

Parameter TAGDOCSDESCRIPTION As %String = "Pour en savoir plus";

Parameter TAGDOCSURL As %String = "http://intersystems.com";

Personnalisez vos API

Vous pouvez personnaliser plusieurs aspects de l'API, tels que les balises, les chemins et les verbes. Pour cela, vous devez utiliser une notation spéciale, déclarée dans le commentaire de la méthode personnalisée.

Syntaxe:

/// @apiPub[assignment clause]
[Method/ClassMethod] methodName(params as type) As returnType {

}

Toutes les personnalisations présentées à titre d'exemple dans cette documentation se trouvent dans la classe apiPub.samples.api.

Personnalisation des verbes

Lorsqu'aucun type complexe n'est utilisé comme paramètre d'entrée, apiPub attribue automatiquement le verbe Get. Dans le cas contraire, le verbe Post sera attribué.

Si vous souhaitez personnaliser la méthode, ajoutez la ligne suivante aux commentaires de la méthode.

/// @apiPub[verb="verb"]

verbe peut être get, post, put, delete ou patch.

Exemple:

/// @apiPub[verb="put"]

Personnalisation des chemins

Cet outil attribue automatiquement des chemins ou des routages aux Méthodes Web. Il utilise le nom de la méthode comme chemin, par défaut.

Si vous souhaitez personnaliser le chemin, ajoutez la ligne suivante aux commentaires de la méthode.

/// @apiPub[path="path"]

chemin peut être n'importe quelle valeur précédée d'un slash, tant qu'il n'entre pas en conflit avec un autre chemin dans la même classe d'implémentation.

Exemple:

/// @apiPub[path="/pet"]

Une autre utilisation très courante du chemin est de définir un ou plusieurs paramètres dans le chemin lui-même. Pour cela, le nom du paramètre défini dans la méthode doit être entouré d'accolades.

Exemple:

/// @apiPub[path="/pet/{petId}"]
Method getPetById(petId As %Integer) As apiPub.samples.Pet [ WebMethod ]
{
}

Lorsque le nom du paramètre interne diffère du nom du paramètre affiché, le nom peut être égalisé selon l'exemple suivant :

/// @apiPub[path="/pet/{petId}"]
/// @apiPub[params.pId.name="petId"]
Method getPetById(pId As %Integer) As apiPub.samples.Pet [ WebMethod ]
{
}

Dans l'exemple ci-dessus, le paramètre interne pId est affiché sous la forme petId.

Personnalisation des balises

Il est possible de définir le tag (regroupement) de la méthode lorsque plus d'un tag est défini dans l'en-tête.

/// @apiPub[tag="value"]

Exemple:

/// @apiPub[tag="user"]

Personnalisation du succès Code d'état

Si vous souhaitez modifier le Code d'état de réussite de la méthode, qui est 200 par défaut, il convient d'utiliser la notation suivante.

/// @apiPub[successfulCode="code"]

Exemple:

/// @apiPub[successfulCode="201"]

Personnalisation de l'exception Code d'état

Cet outil traite toutes les exceptions comme Code d'état 500 par défaut. Si vous souhaitez ajouter de nouveaux codes d'exception à la documentation, utilisez la notation suivante.

/// @apiPub[statusCodes=[{code:"code",description:"description"}]]

Où la propriété statusCodes est un tableau d'objets contenant le code et la description.

Exemple:

/// @apiPub[statusCodes=[
/// {"code":"400","description":"Invalid ID supplied"}
/// ,{"code":"404","description":"Pet not found"}]
/// ]

Lorsque vous soulevez l'exception, incluez Code d'état dans la description de l'exception entre les caractères "<" et ">".

Exemple:

Throw ##Class(%Exception.StatusException).CreateFromStatus($$$ERROR($$$GeneralError, "<400> Invalid ID supplied"))}

Voir la méthode getPetById de la classe apiPub.samples.api

Marquer l'API comme déconseillé

Pour que l'API soit affichée comme déconseillée, la notation suivante doit être utilisée :

/// @apiPub[deprecated="true"]

Personnalisation de l'operationId

Selon la spécification OAS, operationId est une chaîne unique utilisée pour identifier une API ou une opération. Dans cet outil, il est utilisé dans le même but lors des opérations de surveillance et suivi operations.

Par défaut, elle porte le même nom que la méthode de la classe d'implémentation.

Si vous souhaitez le modifier, utilisez la notation suivante

/// @apiPub[operationId="updatePetWithForm"]

Modification du jeu de caractères de la méthode

Le jeu de caractères par défaut est généralement défini à l'aide du paramètre CHARSET de la classe de service, décrit dans étape 2. Si vous souhaitez personnaliser le jeu de caractères d'une méthode, vous devez utiliser la notation suivante ::

/// @apiPub[charset="value"]

Exemple:

/// @apiPub[charset="UTF-8"]

Personnalisation des noms et autres caractéristiques des paramètres

Vous pouvez personnaliser plusieurs aspects des paramètres d'entrée et de sortie de chaque méthode, tels que les noms et les descriptions qui seront affichés pour chaque paramètre.

Pour personnaliser un paramètre spécifique, utilisez la notation suivante

/// @apiPub[params.paramId.property="value"]

ou pour des réponses :

/// @apiPub[response.property="value"]

Exemple:

/// @apiPub[params.pId.name="petId"]
/// @apiPub[params.pId.description="ID of pet to return"]

Dans ce cas, le nom petId et la description ID du pet à rendre sont attribués au paramètre défini comme pId

Lorsque la personnalisation n'est pas spécifique à un paramètre donné, la notation suivante est utilisée

/// @apiPub[params.property="value"]

Dans l'exemple suivant, la description Ceci ne peut être fait que par l'utilisateur connecté est attribuée à l'ensemble de la demande, et pas seulement à un seul paramètre :

/// @apiPub[params.description="Ceci ne peut être fait que par l'utilisateur connecté."]

Autres propriétés qui peuvent être personnalisées pour des paramètres spécifiques

Utilisez la notation suivante pour les paramètres d'entrée ou de sortie :

/// @apiPub[params.paramId.property="value"]

Pour les reponses:

/// @apiPub[response.property="value"]

Propriété
required: "true" si le paramètre est obligatoire. Tous les paramètres de type path sont déjà automatiquement requis
schema.items.enum: afficher les énumérateurs pour les types %String ou %Library.DynamicArray. Voir la méthode findByStatus de la classe apiPub.samples.api
schema.default: Pointe vers une valeur par défaut pour les énumérateurs
inputType: Pour les types simples, il s'agit par défaut d'un paramètre de requête. Pour les types complexes (corps), il s'agit par défaut de application/json. Dans le cas où vous souhaitez changer le type d'entrée, vous pouvez utiliser ce paramètre. Exemple d'utilisation : Téléchargement d'une image, qui n'est généralement pas de type JSON. Voir la méthode uploadImage de la classe apiPub.samples.api.
outputType: Pour les types %Status, la valeur par défaut est header. Pour les autres types, la valeur par défaut est application/json. Si vous souhaitez modifier le type de sortie, vous pouvez utiliser ce paramètre. Exemple d'utilisation : Retourner un jeton ("text/plain"). Voir la méthode loginUser de la classe apiPub.samples.api

Relier des schémas analysables à des types JSON dynamiques (%Library.DynamicObject)

Vous pouvez relier les schémas OAS 3.0 aux types dynamiques internes

L'avantage d'associer le schéma au paramètre, outre le fait d'informer l'utilisateur sur une spécification d'objet requise, est l'analyse automatique de la demande, qui est effectuée pendant l'appel API. Si l'utilisateur de l'API, par exemple, soumet une propriété qui ne figure pas dans le schéma, ou envoie une date dans un format non valide, ou n'inclut pas une propriété obligatoire, une ou plusieurs erreurs seront renvoyées à l'utilisateur contenant des informations sur ces problèmes.

La première étape consiste à inclure le schéma souhaité dans le bloc XDATA, comme indiqué ci-dessous. Dans ce cas, le schéma appelé User peut être utilisé par n'importe quelle méthode. Il doit suivre les mêmes règles que celles utilisées dans la modélisation [OAS 3.0] (https://swagger.io/docs/specification/data-models/).

XData apiPub [ MimeType = application/json ]
{
    {
        "schemas": {
            "User": {
                "type": "object",
                "required": [
                    "id"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "username": {
                        "type": "string"
                    },
                    "firstName": {
                        "type": "string"
                    },
                    "lastName": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "password": {
                        "type": "string"
                    },
                    "phone": {
                        "type": "string"
                    },
                    "userStatus": {
                        "type": "integer",
                        "description": "(short) User Status"
                    }
                }
            }            
        }
    }
}

La deuxième étape consiste à associer le nom du schéma renseigné à l'étape précédente au paramètre interne de type %Library.DynamicObject en utilisant la notation suivante :

/// @apiPub[params.paramId.schema="schema name"]

Exemple associant le paramètre user au schéma User :

/// @apiPub[params.user.schema="User"]
Method updateUserUsingOASSchema(username As %String, user As %Library.DynamicObject) As %Status [ WebMethod ]
{
    code...
}

Exemple de soumission d'une requête avec une erreur. La propriété username2 n'existe pas dans le schéma User. La propriété id n'est pas non plus définie alors qu'elle est requise :

{
  "username2": "devecchijr",
  "firstName": "claudio",
  "lastName": "devecchi junior",
  "email": "devecchijr@gmail.com",
  "password": "string",
  "phone": "string",
  "userStatus": 0
}

Exemple d'une réponse avec une erreur :

{
  "statusCode": 0,
  "message": "ERROR #5001: <Bad Request> Path User.id is required; Invalid path: User.username2",
  "errorCode": 5001
}

Voir les méthodes updateUserUsingOASSchema et getInventory de la classe apiPub.samples.api. La méthode getInventory est un exemple de schéma associé à la sortie de la méthode (réponse), elle n'est donc pas analysable.

Générer le schéma OAS 3.0 à partir d'un objet JSON

Pour faciliter la génération du schéma OAS 3.0, vous pouvez utiliser les éléments suivants ::

Définissez une variable avec un échantillon de l'objet JSON.

set myObject = {"prop1":"2020-10-15","prop2":true, "prop3":555.55, "prop4":["banana","orange","apple"]}

Utilisez la méthode utilitaire de la classe apiPub.core.publisher pour générer le schéma :

do ##class(apiPub.core.publisher).TemplateToOpenApiSchema(myObject,"objectName",.schema)

Copiez et collez le schéma renvoyé dans le bloc XDATA :

Exemple:

XData apiPub [ MimeType = application/json ]
{
    {
        "schemas": {
            {
                "objectName":   
                {
                    "type":"object",
                    "properties":{
                        "prop1":{
                            "type":"string",
                            "format":"date",
                            "example":"2020-10-15"      
                        },
                        "prop2":{
                            "type":"boolean",
                            "example":true
                        },
                        "prop3":{
                            "type":"number",
                            "example":555.55
                        },
                        "prop4":{
                            "type":"array",
                            "items":{
                                "type":"string",
                                "example":"apple"
                            }
                        }
                    }
                }
            }
        }
    }
}

Activer la surveillance (facultatif)

1 - Ajoutez et activez les composants suivants dans votre Production (IRIS Interopérabilité)

ComposantType
apiPub.tracer.bmService (BS)
apiPub.tracer.bsService (BS)
apiPub.tracer.boOpération (BO)

2 - Activez la surveillance de la classe décrite dans [l'étape 2] (https://github.com/devecchijr/apiPub#passo-2)

Le paramètre Traceable doit être activé.

Parameter Traceable As %Boolean = 1;

Parameter TracerBSName = "apiPub.tracer.bs";

Parameter APIDomain = "samples";

Le paramètre APIDomain est utilisé pour regrouper les API à surveiller.

3 - Importez les tableaux de bord

zn "IRISAPP"
Set sc = ##class(%DeepSee.UserLibrary.Utils).%ProcessContainer("apiPub.tracer.dashboards",1)

Vous pouvez également créer d'autres tableaux de bord, basés sur le cube apiPub Monitor.

Utilisez cet outil conjointement avec Intersystems API Manager

Acheminez vos API générées et bénéficiez de l'[Intersystems API Manager] (https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_IAM)

Compatibilité

ApiPub est compatible avec Intersystems IRIS ou Intersystems IRIS pour la santé, à partir de la version 2018.1.

Dépôt

Github: apiPub

2
0 116
Article Irène Mykhailova · Juin 9, 2022 1m read

Les champs peuvent être obtenu à l'aide du schéma INFORMATION_SCHEMA.

INFORMATION_SCHEMA est un schéma système et n'apparaît pas dans le menu SQL du Management Portal par défaut.

La méthode d'affichage est la suivante.

  1. Ouvrez le Management Portal → System Explorer → SQL
  2. Cochez "System" sur le côté gauche du menu déroulant du schéma.
  3. Sélectionnez INFORMATION_SCHEMA dans le menu déroulant du schéma.

Le SQL pour obtenir l'ID, le nom du champ (COLUMN_NAME), le type de données (DATA_TYPE) et la description (DESCRIPTION) pour la table spécifiée (Test.Person) est le suivant.

0
0 1517
Article Irène Mykhailova · Juin 2, 2022 1m read

Étant donné que SELECT ... FOR UPDATE est implémenté dans de nombreux RDBMS en tant que méthode d'acquisition de lock de ligne explicite, vous utilisez probablement cette fonctionnalité dans de nombreux cas.

Cette syntaxe n'entraîne pas d'erreur dans les produits InterSystems, mais elle n'acquiert pas les locks de ligne attendus.

Cet article vous montrera comment obtenir la même fonctionnalité.

DECLARE CURSOR C1 IS
SELECT Name FROM Person WHERE Name LIKE 'A%' FOR UPDATE
OPEN C1
LOOP FETCH C1 INTO name 
...afficher le nom...
...sortir de loop lorsque vous avez terminé...
END LOOP
CLOSE C1

 

L'instruction SQL ci-dessus peut être remplacée par l'instruction SQL suivante.

 &SQL(START TRANSACTION ISOLATION LEVEL READ COMMITTED)
 &SQL(UPDATE Person SET ID=ID Where Name like 'A%')
 &SQL(DECLARE C1 CURSOR FOR SELECT ID,Name into :id,:name FROM Person Where Name like 'A%')
 &SQL(OPEN C1)
 &SQL(FETCH C1)
 While (SQLCODE = 0) {
   Write id, ":  ", name,!  &SQL(FETCH C1)
 }
 &SQL(CLOSE C1)&SQL(COMMIT) 

 

Remarque : &SQL() est appelé Embedded SQL et est une méthode de description qui peut être utilisée lorsque vous souhaitez incorporer des instructions SQL dans la logique côté serveur. Veuillez vous référer au document pour plus de détails.

0
0 211
Article Lorenzo Scalese · Juin 1, 2022 9m read

Un système de stockage global d'aspect plus industriel

Dans le premier article de cette série, nous avons étudié le modèle entité-attribut-valeur (EAV) dans les bases de données relationnelles, et nous avons examiné les avantages et les inconvénients du stockage de ces entités, attributs et valeurs dans des tables. Nous avons appris que, malgré les avantages de cette approche en termes de flexibilité, elle présente de réels inconvénients, notamment une inadéquation fondamentale entre la structure logique des données et leur stockage physique, qui entraîne diverses difficultés.

Pour résoudre ces problèmes, nous avons décidé de voir si l'utilisation de globales - qui sont optimisées pour le stockage d'informations hiérarchiques - serait efficace pour les tâches que l'approche EAV traite habituellement.

Dans la Partie 1, nous avons créé un catalogue pour une boutique en ligne, d'abord en utilisant des tables, puis en utilisant une seule globale. Maintenant, essayons d'implémenter la même structure pour quelques globales.

Dans la première globale, ^catalog, nous allons stocker la structure du répertoire. Dans la deuxième globale, ^good, nous allons stocker les marchandises. Et dans la globale ^index, nous allons stocker les index. Puisque nos propriétés sont liées à un catalogue hiérarchique, nous ne créerons pas de globale séparée pour elles.

Avec cette approche, pour chaque entité (à l'exception des propriétés), nous avons une globale séparée, ce qui est bon du point de vue de la logique. Voici la structure du catalogue global :

 
Set ^сatalog(root_id, "Properties", "capacity", "name") = "Capacity, GB"
Set ^сatalog(root_id, "Properties", "capacity", "sort") = 1

Set ^сatalog(root_id, sub1_id, "Properties", "endurance", "name") = "Endurance, TBW"
Set ^сatalog(root_id, sub1_id, "Properties", "endurance", "sort") = 2

Set ^сatalog(root_id, sub1_id, "goods", id_good1) = 1
Set ^сatalog(root_id, sub1_id, "goods", id_good2) = 1

Set ^сatalog(root_id, sub2_id, "Properties", "avg_seek_time", "name") = "Rotate speed, ms"
Set ^сatalog(root_id, sub2_id, "Properties", "avg_seek_time", "sort") = 3

Set ^сatalog(root_id, sub2_id, "goods", id_good3) = 1
Set ^сatalog(root_id, sub2_id, "goods", id_good4) = 1

 

Une globale avec des marchandises ressemblera à quelque chose comme ceci :

Set ^good(id_good, property1) = value1
Set ^good(id_good, property2) = value2
Set ^good(id_good, property3) = value3
Set ^good(id_good, "catalog") = catalog_id

 

Bien sûr, nous avons besoin d'index afin que pour toute section du catalogue contenant des marchandises, nous puissions trier par les propriétés dont nous avons besoin. Une globale d'index aura une structure semblable à quelque chose comme ceci :

Configurer ^index(id_catalog, property1, id_good) = 1
; Pour obtenir rapidement le chemin complet du sous-catalogue concret
Configurer ^index("path", id_catalog) = "^catalog(root_id, sub1_id)"

 

Ainsi, dans n'importe quelle section du catalogue, on peut obtenir une liste triée. Une globale d'index est facultative. Il n'est utile que si le nombre de produits dans cette section du catalogue est important.

Code ObjectScript pour travailler avec des données de démonstration Demo Data

Maintenant, nous allons utiliser ObjectScript pour travailler avec nos données. Pour commencer, nous allons obtenir les propriétés d'une marchandise spécifique. Nous avons l'ID d'une marchandise particulière et nous devons afficher ses propriétés dans l'ordre donné par la valeur de tri. Voici le code pour cela :

get_sorted_properties(path, boolTable)
{
  ; mémoriser toutes les propriétés dans la globale temporaire
  While $QLENGTH(@path) > 0 {
    if ($DATA(@path("Properties"))) {
      set ln=""
      for {
	    Set ln = $order(@path("Properties", ln))
	    Quit: ln = ""

        IF boolTable & @path("Properties", ln, "table_view") = 1 {
  	      Set ^tmp(@path("Properties", ln, "sort"), ln) = @path("Properties", ln, "name")
	    }
	  ELSE {
  	    Set ^tmp(@path("Properties", ln, "sort"), ln) = @path("Properties", ln, "name")
	  }
    }
  }
}

print_sorted_properties_of_good(id_good)
{
  Set id_catalog = ^good(id_good, "catalog")
  Set path = ^index("path", id_catalog)

  Do get_sorted_properties(path, 0)

  set ln =""
  for {
   Set ln = $order(^tmp(ln))
   Quit: ln = ""
   Set fn = ""
   for {
 	Set fn = $order(^tmp(ln, fn))
 	Quit: fn = ""
 	Write ^tmp(ln, fn), " ", ^good(id_good, fn),!
   }
  }
}

 

Ensuite, nous voulons récupérer les produits de la section catalogue sous la forme de la table, basé sur id_catalog :

print_goods_table_of_catalog(id_catalog)
{
  Set path = ^index("path", id_catalog)
  Do get_sorted_properties(path, 1)

  set id=""
  for {
    Set id = $order(@path("goods"), id)
    Quit: id = ""

    Write id," ", ^good(id, "price"), " "

    set ln =""
    for {
      Set ln = $order(^tmp(ln))
      Quit: ln = ""
      Set fn = ""
      for {
 	    Set fn = $order(^tmp(ln, fn))
 	    Quit: fn = ""
 	    Write ^tmp(ln, fn), " ", ^good(id, fn)
      }
      Write !
    }
  }
}

 

Lisibilité : EAV SQL contre les globales

Comparons maintenant l'utilisation d'EAV et de SQL par rapport à l'utilisation de globales. En ce qui concerne la clarté du code, il est évident qu'il s'agit d'un paramètre subjectif. Mais regardons, par exemple, la création d'un nouveau produit.

Nous allons commencer par l'approche EAV, en utilisant SQL. Tout d'abord, nous devons obtenir une liste des propriétés de l'objet. Il s'agit d'une tâche distincte qui prend beaucoup de temps. Supposons que nous connaissions déjà les IDs de ces trois propriétés : capacité, poids, et endurance.

START TRANSACTION
INSERT INTO good (name, price, item_count, catalog_id) VALUES ('F320 3.2TB AIC SSD', 700, 10, 15);

SET @last_id = LAST_INSERT_ID ();

INSERT INTO NumberValues ​​Values​​(@last_id, @id_capacity, 3200);
INSERT INTO NumberValues ​​Values​​(@last_id, @id_weight, 0.4);
INSERT INTO NumberValues ​​Values​​(@last_id, @id_endurance, 29000);
COMMIT

 

Dans cet exemple, nous n'avons que trois propriétés, et l'exemple ne semble donc pas si inquiétant. Dans le cas général, nous aurions toujours quelques insertions dans la table de texte à l'intérieur de la transaction :

INSERT INTO TextValues ​​Values​​(@last_id, @ id_text_prop1, 'Text value of property 1');
INSERT INTO TextValues ​​Values​​(@last_id, @ id_text_prop2, 'Text value of property 2');
...
INSERT INTO TextValues Values (@last_id, @id_text_propN, 'Text value of property N');

 

Bien sûr, nous pourrions simplifier un peu la version SQL si nous utilisions la notation textuelle à la place des propriétés ID, par exemple "capacité" au lieu d'un nombre. Mais dans le monde SQL, ce n'est pas acceptable. Il est plutôt d'usage d'utiliser un ID numérique pour énumérer les instances d'entités. Cela permet d'obtenir des index plus rapides (il faut indexer moins d'octets), il est plus facile de suivre l'unicité et il est plus facile de créer automatiquement un nouvel ID. Dans ce cas, le fragment d'insertion aurait l'apparence suivante :

INSERT INTO NumberValues ​​Values​​(@last_id, 'capacity', 3200);
INSERT INTO NumberValues ​​Values​​(@last_id, 'weight', 0.4);
INSERT INTO NumberValues ​​Values​​(@last_id, 'endurance', 29000);

 

Voici le même exemple en utilisant des globales :

TSTART
Set ^good(id, "name") = "F320 3.2TB AIC SSD"
Set ^("price") = 700, ^("item_count") = 10, ^("reserved_count") = 0, ^("catalog") = id_catalog
Set ^("capacity") = 3200, ^("weight") = 0.4, ^("endurance") = 29000
TCOMMIT

 

Supprimons maintenant une marchandise en utilisant l'approche EAV :

START TRANSACTION
DELETE FROM good WHERE id = @ good_id;
DELETE FROM NumberValues ​​WHERE good_id = @ good_id;
DELETE FROM TextValues ​​WHERE good_id = @ good_id;
COMMIT

 

Et ensuite, faisons la même chose avec les globales :

Kill ^good(id_good)

Nous pouvons également comparer les deux approches en termes de longueur de code. Comme vous pouvez le constater dans les exemples précédents, lorsque vous utilisez des globales, le code est plus court. C'est une bonne chose. Plus le code est court, moins il y a d'erreurs et plus il est facile à comprendre et à gérer.

En général, un code plus court est aussi plus rapide. Et, dans ce cas, c'est certainement vrai, puisque les globales constituent une structure de données de niveau inférieur aux tables relationnelles.

Mise à l'échelle des données avec EAV et Globales

Ensuite, examinons la mise à l'échelle horizontale. Avec l'approche EAV, nous devons au moins distribuer les trois plus grandes tables sur les serveurs : Good, NumberValues, et TextValues. Les tables contenant des entités et des attributs peuvent simplement être entièrement copiés sur tous les serveurs, car ils contiennent peu d'informations.

Dans chaque serveur, avec une mise à l'échelle horizontale, des produits différents seraient stockés dans les tables Good, NumberValues et TextValues. Nous devrions allouer certains blocs d'identification pour les produits sur chaque serveur afin d'éviter la duplication des identifiants pour des produits différents.

Pour une mise à l'échelle horizontale avec des globales, il faudrait configurer des plages d'ID dans la globale et attribuer une plage de globale à chaque serveur.

La complexité est à peu près la même pour EAV et pour les globales, sauf que pour l'approche EAV, nous devrions configurer des plages d'ID pour trois tables. Avec les globales, nous configurons les ID pour une seule globale. C'est-à-dire qu'il est plus facile d'organiser la mise à l'échelle horizontale pour les globales.

Perte de données avec EAV et avec Globales

Enfin, considérons le risque de perte de données dû à des fichiers de base de données corrompus. Où est-il plus facile de sauvegarder toutes les données : dans cinq tables ou dans trois globales ( y compris une globale d'index ) ?

Je pense que c'est plus facile dans trois globales. Avec l'approche EAV, les données des marchandises différentes sont mélangées dans des tables, alors que pour les globales, les informations sont stockées de manière plus holistique. Les branches sous-jacentes sont stockées et triées séquentiellement. Par conséquent, la corruption d'une partie de la globale est moins susceptible d'entraîner des dommages que la corruption de l'une des tables dans l'approche EAV, où les données sont stockées comme des pâtes entremêlées.

Un autre casse-tête dans la récupération des données est l'affichage des informations. Avec l'approche EAV, les informations sont réparties entre plusieures tables et des scripts spéciaux sont nécessaires pour les assembler en un seul ensemble. Dans le cas des globales, vous pouvez simplement utiliser la commande ZWRITE pour afficher toutes les valeurs et les branches sous-jacentes du nœud.

Les Globales d'InterSystems IRIS : Une meilleure approche ?

L'approche EAV est apparue comme une astuce pour stocker des données hiérarchiques. Les tables n'ont pas été conçus à l'origine pour stocker des données imbriquées. L'approche EAV de facto est l'émulation des globales dans les tables. Étant donné que les tables représentent une structure de stockage de données de plus haut niveau et plus lente que les globales, l'approche EAV échoue par rapport aux globales.

À mon avis, pour les structures de données hiérarchiques, les globales sont plus pratiques et plus compréhensibles en termes de programmation, tout en étant plus rapides.

Si vous avez prévu une approche EAV pour votre projet, je vous suggère d'envisager d'utiliser les globales d'InterSystems IRIS pour stocker les données hiérarchiques.

0
0 408
Article Irène Mykhailova · Mai 31, 2022 1m read

La cause de cette erreur est que la ressource locked est déjà locked par un autre processus dans l'application et que le lock n'est pas libéré pour une raison quelconque.

S'il n'y a aucun signe que d'autres processus avec le lock, il est possible que la table de locks manque d'espace libre. Dans ce cas, le message LOCK TABLE FULL est envoyé au Message Log

Si vous effectuez un traitement transactionnel, il est possible que le report du lock ait un effet.
Veuillez vous référer aux documents suivants pour la transaction et le report de lock.

Using LOCK in Transactions【IRIS】

Using LOCK in Transactions

De plus, s'il existe un grand nombre d'enregistrements mis à jour par des instructions SQL dans la même table au cours d'une transaction, le seuil de lock (la valeur par défaut est 1000) est atteint et une escalade de lock se produit, entraînant un état de lock de table.

Comme vous pouvez le voir, il existe plusieurs causes possibles pour l'erreur de délai d'attente de lock. Tout d'abord, vérifiez l'état actuel du lock dans le menu de locks de Management Portal.

【Version 2011.1 ou ultérieure】
Management Portal : [System Operations]> [Lock]

【Version 2010.2 ou antérieure】
Management Portal :[Operations]> [Lock]

0
0 154
Article Irène Mykhailova · Mai 27, 2022 3m read

Il est possible de construire (reconstruire) l'index pendant que des données sont enregistrées/supprimées, mais si vous construisez l'index pendant ce processus, il sera référencé pendant sa mise à jour, utilisez donc l'utilitaire dédié et procédez à la construction de l'index.

La procédure est la suivante.

  1. Masquez le nom d'index que vous prévoyez d'ajouter l'optimiseur de requête.
  2. Ajoutez la définition de l'index et effectuez la construction de l'index.
  3. Une fois la construction de l'index est terminée, publiez l'index ajouté dans l'optimiseur.

L'exemple d'exécution est le suivant.

* Dans l'exemple, l'index standard HomeStateIdx est défini pour la colonne Home_State (informations d'état de l'adresse de contact) de Sample.Person.

1. Masquez le nom d'index que vous prévoyez d'ajouter l'optimiseur de requête.
SAMPLES>write $system.SQL.SetMapSelectability("Sample.Person","HomeStateIdx",0)
1


2.Après avoir ajouté la définition d'index, reconstruisez-la.
  Exemple de définition: Index HomeStateIdx On Home.State;

SAMPLES>do ##class(Sample.Person).%BuildIndices($LB("HomeStateIdx"))


3. Une fois la construction de l'index est terminée, publiez l'index ajouté dans l'optimiseur.

SAMPLES>write $system.SQL.SetMapSelectability("Sample.Person","HomeStateIdx",1)
1

Reportez-vous au plan de requête pour voir si l'index a été utilisé/non utilisé.
Dans l'exemple suivant, le résultat de la confirmation du plan avec le terminal basculé sur l'environnement d'exécution SQL avec $system.SQL.Shell() s'affiche (lors du référencement dans le Management Portal, après avoir exécuté SQL sur l'écran d'exécution de la requête, cliquez sur le bouton "Affichage du plan").

SAMPLES>do $system.SQL.Shell()
SQL Command Line Shell
----------------------------------------------------
The command prefix is currently set to: <>.
Enter q to quit, ? for help.
SAMPLES>>select ID,Name from Sample.Person where Home_State='NY'
1.      select ID,Name from Sample.Person where Home_State='NY'
ID      Name
61      Alton,Debby O.
138     Isaksen,Charlotte L.
175     Walker,Emily O.
3 Rows(s) Affected
statement prepare time(s)/globals/lines/disk: 0.0026s/35/974/0ms
          execute time(s)/globals/lines/disk: 0.0017s/216/2447/0ms
                          cached query class: %sqlcq.SAMPLES.cls1
---------------------------------------------------------------------------
SAMPLES>>show plan    // ★ Affichage du plan lorsque l'index n'est pas utilisé DECLARE QRS CURSOR FOR SELECT ID , Name FROM Sample . Person WHERE Home_State = ?
Read master map Sample.Person.IDKEY, looping on ID.
For each row:
    Output the row.
SAMPLES>>show plan    // ★ Affichage du plan lors de l'utilisation de l'index DECLARE QRS CURSOR FOR SELECT ID , Name FROM Sample . Person WHERE Home_State = ?
Read index map Sample.Person.HomeStateIdx, using the given %SQLUPPER(Home_State), and looping on ID.
For each row:
    Read master map Sample.Person.IDKEY, using the given idkey value.
    Output the row.
SAMPLES>>

Pour plus de détails, veuillez consulter les documents suivants.
Building Indices on a READ and WRITE Active System【IRIS】

Building Indices on a READ and WRITE Active System

0
0 81
Article Irène Mykhailova · Mai 23, 2022 6m read

Le type DATE correspond au type de données du produit InterSystems %Date et le type TIME correspond à %Time.

%Date enregistre une date interne (premier élément séparé par une virgule de la variable spéciale $Horolog), et %Time enregistre l'heure interne (deuxième élément séparé par une virgule de la variable spéciale $Horolog). La logique côté serveur utilise donc la valeur au format (logique) interne, sauf si vous changez le mode d'affichage.
La méthode permettant de modifier le format d'affichage de la date et de l'heure internes dans la logique côté serveur dépend de la méthode d'exploitation.

Dans les exemples suivants, nous utiliserons le tableau Sample.Person.
(L'exemple d'exécution de la commande est présenté pour une instruction SELECT, mais il peut également être écrit pour une instruction de mise à jour.)

Pour essayer IRIS/IRIS for Health, téléchargez la documentation à partir de (Télécharger des échantillons à utiliser avec InterSystems IRIS),
ou à partir de Articles connexes (téléchargement de la définition de classe de l'échantillon (Sample.Person) et création de données d'échantillon), veuillez commencer par importer la classe Sample.Person et créer les données d'exemple.

Si vous essayez Caché/Ensemble, utilisez Sample.Person dans l'espace de noms SAMPLES.


(1) Si vous utilisez l'Embedded SQL

Pour changer le format d'affichage à l'aide d'Embedded SQL, utilisez #sqlcomple select.
Les valeurs suivantes peuvent être spécifiées.

  • Logical (par défaut)
  • Display
  • ODBC
  • Runtime

Documentation (IRIS) : Compilation du SQL intégré et du préprocesseur de macros【IRIS】
Documentation : Compilation du SQL intégré et du préprocesseur de macros

#sqlcompile select=ODBC
&sql(declare C1 Cursor for select ID,Name,DOB into :pid,:name,:dob from Sample.Person where ID<=5)
&sql(open C1)
for {
    &sql(fetch C1)
    if SQLCODE'=0 { quit }
   //Exemple d'affichage)1-Mastrolito,Susan T.-2013-01-01
    write pid,"-",name,"-",dob,!
}
&sql(close C1)

(2) Si vous utilisez le Dynamic SQL 

Pour changer le format d'affichage en SQL dynamique à l'aide de %SQL.Statement, utilisez la propriété %SelectMode.
Cette propriété doit être définie avant l'exécution de %Execute().

Les valeurs qui peuvent être définies sont les suivantes.

  • 0: mode logique
  • 1: mode ODBC
  • 2: mode d'affichage
SAMPLES>set sql="select ID,Name,DOB from Sample.Person where ID <= 5" SAMPLES>set stmt=##class(%SQL.Statement).%New() SAMPLES>set st=stmt.%Prepare(sql) SAMPLES>set rset=stmt.%Execute() SAMPLES>do rset.%Display()
ID      Name    DOB
1       Gallant,Yan N.  42146
2       Waal,Umberto G. 45359
3       Jenkins,Sam A.  37404
4       Marks,Milhouse B.       52043
5       Hernandez,Phyllis W.    64590 5 Rows(s) Affected
SAMPLES>

(3) Lorsque vous utilisez une requête de classe 

Pour changer le format d'affichage dans une requête de classe, utilisez le paramètre de définition de la requête : SELECTMODE.
Les valeurs qui peuvent être spécifiées sont les suivantes

  • RUNTIME (par défaut)
  • LOGICAL
  • DISPLAY
  • ODBC

Voici un exemple de définition.

Query NewQuery1() As %SQLQuery(SELECTMODE = "ODBC")&lt;br>{&lt;br>select ID,Name,DOB from Sample.Person where ID&lt;=5&lt;br>}

(4) Comment changer le format d'affichage des processus en cours

L'objet système $SYSTEM.SQL.SetSelectMode() peut être utilisé pour modifier le format d'affichage du processus en cours.
Les arguments et les valeurs de retour sont les suivants.

  • Spécifiez 0 (logique), 1 (ODBC) ou 2 (affichage) comme premier argument.
  • Le second argument est un argument de type pass-by-reference dont le résultat d'exécution est défini par %Status.
  • La valeur de retour est le numéro du mode d'affichage en cours.

Veuillez vous référer à la page du document ci-dessous pour plus de détails.

Les bases d'InterSystems SQL - Options d'affichage des données【IRIS】
Options d'affichage de CachéSQL Basics_Data

// Changement du format par défaut au format ODBC
SAMPLES>set cm=$system.SQL.SetSelectMode(1,.st)
SAMPLES>set sql="select ID,Name,DOB from Sample.Person where ID <= 5"
SAMPLES>set stmt=##class(%SQL.Statement).%New()
SAMPLES>set st=stmt.%Prepare(sql)
SAMPLES>set rset=stmt.%Execute()
SAMPLES>do rset.%Display()
ID      Name    DOB
1       Gallant,Yan N.  1956-05-23
2       Waal,Umberto G. 1965-03-10
3       Jenkins,Sam A.  1943-05-30
4       Marks,Milhouse B.       1983-06-28
5       Hernandez,Phyllis W.    2017-11-03 5 Rows(s) Affected
SAMPLES>

※Après avoir changé le format d'affichage d'un processus, si le format d'affichage est modifié pour chaque méthode d'exécution SQL, le dernier format d'affichage spécifié sera utilisé.

(5) Comment convertir le format d'affichage à l'aide de fonctions ObjectScript

Une autre méthode consiste à utiliser les fonctions de conversion d'affichage d'ObjectScript pour convertir le format interne en format d'affichage.

Pour les fonctions de datation,
 Affichage -> Format interne $ZDATEH(yyyymmdd,8) ou $ZDATE(yyyy-mm-dd,3)
 Interne -> Pour obtenir le résultat du format d'affichage YYYYYMMDD : $ZDATE(+$Horolog,8) Si vous voulez obtenir le résultat de YYYYY-MM-DD : $ZDATEH(+$H,3), dans la fonction horaire
 Affichage -> format interne $ZTIMEH("HH:MM:SS")
 Interne -> Si vous voulez obtenir le résultat au format d'affichage HH:MM:SS : $ZTIMEH($piece($Horolog,"",2)), il existe également les fonctions $ZDATETIME() et $ZDATETIMEH() pour manipuler la date et l'heure.

Vous trouverez plus de détails sur les fonctions de date dans des documents suivants.
ObjectScript fonction【IRIS】
ObjectScript fonction

SAMPLES>write $horolog
63895,34979
SAMPLES>write $ZDATE(+$horolog,8)  /Conversion au format yyyymmdd>63895
SAMPLES>write $ZDATEH("2015-12-09",3)  // Conversion du format yyyy-mm-dd en format interne
63895
SAMPLES>write $ZTIME($piece($horolog,",",2))  // Conversion du format interne en format horaire
09:44:16
SAMPLES>write $ZTIMEH("10:01:11")  // Conversion de l'heure d'affichage au format interne
36071
SAMPLES>write $ZDATETIME($horolog,8)  // Conversion date/heure avec $horolog
20151209 09:45:15
SAMPLES>write $ZDATETIME($horolog,3)
2015-12-09 09:45:16
SAMPLES>
0
0 88
Annonce Irène Mykhailova · Mai 21, 2022

Les prospects, les clients et les employés peuvent désormais télécharger IRIS et IRIS for Health, les éditions Community et Enterprise sur https://evaluation.intersystems.com 

Cela permettra aux clients potentiels et aux clients actuels de tester les nouvelles fonctionnalités qui n'ont pas encore été publiées pour goûter les dernières et meilleures nouveautés en cours de développement.

Comment afficher :

Pour les Prospects il suffit de sélectionner une option avec "(Preview)" dans le nom pour accéder au téléchargement du logiciel d'aperçu

Pour les Clients et les Employés d'InterSystems - activez simplement la case à cocher Preview et cela inclura le logiciel d'aperçu dans le menu déroulant pour la version disponible :

Ressources additionnelles :

https://community.intersystems.com/post/introducing-evaluation-service-community-edition-downloads  

https://community.intersystems.com/post/intersystems-evaluation-service
 

0
0 72
Annonce Irène Mykhailova · Mai 9, 2022

Learning Services a publié le calendrier des formations en classe virtuelle jusqu'en septembre ! Tous les cours ont lieu de 9 h à 17 h, heure de l'Est des États-Unis, sous forme de salles de classe virtuelles en direct dirigées par un instructeur avec des exercices pratiques et des discussions interactives. Rendez-vous sur classroom.intersystems.com pour consulter l'horaire, vous inscrire à un cours ou demander une formation privée pour 5 à 15 personnes dans votre entreprise.

Suivre nos cours fait partie d'une excellente façon de se préparer à nos examens de certification professionnelle! Il convient de noter que du 7 au 9 septembre, nous proposons la formation InterSystems Change Control: Tier 1 Basics qui fait partie de la préparation recommandée pour le nouvel examen InterSystems CCR Technical Implementation Specialist. Rendez-vous sur certification.intersystems.com pour en savoir plus sur les examens disponibles, les exigences et les instructions de planification. De plus, InterSystems Certification surveillera les examens de certification gratuits (valeur de 150 $) au Global Summit 2022.

0
0 89
Annonce Irène Mykhailova · Avr 10, 2022

Docker 20.10.14 (publié le 23 mars 2022) modifie les capacités Linux accordées aux conteneurs d'une manière incompatible avec le vérificateur de capacités Linux dans les conteneurs InterSystems IRIS 2021.1 (et versions ultérieures).

Les utilisateurs exécutant Docker 20.10.14 sous Linux constateront que les conteneurs IRIS 2021.1+ ne démarreront pas et les journaux signaleront à tort que les fonctionnalités Linux requises sont manquantes. Par example :

[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.

Quoi faire

Les utilisateurs rencontrant ce problème devront ajuster la ligne de commande transmise au point d'entrée du conteneur pour désactiver la vérification des fonctionnalités Linux. À partir de la ligne de commande, ajoutez --check-caps false après l'image dans votre commande docker run ou docker start. Par example :

docker run containers.intersystems.com/intersystems/iris-community:2022.1.0.152.0 --check-caps false

Si vous utilisez docker-compose, le changement correspondant serait le suivant :

  command: --check-caps false

La vérification de capacité agit comme un moyen de vérifier les erreurs de configuration courantes avant de démarrer les processus IRIS. La désactivation de la vérification des capacités Linux n'a aucun impact sur les processus IRIS exécutés dans le conteneur.

En savoir plus

2
0 118
Article Irène Mykhailova · Avr 22, 2022 2m read

Comment rechercher une globale contenant un string spécifique ?

Vous pouvez afficher les globales dans le Management Portal et effectuer une recherche avec Ctrl + F, mais les grandes globales peuvent prendre du temps et être difficiles à afficher.

Bien sûr, vous pouvez effectuer une boucle en utilisant les fonctions $ORDER et $QUERY pour trouver la chaîne.

Mais il existe un moyen plus simple et plus pratique.

Il s'agit d'une méthode qui utilise la fonction de recherche globale de chaîne de caractères qui peut être effectuée dans le Management Portal.

Cela peut être facilement fait dans [System Explorer]> [Globals] : Rechercher dans le Management Portal.

Par exemple, pour rechercher dans le global ^%ISCLOG une variable contenant l'erreur "Erreur CSP de nettoyage après la page" :

 ↓


Si vous voulez vraiment le faire par programmation en utilisant les fonctions $ORDER et $QUERY :

* S'il y a plusieurs indices, utilisez la fonction $QUERY pour boucler dans plusieurs couches.

set glb="^%ISCLOG"
set glb=$query(@glb@(""))
for {
  if glb="" quit
  
  if @glb [ "CSP error cleaning up after page" {
     write glb,"=",@glb,! ;; <= you can take values with @glb
  }
  set glb=$query(@glb)
}


Le résultat de l'exécution est le suivant (la routine ci-dessus est enregistrée et exécutée par test.mac).

%SYS>Do ^test
^%ISCLOG("Data",5960)=
                        CSPServerUError cleaning up after page, HALTing ...
^%ISCLOG("Data",5960,0,"$ZE")=CSP error cleaning up after page, HALTing
^%ISCLOG("Data",10046)=
                         CSPServerUError cleaning up after page, HALTing...
^%ISCLOG("Data",10046,0,"$ZE")=CSP error cleaning up after page, HALTing
^%ISCLOG("Data",13398)=
                         CSPServerUError cleaning up after page, HALTing ...
^%ISCLOG("Data",13398,0,"$ZE")=CSP error cleaning up after page, HALTing
 
%SYS>
0
0 102
Article Sylvain Guilbaud · Avr 20, 2022 4m read

Lors d'une montée de version majeure il est conseillé de recompiler les classes et les routines de tous vos espaces de noms (cf. Major Version Post-Installation Tasks).

do $system.OBJ.CompileAllNamespaces("u")
do ##Class(%Routine).CompileAllNamespaces()

Pour automatiser cette tâche d'administration et conserver un journal des erreurs éventuelles, vous trouverez ci-dessous un exemple d'une classe à importer et compiler dans l'espace de noms USER que vous pourrez utiliser après chaque montée de version : admin.utils.cls

0
1 175
Article Sylvain Guilbaud · Avr 19, 2022 2m read

Kong fournit en open source un outil de gestion de ses configurations (écrit en Go), appelé decK (pour declarative Kong)

  • Vérifiez que decK reconnaît votre installation Kong Gateway via deck ping
deck ping   
Successfully connected to Kong!
Kong version:  2.3.3.2-enterprise-edition
  • Exporter la configuration de Kong Gateway dans un fichier "kong.yaml" via deck dump
deck dump
  • Après avoir modifié le kong.yaml, afficher les différences via deck diff
0
0 182
Article Irène Mykhailova · Avr 18, 2022 7m read

Vous avez probablement entendu parler des bases de données NoSQL. Il existe plusieurs définitions, mais pour simplifier, ce terme est couramment utilisé pour désigner les bases de données qui n'utilisent littéralement pas le langage SQL, c'est-à-dire les bases de données autres que les bases de données relationnelles (RDB).

InterSystems IRIS Data Platform vous permet de définir des tableaux et d'accéder aux données en SQL. Par conséquent, InterSystems IRIS Data Platform n'est pas strictement une base de données NoSQL. Cependant, les " Globales " à l'origine des hautes performances d'InterSystems IRIS sont une technologie de base d'InterSystems depuis 40 ans, fournissant ce que nous appellerions aujourd'hui une base de données NoSQL. Cet article montre comment créer des structures graphiques dans les "Globales" InterSystems IRIS et y accéder en Python.

NoSQL

Il y a des bases de données classées comme NoSQL qui traitent une variété de modèles de données. Des exemples typiques sont énumérés ci-dessous.

  • Key-Value: Maintient la correspondance entre les clés et les valeurs. Une base de données typique : Redis
  • Document: JSON ou XML sont utilisés comme modèle de données. Une base de données typique : MongoDB
  • Graph: Un modèle de structure de graphe comprenant des sections et des nœuds. Une base de données typique : Neo4j

Il existe une multitude d'autres produits et modèles de données. 

Historique de NoSQL

Pourquoi NoSQL est-il apparu et pourquoi est-il devenu si populaire ? Dans cet article, nous souhaiterions citer les raisons suivantes.

  • Les structures de données qui ne peuvent pas être représentées naturellement au moyen de tableaux: Théoriquement, toute structure de données peut être représentée dans un tableau et accessible par SQL, mais il peut y avoir des problèmes tels que la complexité SQL et des performances médiocres. Dans de tels cas, il est préférable d'utiliser un modèle de données adapté à la structure plutôt qu'un tableau.
  • Optimisation pour les environnements distribués:L'un des domaines où l'utilisation de NoSQL a pris de l'ampleur est celui de l'infrastructure des services de réseaux sociaux tels que Facebook. Pour prendre en charge de grandes quantités de données, de nombreux utilisateurs et une haute disponibilité, il est essentiel de distribuer la base de données. Les RDB ne fonctionnent pas toujours de manière optimale dans un environnement distribué. L'approche transactionnelle et sous-transactionnelle de la RDB, décrite ci-dessous, est également un facteur qui rend difficile sa mise en œuvre dans un environnement distribué.
  • Demande de traitement d'une transaction:Le traitement des transactions et l'intégrité des données sont des fonctions dans lesquelles les RDBs possèdent des points forts. Il va sans dire qu'un support strict du traitement des transactions et de l'intégrité des données est essentiel pour les systèmes qui gèrent les comptes bancaires, par exemple. Cependant, le maintien de l'intégrité des données dans le traitement des transactions est très difficile à mettre en œuvre dans un environnement distribué, notamment en ce qui concerne la compatibilité avec les performances. Par conséquent, si vous souhaitez donner la priorité à l'amélioration des performances et de la disponibilité dans un environnement distribué plutôt qu'au maintien d'une cohérence stricte, NoSQL pourrait mieux répondre à vos besoins que RDB.

Globales

InterSystems IRIS utilise une structure de données appelée Globales au cœur de la base de données. Les Globales sont modélisées comme des variables de tableau, comme le montre la figure suivante.

Les Globales n'ont pas besoin d'être définies préalablement (sans schéma), ce qui permet une conception très souple des structures de données. En outre, les données sont toujours triées par ordre d'indice (clé), tant sur le disque que dans le cache mémoire, ce qui localise et accélère l'accès aux données et évite la fragmentation.

Bien que les Globales aient la forme de variables de tableau, ils peuvent en fait être utilisés dans IRIS ObjectScript, qui est un langage de script pour IRIS, avec presque la même syntaxe que les variables en mémoire, ce qui améliore les perspectives de développement de programmes. Pour plus d'informations sur les Globales, voir la section Global Usage Documentation.

Accès en utilisant Python

Voici un exemple de manipulation de Globales en utiisant Python à l'aide de Python Native API.

Nous utiliserons les données "WikiSpeedia" de SNAP à l'Université de Standford comme point de départ. WikiSpeedia est un jeu dans lequel les joueurs s'affrontent pour voir à quelle vitesse ils peuvent atteindre un mot cible à partir d'un mot donné en suivant uniquement les liens Wikipédia. SNAP compte environ 110 000 liens suivis par des utilisateurs réels, qui sont stockés globalement dans InterSystems IRIS.

Structure du graphe

Cette section décrit la structure du graphe.

La figure suivante présente les principes de base de la structure d'un graphe. Un graphe est constitué de nœuds et d'arêtes. Une arête relie deux nœuds.

Par exemple, une relation d'amitié sur Facebook peut être représentée par nœud = utilisateur, arête = relation d'amitié. Une structure de données pouvant être utilisée pour la recherche d'itinéraires est aussi réalisable en définissant le nœud = station, l'arête = station voisine de la précédente station, et la caractéristique de l'arête = distance entre les stations.

Dans l'exemple de ce document, la structure du graphe est utilisée comme suit : nœud = article Wikipédia (mot-clé) et arête = relation entre l'article original et l'article lié vers lequel l'utilisateur de WikiSpeedia a cliqué.

Structure des Globales

Examinons la structure des Globales.

^Links("Tokyo", "18th_century")=""
^Links("Tokyo", "London")=""
^Links("Osaka", "Aquarium")=""

Par exemple, la ligne supérieure indique que l'utilisateur a cliqué sur un lien à partir de l'article "Tokyo" vers l'article "18th_century". La troisième ligne indique que l'utilisateur a cliqué à partir de "Osaka" vers "Aquarium".

Les Globales sont optimisées pour un accès de gauche à droite aux souscripteurs (clés). Ainsi, le

^Links("Article original", "Cliquer sur l'article")=""

est optimale. En outre, dans ce cas, la valeur est "", mais si vous voulez que les arêtes aient un certain attribut, vous pouvez le définir sur une valeur globale.

Code Python

Cette section décrit le code Python. D'abord, c'est import.

import irisnative
import networkx as nx

Pour utiliser l'API native Python, importez le module irisnative. Ce module est un fichier .whl placé dans le répertoire dev/python lors de l'installation d'IRIS et installé dans l'environnement python avec la commande pip. De plus, comme NetworkX est utilisé pour maintenir la structure du graphe, importez-le également.

connection = irisnative.createConnection("localhost", 9091, "user", "horita","horita")
iris_native = irisnative.createIris(connection)

Dans ces deux lignes, createConnection() établit la connexion à IRIS et createIris() crée l'objet d'interface pour les opérations globales.

def addNodes(key, g, d):
    g.add_node(key)
    if d > 3:
        return
    
    iter = iris_native.iterator("Links", key)
    nodelist = [k for k,v in iter.items()]

    Limité à 3 liens à suivre pour des raisons de démonstration
    random.shuffle(nodelist)
    nodelist = nodelist[0:3]

    edgelist = [(key, n) for n in nodelist]
    g.add_nodes_from(nodelist)
    g.add_edges_from(edgelist)
    
    for subk in nodelist:
        addNodes(subk, g, d + 1)

Définition de la fonction addNodes(). Cette fonction construit une structure de graphe en tant qu'objet NetworkX en suivant les liens des noeuds dans un graphe donné. Des appels récursifs sont utilisés pour traverser le troisième niveau de la hiérarchie. Le point principal ici est

    iter = iris_native.iterator("Links", key)
    nodelist = [k for k,v in iter.items()]

Dans iris_native.iterator("Links", key), l'API native Python crée un itérateur pour l'indice. Par exemple, key='Tokyo' serait un itérateur qui itère sur la chaîne dans la partie * de ^Links("Tokyo", *).

L'itérateur est ensuite répété dans Python pour créer une liste. Comme vous pouvez le constater, l'itérateur de la globale s'intègre parfaitement au modèle itératif de Python, ce qui permet d'obtenir un code simple.

curkey = 'Tokyo'
G = nx.Graph()
addNodes(curkey, G, 1)

Ensuite, addNodes() est appelé en prenant le mot "Tokyo" comme clé. Cela nous donnera l'enchaînement des liens tracés à partir du mot "Tokyo". Il est montré dans la figure suivante.

Le réseau des mots cliqués à partir du mot "Tokyo" est ainsi représenté.

Conclusion

Les globales d'InterSystems IRIS sont une force avec laquelle il faut compter dans les cas où une base de données NoSQL est la base de données de choix. En outre, l'API native Python vous permet de manipuler les globales de manière naturelle à partir de vos programmes Python.

Nous vous encourageons à l'essayer. Par ailleurs, nous serions très heureux si vous pouviez écrire vos questions dans les commentaires de cet article.

0
0 191
InterSystems officiel Guillaume Rongier · Mars 20, 2022

L'équipe des Plateformes de Données est très heureuse d'annoncer la version 2021.2 d'InterSystems IRIS Data Platform, InterSystems IRIS for Health et HealthShare Health Connect qui sont désormais généralement disponibles (GA) pour nos clients et partenaires.

Faits saillants de la version

InterSystems IRIS Data Platform 2021.2 facilite encore plus le développement, le déploiement et la gestion d'applications augmentées et de processus d'affaires qui relient les entrepôt de données et d'applications. Il a de nombreuses nouvelles fonctionnalités, notamment:

0
0 57
InterSystems officiel Guillaume Rongier · Mars 19, 2022

REMARQUE : Nous avons précédemment détecté un problème avec les versions 2021.1.1.324.0. Les versions de maintenance 2021.1.1 ont été supprimées du WRC et remplacées par les versions 2021.1.2.336.0.  Les conteneurs 2021.1.2 seront bientôt disponibles.

Deux nouveaux ensembles de versions de maintenance sont désormais disponibles: 

  • Caché  2018.1.6, Ensemble 2018.1.6 et HSAP 2018.1.6
  • InterSystems IRIS 2020.1.2, IRIS for Health 2020.1.2 et HealthShare Health Connect 2020.1.2

Les kits d'installation et les conteneurs peuvent être téléchargés sur le site WRC Software Distribution. Les images de conteneur pour les éditions Enterprise d'InterSystems IRIS et IRIS for Health et tous les éléments correspondants sont disponibles dans InterSystems Container Registry.

0
0 97
InterSystems officiel Guillaume Rongier · Mars 18, 2022

Ce message renvoie à 14 avis récents qui ont été publiés sur la page InterSystems Product Alerts and Advisories page. Tous les éléments affectent les produits HealthShare, et les trois premiers éléments affectent également InterSystems IRIS for Health.

0
0 59
InterSystems officiel Guillaume Rongier · Mars 18, 2022

La version 3.3 d'InterSystems Kubernetes Operation (IKO) est désormais disponible via la page de téléchargement WRC et le registre de conteneurs InterSystems.

IKO simplifie le travail avec InterSystems IRIS ou InterSystems IRIS for Health dans Kubernetes en fournissant une définition de ressource irisCluster facile à utiliser. Consultez la documentation pour une liste complète des fonctionnalités, y compris le sharding, le mirroring et la configuration d'ECP.

Faits saillants de l'IKO 3.3 :

  • Le support des éditions 2021.2 et 2022.1 d'InterSystems IRIS et IRIS for Health
  • Le support de Kuberentes 1.21
  • Déployez des configurations communes d'Alerte et de Surveillance du Système (ASS) dans le cadre de votre irisCluster
  • InterSystems API Manager (IAM) peut désormais également être déployé et géré dans le cadre de votre irisCluster
  • Balisage automatique du côté actif de la paire de miroirs, de sorte qu'un service puisse toujours pointer vers le miroir actif.
0
0 67
InterSystems officiel Guillaume Rongier · Mars 16, 2022

InterSystems est très heureux d'annoncer la sortie de la version 2021.1 de la plateforme de données InterSystems IRIS, InterSystems IRIS for Health et HealthShare Health Connect, qui sont maintenant généralement disponibles pour nos clients et partenaires.

Les améliorations apportées à cette version offrent aux développeurs une plus grande liberté pour créer des applications rapides et robustes dans le langage de leur choix, tant du côté serveur que du côté client. Cette version permet également aux utilisateurs de consommer plus efficacement de grandes quantités d'informations grâce à de nouvelles capacités d'analyse plus rapides.

Nous nous attendons à ce que de nombreux clients et partenaires mettent à niveau leurs déploiements de Caché et d'Ensemble vers cette version d'IRIS d'InterSystems et nous avons tout mis en œuvre pour que cette transition se fasse sans heurts et soit utile. La plupart des applications verront des avantages immédiats en termes de performance juste en fonctionnant sur InterSystems IRIS, avant même d'explorer les nombreuses et puissantes capacités qu'IRIS apporte.

Nous vous invitons cordialement à participer à notre webinaire présentant les points forts de la nouvelle version, le 17 juin à 11h00 EDT. Le webinaire sera enregistré et pourra être revisionné par la suite. Vous pouvez également écouter l'épisode de notre podcast Data Points sur les nouveautés de la version 2021.1.

Points forts de la version

Avec InterSystems IRIS 2021.1, les clients peuvent déployer InterSystems IRIS Adaptive Analytics, un produit complémentaire qui étend InterSystems IRIS pour fournir aux utilisateurs professionnels une facilité d'utilisation supérieure et des capacités d'analyse en libre-service pour visualiser, analyser et interroger de vastes quantités de données afin d'obtenir les informations dont ils ont besoin pour prendre des décisions commerciales précises et opportunes, sans être des experts en conception ou en gestion de données. Adaptive Analytics accélère de manière transparente les charges de travail de requêtes analytiques qui s'exécutent contre InterSystems IRIS en construisant et en maintenant de manière autonome des structures de données intermédiaires en arrière-plan.

Les autres fonctionnalités phares de cette version sont les suivantes :

  • Une meilleure gestion pour nos serveurs de langues externes, qui couvrent désormais également R et Python. Cette technologie de passerelle permet de tirer parti de manière robuste et évolutive du code côté serveur dans le langage de votre choix
  • InterSystems Kubernetes Operator (IKO) offre une configuration déclarative et une automatisation pour vos environnements, et prend désormais en charge le déploiement d'InterSystems System Alerting & Monitoring (SAM).
  • InterSystems API Manager v2.3, comprenant une expérience utilisateur améliorée, la prise en charge de Kafka et le mode hybride.
  • Disponibilité généralisée d'IntegratedML, permettant aux développeurs SQL de créer et de déployer des modèles d'apprentissage automatique directement dans un environnement purement SQL. 
  • Prise en charge des champs de flux sur les tables sharded, vous offrant une flexibilité totale des schémas SQL sur l'architecture horizontalement extensible InterSystems IRIS
  • Une image de conteneur iris-lockeddown, mettant en œuvre de nombreuses bonnes pratiques de sécurité telles que la désactivation de l'accès Web au portail de gestion et les permissions appropriées au niveau du système d'exploitation.
  • Prise en charge de la clé de preuve pour l'échange de codes (PKCE) pour Oauth 2.0

InterSystems IRIS for Health 2021.1 comprend toutes les améliorations d'InterSystems IRIS. En outre, cette version étend encore la prise en charge complète de la plateforme pour la norme FHIR® grâce à des API permettant d'analyser et d'évaluer les expressions FHIRPath par rapport aux données FHIR. Cela s'ajoute aux importantes capacités liées à FHIR publiées depuis 2020.1, notamment la prise en charge des profils FHIR, des transformations FHIR R4 et de l'API client FHIR.

Cette version comprend également HealthShare Health Connect, notre moteur d'intégration basé sur InterSystems IRIS for Health, qui assure la prise en charge de transactions à haut volume, la gestion des processus et la surveillance pour soutenir les applications critiques. Pour un aperçu détaillé de la comparaison de son ensemble de fonctionnalités avec InterSystems IRIS for Health, veuillez consulter ce lien.

Vous trouverez plus de détails sur toutes ces fonctionnalités dans la documentation du produit, qui a récemment été rendue encore plus facile à naviguer grâce à une table des matières latérale pratique.

Si vous effectuez une mise à niveau à partir d'une version antérieure et utilisez TLS 1.3, veuillez consulter ces considérations de mise à niveau.

Comment obtenir le logiciel

InterSystems IRIS 2021.1 est une version de maintenance étendue (EM) et est livré avec des paquets d'installation classiques pour toutes les plateformes prises en charge, ainsi que des images de conteneur au format OCI (Open Container Initiative), c-à-d. au format Docker. 

Les packages d'installation complets pour chaque produit sont disponibles sur le site de téléchargement des produits du WRC. L'utilisation de l'option d'installation « personnalisée » permet aux utilisateurs de choisir les options dont ils ont besoin, telles que InterSystems Studio et IntegratedML, afin de réduire l'empreinte de leur installation.

Les images de conteneur pour les éditions Enterprise d'InterSystems IRIS et d'InterSystems IRIS for Health et tous les composants correspondants sont disponibles à partir du registre de conteneurs InterSystems à l'aide des commandes suivantes :

docker pull containers.intersystems.com/intersystems/iris:2021.1.0.215.0
docker pull containers.intersystems.com/intersystems/iris-ml:2021.1.0.215.0
docker pull containers.intersystems.com/intersystems/irishealth:2021.1.0.215.0
docker pull containers.intersystems.com/intersystems/irishealth-ml:2021.1.0.215.0

Pour une liste complète des images disponibles, veuillez vous référer à la documentation ICR.

Les images de conteneur pour l'édition communautaire peuvent également être tirées de la boutique Docker à l'aide des commandes suivantes :

docker pull store/intersystems/iris-community:2021.1.0.215.0docker pull store/intersystems/iris-ml-community:2021.1.0.215.0docker pull store/intersystems/irishealth-community:2021.1.0.215.0docker pull store/intersystems/irishealth-ml-community:2021.1.0.215.0

Alternativement, des versions tarball de toutes les images de conteneur sont disponibles via le site de téléchargement de produits du WRC.

InterSystems IRIS Studio 2021.1 est un IDE autonome à utiliser avec Microsoft Windows et peut être téléchargé via le site de téléchargement de produits du WRC. Il fonctionne avec InterSystems IRIS et InterSystems IRIS for Health version 2021.1 et suivantes. InterSystems prend également en charge le plugin ObjectScript VSCode pour développer des applications pour InterSystems IRIS avec Visual Studio Code, qui est disponible pour Microsoft Windows, Linux et MacOS.

D'autres composants autonomes d'InterSystems IRIS 2021.1, tels que le pilote ODBC et la passerelle Web, sont disponibles sur la même page.

Partager vos expériences

Nous n'avons l'occasion d'annoncer qu'une seule version EM par an. Nous sommes donc ravis de voir cette version franchir le cap de GA et impatients de connaître vos expériences avec le nouveau logiciel. N'hésitez pas à nous contacter par l'intermédiaire de votre équipe de compte ou ici sur la Communauté des développeurs pour nous faire part de vos commentaires sur la technologie ou les cas d'utilisation que vous traitez avec elle.

Pour certaines nouvelles fonctionnalités et certains nouveaux produits, nous avons mis en place des programmes d'accès anticipé afin de permettre à nos utilisateurs d'évaluer le logiciel avant sa sortie. Grâce à ces initiatives ciblées, nous pouvons apprendre de notre public cible et nous assurer que le nouveau produit répond à ses besoins lors de sa sortie. Si vous souhaitez participer à l'un de ces programmes, veuillez contacter l'équipe en charge de votre compte ou consulter la Communauté des développeurs.

0
0 92