Use Versioning on a model class when you need to retain each stored state of its objects and query those historical states with OCL expressions.
What Versioning does
Versioning is an optional MDriven Framework runtime feature for specific classes. When a class is marked Versioned, MDriven retains the history of changes to each object in that class.
For a versioned class, MDriven does not use SQL UPDATE or DELETE commands for that class. It stores changes as inserts and adds the non-attribute database columns TimeStampStart and TimeStampStop. These columns define the period in which a stored version was current.
For example, if you version a Customer class and change one customer's address three times, MDriven records the earlier states. You can then retrieve the customer's state at a previous timestamp.
Enable Versioning
Set Versioned on the class that requires history. Use it only for classes where historical states are required, because each modification creates another stored version.
After Versioning is enabled, you can retrieve historical versions with these OCL operators:
| Operator | Purpose | Example |
|---|---|---|
changePoints(start, stop)
|
Returns stored versions within an integer timestamp range. Use -1 as stop for all recorded history after start.
|
Customer.allInstances->first.changePoints(0, -1)
|
atTime
|
Retrieves an object's state at a timestamp. | Use a timestamp obtained from objectTimeStamp.
|
allInstancesAtTime
|
Retrieves the instances of a class as they existed at a timestamp. | Query a historical set of Customer objects at a selected timestamp.
|
objectTimeStamp
|
Returns the timestamp for the current stored object version. | x.objectTimeStamp
|
Query object history
Use changePoints to return every stored version of an object over a time range. Its syntax is:
self.changePoints(startTime, stopTime)
Both arguments are integer timestamps. The startTime argument is inclusive from the requested point in history. Set stopTime to -1 to include history through the latest recorded version.
For example, this expression returns all versions of the first Customer:
Customer.allInstances->first.changePoints(0, -1)
To inspect all recorded versions of all objects in a versioned Class1, including their timestamps and corresponding calendar times, use:
Class1.allinstances.changepoints(0,-1)->collect(x|x,x.objectTimeStamp, x.objectTimeStamp.timeStampToTime,x.objectTimeStamp.timeStampToTime.timeToTimeStamp)
In this example:
Class1.allinstances.changepoints(0,-1)returns all stored versions of allClass1objects.x.objectTimeStampreturns the integer timestamp of each version.x.objectTimeStamp.timeStampToTimeresolves that timestamp to the corresponding calendarDateTimethroughClockLog.x.objectTimeStamp.timeStampToTime.timeToTimeStampconverts the resolvedDateTimeback to an integer timestamp.
objectTimeStamp is required when an operator such as atTime needs a timestamp from the current object version.
Versioning versus MDriven package versions
Object Versioning stores historical business data. It is separate from the version of MDriven assemblies and NuGet packages used by your application.
MDriven runtime assemblies are distributed through NuGet, while the MDriven Designer Visual Studio plugin is installed locally as a VSIX extension. Current assemblies use the assembly version 7.2.0.0; the build number is carried by the NuGet package. This arrangement supports compatible operation between design-time support and the NuGet packages used by your application.
The VSIX design-time assemblies and runtime/NuGet assemblies have different public key tokens. This is intentional: it prevents Visual Studio from loading project assemblies and VSIX assemblies into conflicting load contexts.
