diff --git a/docs-process/DOCS-DESC-OMITTED.md b/docs-process/DOCS-DESC-OMITTED.md new file mode 100644 index 0000000000..fc5004d571 --- /dev/null +++ b/docs-process/DOCS-DESC-OMITTED.md @@ -0,0 +1,45 @@ +# DOCS-DESC-OMITTED — сознательно не документируемый функционал + +Реестр функционала, который при доработке документации lsFusion (**Paradigm + Language**) +был **сознательно опущен** — с причиной. Цель: + +- не терять такие решения и их обоснование; +- не объяснять одно и то же дважды на ревью (ревьюер видит, что omission осознан); +- собрать кандидатов на **отдельное (каноническое) описание** в будущем. + +Это процессный / AI-facing файл (как `docs/AGENTS.md`). **Дополнять может любой исполнитель:** +добавляй раздел своего блока отдельным коммитом. Ведётся **по блокам**. + +Колонки таблицы: *Конструкция / опция* · *Где (статья)* · *Почему опущено* · *Источник в коде* · *Кандидат на отдельную статью?* + +> Опускаем по правилам `docs/AGENTS.md`: «не документировать внутренние оптимизации», +> «не документировать deprecated/недокументированный синтаксис», «minor technical details +> MAY be omitted». Нишевость дополнительно подтверждаем поиском использований по всему +> workspace (`erp`, `mycompany`, `custom-logics`, …), а не только по системным `.lsf`. + +--- + +## B14 — События (трек T2) + +| Конструкция / опция | Где (статья) | Почему опущено | Источник в коде | Отдельная статья? | +|---|---|---|---|---| +| `ON … SINGLE` | `language/ON_statement` | Оптимизация применения (`singleApply` → пакетная запись `pendingSingleTables`), не семантика; **0 использований** во всём workspace | `LsfLogics.g` → `globalEventStatement`; `DataSession.startPendingSingles` | нет (внутренняя оптимизация) | +| Имя события (`name=ID` в `ON` / `WHEN`) | `language/ON_statement`, `language/Event_description_block` | Нишевый механизм — ссылка на событие в чужом `AFTER`; **0 использований** во всём workspace | `LsfLogics.g` → `baseEventNotPE` / `baseEventPE`; `addBaseEvent` (`makeActionPublic`) | при необходимости — вместе с описанием `AFTER`-упорядочивания событий | +| `NOINLINE` / `INLINE` (в `WHEN`, и шире) | `language/WHEN_statement` | Сквозной механизм инлайнинга (≈738 `.lsf`-файлов, множество конструкций), хинт производительности, не семантика; **нигде** в доках не описан — частичное упоминание только в `WHEN` было бы непоследовательным и неполным (есть и форма `NOINLINE(params)`) | `LsfLogics.g` → `inlineStatement` | **да — отдельная каноническая статья** про инлайнинг (общий механизм), затем ссылки из конструкций, которые его поддерживают | +| Форма `<- WHEN DO …` | `language/lt-_WHEN_statement` | Недокументированный синтаксис — помечено в грамматике (`// DO - undocumented syntax`) | `LsfLogics.g` → `writeWhenStatement` | нет | + +**Упрощения, оставленные намеренно (не omission, но осознанный выбор формулировки):** + +- «если условие не содержит `PREV`» (в `WHEN` / `Simple_event` / `lt-_WHEN`) — читабельное упрощение + точного код-guard'а: обёртка в `SET` происходит при `!noDB()` = `noOld()` = `getParseOldDepends().isEmpty()`, + т.е. ровно когда у условия нет `PREV`/old-зависимостей. + +**Границы блока (правились только parity/мелочи, по сути не дорабатывались — относятся к другим трекам):** + +- `language/Event_block` — события формы (paradigm `Form_events.md`, трек форм). Полнота списка типов + событий формы (`CHANGEWYS`, `EDIT`, `GROUPCHANGE`, `CONTEXTMENU`, `KEYPRESS`, `REPLACE`/`NOREPLACE`) — вне B14. +- `language/AFTER_statement`, `language/BEFORE_statement` — аспекты действий (paradigm `Actions.md`), не события. + +--- + + diff --git a/docs/language/en/Event_description_block.md b/docs/language/en/Event_description_block.md index 601ecb702f..1bed2ca9c2 100644 --- a/docs/language/en/Event_description_block.md +++ b/docs/language/en/Event_description_block.md @@ -8,7 +8,7 @@ title: 'Event description block' ### Syntax ``` -[GLOBAL | LOCAL] [FORMS formName1, ..., formNameN] [GOAFTER propertyId1, ..., propertyIdM] [AFTER propertyId1, ..., propertyIdM] +[GLOBAL | LOCAL] [FORMS formName1, ..., formNameN] [(GOAFTER | AFTER) propertyId1, ..., propertyIdM] ``` ### Parameters @@ -26,8 +26,9 @@ title: 'Event description block' A list of names of the [forms](../paradigm/Forms.md) in which the event will occur. Each element of the list is a [composite ID](IDs.md#cid). If the list is not defined, the event will occur in all forms. - `GOAFTER` | `AFTER` - Keywords can be used either first or second. They are followed by a list of properties. + + Synonymous keywords; either of them is followed by the list of properties or actions. - `propertyId1, ..., propertyIdM` - List of [property IDs](IDs.md#propertyid). This list means that all event handlers that change one of the specified properties must be executed earlier than the handlers that will be defined in the statement for which this event description block is being defined. + List of [IDs](IDs.md#propertyid) of properties or actions. This list means that all event handlers that change one of the specified properties, as well as the specified actions, must be executed earlier than the handlers that will be defined in the statement for which this event description block is being defined. diff --git a/docs/language/en/WHEN_statement.md b/docs/language/en/WHEN_statement.md index b824e4a92c..42a99c998f 100644 --- a/docs/language/en/WHEN_statement.md +++ b/docs/language/en/WHEN_statement.md @@ -36,7 +36,7 @@ but it also has [a number of advantages](../paradigm/Simple_event.md). - `eventExpr` - An [expression](Expression.md) whose value is used as a condition for the created simple event. If the obtained property does not contain the [`PREV`](../paradigm/Previous_value_PREV.md) operator, the platform automatically wraps it into the [`CHANGE`](../paradigm/Property_change_CHANGE.md) operator. + An [expression](Expression.md) whose value is used as a condition for the created simple event. If the obtained property does not contain the [`PREV`](../paradigm/Previous_value_PREV.md) operator, the platform automatically wraps it into the [`SET`](../paradigm/Change_operators_SET_CHANGED_etc.md) operator. - `eventAction` diff --git a/docs/language/en/lt-_WHEN_statement.md b/docs/language/en/lt-_WHEN_statement.md index 2ff4c9c524..8302d8bd8c 100644 --- a/docs/language/en/lt-_WHEN_statement.md +++ b/docs/language/en/lt-_WHEN_statement.md @@ -33,7 +33,7 @@ Only one calculated event can be defined for a property. - `eventExpr` - An expression whose value is a condition for the generated event. + An expression whose value is a condition for the generated event. If the obtained property does not contain the [`PREV`](../paradigm/Previous_value_PREV.md) operator, the platform automatically wraps it into the [`SET`](../paradigm/Change_operators_SET_CHANGED_etc.md) operator. ### Examples diff --git a/docs/language/ru/AFTER_statement.md b/docs/language/ru/AFTER_statement.md index 14c0b943aa..7d34aba553 100644 --- a/docs/language/ru/AFTER_statement.md +++ b/docs/language/ru/AFTER_statement.md @@ -33,6 +33,7 @@ AFTER action(param1, ..., paramN) DO aspectAction; ```lsf changePrice(Sku s, DATE d, NUMERIC[10,2] price) { price(s, d) <- price; } + // Сообщение будет показано после каждого вызова changePrice AFTER changePrice(Sku s, DATE d, NUMERIC[10,2] price) DO MESSAGE 'Price was changed'; ``` diff --git a/docs/language/ru/BEFORE_statement.md b/docs/language/ru/BEFORE_statement.md index 372d9c1ab1..aafb0b348a 100644 --- a/docs/language/ru/BEFORE_statement.md +++ b/docs/language/ru/BEFORE_statement.md @@ -11,7 +11,7 @@ title: 'Инструкция BEFORE' BEFORE action(param1, ..., paramN) DO aspectAction; ``` -Описание +### Описание Инструкция `BEFORE` задает действие (будем называть его *аспектом*), которое будет вызываться перед вызовом указанного действия. @@ -33,6 +33,7 @@ BEFORE action(param1, ..., paramN) DO aspectAction; ```lsf changeName(Sku s, STRING[100] name) { name(s) <- name; } + // Сообщение будет показано перед каждым вызовом changeName BEFORE changeName(Sku s, STRING[100] name) DO MESSAGE 'Changing user name'; ``` diff --git a/docs/language/ru/Event_block.md b/docs/language/ru/Event_block.md index a00e9b1833..762e8a4110 100644 --- a/docs/language/ru/Event_block.md +++ b/docs/language/ru/Event_block.md @@ -74,6 +74,7 @@ FORM invoice 'Инвойс' // создаем форму по редактиро // указываем, что при нажатии пользователем OK должно выполняться действия, // которое выполнит действия по "проведению" данного инвойса ON OK { posted(i) <- TRUE; }, + // по нажатию кнопки formDrop выдаем сообщение, что такого не может быть, так как эта кнопка // по умолчанию будет показываться только в форме по выбору инвойса, а эта форма по сути // является формой редактирования инвойса @@ -113,5 +114,7 @@ EXTEND FORM POS // при открытии формы выполняем действие по созданию нового чека, которое заполняет смену, // кассира и прочую информацию ON INIT createReceipt() + // применять каждые 60 секунд + ON SCHEDULE PERIOD 60 FIXED apply(); ; ``` diff --git a/docs/language/ru/Event_description_block.md b/docs/language/ru/Event_description_block.md index c7bb25a432..c82147ad99 100644 --- a/docs/language/ru/Event_description_block.md +++ b/docs/language/ru/Event_description_block.md @@ -8,7 +8,7 @@ title: 'Блок описания события' ### Синтаксис ``` -[GLOBAL | LOCAL] [FORMS formName1, ..., formNameN] [GOAFTER propertyId1, ..., propertyIdM] [AFTER propertyId1, ..., propertyIdM] +[GLOBAL | LOCAL] [FORMS formName1, ..., formNameN] [(GOAFTER | AFTER) propertyId1, ..., propertyIdM] ``` ### Параметры @@ -26,8 +26,9 @@ title: 'Блок описания события' Список имен [форм](../paradigm/Forms.md), в которых будет происходить событие. Каждый элемент списка является [составным идентификатором](IDs.md#cid). Если список не задается, то событие будет происходить во всех формах. - `GOAFTER` | `AFTER` - Ключевые слова, можно использовать как первое, так и второе. После них следует список свойств. + + Синонимичные ключевые слова; после любого из них следует список свойств или действий. - `propertyId1, ..., propertyIdM` - Список [идентификаторов свойств](IDs.md#propertyid). Этот список обозначает, что все обработчики событий, которые изменяют какое-либо из перечисленных свойств, должны выполняться раньше, чем обработчики, которые будут заданы в инструкции, для которой задается этот блок описания события. + Список [идентификаторов](IDs.md#propertyid) свойств или действий. Этот список обозначает, что все обработчики событий, которые изменяют какое-либо из перечисленных свойств, а также сами перечисленные действия, должны выполняться раньше, чем обработчики, которые будут заданы в инструкции, для которой задается этот блок описания события. diff --git a/docs/language/ru/WHEN_statement.md b/docs/language/ru/WHEN_statement.md index 485b2a1d1c..2e3e093ec2 100644 --- a/docs/language/ru/WHEN_statement.md +++ b/docs/language/ru/WHEN_statement.md @@ -36,7 +36,7 @@ ON eventClause FOR eventExpr [ORDER [DESC] orderExpr1, ..., orderExprN] DO event - `eventExpr` - [Выражение](Expression.md), значение которого используется в качестве условия создаваемого простого события. Если полученное свойство не содержит внутри [оператора `PREV`](../paradigm/Previous_value_PREV.md), то платформа автоматически оборачивает его в [оператор `CHANGE`](../paradigm/Property_change_CHANGE.md). + [Выражение](Expression.md), значение которого используется в качестве условия создаваемого простого события. Если полученное свойство не содержит внутри [оператора `PREV`](../paradigm/Previous_value_PREV.md), то платформа автоматически оборачивает его в [оператор `SET`](../paradigm/Change_operators_SET_CHANGED_etc.md). - `eventAction` diff --git a/docs/language/ru/lt-_WHEN_statement.md b/docs/language/ru/lt-_WHEN_statement.md index 1b4c9ec6e4..3d9e946062 100644 --- a/docs/language/ru/lt-_WHEN_statement.md +++ b/docs/language/ru/lt-_WHEN_statement.md @@ -33,7 +33,7 @@ propertyId(param1, ..., paramN) <- valueExpr WHEN eventExpr; - `eventExpr` - Выражение, значение которого является условием создаваемого события. + Выражение, значение которого является условием создаваемого события. Если полученное свойство не содержит внутри [оператора `PREV`](../paradigm/Previous_value_PREV.md), то платформа автоматически оборачивает его в [оператор `SET`](../paradigm/Change_operators_SET_CHANGED_etc.md). ### Примеры diff --git a/docs/paradigm/en/Calculated_events.md b/docs/paradigm/en/Calculated_events.md index fdfb2efff5..bf1627d263 100644 --- a/docs/paradigm/en/Calculated_events.md +++ b/docs/paradigm/en/Calculated_events.md @@ -3,7 +3,7 @@ slug: "/Calculated_events" title: 'Calculated events' --- -*Calculated* events are events that change the value of a property when the value of some other property (*condition*) changes to a non-`NULL` value. Moreover, unlike [simple](Simple_event.md) events, this change is not made at the moment the condition is changed but is calculated each time the changed property is accessed. If the property has already been [changed](Property_change_CHANGE.md) in the same session, this change is considered higher priority than the change in the calculated event. +*Calculated* events are events that change the value of a [data property](Data_properties_DATA.md) when the value of some other property (*condition*) changes to a non-`NULL` value. Moreover, unlike [simple](Simple_event.md) events, this change is not made at the moment the condition is changed but is calculated each time the changed property is accessed. If the property has already been [changed](Property_change_CHANGE.md) in the same session, this change is considered higher priority than the change in the calculated event. For each property, there can only be one calculated event that changes this property. diff --git a/docs/paradigm/en/Events.md b/docs/paradigm/en/Events.md index cd5bd5f339..ee69cd6dee 100644 --- a/docs/paradigm/en/Events.md +++ b/docs/paradigm/en/Events.md @@ -26,18 +26,20 @@ Advantages of synchronous events: Advantages of asynchronous events: -- You can release the user immediately and perform the handling "in the background". This improves system ergonomics; however, it is possible only when updating the data is not critical for the user's further work (for global events, for example, within the next 5-10 minutes, until the server has time to complete the next handling cycle). -- Handlings are grouped for a large number of changes, including those made by different users (in the case of global events), and, accordingly, are performed fewer times, thereby improving the overall system performance. +- You can release the user immediately and run the handlers "in the background". This improves system ergonomics; however, it is possible only when updating the data is not critical for the user's further work (for global events, for example, within the next 5-10 minutes, until the server has time to complete the next handling cycle). +- Handlers are grouped for a large number of changes, including those made by different users (in the case of global events), and, accordingly, are run fewer times, thereby improving the overall system performance. Advantages of local events: -- The user sees the results of event handling immediately, not only after he has saved to the common database. +- The user sees the results of the event handlers immediately, not only after he has saved to the common database. Advantages of global events: -- They provide better performance and integrity, due both to the fact that the handling is performed only after the changes are saved to the common database (that is, significantly less often), and to the use of the numerous DBMS capabilities for working with transactions. +- They provide better performance and integrity, due both to the fact that the handlers are run only after the changes are saved to the common database (that is, significantly less often), and to the use of the numerous DBMS capabilities for working with transactions. -The platform also allows to additionally specify that the event will occur only if the change session belongs to one of the given forms. If this is not done, then it must be kept in mind that most of the described events occur very often, so their handling should not have side effects (for example, showing messages) if there are no changes in the session. Ideally, events should be [simple](Simple_event.md) and should generally be used only to optimize the performance of really complex cases. +The platform also allows to additionally specify that the event will occur only if the change session belongs to one of the given forms. If this is not done, then it must be kept in mind that most of the described events occur very often, so their handlers should not have side effects (for example, showing messages) if there are no changes in the session. Ideally, events should be [simple](Simple_event.md) and should generally be used only to optimize the performance of really complex cases. + +When several handlers react to the same change, the order in which they are executed follows the data dependencies between them: a handler that uses data modified by another handler is executed after it. A handler can also be required explicitly to be executed after the specified properties and actions. ### Change operators' event mode {#change} diff --git a/docs/paradigm/en/Simple_event.md b/docs/paradigm/en/Simple_event.md index ee87ccff21..17992e755b 100644 --- a/docs/paradigm/en/Simple_event.md +++ b/docs/paradigm/en/Simple_event.md @@ -8,7 +8,7 @@ title: 'Simple event' - event [type](Events.md#type), which determines the point in time when this simple event will occur (including checking the condition). - event [handler](Events.md) - an [action](Actions.md) to be executed upon the occurrence of this simple event -Compared to a basic event, a simple event just wraps its handling in a [loop](Loop_FOR.md) operator whose condition is an event condition. However, simple events have a number of important additional features: +Compared to a basic event, a simple event merely runs its handler for every object collection that satisfies the event condition. However, simple events have a number of important additional features: - If the condition does not contain the [previous value operator (`PREV`)](Previous_value_PREV.md), the platform itself wraps the specified condition in a [change operator (`SET`)](Change_operators_SET_CHANGED_etc.md). This significantly reduces the risk of creating incorrect handling (which will have consequences if the change session is empty) - Such events are more understandable and readable, as they reflect the classic cause-effect relationship (when one thing occurs, another is done) diff --git a/docs/paradigm/ru/Calculated_events.md b/docs/paradigm/ru/Calculated_events.md index e9294d4638..552c52c17d 100644 --- a/docs/paradigm/ru/Calculated_events.md +++ b/docs/paradigm/ru/Calculated_events.md @@ -3,7 +3,7 @@ slug: "/Calculated_events" title: 'Вычисляемые события' --- -*Вычисляемые* события - события, которые при изменении значения свойства (*условия*) на не `NULL`, изменяют значение одного свойства на другое. При этом, в отличии от [простых](Simple_event.md) событий, это изменение происходит, не в момент изменения условия, а вычисляется каждый раз при обращении к изменяемому свойству. Если в сессии уже есть [изменение](Property_change_CHANGE.md) этого свойства, это изменение считается более приоритетным, чем изменение в вычисляемом событии. +*Вычисляемые* события - события, которые при изменении значения свойства (*условия*) на не `NULL`, изменяют значение [первичного свойства](Data_properties_DATA.md). При этом, в отличии от [простых](Simple_event.md) событий, это изменение происходит, не в момент изменения условия, а вычисляется каждый раз при обращении к изменяемому свойству. Если в сессии уже есть [изменение](Property_change_CHANGE.md) этого свойства, это изменение считается более приоритетным, чем изменение в вычисляемом событии. Для каждого свойства может быть только одно вычисляемое событие, которое изменяет это свойство. diff --git a/docs/paradigm/ru/Events.md b/docs/paradigm/ru/Events.md index ca1a8438d9..122a92a298 100644 --- a/docs/paradigm/ru/Events.md +++ b/docs/paradigm/ru/Events.md @@ -39,6 +39,8 @@ title: 'События' Также в платформе существует возможность дополнительно указать, что событие будет происходить, только если сессия изменений принадлежит одной из заданных форм. Если этого не сделано, то необходимо учитывать, что большинство описанных событий происходят очень часто, поэтому их обработки не должны иметь последействия (например, выдавать сообщения) при отсутствии изменений в сессии. В идеале события должны быть [простыми](Simple_event.md), а использоваться в общем случае только для оптимизации выполнения действительно сложных случаев. +Когда на одно и то же изменение реагирует несколько обработок, порядок их выполнения определяется зависимостями по данным между ними: обработка, использующая данные, изменённые другой обработкой, выполняется после неё. Также можно явно потребовать, чтобы обработка выполнялась после заданных свойств и действий. + ### Событийный режим операторов изменений {#change} При выполнении обработки событий [операторы изменений](Change_operators_SET_CHANGED_etc.md) переключаются в специальный режим (будем называть его *событийным*): они возвращают изменения, накопленные с момента предыдущего возникновения этого события (а точнее, с момента окончания выполнения всех его обработок), вместо изменений с начала сессии. Оператор [предыдущего значения](Previous_value_PREV.md) режим не переключает — он всегда использует область видимости начала сессии, — но для глобального синхронного события применение выполняется в свежей транзакции, поэтому "начало сессии" внутри обработчика соответствует моменту окончания обработки предыдущего возникновения события. diff --git a/docs/paradigm/ru/Simple_event.md b/docs/paradigm/ru/Simple_event.md index 692167763e..d78bf86545 100644 --- a/docs/paradigm/ru/Simple_event.md +++ b/docs/paradigm/ru/Simple_event.md @@ -8,7 +8,7 @@ title: 'Простые события' - [тип](Events.md#type) события, которое определяет момент времени, когда это простое событие будет возникать (в том числе проверяться условие). - [обработку](Events.md) события - [действие](Actions.md), которое необходимо выполнять при наступлении этого простого события -По сравнению с обычным событием, простое событие не более чем оборачивает свою обработку в оператор [цикла](Loop_FOR.md), условием которого является условие события. Однако при этом простые события имеют ряд важных дополнительных возможностей: +По сравнению с обычным событием, простое событие лишь выполняет свою обработку для каждого набора объектов, удовлетворяющего условию события. Однако при этом простые события имеют ряд важных дополнительных возможностей: - Если условие не содержит внутри [оператор предыдущего значения (`PREV`)](Previous_value_PREV.md), то платформа сама оборачивает указанное условие в [оператор изменений (`SET`)](Change_operators_SET_CHANGED_etc.md). Тем самым значительно снижается вероятность создать некорректную обработку (которая будет иметь последействие при пустой сессии изменений) - Такие события понятнее и читабельнее, так как отражают классическую причинно-следственную связь (когда случилось что-то, сделать то-то)