Question
· Fév 4

Appel d'une classe depuis un autre Namespace, Y-a-t-il un moyen de mapper une table d'un NS dans un autre ?

Bonjour à tous,

Je cherche la syntaxe ou le moyen pour utiliser une classe créée dans le Namespace "BNA" (mon application) depuis le Namespace %SYS.

Voici le contexte :

Je dispose d'une application "BNA" contenue dans le NS "BNA", cette application met à disposition une fonctionnalité de création des utilisateurs. Cette fonctionnalité crée à la fois l'utilisateur dans une table de l'application et dans le système Iris.

J'ai créé un script d'initialisation de ma base pour pouvoir la réinitialiser à volonté, ce script commence par vider la base de ces données, puis initialise les données de base. Nous sommes en test de la fonctionnalité de création des utilisateurs, que nous réalisons avec un outil e2e (cypher). Lors de ces tests, nous créons une quinzaine d'utilisateurs avec des login auto-générés.

Dans mon script, je sais supprimer facilement les utilisateurs dans l'application, mais pour les utilisateurs Iris j'ai commencer une méthode pour récupérer les ID des utilisateurs, puis pour les supprimer. Pour l'instant j'ai développé uniquement la sélection et je souhaite utiliser une méthode d'une classe de mon application (##class(Bna.Utils.Sql).SelectFirstColsInArray()) qui me renvoie un tableau dynamique.

ClassMethod RemoveIrisTestUsers() As %Status
{
	New $NameSpace
	Set $NameSpace="%SYS"
	// Get test users by login begining
	Set query = "select * from Security.Users "_
				"where "_
    				"ID like LOWER('ARS%') or"_
		    		"ID like LOWER('CHERCHEUR%') or"_
    				"ID like LOWER('CS%') or"_
    				"ID like LOWER('DGOS%') or"_
					"ID like LOWER('CENTRE%')"
	Set sc = ##class(Bna.Utils.Sql).SelectFirstColsInArray(query, .userIds)
	if 'sc Return sc
	zw userIds

	Return $$$OK
}

 A l'exécution, j'obtiens 

<CLASS DOES NOT EXIST>RemoveIrisTestUsers+11^Bna.Init.Main.1 *Bna.Utils.Sql

Ce qui est normal, compte-tenu que je suis passé dans le NS "%SYS", d'ou ma question :

Appel d'une classe depuis un autre Namespace ?

Une alternative serait de rester dans le NS "BNA", mais dans ce cas c'est la table $Security.Users qui n'est pas accessible, d'ou ma seconde questrion.

Y-a-t-il un moyen de mapper une table d'un NS dans un autre ?

PS : Je sais tout à fait me passer d'utiliser ma méthode ##class(Bna.Utils.Sql).SelectFirstColsInArray(), mais j'aimerai bien connaitre les possibilités de travail entre les NS

Version du produit: IRIS 2023.3
$ZV: IRIS for UNIX (Ubuntu Server 22.04 LTS for x86-64) 2023.1 (Build 229U) Fri Apr 14 2023 17:29:40 EDT
Discussion (5)2
Connectez-vous ou inscrivez-vous pour continuer

Bonjour @Pierre LaFay

Oui, il est possible de faire du mapping, mais il faut bien distinguer deux choses:

  1. Package mapping Celui-ci permet de rendre accessible des package d'un namespace à un autre.   Dans le cas d'une classe %Persistent, il faut bien comprendre que seul le code sera mappé. En ce qui concerne les données enregistrée cela nous amène au 2ème point.  
  2. Global Mapping Il permet de rentre accessible les données de vos globals à votre namespace en spécifiant la base de données source.

Ces configurations peuvent s'effectuer par programmation ou plus simplement via le portail d'administration au niveau de la configuration du namespace (voici le lien de la doc officiel si cela peut vous être utile).

Dans le cas qui vous occupe peut être qu'il serait plus simple d'effectuer la requête SQL directement dans "RemoveIrisTestUsers" étant donné que vous faites déjà le changement de namespace.

Toutefois, pour un package de classe utilitaire comme "Bna.Utils" peut être que vous pourriez le mapper sur le namespace %ALL.

Le namespace %ALL, est spécial, les packages (ou les globals et routines) qui y sont mappées sont automatiquement accessible pour tous les autres namespace.  Donc le code : 

Set sc = ##class(Bna.Utils.Sql).SelectFirstColsInArray(query, .userIds)

Pourra être exécuter même si vous venez de faire un Set $Namespace = "%SYS".

Si besoin, je peux vous fournir une réponse plus complète avec des captures d'écran concernant la configuration avec %ALL.

Lorenzo.

Merci beaucoup @Lorenzo Scalese pour ta réponse rapide, claire et précise.

J'avais déjà pensé au mapping que j'ai déjà utiliser, mais je ne sais mapper que l'intégralité des routines ou des globales d'une base dans une autre, ce que je trouve trop global.

Dans mon cas précis, je m'en suis tiré en faisant hériter la classe contenant ma méthode RemoveIrisTestUsers de la classe Bna.Utils.Sql. Cela fonctionne car maintenant la méthode est dans la classe courante, le lien est fait avant que je ne change de NS :

ClassMethod RemoveIrisTestUsers() As %Status
{
    w "Suppression des utilisateurs de tests",!

	New $NameSpace
	Set $NameSpace="%SYS"

	// Get test users by login begining
	Set query = "select UPPER(ID) from Security.Users "_
				"where "_
    				"ID like LOWER('ARS-%') or "_
		    		"ID like LOWER('CHERCHEUR-%') or "_
    				"ID like LOWER('CS-%') or "_
    				"ID like LOWER('DGOS-%') or "_
					"ID like LOWER('CENTRE-%')"
	Set sc = ..SelectFirstColsInArray(query, .userIds)
	if 'sc Return sc
	for i=0 : 1 : userIds-1 {
		w userIds.%Get(i),!
	}

	Return $$$OK
}

Merci @Pierre LaFay .

Content que tu as pu trouver une solution :)

Le mapping même avec le namespace %ALL permet de sélectionner exactement ce que tu souhaites mettre à disposition des autres namespaces (donc pas forcément tout ce qui est dans une DB, une sélection peut être effectuée).  Je souligne ce point juste au cas ou cela te serait utile à l'avenir.

Lorenzo.

Merci @Lorenzo Scalese 

Je vais fouiller ça dans la doc, car je n'ai jamais fait de mapping autrement que globalement pour une BD. Je pense que cela doit être pratique dans certains cas (j'ai une reprise de données à faire, je pense que j'utiliserai cela pour accéder à certaines tables de la base source dans la nouvelle base).

Merci également pour le NS %All que je ne connaissais pas et qui semble très pratique !

Pierre