Falei um pouco sobre integração entre Cosmos DB e Xamarin Forms neste post. Lá expliquei também sobre o que é o Cosmos DB e como ele pode nos ajudar a escalar nossa aplicação mundialmente e acelerar a criação dos nossos apps.
Neste post vamos ver como criar uma Stored Procedure no Cosmos DB com JavaScript.
Porque Stored Procedures?
Nos modelos on-premisses as stored procedures normalmente são utilizadas para executar tarefas repetitivas de manipulação de dados de forma transacional.
Stored Procedures usam o SDK Javascript do servidor do Cosmos DB para fazer operações de banco de dados como criar, ler, atualizar, excluir e consultar documentos, bem como ler do corpo da solicitação e gravar no corpo da resposta de uma stored procedure. Ela tem escopo transacional como no modelo on-primesses. O escopo transacional é na verdade uma transação atômica. Essa funcionalidade atômica permite que um aplicativo combine operações relacionadas em um único lote para que todas ou nenhuma delas seja bem-sucedida. Em resumo, a atomicidade garante que todo o trabalho realizado dentro de uma transação seja tratado como uma única unidade em que tudo é confirmado ou não
Javascript?
Sim, as stored procedures do Cosmos DB são desenvolvidas com a linguagem Javascript e o SDK do Cosmos. Você pode desenvolver suas procedures dentro do portal do azure. Toda a construção da procedure será um function Javascript e no retorno da funtion, você poderá atribuir um body JSON personalizado em cada function com as informações que você quiser retornar.
Vale citar que o Javascript suportado para criação de procedures no Cosmos é o ECMA Script 2015
Criando e Executando Stored Procedures
Como citado acima, as stored procedures são criadas com a linguagem Javascript e podem ser criadas diretamente no portal do Azure. Você pode consultar a documentação das stored procedures no Cosmos DB neste endereço
A stored procedure necessariamente irá pertencer a uma collection que pertence a um schema de dados, veja o modelo de dados abaixo:
No portal do azure, dentro do seu Cosmos DB, clique na opção Settings para acessar o painel com seus schemas e collections
![setting](/wp-content/uploads/2018/04/1.png)
Clique na opção New Stored Procedure, você verá um exemplo de procedure padrão gerado automaticamente pelo azure.
![new procedure](/wp-content/uploads/2018/04/2.png)
Personalizei este exemplo para realizar um update nos registros retornados pelo meu SELECT, veja como ficou:
function updateClubNames(prefix) {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT * FROM Clubs c',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) {
var response = getContext().getResponse();
response.setBody('no clubs found');
}
else {
var response = getContext().getResponse();
var totalAtualizados = 0;
for (var i = 0; i < feed.length; i++) {
feed[i].Name = prefix;
var accept = collection.replaceDocument(feed[i]._self, feed[i],
function (err, docReplaced) {
if (err) throw "não foi possível concluir a atualizacao ";
});
totalAtualizados++;
}
response.setBody(JSON.stringify('Foram atualizados ' + totalAtualizados + ' clubes'));
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Na procedure acima resgatamos o endereço da collection atual com o método getContext().getCollection() definimos qual será a massa de dados no método queryDocuments que recebe o endereço da collection, o Select a ser executado e uma função de erro. Veja que o meu select está retornando todos os dados, mas nada me impediria de utilizar uma cláusula WHERE e retornar apenas dedos que se encaixassem em uma determinada condição. Além disto no comando collection.replaceDocument estamos salvando as alterações feitas nos documentos. Este método recebe o endereço do documento, o novo documento e uma função de erro. Por fim estamos setando o corpo do nosso response com a uma frase personalizada.
Após concluída a edição da procedure, clique em Save para armazenar as alterações.
Para executar a procedure no próprio portal do azure, clique no botão Execute. O azure abrirá uma nova janela para você informar parametros da procedure. Neste caso definimos como parametro a variável prefix na assinatura da função.
Clique em + Add New Parameter, preencha o campo e clique em Execute
![parametros](/wp-content/uploads/2018/04/4-1.png)
O resultado da execução será mostrado abaixo do codigo fonte da procedure na aba Result
![result](/wp-content/uploads/2018/04/5.png)
Executando a procedure a partir do C#
Para executar a procedure no seu C# você poderá utilizar o comando ExecuteStoredProcedureAsync do SDK do Cosmos DB informando um array de dynamic para os parâmetros. A resposta será um StoredProcedureResponse que conterá o campo Response com o conteudo que definimos na procedure. Para executar a procedure pelo client do SDK é necessário passar o path inteiro da procedure, desde o schema. Para isto vamos utilizar o nome do schema e o nome da collection para criar o storedProcedureLink . Veja o exemplo abaixo:
public async Task<dynamic> Create(Club document)
{
try
{
var documentCollectionUri = UriFactory.CreateDocumentCollectionUri("SampleCosmos", "Clubs");
var documentClient = new DocumentClient(new Uri(DocumentDbConstants.Url), DocumentDbConstants.ReadWritePrimaryKey);
var result = await documentClient.ExecuteStoredProcedureAsync<dynamic>(documentCollectionUri + @"/sprocs/updateClubNames" , new dynamic[] { "real madrid" });
return result.Response;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}
Conclusão
Se você possui tarefas repetitivas para serem executas e deseja centralizar isto em uma rotina, talves as stored procedures do Cosmos DB seja uma boa opção para você. O recurso oferecido pelo Cosmos é bastante interessante e flexivel, vale a pena ter como opção no desenvolvimento das nossas aplicações.
Você pode ler mais sobre stored procedures no Cosmos DB neste endereço
Comentários