%OnAddToSaveSet - what has changed
Hi community,
what is the best way to determine if a certain property got changed between %OpenId and %Save? Preferably in the %OnAddToSaveSet method.
Thanks,
Jiri
Comments
If you look for a dedicated Property You may use <propertyname>GetStored(id) to compare against the object in memory
e.g.
set old=##class(Sample.Person).SSNGetStored(id)
so you bypass also the case when a value is written back finally unchanged (false modified)
where is m%PropName documented?
all I found is:
Internally, Caché also uses additional instance variables with names such as r%PropNameand m%PropName,
but these are not supported for direct use.
And no hint how they could be used.
You can determine that in run time with:
- $system.CLS.GetModified(oref) to ger if oref was modified
- m%property to get if property changed
Here's a simple example of how it all works
Class User.Person Extends (%Persistent){Property Name As %String(DISPLAYNAME = "Name");Property Age As %Integer(DISPLAYNAME = "Age");/// Create one userClassMethod Recreate() As %Status{ do ..%KillExtent() set person = ..%New() set person.Age = $random(100) set person.Name = $random(100) quit person.%Save()}/// do ##class(User.Person).Test()ClassMethod Test(){ $$$QuitOnError(..Recreate()) set person = ..%OpenId(1) do person.ModificationState() set person.Age = $random(100) do person.ModificationState() set person.Name = $random(100) do person.ModificationState()}/// Show current object stateMethod ModificationState(){ write "Object modified: ", $system.CLS.GetModified(), ! write "Name prop modified: ", ..IsNameModified(), !, !}/// Get name property modification statusMethod IsNameModified() As %Boolean{ quit m%Name}}Executing in terminal:
>do ##class(User.Person).Test() Object modified: 0 Name prop modified: 0 Object modified: 1 Name prop modified: 0 Object modified: 1 Name prop modified: 1
Note that changing value back would still mark property as modified.
m%PropName returns 1 if the property value was modified, 0 if not.
do you have any indication if this is just isModified()
or if new content is checked against old content
Reason: in past isModified () just checked write access, not the content.
So a change from TRUE to FALSE and back to TRUE between %OpenId() and %Save() was marked as change (false positive)
so this was finally dropped in favor of GetStored()
As I originally said
Note that changing value back would still mark property as modified.
Any change (except immediate same value) would set m%PropName to 1.
I think that checking m%PropName and only if it equals one additionally checking GetStored would work faster.
An interesting combination!
But (from Sample.Person):
Quit $Select(id'="":$listget($g(^Sample.PersonD(id)),2),1:"") }
there isn't that much to win.
If it then ends with %Save() it is kind of a prefetch of the global buffer.
I saw it mostly used instead of %Open() loading / swizzling the whole object in memory
if just 1 specific property was required.
(A kind of direct global access in disguise) ![]()