Code to copy class definition from one Namespace to another?
I have a situation where I have a handful of classes which I need to copy to another Namespace (which uses a different RoutineDB) on the same instance, load it and compile it.
Can anyone help me come up with a command that will do this quickly and easily? Perhaps something with extended reference?
This is somewhat time sensitive so thank you in advance for your ideas!
Comments
Wouldn't the quickest way just be something like $System.OBJ.Export(.items, exportfn) and $System.OBJ.Load(exportfn, "c")?
https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic…
Yes, with a ZNSPACE in between.
Thanks Matt, I am trying to avoid using the OS as the middle-man in this case as we have 300+ namespaces to do this on and so should be scripted. I can create a %Method that would do this but was hoping for a quick command that could just do the transfer
You could use %Dictionary.ClassDefinition to open the class definitions, use %ConstructClone and then save to another namespace.
Thanks Vik ... that sounds like a good approach to play with!
Consider $System.OBJ.ExportToStream() and .LoadStream() to avoid local files with a change to the appropriate implicit namespace between.
Thanks Chad - I think that this would be the lowest impact overhead approach if I don't copy the definitions directly via a clone or the globals
Set source = "NAMESPACE1" Set target = "NAMESPACE2" Kill ^|target|oddDEF(classname) Merge ^|target|oddDEF(classname) = ^|source|oddDEF(classname) New $Namespace Set $Namespace = target $$$ThrowOnError($System.OBJ.Compile(classname,"ck"))
EDIT: Don't do this. Everybody should ignore me and do what @Chad Severtson said instead.
thanks Tim - this is along the lines of what I was thinking about. Much appreciated!
You also need to merge over the index entry in ^rINDEXCLASS($$$UPPER(classname)) to the new namespace.
Don't forget to move all related classes such as Serial classes, datatype classes, super classes, references, etc.
This is exactly why my quick-and-dirty approach didn't (seem to?) work in a first quick attempt. ExportToStream/LoadStream it is!
(for context, this is moving class definitions over in conjunction with changing routine mappings)
Please do NOT make any assumptions about system globals such as the ^odd series. User code should stick to documented APIs such as the Export and Clone options described earlier in the thread.
Could you create an %ALL namespace and map the the routines in the %ALL namespace so they are available across all the namespaces?
We are using %ALL for some other things but unfortunately it won't apply in this case. Specifically, this is for a HS instance where we need to move auto-created classes into a new routine DB. So I can't add a mapping for each and every package (300 packages).
What about the export/import stream methode??
https://docs.intersystems.com/iris20222/csp/documatic/%25CSP.Documatic…
Thanks Clark - this is one of the approaches I hadn't thought of previously
with studio, I open 1 for each namespace and then drag and drop it from 1 NS to the other
works single or multiple
not so useful for 300. ns %ALL looks more promising
thanks for the input Robert ... %All is powerful but won't work for me in this scenario.
Why not map packages (also maybe use %ALL namespace to map to all namespaces at once)?
300 unique packages makes this approach unwieldy
Have you tried using a Installation Manifest
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cl…
💡 This question is considered a Key Question. More details here.
I know this is old, but recently I found a new way to export/import a package to a global, this may simplify the solution.
1) create a studio project with all the classes that need to me exported. This can be done programmatically, create an instance of %Studio.Project, use AddItem()...etc.
2) Export the project to a global like ^IRIS.Temp("myProjExport"). Open %Studio.Project, export ot global using DeployToGbl() method
3) in target namespace import calling ##class(%Studio.Project).InstallFromGbl()
Using ^IRIS.Temp has the advantage of easy/shared access from all namespaces.
Enrico