Search code examples
persistenceoclmdriven

How to use MDriven OclPs to find all objects matching a list of strings?


In an application I receive a list of strings. Then I want to use OclPs to find all objects where a specific attribute equals any of the strings in the list. E.g. if we have Person objects and receive a list of last names, find all persons whose last name appears in the list.

Although this can surely be done in MDriven's in-memory OCL engine, I can't seem to achieve this in the more limited OclPs (which translates the OCL to SQL and evaluates it as such in the database).

Attempt 1: First assign the list of names to vNames (collection of strings), then:

Person.allInstances->select(p|vNames->exists(n|n = p.LastName))

This gives error "Loop variables can only have class type, not System.String".

Attempt 2: First assign a "|" separated string of the sought names, including leading and trailing "|", to vNames, then:

Person.allInstances->select(p|vNames.SqlLike('%|' + p.LastName + '|%'))

This gives error saying strings cant be added in Firebird. But Firebird does support string concatenation using the || operator.

Trying with .Contains(...) instead of .SqlLike(...) says it's not supported in OclPs. Besides, it would find persons with a last name that is CONTAINED in any of the sought names, i.e. an incorrect search.

I'm out of ideas...


Solution

  • In this case when you have a long list of strings and you want a list of objects I think you best option is to use SQL with sqlpassthroughobjects:

    https://wiki.mdriven.net/index.php/OCLOperators_sqlpassthroughobjects

    Person.sqlpassthroughobjects('select personid from person where lastname in ('+vNames->collect(n|'\''+n+'\'')->asCommaList+')')