Skip to content

Kitto.Rules

This unit contains the classes that make up Kitto's support for rules. A rule in Kitto is a business rule, or constraint, applied during data entry. Rules are associated to models, model fields, view tables and view table fiels, in a subnode Rules of the object definition.

A rule influences Kitto's data entry behaviour at different times and places. For example, a rule that forces character case on a given field is applied on the client side through ExtJS, while a custom rule written in Delphi code that performs cross-field checks for data integrity before writing a record to the database is applied on the server after a form is submitted.

Kitto includes a number of predefined rules for common validation tasks, defined both in this unit and in Kitto.Ext.Rule. You can add new rules by creating classes inherited from TKRuleImpl and registering them this way:

<code lang="Delphi"> initialization TKRuleImplRegistry.Instance.RegisterClass(TKExtMyRule.GetClassId, TKExtMyRule); finalization TKRuleImplRegistry.Instance.UnregisterClass(TKExtMyRule.GetClassId); </code> You then use it by mentioning it in the definition of a model, a model field, a view table or a view table field. Rules are called (applied) depending on where they are used:

  • A model-level rule is always applied.
  • A table-view-level rule is always applied when editing data through the view, in addition to (and before) any model-level rules.
  • A model-field-level rule is always applied unless a view-table-field-level rule of the same type is also defined (for example, you cannot force case to upper case in the model and lower case in the view - you have to do it only once where it's appropriate).
  • A view-table-field-level rule is always applied when editing data through the view.

TKRuleImplHow to create custom rules.</seealso>

EKRuleError class

Base exception for rule failures (raised when a rule aborts an operation).

EKValidationError class

Rule error signalling a failed data validation; shown to the user and aborting the operation.

TKRuleImpl class

Base class for all classes that implement rules.

pascal
procedure AfterConstruction;

Creates the cache of referenced-model stores used by GetReferencedModelInstance.

pascal
destructor Destroy;

Frees the cached referenced-model stores.

pascal
property Rule: TKRule read FRule write SetRule;

The rule metadata node this implementation was created from (holds its parameters).

pascal
function IsClientSide: Boolean;

Client-side (Javascript) rules return True. The default implementation returns False, assuming it is a server-side rule.

pascal
procedure NewRecord(const ARecord: TKRecord);

Called when creating a new record before showing it in the user interface. Descendants may set computed default values (declarative default values are already applied when this method is called). Calling RaiseError in this method displays an error message to the user and aborts the insert operation.

If an exception is raised, the insert operation is aborted.

Parameters:

  • ARecord — The record being created. It is usually an instance of TKViewTableRecord.
pascal
procedure EditRecord(const ARecord: TKRecord);

Called when editing a record in the user interface. Descendants may set computed values. Calling RaiseError in this method displays an error message to the user and aborts the edit operation.

If an exception is raised, the edit operation is aborted.

Parameters:

  • ARecord — The record being edited. It is usually an instance of TKViewTableRecord.
pascal
procedure AfterShowEditWindow(const ARecord: TKRecord);

Called after creating Windows for editing a record in the user interface. Descendants may set computed values.

Parameters:

  • ARecord — The record being edited. It is usually an instance of TKViewTableRecord.
pascal
procedure DuplicateRecord(const ARecord: TKRecord);

Called when duplicating a record. Descendants should read the values in ARecord and call RaiseError (which will raise an exception with the default or a custom message) in order to stop the duplicate operation and display an error to the user.

Descendants may also change values.

If an exception is raised, any change is lost.

Parameters:

  • ARecord — The duplicate record being created. It is usually an instance of TKViewTableRecord.
pascal
procedure BeforeAdd(const ARecord: TKRecord);

Server side validation before writing a new record to the database. Descendants should read the values in ARecord and call RaiseError (which will raise an exception with the default or a custom message) in order to stop the write operation and display an error to the user.

Descendants may also change values.

If an exception is raised, any change is lost.

Parameters:

  • ARecord — The record being created. It is usually an instance of TKViewTableRecord.
pascal
procedure BeforeUpdate(const ARecord: TKRecord);

Server side validation before updating an existing database record. Descendants should read the values in ARecord and call RaiseError (which will raise an exception with the default or a custom message) in order to stop the write operation and display an error to the user.

Descendants may also change values.

If an exception is raised, any change is lost.

Changing key values has the effect of updating a different record.

Parameters:

  • ARecord — The record being written to the database. It is usually an instance of TKViewTableRecord.
pascal
procedure BeforeDelete(const ARecord: TKRecord);

Server side validation before deleting a database record. Descendants should read the values in ARecord and call RaiseError (which will raise an exception with the default or a custom message) in order to stop the delete operation and display an error to the user.

Descendants may also change values, although the changes are meaningless.

Changing a key value will have the effect of deleting a different record.

Parameters:

  • ARecord — The record being deleted. It is usually an instance of TKViewTableRecord.
pascal
procedure AfterAdd(const ARecord: TKRecord);

Called after successfully writing a new record to the database. This method can still raise an exception (by calling RaiseError) causing the transaction to be rolled back.

Any values set or changed at the database level (by database triggers, for example), are not available at this point. Changes performed in BeforeAdd by this or another rule are.

pascal
procedure AfterUpdate(const ARecord: TKRecord);

Called after successfully updating a record in the database. This method can still raise an exception (by calling RaiseError) causing the transaction to be rolled back.

Any values set or changed at the database level (by database triggers, for example), are not available at this point. Changes performed in BeforeUpdate by this or another rule are.

pascal
procedure AfterDelete(const ARecord: TKRecord);

Called after successfully deleting a record in the database. This method can still raise an exception (by calling RaiseError) causing the transaction to be rolled back.

pascal
procedure BeforeFieldChange(const AField: TKField;

Called before changing a field's value. This method can silently disallow the change by setting ADoIt to False, or it can call RaiseError to abort with an error message, or even modify the new value before it is written to the field by modifying ANewValue.

pascal
procedure AfterFieldChange(const AField: TKField;

Called after a field's value has been successfully changed. This method can still abort the operation but the old field value will not be restored automatically.

pascal
function GetReferencedModelInstance(const AReferenceName: string;

Creates and returns a store with one record containing the values of the model instance pointed to by the specified reference field. Raises exceptions if the field is not found or is not a reference.

If no referenced model instance is found, the returned store is empty.

The caller does not need to free the returned object - it will be freed together with this object.

pascal
function GetReferencedModelInstanceValue(const AReferenceName, AFieldName: string;

Returns a value from the model instance pointed to by the specified reference field. Raises exceptions if the field is not found or is not a reference.

pascal
procedure AfterRefreshReferenceField(const AField: TKField);

Called after a reference field has been refreshed (e.g. after the user picks a related record). The default implementation does nothing.

TKRuleImplRegistry class

Registry of rule-implementation classes, keyed by rule id.

pascal
class destructor Destroy;

Frees the singleton registry instance.

pascal
procedure RegisterClass(const AId: string;

Adds a rule implementation class to the registry.

TKRuleImplFactory class

Creates rule implementations by id from the registered classes.

pascal
class destructor Destroy;

Frees the singleton factory instance.

pascal
function CreateObject(const AClassId: string): TKRuleImpl;

Creates and returns an instance of the rule implementation class identified by AClassId. Raises an exception if said class is not registered.

TKEnforceRange class

Predefined rule enforcing that the field named by param From is less than or equal to the field named by param To.

Released under Apache License, Version 2.0.