Оператор NEWSESSION
Оператор NEWSESSION создаёт действие, которое выполняет другое действие в новой сессии.
Синтаксис
NEWSESSION [NEWSQL] [FORMS formId1, ..., formIdM] [NESTED [nestedPropertySelector] [CLASSES]] [SINGLE] action
где nestedPropertySelector имеет один из следующих вариантов:
LOCAL
(propertyId1, ..., propertyIdN)
Описание
Оператор NEWSESSION создаёт действие, которое выполняет другое действие в новой сессии. NEWSQL и NESTED взаимно исключающие: при указании NEWSQL весь блок NESTED ... [CLASSES] игнорируется, и новая сессия не наследует от текущей ни значения локальных свойств, ни изменения классов. Если оператор выполняется во время транзакции применения текущей сессии, новая сессия не создаётся — выполняемое действие откладывается и выполняется в текущей сессии внутри той же транзакции.
Параметры
-
NEWSQLОпциональное ключевое слово. Открывает новую сессию на отдельном SQL-соединении, независимом от соединения текущей сессии.
-
formId1, ..., formIdMСписок идентификаторов форм, указываемый после
FORMS, к которым привязывается новая сессия. Сессия становится сессией изменений этих форм; используется, когда выполняемое действие должно вести себя так, как если бы оно было вызвано из этих форм. -
NESTEDОпциональное ключевое слово, после которого можно указать, какие локальные свойства текущей сессии считаются вложенными для этого оператора: при создании новой сессии их текущие значения копируются в неё, а по завершении выполняемого действия их значения из новой сессии копируются обратно в текущую. Из покрытых свойств переносятся только те, которые выполняемое действие использует или изменяет; если действие открывает интерактивные формы — все покрытые свойства.
APPLYвнутри новой сессии сбрасывает изменения этих свойств так же, как и всех остальных локальных свойств (обратно тогда будут скопированы уже сброшенные значения) — чтобы сохранить значения, пометьте свойства вложенными также в оператореAPPLYлибо объявите ихNESTEDв оператореDATA, что покрывает оба случая. Свойства, объявленныеNESTEDв оператореDATA, переносятся и без указания в этом списке. Само по себе, безLOCALи без списка свойств, ключевое слово на поведение оператора не влияет. -
LOCALКлючевое слово. Если указывается после
NESTED, переносятся все локальные свойства текущей сессии. -
propertyId1, ..., propertyIdNНепустой список локальных свойств, указываемый после
NESTEDв круглых скобках, которые переносятся. Каждый элемент списка должен являться идентификатором свойства. -
CLASSESОпциональное ключевое слово. Если указывается после
NESTEDи необязательного селектора локальных свойств, в новую сессию помимо тех локальных свойств, которые покрыл селектор, также переносятся изменения классов существующих объектов (и объекты, созданные в текущей сессии). -
SINGLEОпциональное ключевое слово. Если
NEWSESSIONсам вызывается внутри транзакции применения, этот флаг распространяется на внутреннее действие: изменения хранимых свойств, используемых им, записываются в базу инкрементально по ходу транзакции, а не одним пакетом в конце применения. -
actionКонтекстно-зависимый оператор-действие, описывающий действие, которое должно быть выполнено в новой сессии.
Примеры
testNewSession () {
NEWSESSION {
NEW c = Currency {
name(c) <- 'USD';
code(c) <- 866;
}
APPLY;
}
// здесь новый объект класса Currency уже в базе данных
LOCAL local = BPSTRING[10] (Currency);
local(Currency c) <- 'Local';
NEWSESSION {
MESSAGE (GROUP SUM 1 IF local(Currency c) == 'Local'); // возвратит NULL
}
NEWSESSION NESTED (local[Currency]) {
// возвратит кол-во объектов класса Currency
MESSAGE (GROUP SUM 1 IF local(Currency c) == 'Local');
}
NEWSESSION {
NEW s = Sku {
id(s) <- 1234;
name(s) <- 'New Sku';
SHOW sku OBJECTS s = s;
}
}
}
// переносим в новую сессию созданный объект вместе с локальным свойством selected
selected = DATA LOCAL BOOLEAN (Sku);
markSelected () {
NEW s = Sku;
selected(s) <- TRUE;
NEWSESSION NESTED (selected[Sku]) CLASSES {
// здесь видны и созданный Sku, и selected[Sku]
MESSAGE (GROUP SUM 1 IF selected(Sku s));
}
}
// вычисляем значение в новой сессии и читаем его после завершения блока
currencyCount = DATA LOCAL INTEGER ();
countCurrencies () {
NEWSESSION NESTED (currencyCount) {
currencyCount() <- GROUP SUM 1 IF Currency c IS Currency;
}
MESSAGE currencyCount(); // значение, вычисленное в новой сессии
}
// привязываем новую сессию к конкретной форме
showOnOrders () {
NEWSESSION FORMS orders {
SHOW orders;
}
}
// запускаем действие в свежем SQL-соединении
backgroundJob () {
NEWSESSION NEWSQL {
APPLY;
}
}
// SINGLE имеет смысл только когда NEWSESSION сам вызывается внутри транзакции применения
recalc () {
APPLY {
NEWSESSION SINGLE {
// изменения здесь записываются в базу инкрементально по ходу внешнего apply
id(Sku s) <- (GROUP MAX id(Sku ss)) (+) 1;
}
}
}