You can enable Versioned on a class when you need to retain each stored state of its objects and query that history with temporal OCL operators.
What Versioned does
Set the class's Versioned property to True to make MDriven retain historical rows for that class. Instead of updating or deleting an existing row with SQL UPDATE or DELETE, MDriven stores changes as inserts.
MDriven adds TimeStampStart and TimeStampStop as non-attribute database columns. They are persistence columns, not attributes that you add to the class model. These columns define the time interval during which each stored version represents the object.
For example, if a versioned Customer object's Name changes from Anna to Anne, the earlier stored version remains available for historical queries and a new version represents the changed state.
| Concern | Behavior for a versioned class |
|---|---|
| Change an object | MDriven stores a new version rather than updating the existing stored row. |
| Delete an object | MDriven does not use SQL DELETE for that class; the stored history remains available.
|
| Query the current state | Use the normal class and object queries. |
| Query a previous state | Use temporal OCL operators with an integer timestamp. |
Enable versioning on a class
- In MDriven Designer, select the class that requires history.
- Set the class's Versioned property to
True. - Update the database schema so that the versioning persistence columns and history support are available.
- Make changes to objects of the class, then query their change points or a specified historical time.
Enable versioning before you depend on history. Historical queries require the execution engine to have recorded history for the target class.
Query historical data
A temporal query uses an integer timestamp. When you begin with a calendar DateTime, convert it with timeToTimeStamp. You can convert an integer timestamp back to a calendar time with timeStampToTime.
| Need | Operator | Example |
|---|---|---|
| Find every stored version of one object in a time range | changePoints | customer.changePoints(0, -1)
|
| Read one object as it was at a specified time | atTime | customer.atTime(DateTime.Parse('2025-01-01 00:00:00').timeToTimeStamp)
|
| Reconstruct every instance of a class at a specified time | allInstancesAtTime | Customer.allInstancesAtTime(DateTime.Parse('2025-01-01 00:00:00').timeToTimeStamp)
|
List an object's recorded versions
Use changePoints(startTime, stopTime) on a versioned object. Pass 0 as the start timestamp to search from the beginning of recorded history. Pass -1 as the stop timestamp to include history through the latest recorded version.
Customer.allInstances->first.changePoints(0, -1)
This expression returns every recorded version of the first Customer. See changePoints for its complete behavior and range semantics.
Inspect timestamps
A versioned object exposes objectTimeStamp, which returns its integer timestamp. Use the conversion operators when you need to display or use a calendar value.
x.objectTimeStamp
x.objectTimeStamp.timeStampToTime
x.objectTimeStamp.timeStampToTime.timeToTimeStamp
The first expression returns the integer timestamp. The second obtains the corresponding calendar DateTime through ClockLog. The third demonstrates converting that DateTime back to an integer timestamp.
Reconstruct the class at a calendar date
Use allInstancesAtTime on the class when a report needs the complete population as it existed at one point in time. Convert the DateTime; passing a DateTime directly is not valid because the operator requires an integer.
Complaint.allInstancesAtTime(DateTime.Parse('2025-01-01 00:00:00').timeToTimeStamp)
The resulting objects represent the state at that time. For a single object's read-only historical representation, use atTime.
Design and operational considerations
Versioning retains every stored change. Plan database capacity and query use accordingly, especially for classes that change frequently.
If you need a separate historical database for synchronized data, use a History Slave. Before applying the master model, a History Slave sets classes to Versioned so that it becomes a vault of changes. For setup steps and history retention options such as NoHistory and HistoryKeepWeeks, see Setting up a History slave.
