Mack Altman · Jan 6, 2017

What is the best method for copying Mappings and Routines?

Currently, we have an application running in one namespace ("Database B") that has globals and routines mapped to another database ("Database A"). After enforcing clean up on Database A, we found that 90% of the disk is free. We would like to compact Database A and release the unused space. However, we are running OpenVMS, which seems to be the issue.

For databases consisting of only globals, we are able to use ^GBLOCKCOPY; however, we need to ensure that the routines and mappings are also copied.

What would be the best recommended way to do this?

0 859
Discussion (8)0
Log in or sign up to continue

You could use the 'List' queries in Config.MapGlobals, Config.MapPackages, and Config.MapRoutines, match those to the database that you are copying from, then change those specific mappings to the new database. Here is an example that will change mappings for routines in the USER namespace from the USER database to the TEST database:

s startdb = "USER"
s enddb = "TEST"
s ns = "USER"
s rs=##class(%ResultSet).%New()
s rs.ClassName="Config.MapRoutines"
s rs.QueryName="List"
s sc=rs.Execute(ns) 
If 'sc Do DisplayError^%apiOBJ(sc) Quit
  while rs.%Next() {
   if (rs.GetDataByName("Database")=startdb) {
   s Properties("Database")=enddb
   d ##class(Config.MapRoutines).Modify(ns,rs.GetDataByName("Routine"),.Properties)
  d rs.%Close()

Routine and classes are just stored in globals like everything else. So if you copy all globals from one database to a brand new database then it will copy any routines/classes that were present in the original database to the new database too.

I see another answer already addressed the mapping question.

Quick'n'dirty way is to edit the cache.cpf file and then reactivate the config change. Simplest way to reactivate (though not always convenient) is to restart Caché.

write ##class(Config.CPF).Activate()

Would read and activate current configuration file without system restart.

Thanks Eduard. I'd add, this has to be done from the %SYS namespace.

S (A, B, C) = "^ SGCO" FSA = $ O (^ $ GLOBAL (A)) Q: A = !,UMA


It seems to me that your real issue is that your database is taking up too much space on disk and you want to shrink it.  To do this you really don't need to create a whole new database and namespace.  Even on non VMS systems before we had the compact and truncate functions I used to compact databases using GBLOCKCOPY which is pretty simple.

1.   Create a new database to hold the compacted globals

2.   Use GBLOCKCOPY to copy all globals from the large database to the new database you created in step 1.  Because routines are stored in the database they will be copied as well.

3.  Shutdown (or unmount) the original database and new compacted database

4.  Replace the huge CACHE.DAT file with the new compacted one.

5.  Remount new compacted database.

Global and Routine mappings are stored in the cache.cpf file and are related to the namespace configuration and not the database configuration.  After completing this process the database will be compacted and global/routine mappings will be preserved.

And of course, you shouldnt do any of this without a good backup of your original database.