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.
procedure AfterConstruction;Creates the cache of referenced-model stores used by GetReferencedModelInstance.
destructor Destroy;Frees the cached referenced-model stores.
property Rule: TKRule read FRule write SetRule;The rule metadata node this implementation was created from (holds its parameters).
function IsClientSide: Boolean;Client-side (Javascript) rules return True. The default implementation returns False, assuming it is a server-side rule.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
class destructor Destroy;Frees the singleton registry instance.
procedure RegisterClass(const AId: string;Adds a rule implementation class to the registry.
TKRuleImplFactory class
Creates rule implementations by id from the registered classes.
class destructor Destroy;Frees the singleton factory instance.
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.
