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 $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
}
ObjectScriptObjectScript
At run I get :
<CLASS DOES NOT EXIST>RemoveIrisTestUsers+11^Bna.Init.Main.1 *Bna.Utils.Sql
ObjectScriptObjectScript
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
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 $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 =obj.SelectFirstColsInArray(query, .userIds) if 'sc Return sc zw userIds Return $$$OK } Method SelectFirstColsInArray(query, test) { zwrite query,test return $$$OK } }
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.
Thanks to @Ashok Kumar & @Timo Lindenschmid
This is working fine, and I do that but this not an answer to my questions :
I think this must be possible by mapping %SYS bases, but I find this not very secure, I will search more in the doc...
@Pierre LaFay You could try %ALL mapping?
This may be useful: https://docs.intersystems.com/healthconnect20211/csp/docbook/DocBook.UI....
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
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.
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)
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
💡 This question is considered a Key Question. More details here.