Is there a way to do an override of a %ALL Global Mapping?
Let's say I have an InterSystems IRIS instance with 6 Namespaces:
- Foo1
- Foo2
- Foo3
- Foo4
- Foo5
- Bar
And the number of Foo# namespaces can increase at any time for a number of reasons. I need to ensure that they all have identical configuration globals stored in a DB called CONFIG, so I do the following in my configuration file:
[Map.%ALL]
Global_SYS=%DEFAULTDB
Global_SYS("CommonConfig")=CONFIG
Global_SYS("CommonOtherSettings")=CONFIG
Global_SourceControl=CONFIG
This will ensure that all Namespace see the exact same settings when they reference ^SYS("CommonConfig") or ^SourceControl, etc.
Now...
... say that I need the "Bar" namespace to have unique ^SYS("CommonConfig") values and so I need to explicitly map it to a BARCONFIG database. Is there a way I can do this while maintaining my exiting %ALLl mappings? Please note that this isn't hypothetical, and the existing %ALL mappings are already deployed production configurations, so reworking those is not an option. I just need to figure out if there is an out of the box way to have my Bar namespace see different versions of these globals, or if I am going to have to write special logic to have Bar know it needs to look somewhere other than the standard configuration for its globals (which I really want to avoid since there are many, many places relying on these global locations)
Any advice and/or help would be most appreciated!!
"You cannot create namespace-specific mappings to resources that are mapped in the %ALL namespace, as %ALL mappings override any namespace-specific mappings to the same resource." - Docs
Create subscript level mappings for a correct database.
%ALL global mapping is higher priority than namespace mapping: if %ALL has ^a global mapped to db A and your namespace has ^a mapped to db B, global ^a from db A would be used when you access it from your namespace.
But, subscript mapping is higher priority than global mapping: if %ALL has ^a global mapped to db A and your namespace has ^a(1) mapped to db B, global ^a(1) from db B would be used when you access ^a(1) from your namespace.
thank you @Eduard Lebedyuk ... this is an interesting approach. Unfortunately, a couple of the globals I need to override for Bar are top level %ALL mappings, but others are subscripts so I may be able to cut down my custom coding using this approach.
You may have the option of using Extended Global References and in particular Bracket Syntax with References to Databases.
In your code you need to change all your global references from:
^SYS("CommonConfig")
to
^[%dbConfig]SYS("CommonConfig")
Then, for normal situation where you want the %ALL mapping to apply, just use:
set %dbConfig=""
When you need to explicitly map it to a BARCONFIG database, then:
set %dbConfig="^^:ds:BARCONFIG"
This way you can switch from default %ALL mapping to "explicit reference" within your code.
In the example I used a % local variable (%dbConfig) to hold the "database name reference" because it has a global scope, you may use a different approach like a property in some of your classes, a macro with some reference (in a global?) or...whatever is appropriate for your environment.
I like this in combination with a global mapped to %ALL that has:
^SYS("ConfigDatabaseOverride","BAR")="^^:ds:BARCONFIG"
So prior to references to the possibly-mapped global, you'd look to see if there's an override for the current namespace, and if there is, use it.
From a SMS point of view this is major hell.
If you are coding you application currently, then rather then checking a database for settings instead of using global mappings, code your application that it checks a "higher-priority global first" then defaults to the global default mapping.
example core config uses ^ %SYS for instance wide config and ^SYS for local namespace config.
In this scenario you would not even need a %ALL namespace global mapping.
I agree, but that's not the scenario of the initial question!
I tried to address and provide a solution to the original question that it seems has some previous constraints imposed by the current design, not to argue of what it could have been done if....
... I said the same thing that Enrico said. :p
💡 This question is considered a Key Question. More details here.