1

How to call a Cache ObjectScript routine when SET or KILL is applied to a specific global variable?

Gabe
  • 84,912
  • 12
  • 139
  • 238

2 Answers2

3

I'm not sure what you mean, but I think you don't know, how to use global variables in SET and KILL commands. Well, a lot of variants to do that, and you have to read documentation, if you haven't know it yet.
Code for example:

set ^MyGlobal="testval" 
kill ^MyGlobal

UPDATE:
Well, as you say about 'trigger' for changing your globals, you could use macro definitions.

#; macro defenitions for set and kill
#define set(%var,%val) set %var=%val,%triggerSC=$$setTrigger($name(%var),%val)
#define kill(%var) kill %var s %triggerSC=$$killTrigger($name(%var))
    kill

    kill ^logGlobal

    #; trigger fo direct global variable
    $$$set(^global, "test")

    #; trigger for global variable by name
    set gn=$name(^global("ind"))
    $$$set(@gn, "test")
    $$$set(@gn@("123"), "test")

    #; trigger for local variable
    $$$set(testLocal, "test")
    zwrite ^global

    #; trigger for kill
    $$$kill(^global)
    $$$kill(testLocal)
    zwrite ^logGlobal
    quit
setTrigger(varName, value) public {
    set ^logGlobal($increment(^logGlobal))=$listbuild("SET",varName, $get(value))
    quit $$$OK
}

killTrigger(varName) public {
    set ^logGlobal($increment(^logGlobal))=$listbuild("kill",varName)
    quit $$$OK
}

you can put macro definitions and methods setTrigger and killTriggers to any yours .inc file, and use it in your code.

and result for this code

^global="test"
^global("ind")="test"
^global("ind",123)="test"
^logGlobal=6
^logGlobal(1)=$lb("SET","^global","test")
^logGlobal(2)=$lb("SET","^global(""ind"")","test")
^logGlobal(3)=$lb("SET","^global(""ind"",123)","test")
^logGlobal(4)=$lb("SET","testLocal","test")
^logGlobal(5)=$lb("kill","^global")
^logGlobal(6)=$lb("kill","testLocal")

UPDATE2: example with reading journal files.

#dim jrn As %SYS.Journal.File = ##class(%SYS.Journal.System).GetCurrentFile()
#dim rec As %SYS.Journal.Record = jrn.FirstRecord
while $isobject(rec) {
    set addr=rec.Address

    if rec.%IsA("%SYS.Journal.SetKillRecord") {
        set glo=rec.GlobalNode
        set db=rec.DatabaseName
        set type=rec.TypeName
        if type="SET" {
            write "set ",glo,"=",rec.NewValue,!
        } elseif type="KILL" {
            write "kill ",glo,!
        }
    }

    set rec=rec.Next
}
q
DAiMor
  • 3,185
  • 16
  • 24
  • Consider i have a global ^TESTA. whenever i apply SET/KILL to that particular global, relatively i have to modify few other globals also. I face such big problem.so if i can able to call a COS at the time of set / kill initiation i could achieve my solution. so currently i do work on Filters under journaling. it doest work at the instant of set / kill so i search for most suitable solution. – Krishnamuthu Jul 01 '14 at 06:46
  • Can i able to monitor each set/Kill operation recorded in the journal file. if so i could reach my solution possibly. – Krishnamuthu Jul 02 '14 at 07:29
  • You can read journal files via classess in package %SYS.Journal - http://docs.intersystems.com/cache20121/csp/documatic/%25CSP.Documatic.cls?APP=1PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25SYS.Journal you can open any journal file, and go on records in it, and of course you can see type of record, and values wich changed in this – DAiMor Jul 02 '14 at 08:15
  • 1
    I updated my answer with new example with journal files – DAiMor Jul 06 '14 at 14:51
1

If you are talking about "trigger" style code execution when something sets or kills a global, it's not possible. You should use Objects, SQL, or your own framework to handle such situations.

SSH
  • 2,533
  • 16
  • 21