· Jul 14, 2022

Clone Class

Hi Guys,


How can I create a clone class so I can keep a copy of all records in that clone class?

Basically, I have a class where sometime records might be delete from it, so I would like to create clone class or merge the global content in another backup global so that records can be deleted from the original class but still have a copy of those delete records in my clone or backup global ?



Product version: Caché 2014.1
Discussion (5)1
Log in or sign up to continue
Replace hard delete with soft delete.

You soft delete by creating a new property, usually a DeletedOn timestamp. If it's empty then the record is not deleted.

Deletion now consists of setting DeletedOn property to a soft deletion timestamp.

As an additional precaution you can add a BEFORE DELETE trigger which always errors out, forbidding hard deletions. It would save you from every delete except for global kill.

Additionally, you can add versioning, check out this discussion.


The best way it to do it is to use the dictionary to loop on properties of the original class and create a new class  which is identical, but with a different storage. The cloning is done by using %ConstructClone
Usually, the new class for backup, does not need to have methods, indices or triggers, so those can be "cleaned" before saving it.

Have the original and the destination class objects:

S OrigClsComp=##class(%Dictionary.CompiledClass).%OpenId(Class)
S DestCls=OrigCls.%ConstructClone(1)

You should give the destination class a name and type:

S DestCls.Name="BCK."_Class , DestCls.Super="%Persistent"

Usually the destination class does not need to have anything than the properties, so in case there are methods, triggers or indices that need to be removed from the destination class, you may do: 

F i=1:1:DestCls.Methods.Count() D DestCls.Methods.RemoveAt(i)      ; clear methods/classmethods
F i=1:1:DestCls.Triggers.Count() D DestCls.Triggers.RemoveAt(i)     ; clear triggers
F i=1:1:DestCls.Indices.Count() D DestCls.Indices.RemoveAt(i)       ; clear indices

Setting the new class storage:

S StoreGlo=$E(OrigCls.Storages.GetAt(1).DataLocation,2,*)
S StoreBCK="^BCK."_$S($L(StoreGlo)>27:$P(StoreGlo,".",2,*),1:StoreGlo)

S DestCls.Storages.GetAt(1).DataLocation=StoreBCK
S DestCls.Storages.GetAt(1).IdLocation=StoreBCK
S DestCls.Storages.GetAt(1).IndexLocation=$E(StoreBCK,1,*-1)_"I"
S DestCls.Storages.GetAt(1).StreamLocation=$E(StoreBCK,1,*-1)_"S"
S DestCls.Storages.GetAt(1).DefaultData=$P(Class,".",*)_"DefaultData"

Then just save the DestCls

S sc=DestCls.%Save()

@Yaron Munz 
What are these Methods,Triggers,Incidies and Storages properties or params on the DestCls?  I don't see them as part of the %Persistent class or any super classes in the class reference, so I'm wondering exactly what you're referencing here?

I tested this on my command line and I get:

W clone.Methods.Count()

Was this pseudo code for something or are they properties that you defined in the class?