Question
Matthew Giesmann · Dec 16, 2021

Attempting to Override Values Set by SQLComputeCode

I have an auditing class that defines some sqlComputed properties and can be extended by other persistent classes to enable auditing of its properties.  

Class Audit.ModifiedTracker [ abstract ] {
/// Last time this record was saved
Property LastModifiedTime As %TimeStamp [ SqlComputeCode = {Set {*}=$zdt($zts,3)}, SqlComputed, SqlComputeOnChange = ("%%INSERT", "%%UPDATE") ]; 
/// User responsible for modifying record
Property LastModifiedUser As %String [ SqlComputeCode = {set {*} = ..GetModifiedUser()}, SqlComputed, SqlComputeOnChange = ("%%INSERT", "%%UPDATE") ];

Now, I would like to migrate some historical audit data stored somewhere else to this standard auditing class. However, I need to set these sqlComputed properties with their values from the other source... not the values that would be computed (i.e. always the current time, and the user running the migration code).

I would like to avoid direct global manipulation if possible... is there a good way to do what I'm looking to do?

Product version: Caché 2018.1
1
1 127
Discussion (3)3
Log in or sign up to continue

As your properties are NOT Calculated then there is a Storage Entry (check Storage section) 
they are persisted and not just there on run-time

  • copy the class including Storage Definition !!!
  • set class Parameter MANAGEDEXTENT  = 0;  to allow access to original Globals
  • remove SqlCompute*  from the Properties LastModified*   ; to make it normal Properties
  • now write to these properties whatever you need to do by object access or SQL  

Note that it requires that you're the only writer on the system during that update.

Thank you, @Robert Cemper and @Eduard Lebedyuk!

I did not know about MANAGEDEXTENT, assuming there was no way to use the same storage in another class.  Ed's warning is relevant though, I can't ensure that there wouldn't be other concurrent writes.

Here is my working solution.... Subclassing of the record class with Setters for the 2 properties seems to work.  Simply overriding the 2 properties without [ SqlComputed ] did not change the computed behavior.

Class Audit.HistoricalRecord Extends Audit.Record {

Method LastModifiedTimeSet(value As %String) As %Status
 {
    Set i%LastModifiedTime = value
    quit $$$OK
 }

Method LastModifiedUserSet(value As %String) As %Status
{
    Set i%LastModifiedUser = value
    quit $$$OK
}

}

My migration routine can now create and save objects of the HistoricalRecord class