Перейти к основному содержимому
Версия: 7.0

Вычисляемые события

Вычисляемые события - события, которые при изменении значения свойства (условия) на не NULL, изменяют значение первичного свойства. При этом, в отличии от простых событий, это изменение происходит, не в момент изменения условия, а вычисляется каждый раз при обращении к изменяемому свойству. Если в сессии уже есть изменение этого свойства, это изменение считается более приоритетным, чем изменение в вычисляемом событии. При отсутствии такого изменения событие записывает вычисленное значение и тогда, когда оно равно NULL.

Для каждого свойства может быть только одно вычисляемое событие, которое изменяет это свойство.

Условие и значение вычисляемого события не могут зависеть от самого изменяемого свойства: оно тогда зависело бы от собственного изменения, и при старте сервера такой цикл приводит к ошибке Property ... is recursive. Защита от перезаписи явного изменения при этом и не нужна — явное изменение и так приоритетнее события. Если значение должно выставляться только пока свойство ещё не заполнено, используется простое событие: в нём запись выполняет действие-обработчик, и цикла не возникает (см. пример ниже).

Язык

Для задания вычисляемых событий используется инструкция <- WHEN.

Примеры

// при добавлении клиента, по умолчанию, предоставить ему заданную скидку
defaultDiscount = DATA NUMERIC[6,2] ();
discount = DATA NUMERIC[6,2] (Customer);
discount(Customer c) <- defaultDiscount() WHEN SET(c IS Customer);

quantity = DATA NUMERIC[10,2] (OrderDetail);
price = DATA NUMERIC[10,2] (OrderDetail);
sum = DATA NUMERIC[10,2] (OrderDetail);

sum(OrderDetail d) <- quantity(d) * price(d) WHEN CHANGED(quantity(d)) OR CHANGED(price(d));
defaultBonus = DATA NUMERIC[6,2] ();
bonus = DATA NUMERIC[6,2] (Customer);

// нельзя: условие вычисляемого события зависит от изменяемого свойства - при старте сервера будет ошибка 'is recursive'
// bonus(Customer c) <- defaultBonus() WHEN SET(c IS Customer) AND NOT bonus(c);

// чтобы выставить бонус только клиентам, у которых он еще не заполнен, используется простое событие
WHEN SET(Customer c IS Customer) AND NOT bonus(c) DO bonus(c) <- defaultBonus();