/**
* Класс SessionStack
*/
class TransactionStack {
/**
* Конструктор стека
* @param params
*/
constructor(params) {
this.stack = params.stack || new Array();
}
/**
* Добавление элемента (транзакции) в конец массив
* @param item - {TransactionItem} - объект транзакции
* @returns {Number} - длина стека
*/
push(item) {
return this.stack.push(item);
}
/**
* Удаление последнего элемента из стека
* @returns {TransactionItem} - удаляемый объект транзакции
*/
pop() {
return this.stack.pop();
}
/**
* Удаление транзакции по индексу в стеке
* @param index
*/
removeItemByIndex(index) {
let self = this;
let stack = self.getStack();
stack = stack.filter((item, i) => {
return index !== i;
});
this.stack = stack;
}
/**
* Удаление транзакции по идентификатору в стеке
* @param index
*/
removeItemById(id) {
let self = this;
let stack = self.getStack();
stack = stack.filter((item) => {
return item.guid !== id;
});
this.stack = stack;
}
/**
* Получение объектов стека
* @returns {*|Array} - массив транзакций
*/
getStack() {
return this.stack;
}
/**
* Применение транзакции, заданной по индексу в стеке
* @param index (number) - индекс транзакции в стеке
* @returns {Promise.<boolean>} - результат применения транзакции
*/
async commit(index) {
let self = this;
let item = self.getStack()[index];
let commitResult = false;
try {
commitResult = await item.execute();
}
catch (e) {
commitResult = undefined;
}
if (commitResult) {
self.stack = self.stack.filter((item) => {
return item.getState() !== true;
});
}
return commitResult;
}
/**
* Применение транзакции, заданной по ее id (guid - вычисляется автоматически при создании транзакции)
* @param id (guid) - идентификатор транзакции
* @returns {Promise.<boolean>} - результат применения транзакции
*/
async commitById(id) {
let self = this;
let items = self.getStack();
let item = items.find((transactionItem) => {
return transactionItem.getId() === id;
});
if (!item) return undefined;
let commitResult = false;
try {
commitResult = await item.execute();
}
catch (e) {
commitResult = undefined;
}
if (commitResult) {
self.stack = self.stack.filter((item) => {
return item.getState() !== true;
});
}
return commitResult;
}
/**
* Применение всех транзакций
* @returns {Promise.<Array>} - результаты применения транзакций {result: false/true, transactionId - идентификатор}
*/
async commitAll() {
let self = this;
let commitResults = [];
for (let i = 0; i < self.getStack().length; i++) {
let stack = self.getStack();
let guid = stack[i].getId();
let result = await self.commit(i);
commitResults.push({
transactionId: guid,
result: result,
state: result.state
});
}
return commitResults;
}
/**
* Очистка стека транзакций
* @returns {*|Array} - новый пустой стек транзакций
*/
clear() {
this.stack = new Array();
return this.stack;
}
}
let stack;
function init() {
stack = new TransactionStack({});
return stack;
}
function getStack() {
if (!stack) stack = init();
return stack;
}
module.exports = getStack();