major
nice-to-have
minor
Background
Consistency rules currently cannot be expressed in the model at all. The only form of validation is "mandatory" annotations and unique keys defined directly on the tables in the persistence layer.
Consistency rules are currently stored only in the GUI and are checked only shortly before saving.
Problem
Validation at the GUI is problematic for at least two reasons:
- The validation occurs decentrally in command handlers. If the model is extended, many command handlers may need to be adapted.
- Validation immediately before the commit cannot prevent an inconsistency in a concurrent situation because there is no guarantee that another change will not violate the consistency of the commit currently being prepared before the commit is actually made.
Goal
A declarative mechanism is needed to express common types of consistency rules. Additionally, an API is required that allows complex tests to be performed in the context of a commit.
On the one hand, the rules should be checked during the transaction, but they should also be able to provide feedback to the user while they are entering data via the GUI.
Application
A model constraint can be defined either in-app as a “check” on an attribute or a reference.
In model XML, the constraint can be declared as follows:
#!xml
<property name="myProperty" type="...">
<annotations>
<constraints>
<constraint-by-expression>
<check>
value -> self -> if($value and !$self.get(`DemoTypes:DemoTypes.A#booleanMandatory`),
#('May only be set if booleanMandatory is also set'@de,
'Must only be checked if booleanMandatory is also checked.'@en))
</check>
</constraint-by-expression>
</constraints>
</annotations>
</property>
A constraint check can also be implemented as a plug-in. To do this, an implementation of tl:ConstraintCheck must be created and added to the <constraints> annotation using <constraint class="..."/>. See tl:TLConstraints and tl:ConstraintCheck.
Code Migration
- AttributeUpdateFactory.createAttributeUpdateFor...(...) must also be passed the AttributeUpdateContainer.
- The same applies to MetaAttributeFilter.getSearchValuesAsUpdate(...).
- AttributeUpdateContainer.putAttributeUpdate(update) is no longer needed because an update is automatically linked during construction.
- The same applies to AttributeUpdate.setDomain(...). The domain must/can be specified during construction.
- Minor signature changes to StorageImplementation: setAttributeValue() → internalSetAttributeValue(), Wrapper → TLObject.
- The configuration schema for GridCreateHandlerByExpression has changed.
- Execute the Ant task z_migrate_Ticket_10091 in separate modules.
- In-app layouts in the database are automatically migrated the next time the application is started.