Создание триггеров и определяемых пользователем функций
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;
}