Создание триггеров и определяемых пользователем функций

Завершено

Azure Cosmos DB поддерживает предварительные и пост-триггеры. Претриггеры выполняются перед изменением элемента базы данных и после активации после изменения элемента базы данных. Триггеры не выполняются автоматически. Они должны быть указаны для каждой операции базы данных, в которой они должны выполняться. После определения триггера его необходимо зарегистрировать с помощью пакетов SDK для Azure Cosmos DB.

Примеры регистрации и вызова триггера см. в разделе предварительных и пост-триггеров.

Предварительные заполнения

В следующем примере показано, как средство предварительного выполнения используется для проверки свойств создаваемого элемента Azure Cosmos. Он добавляет свойство метки времени в только что добавленный элемент, если он не содержит его.

function validateToDoItemTimestamp() {
    var context = getContext();
    var request = context.getRequest();

    // item to be created in the current operation
    var itemToCreate = request.getBody();

    // validate properties
    if (!("timestamp" in itemToCreate)) {
        var ts = new Date();
        itemToCreate["timestamp"] = ts.getTime();
    }

    // update the item that will be created
    request.setBody(itemToCreate);
}

Предварительные параметров не могут иметь входных параметров. Объект запроса в триггере используется для управления сообщением запроса, связанным с операцией. В предыдущем примере при создании элемента Azure Cosmos выполняется претригатор, а текст сообщения запроса содержит элемент, который будет создан в формате JSON.

При регистрации триггеров можно указать операции, с помощью которых их можно запустить. Этот триггер должен быть создан со TriggerOperation значением TriggerOperation.Create, используя триггер в операции замены, не допускается.

Примеры регистрации и вызова претриггера см. в статье о предварительной подготовке.

Триггеры последующего выполнения

В примере ниже показан триггер последующего выполнения. Этот триггер запрашивает элемент метаданных и обновляет его дополнительными сведениями о вновь созданном элементе.

function updateMetadata() {
var context = getContext();
var container = context.getCollection();
var response = context.getResponse();

// item that was created
var createdItem = response.getBody();

// query for metadata document
var filterQuery = 'SELECT * FROM root r WHERE r.id = "_metadata"';
var accept = container.queryDocuments(container.getSelfLink(), filterQuery,
    updateMetadataCallback);
if(!accept) throw "Unable to update metadata, abort";

function updateMetadataCallback(err, items, responseOptions) {
    if(err) throw new Error("Error" + err.message);
        if(items.length != 1) throw 'Unable to find metadata document';

        var metadataItem = items[0];

        // update metadata
        metadataItem.createdItems += 1;
        metadataItem.createdNames += " " + createdItem.id;
        var accept = container.replaceDocument(metadataItem._self,
            metadataItem, function(err, itemReplaced) {
                    if(err) throw "Unable to update metadata, abort";
            });
        if(!accept) throw "Unable to update metadata, abort";
        return;
    }
}

Важно отметить одну вещь, а именно — транзакционное выполнение триггеров в Azure Cosmos DB. Триггер последующего выполнения запускается как часть транзакции базового элемента. Исключение во время выполнения после триггера завершается сбоем всей транзакции. Все фиксации выполняется откат и возвращается исключение.

Пользовательские функции

В следующем примере создается определяемая пользователем функция для расчета подоходного налога для различных доходов. Эта функция затем будет использоваться в запросе. В этом примере предполагается, что есть контейнер с именем "Доходы" со свойствами следующим образом:

{
   "name": "User One",
   "country": "USA",
   "income": 70000
}

Следующий пример кода — это определение функции для вычисления налога на доходы для различных квадратных скобок дохода:

function tax(income) {

        if(income == undefined)
            throw 'no input';

        if (income < 1000)
            return income * 0.1;
        else if (income < 10000)
            return income * 0.2;
        else
            return income * 0.4;
    }