Discussion Sylvain Guilbaud · Feb 21, 2022

Let's consider you would like to efficiently store your historical data in a similar structure than the one used for your current data, but without sharing the same physical storage (ie : not in the same global). What is the most efficient way to do it ?

Below a simple class of your current data : 


Class data.current.person Extends (%Persistent, %Populate)
{

Parameter DEFAULTGLOBAL = "^on.person";

9
0 540
Article Sylvain Guilbaud · Oct 6, 2016 3m read

to dismount/mount a database, use Dismount() and Mount() methods in SYS.Database class available in %SYS namespace.
NB: the database ID is its Directory

You'll find  some examples of how to dismount/mount and check if a database is mounted (Mounted=1) or not (Mounted=0), and quickly see all the attributes of a database (via zwrite)


%SYS>set db="/opt/irisapp/data" 

%SYS>w ##class(SYS.Database).%OpenId(db).Mounted                     
1
%SYS>w ##class(SYS.Database).%OpenId(db).Dismount()
1
%SYS>w ##class(SYS.Database).%OpenId(db).Mounted   
0
%SYS>w ##class(SYS.Database).%OpenId(db).Mount()   
1
%SYS>w ##class(SYS.Database).%OpenId(db).Mounted
1
%SYS>zw ##class(SYS.Database).%OpenId(db)
+----------------- general information ---------------
|      oref value: 3
|      class name: SYS.Database
|           %%OID: $lb("/opt/irisapp/data","SYS.Database")
| reference count: 2
+----------------- attribute values ------------------
|       %Concurrency = 0  <Set>
|        BlockFormat = 2
|          BlockSize = 8192  <Set>
|             Blocks = 780288
|       BlocksPerMap = 62464
|   ClusterMountMode = 0  <Set>
|     ClusterMounted = 0  <Set>
|        CurrentMaps = 13
|          Directory = "/opt/irisapp/data/"  <Set>
|     DirectoryBlock = 3
|        EncryptedDB = 0  <Set>
|    EncryptionKeyID = ""
|          Expanding = 0
|      ExpansionSize = 0  <Set>
|               Full = 0
| GlobalJournalState = 3  <Get,Set>
|     InActiveMirror = 0
|  LastExpansionTime = "09/06/2023 20:00:01"
|            MaxSize = 0  <Set>
|MirrorActivationRequired = 0
|    MirrorDBCatchup = 0
| MirrorDBCreatedNew = 0
|       MirrorDBName = ""
|     MirrorDBPaused = 0
|   MirrorFailoverDB = 0
|      MirrorNoWrite = 0
|     MirrorObsolete = 0
|      MirrorSetName = ""
|           Mirrored = 0
|            Mounted = 1
| NewGlobalCollation = 5  <Set>
|NewGlobalGrowthBlock = 50  <Set>
|    NewGlobalIsKeep = 0  <Set>
|NewGlobalPointerBlock = 16  <Set>
|   NumberOfConfigDB = 0
|       ROReasonCode = 0
|       ROReasonText = ""
|           ReCreate = 0
|           ReadOnly = 0  <Set>
|    ReadOnlyMounted = 0
|       Reinitialize = 0
|        RequestSize = 0
|       ResourceName = "%DB_IRISAPP-DATA"
|RunCatchupDBOnCreate = 1
|                SFN = 6
|               Size = 6096  <Set>
|           Skeleton = 0
|           SparseDB = 0
+----------------------------------------------------- 
%SYS>
2
1 2953
Article Sylvain Guilbaud · Oct 4, 2016 6m read

This sample class will add parameter DSINTERVAL to each class containing the parameter DSTIME

To execute it from a Terminal :


SAMPLES>d ##class(adm.param).add(,,1)
[SAMPLES] parameter DSINTERVAL=5 added to class DeepSee.Study.CityRainfall (via adm.param)
[SAMPLES] parameter DSINTERVAL=5 added to class HoleFoods.Transaction (via adm.param)
[SAMPLES] parameter DSINTERVAL=5 added to class News.DeepSee.NewsArticle (via adm.param)
DSINTERVAL parameter was added to 3 classes

Class adm.param [ Abstract ]
{

/// this class will add DSINTERVAL parameter to each class containing DSTIME
/// in order to synchronize a cube that is based on a source table on a mirror system
/// see: http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=D2IMP_ch_current#D2IMP_current_dstime_enabling
ClassMethod add(name As %String = "DSINTERVAL", value As %String = "5", verbose As %Boolean = 0) As %Status
{
    set sc = $$$OK
    try {
        set statement = ##class(%SQL.Statement).%New()
        // %Dictionary classes are useful to select classes based on their content
        // here we use %Dictionary.ParameterDefinition class which contains all the parameters defined in all classes
        // then we will open the parent class to add the missing parameter
        set query="SELECT a.parent "
                 _"FROM %Dictionary.ParameterDefinition a "
                 _"WHERE a.name='DSTIME' "
                 _"AND substr(a.parent,1,1)<>'%' "
                 _"AND NOT EXISTS (SELECT null "
                 _"FROM %Dictionary.ParameterDefinition b "
                 _"WHERE b.name='"_name_"' and b.parent=a.parent)"
        set sc = statement.%Prepare(query)
        quit:$$$ISERR(sc)
        set classes="",nb=0
        set rs = statement.%Execute()
        while (rs.%Next(.sc)) {
            quit:$$$ISERR(sc)
            if (rs.parent '="") {
                // opening of the parent class 
                set class = ##class(%Dictionary.ClassDefinition).%OpenId(rs.parent)
                if $IsObject(class) {
                    // creating the new parameter
                    set param=##class(%Dictionary.ParameterDefinition).%New()
                    set param.Name=name
                    set param.Default=value
                    // adding the parameter to the parent class
                    do class.Parameters.Insert(param)
                    set sc=class.%Save()
                    // if parent class is successfully saved set the following message
                    set:sc msg="["_$namespace_"] parameter "_name_"="_value_" added to class "_rs.parent_" (via "_..%ClassName(1)_")",severity=0
                    // if parent class is not saved set the following message
                    set:'sc msg="["_$namespace_"] ERROR while saving "_rs.parent_" after having added the parameter "_name_"="_value_" (via "_..%ClassName(1)_") :"_$system.Status.GetErrorText(sc),severity=1
                    // if verbose=1 write the message to the terminal
                    write:verbose msg,!
                    // write the message to cconsole.log
                    do ##class(%SYS.System).WriteToConsoleLog(msg,verbose,severity)
                    // add the class name to compile 
                    set classes(rs.parent)="",nb=$increment(nb)
                }
            }
        }
        set:nb=0 msg=name_" parameter was not added to any class"
        set:nb=1 msg=name_" parameter was added to "_nb_" class"
        set:nb>1 msg=name_" parameter was added to "_nb_" classes"
        write:verbose msg,!
        // compile all modified classes 
        if nb>0 { 
            set sc=$system.OBJ.Compile(.classes,"ck"_$select(verbose:"d",1:"-d"))
            set:sc msg="["_$namespace_"] modified "_$select(nb=1:"class",1:"classes")_" successfully compiled",severity=0
            set:'sc msg="["_$namespace_"] ERROR while compiling classes : "_$system.Status.GetErrorText(sc),severity=1
            do ##class(%SYS.System).WriteToConsoleLog(msg,verbose,severity)
            write:verbose msg,!
        }    
    }
    catch(ex) {
        set sc = ex.AsStatus()
        set msg="["_$namespace_"] error while executing "_..%ClassName(1)_":add("_name_","_value_") : "_ex.DisplayString(),severity=1
        write:verbose msg,!
        do ##class(%SYS.System).WriteToConsoleLog(msg,1,severity)
    }
    return sc
}

}
6
1 1178
Article Sylvain Guilbaud · Feb 24, 2016 1m read

C:\data\backup.bat :

C:\InterSystems\Ensemble\bin\cache -s"C:\InterSystems\Ensemble\Mgr" -U%%SYS ##Class(Backup.General).ExternalFreeze() <C:\data\login.scr 

echo %ERRORLEVEL%

rem note that we need to check errorlevel from highest to lowest here.

0
0 1943