Written by

CEO at Ellipse
Question Pierre LaFay · Feb 4, 2024

Calling a class from another Namespace

Hello everyone,

I am looking for the syntax or the way to use a class created in the "BNA" Namespace (my application) from the %SYS Namespace.

Here is the context:

I have a "BNA" application contained in the "BNA" NS, this application provides a user creation functionality. This feature creates both the user in a table in the application and in the Iris system.

I created an initialization script for my database to be able to reset it at will, this script starts by emptying the database of this data, then initializes the basic data. We are testing the user creation functionality, which we are doing with an e2e tool (cypher). During these tests, we create around fifteen users with auto-generated logins.

In my script I know how to easily delete users in the application, but for Iris users I started a method to retrieve user IDs and then delete them. For the moment I have only developed the selection and I want to use a method of a class of my application (##class(Bna.Utils.Sql).SelectFirstColsInArray()) which returns me a dynamic array.

ClassMethod RemoveIrisTestUsers() As%Status
{
	New$NameSpaceSet$NameSpace="%SYS"// Get test users by login beginingSet 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
}

 At run I get : 

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

Which is normal, given that I moved to the NS "%SYS", hence my question:

Calling a class from another Namespace?

An alternative would be to stay in the NS "BNA", but in this case it is the $Security.Users table which is not accessible, hence my second question.

Is there a way to map a table from one NS to another?

PS: I know perfectly well without using my ##class(Bna.Utils.Sql).SelectFirstColsInArray() method, but I would like to know the possibilities of working between the NS

Comments

Ashok Kumar T · Feb 4, 2024

Hi @Pierre LaFay 

Define a Method instead of  ClassMethod and Instantiate the object for that class and call the required method. It will work

Class Bna.Utils.Sql Extends%RegisteredObject
{

ClassMethod RemoveIrisTestUsers() As%Status
{
    set obj = ..%New()
    New$NameSpaceSet$NameSpace="%SYS"// Get test users by login beginingSet 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 =obj.SelectFirstColsInArray(query, .userIds)
    if 'sc Return sc
    zw userIds

    Return$$$OK
}

Method SelectFirstColsInArray(query, test)
{
    zwrite query,test
    return$$$OK
}

}
0
Timo Lindenschmid · Feb 5, 2024

Your approach is actually correct. Just in class Bna.Init.Main extend Bna.Utils.Sql.

Then call the get method using set status=..SelectFirstColsInArray(query, .userIds)

That should work.

0
Pierre LaFay · Feb 5, 2024

Thanks to @Ashok Kumar T & @Timo Lindenschmid 
This is working fine, and I do that but this not an answer to my questions :

  • Calling a class from another Namespace?
  • Is there a way to map a table from one NS to another?

I think this must be possible by mapping %SYS bases, but I find this not very secure, I will search more in the doc...

0
Robert Cemper  Feb 5, 2024 to Pierre LaFay

You can map PACKAGE [aka. SQL Schema] to another Namespasce (not a single table)
e.g. Bna.Utils to namespace %ALL or just to a specific namespace
so you have Table and Class  (= the code) available.

If you want to share also DATA  you need to map also  the related Global 

0
Timo Lindenschmid  Feb 6, 2024 to Robert Cemper

Roberts approach is correct for mapping the class into another namespace. You have to use package mapping to map the class AND Global mapping to map the storage location. 

0
Prasanth Annamreddy · Feb 5, 2024

Hi Pierre,

It looks the error showing class does not exist, Here NS is defined in Uppercase letters and using the class name in different. Can you try like this..

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

0
Pierre LaFay  Feb 9, 2024 to Prasanth Annamreddy

Thanks for tour answer @Prasanth Annamreddy but the problem wasn't in the Package Name 

(in ##class() the param is full className : package.class), so in my Case Bna.Utils is the package and Sql is the classs

0