XQuery Update Gestão e Tratamento da Informação DEI IST (baseado nos slides de Ioana Manolescu, acessíveis em: http://www-rocq.inria.fr/~abitebou/Master-SSD/slxqupdate.pdf) Agenda Aspectos básicos Príncipios Requisitos para a linguagem XQuery Update Conceitos XQuery Update Modelo de processamento do XQuery Update Actualizações XQuery Porquê XQuery Update? Expressões de inserção, remoção, actualização, renomeação, transformação Exemplo de programação com XQuery Update Comparação entre SQL e XQuery Update Porquê XQuery Update? XQuery é uma linguagem só de leitura (read-only): pode retornar uma instãncia do modelo de dados XQuery, mas não pode modificar uma instância existente Paralelo em SQL: select... from... where... Sem: insert into table... update table... Como as aplicações necessitam de ler e actualizar dados XML, surgiu: XQuery Update Facility: um documento de trabalho, que ainda não é uma especificação http://www.w3.org/TR/xquery-update-10/ Requisitos para a linguagem XQuery Update Poder de expressividade: Inserção (Insert) Remoção (Delete) Actualização (Update) Cópia com nova identidade Extensão do próprio XQuery: Simplifica a compreensão e aprendizagem da linguagem Tem uma semântica bem definida É concisa Presta-se a uma implementação eficiente... Conceitos de XQuery Update Todas as expressões XQuery podem ser classificadas em: Expressões que efectuam actualização Expressões que não efectuam actualização XQuery Update introduz 5 novos tipos de expressões: insert, delete, replace, rename: expressões que efectuam actualizações transform: expressões que não efectuam actualizações XQuery Update especifica: Lugares onde cada tipo de expressão pode aparecer Sintaxe e semântica de cada expressão nova Modelo de processamento de XQuery Update A avaliação de uma expressão produz: Uma instância do modelo de dados XQuery Uma lista de actualizações pendentes: conjunto de primitivas de actualização, ou seja mudanças ao estado de um nó, que têm que ser aplicadas Na especificação corrente, uma das duas tem que ser vazia. Isto pode mudar no futuro. (A avaliação de uma XQuery simples produz uma instância do modelo de dados XQuery) Cada primitiva de actualização tem um nó alvo. As primitivas de actualização são verificadas, de modo a detectar conflitos. Se não existir nenhum conflito, então são aplicadas Expressões de inserção (1) Insert é uma expressão de actualização Forma geral: InsertExpr::=insert (node|nodes) SourceExpr InsertExprTargetChoice TargetExpr InsertExprTargetChoice::=((as (first|last))? into) | after | before SourceExpr::=ExprSingle TargetExpr::=ExprSingle A primeira expressão é chamada de fonte, e a segunda de alvo. As expressões fonte e alvo não devem efectuar actualizações Exemplos: Inserir o elemento year depois do publisher do 1º livro insert nodes <year>2005</year> after doc(bib.xml)/books/book[1]/published Através da variável $article, inserir a lista de autores a ela associada como filhos do 3º livro insert nodes $article/author as last into doc(bib.xml)/books/book[3] ExprSingle ExprSingle ::= FLWORExpr | QuantifiedExpr | TypeswitchExpr | IfExpr | InsertExpr | DeleteExpr | RenameExpr | ReplaceExpr | TransformExpr | OrExpr Expressões de inserção (2) A lista de actualizações pendentes (lap) é obtida da seguinte maneira: Avaliar o alvo de actualização, que são os nós que devem receber novos filhos Para cada um desses nós, adicionar à lap as correspondentes operações adiciona-filho Exemplo: Navegando através de várias váriáveis, inserir um novo relatório de polícia na lista de relatórios de polícia para um determinado acidente insert node $new-police-report as last into doc(“insurance.xml”)//policies/policy[id=$pid] /driver[licence=$licence]/accident[date=$dateacc] /police–reports Localiza o elemento police-reports adequado Para cada elemento dentro da variável $new-police-report, adiciona uma operação adiciona-ultimo-filho à lap Expressões de remoção Delete é uma expressão que efectua actualizações. Produz uma lista de actualizações pendentes não vazia Forma geral: deleteExpr ::= delete (node|nodes) TargetExpr TargetExpr ::= ExprSingle Exemplos: Apagar o nome do último autor do primeiro livro de uma determinada bibliografia delete nodes doc(bib.xml)/books/book[1]/ author[last()] Apagar todas as mensagens de email que são mais velhas do que 365 dias delete nodes /email/message[fn:currentDate()-date > xdt:dayTimeDuration(P365D)] Expressões de substituição Replace é uma expressão de actualização. Produz uma lista de actualizações pendentes não vazia Forma geral: ReplaceExpr::= replace (value of)? node TargetExpr with ExprSingle TargetExpr::= ExprSingle Se value of é especificado, a expressão de substituição é usada para modificar o valor de um nó, mas preservando a sua identidade Exemplos: Substituir o editor (publisher) do primeiro livro pelo editor do segundo livro replace node doc(“bib.xml”)/books/book[1]/publisher with doc(“bib.xml”)/books/book[2]/publisher Aumentar o preço do primeiro livro em 10% replace value of node doc(“bib.xml”)/books/book[1]/price with doc(“bib.xml”)/books/book[1]/price*1.1 Expressão de renomeação Rename é uma expressão que efectua actualizações Forma geral: RenameExpr::= rename node TargetExpr as NewNameExpr TargetExpr::= ExprSingle NewNameExpr::= ExprSingle Exemplos: Renomear o primeiro elemento author do primeiro livro para main-author rename node doc(“bib.xml”)/books/book[1]/author[1] as “main–author” Renomear o primeiro elemento author do primeiro livro com o valor da variável $newname. rename node doc(“bib.xml”)/books/book[1]/author[1] as $newname Expressões de transformação (1) Transform é uma expressão que não efectua actualizações Forma geral:: TransformExpr::= copy $ VarName := ExprSingle (, $ VarName := ExprSingle)* modify ExprSingle return ExprSingle Pode ser usada para criar cópias modificadas de nós existentes numa instância do modelo de dados XQuery Uma expressão transform consiste em 3 claúsulas, denotadas pelas palavras chave: copy, modify, and return Exemplo: retornar todos os gestores, omitindo os seus salários e substituindo-os pelo atributo xsi:nil. Nota: Pode ser feito em XQuery, mas é rebuscado! Transform retorna uma cópia modificada, sem produzir impacto na base de dados original (visto que é uma expressão que não efectua actualizações) Expressões de transformação (2) Documento inicial <employees> <employee mgr="true" dept="Toys"> <name>Smith</name> <salary>100000</salary> </employee> <employee dept="Toys"> <name>Jones</name> <salary>60000</salary> </employee> <employee mgr="true" dept="Shoes"> <name>Roberts</name> <salary>150000</salary> </employee> </employees> Resultado desejado <employee mgr="true" dept="Toys"> <name>Smith</name> <salary xsi:nil="true"/> </employee> <employee mgr="true" dept="Shoes"> <name>Roberts</name> <salary xsi:nil="true"/> </employee> Pode ser feito em XQuery, mas não é fácil. Tentar como exercício.... Expressões de transformação (3) Retornar todos os gestores, omitindo os seus salários e substituindo-os com um atributo xsi:nil. for $e in doc("employees.xml")//employee where $e/@manager=true() return copy $emp := $e modify ( replace value of node $emp/salary with "" , insert nodes (attribute xsi:nil{"true"}) into $emp/salary ) return $em Programar com XQuery Update (1) Sincronização de livro de endereços: Uma versão de arquivo e duas cópias c1 = a e c2 != a => propagar c2 para a e c1 c1 != a, c2 != a => Se possível, fazer o apanhado das diferenças e propagá-las para a, e depois para c1 e c2 Senão, dar erro Entradas da agenda são da forma: <entry> <name> Benjamin </name> <contact> [email protected] </contact> </entry> <entry> <name> Anthony </name> <contact> [email protected] </contact> </entry> Programar com XQuery Update (2) for $a in doc("archive.xml")//entry , $v1 in doc("copy1.xml")/version/entry , $v2 in doc("copy2.xml")/version/entry where $a/name = $v1/name and $v1/name = $v2/name return if ($a/contact = $v1/contact and $v1/contact =$v2/contact then () else if ($v1/contact = $v2/contact) then replace value of node $a/contact with $v1/contact else if ($a/contact = $v1/contact) then ( replace value of node $a/contact with $v2/contact , replace value of node $v1/contact with $v2/contact ... Programar com XQuery Update (3) ... if ($a/contact = $v1/contact ) then ... else if ($a/contact = $v2/contact ) then ( replace value of node $a/contact with $v1/contact , replace value of node $v2/contact with $v1/contact ) else ( insert node <fail> <arch>{ $a }</arch> <v1>{ $v1 }</v1> <v2>{ $v2 }</v2> </fail> into doc("log.xml")/ log ), replace value of node doc("archive.xml")/*/last-synch-time with current-dateTime() Notas sobre XQuery Update XQuery Update não é uma linguagem de interrogação, porque falta: Controlo sobre o âmbito de snapshots, isto é, quando é que as minhas actualizações se tornam visíveis para outra interrogação? XQuery Update: depois da interrogação corrente ter acabado de se executar Controlo sobre a atomicidade, isto é, que expressões têm que ser executadas atomicamente? Tratamento de erros Implementações XQuery Update eXist MonetDB XQilla Saxon Referências Ioana Manolescu, slides about XQuery Update, course about “Web Data Management and Distribution”, Master Recherche Informatique Paris Sud, http://wwwrocq.inria.fr/~abitebou/Master-SSD/slxqupdate.pdf www.perfectxml.com/XQuery.html XQuery: A Guided Tour (book chapter from XQuery from the Experts)