Discussion (14)2
Log in or sign up to continue

I'll be interested to see others' thoughts on this as well, but one approach is:

  • Create a new empty database for the globals
  • Use GBLOCKCOPY or MERGE to copy each of the globals from the current DB to the new globals DB. I believe GBLOCKCOPY is faster than MERGE.
  • After they are copied/merged to the new DB kill the globals in the currrent DB. This then becomes your routines DB.

Or you can do the opposite and export all of your routines from the current DB, import them into a new routines DB, then delete them from the current DB which becomes your globals DB. This would be faster than the first approach unless your globals are really small.

That's in fact happening by separating Globals-DB from Routine-DB in the namespace definition.
Those globals are visible in any DB but they are used only for RoutineDB with a kind of implicit routine mapping.  (ages old and implemented shortly after "Big Bang") 
Once the Routine-DB is clean and isolated just copy the full DB 
or use $system.OBJ.Export(....)

As example of this implicit mapping a view of my ^ROUTINE in namespace DEMO

I agree with Steve

You can use ^%GOF, GBLOCKCOPY,  or even Merge ^Global=^[{Old_Namespace_Name}]Global as long as you know which globals you need, that the globals are not already mapped from some other namespace.

When it comes to your code you have to take into account your Classes (.cls), include files (.inc), routines (.int) (rarely used in new Ensemble/IRIS applications but there are applications that are written entirely in routines and use old style "nested dot" syntax in the form:

TestList xx (xx,TestList)=""
sort="" f  sort=$o(^Global($zn,$j,"Literal",dh1,SORT,dh2,Master,report,sort),-1) q:sort=""  d
. epis="" f  epis=$o(^Global($zn,$j,"Literal",dh1,SORT,dh2,Master,report,sort,id)) q:epis=""  d
. . depseq="" f  depseq=$o(^Global($zn,$j,"Literal",dh1,SORT,dh2,Master,report,sort,id,depseq)) q:depseq=""  d
. . . dep="" f  dep=$o(^Global($zn,$j,"Literal",dh1,SORT,dh2,Master,report,sort,id,depseq,dep)) q:dep=""  d
. . . . sectseq="" f  sectseq=$o(^Global($zn,$j,"Literal",dh1,SORT,dh2,Master,report,sort,id,depseq,dep,sectseq)) q:sectseq=""  d
. . . . . sect="" f  sect=$o(^Global($zn,$j,"Literal",dh1,SORT,dh2,Master,report,sort,id,depseq,dep,sectseq,sect)) q:sect=""  d
. . . . . . tsseq="" f  tsseq=$o(^Global($zn,$j,"Literal",dh1,SORT,dh2,Master,report,sort,id,depseq,dep,sectseq,sect,xyzseq)) q:tsseq=""  d
 

I kid you not... 

There are .mac (same as .int but with embedded SQL, which compile down to .int), BPL's, DTL's, Business Rules,  modified HL7 schema's, CSP pages in /csp/{namesapce}, corresponding .js and .css in the /csp/broker/ directory but not necessarily, it depends on how they are referenced in the HTML Header.

So, in my opinion, Steve is correct. Either dismount the current database (you can tell that it is not mounted if there is no .lck file in the database directory. If there is a .lck file and you proceed with copying the .dat database file, there is a good chance that when you try and assign the new .dat to a namespace, it may fail to mount. Better to shut down the instance.

It is probably easier to delete the globals from the original database than to delete the logic as there are so many extensions that you need to check for (as listed above, and if you didn't write the original application, it is easy to forget about the .inc, .dtl,  .bpl, .hl7, .mac, .int entities (if there are any of course).

Export the globals you plan to delete from the original database, and I would use the Management Portal frankly as it is easier to check the checkboxes next to the global names you want to delete (and export first before you delete) than type in the global names in any of the terminal utility such as ^%GOF. One typo, and you think you exported ^Customer but actually exported ^Kustomer, but you killed ^Customer, and then you realise that ^Customer was actually mapped into the namespace. Now you've deleted it in the source database, and you need to restore it, but you don't have an export because of that typo. The Management Portal allows you to exclude System Globals and Mapped Globals and avoid an accidental kill.

It is also a good idea to adopt a meaningful naming convention to indicate the difference between your DEV, QC, UAT and PRD databases and whether the database is for data (DT) or code (RT or RTN). It is also worth considering separating your stream data into a third database using global mapping. The reason for this is that if you have, for example, a Patient Class and one of the properties is Picture as %BinaryStream, the Binary Stream content will be stored in the 'S' global in the Storage Definition. Pictures of your Patient may be useful to display in your Patient Registration UI. Still, unless you are exporting that Patient as a FHIR Patient Resource, it is unlikely that you will reference the picture very often. Even with Objects, IRIS won't load the Picture into memory (Global Buffer Pool or your User Process) unless specifically referenced, i.e. "Patient.Picture". IRIS creates a "stream" directory though I am not sure what its purpose is. 

MyDatabase-DT-PRD (Data, Production)

MyDatabase-RT-PRD (Code, Production)

form Namespace

MyNamespace-PRD

Nigel