🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
OCLps Example
This page was created by Wikiadmin on 2026-07-29. Last edited by Wikiadmin on 2026-07-29.

You can use OCLps and PSEval operators to find a logged-in user's comments or count an article's liked comments without first loading every comment into memory.

Scenario

This example uses a small discussion model with these classes:

Class Purpose in this example
Article The article whose comment section you display.
Comment A comment associated with an article and a SysUser.
SysUser The user who wrote a comment. In this page, my comments means comments written by the logged-in user.

The model must let you navigate between Comment and both Article and SysUser. A typical screen starts with one selected article and needs either:

  • the comments on that article written by the current user, or
  • a count of comments on that article that have been liked.

The exact association-end and attribute names are model-specific. Substitute the names used in your model in the examples below.

Choose where the query runs

OCL normally evaluates objects already loaded in memory. This is appropriate after the screen has a small result set. It is not appropriate as the first step when an article can have many comments: evaluating Comment.allinstances in normal OCL can load all comments before filtering them.

OCLps is the subset of OCL that MDriven translates to SQL and evaluates in persistent storage. Use it to find the initial, limited set of objects. Then use normal OCL in the ViewModel to navigate, present attributes, and evaluate UI logic for those loaded objects.

Need Recommended approach Example outcome
Find comment objects to show in a list PSEval Load only the matching comments, such as the current user's comments on the selected article.
Obtain a database-calculated scalar, such as a like count PSEvalValue Return the count without loading every matching comment object.
Work with a small set of objects already loaded for the screen Normal OCL Filter or format the loaded comments.

Find the current user's comments

Use OCLps to filter comments in the database by both the selected article and the current user. The query should return Comment objects, not comment attributes. After MDriven has the matching identities, it can load those comments and normal OCL can handle the rest of the ViewModel behavior.

Conceptually, the OCLps selection is:

Comment.allinstances->select(c |
  c.Article = selectedArticle and
  c.Author = loggedInUser)

Here, c is the iterator: it represents one candidate comment while the select condition is evaluated. Replace Article, Author, selectedArticle, and loggedInUser with the association ends and ViewModel values in your model.

To use that OCLps expression from a normal OCL or EAL expression, call PSEval. Its form is:

SomeClass.PSEval(<ps-expression>, maxfetch, offset, <dependon>)

For example, if the selected article's comment association is available as self.Comments, the shape of a ViewModel expression can be:

Comment.PSEval(
  self.Comments->select(c | c.Author = loggedInUser),
  100,
  0,
  self.Comments)

This expression is illustrative. It assumes that self is the selected article and that the names shown exist in your model.

Limit and page the result

The second PSEval argument, maxfetch, limits how many objects MDriven loads. Set it to the number of comments that the current page displays. The third argument, offset, is zero-based.

Page maxfetch offset
First 25 comments 25 0
Next 25 comments 25 25

Do not use a large unrestricted fetch for a comment feed. Use paging and a stable ordering when the screen must show more than one page. See orderBy for ordering guidance.

Count liked comments without loading them

A like-count label does not need Comment objects. When your model represents whether a comment has a like, use PSEvalValue to calculate the scalar value in the database rather than loading every comment and counting in memory.

For example, the intent is to count only comments that belong to the selected article and meet your model's liked condition:

comments for selected article
  ->select(c | c has a like)
  ->size

Express the same filtering and count through PSEvalValue using the actual association or attribute that represents a like in your model. This is most useful when an article can have many comments and the UI needs only the number.

If the UI must also display the liked comments, use PSEval to fetch only the matching Comment objects. That still instantiates objects, but it avoids loading comments that cannot appear in the result.

Make results refresh deliberately

PSEval reads from persistent storage but does not subscribe to database result sets. A PSEval result does not automatically update when an object starts or stops matching the query.

For example, if a user likes or unlikes a comment, a previously calculated like count can remain unchanged until the expression runs again. Likewise, a "my comments" list does not automatically acquire a newly created matching comment only because it was added to the database.

Provide the dependon expression to identify a value whose change should rerun the PSEval expression. A dependency can be a relevant loaded collection or another value that your application changes when the screen must refresh. The PSEval example above uses self.Comments as that dependency.

Test this behavior explicitly:

  1. Open an article with its comment list and like count.
  2. Add or remove a like, or create a comment for the current user.
  3. Confirm whether the value or list reruns from its configured dependency.
  4. If it does not, arrange for the relevant ViewModel value to change when the UI needs a refresh.

This trade-off is important: PSEval reduces the initial data loaded, but it does not provide the normal automatic subscription behavior for changes to the database result set.

Limits and performance checks

OCLps is intentionally more restricted than normal OCL. It has no side effects, cannot use your methods even when they are marked IsQuery, and does not support collect, groupby, or other tuple-returning operators. Use it primarily to identify the objects that should be loaded; continue with normal OCL after that.

Before releasing a query:

  1. Run a model check. MDriven dynamically type-checks OCL, EAL, and OCLps when the model is loaded or saved, and when you run ModelCheck.
  2. Test with an article that has enough comments to expose an in-memory loading problem.
  3. Verify that the selected comments and counts are correct after creating comments and changing likes.
  4. Check that the database has indexes and other performance configuration needed by the SQL generated from the query.
  5. Keep the fetch limit appropriate for the screen and use offset only for later pages.

Use PSEvalTuples when the database query must return tuples rather than objects. Validate aggregation results carefully, especially when an expression uses multiple aggregates over different data sets.

See also