🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Versioned on class
This page was created by Hans.karlsen on 2022-02-19. Last edited by Wikiadmin on 2026-07-29.

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

  1. In MDriven Designer, select the class that requires history.
  2. Set the class's Versioned property to True.
  3. Update the database schema so that the versioning persistence columns and history support are available.
  4. 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.

See also