Monday, June 14, 2004

O artigo abaixo foi publicado na MSDN Magazine brasileira em Março de 2004.

 

 

Um dos pilares do novo sistema operational da Microsoft, codename Longhorn, é o novo sistema de arquivos chamado WinFS. Opath é uma linguagem de consulta utilizada por WinFS para recuperar e selecionar objetos a partir de uma fonte de dados.  Este artigo apresenta as razões para a criação de uma nova linguagem de consulta e introduz seus conceitos básicos.  Será apresentado também exemplos simples de filtros Opath que resulta em consultas de complexidade média.

 

Linguagem de Consulta

Opath é denominada como uma linguagem de consulta (Query Language) e não uma linguagem genérica de programação. O objetivo da linguagem OPath é permitir que o programador expresse com exatidão quais os objetos que deseja recuperar de uma base de dados. Opath não apresenta, pelo menos atualmente, nenhuma sintaxe para controle de fluxo (comandos do tipo IF, WHILE, entre outros), ou para criação de novos tipos e classes, aspectos típicos de uma linguagem de programação.

O membro mais famoso das linguagens de consulta é a linguagem SQL (Structured Query Language), sendo amplamente adotada pela maioria dos bancos de dados relacionais. Um dos benefícios da linguagem SQL é possibilitar que o gerenciador de banco de dados receba um comando semelhante ao da Listagem 1 e recupere as informações desejadas sem que o cliente tenha conhecimento dos detalhes de como tal informação foi armazenada em disco ou recuperada, qual o formato físico dos registros de cada tabela, qual a representação binária dos tipos de cada coluna, e outras características que só importam ao gerenciador de banco de dados.

O proprietário da tabela Clientes tem a flexibilidade de adicionar ou remover colunas da tabela (exceto as colunas ClienteID e ClienteName) que o comando da Listagem 1 continuará a ser executado com sucesso.  Cabe ao gerenciador de banco de dados a função de encapsular toda a complexidade envolvida em persistir dados num disco rígido. Da mesma forma, a linguagem OPath possibilita que toda a complexidade envolvida em persistir objetos seja encapsulada na camada de persistência de objetos, permitindo maior flexibilidade para o programador.  Na seção abaixo veremos no que consiste esta complexidade.

 

Listagem 1.  Exemplo de um comando SQL

Select ClienteID, Nome from Clientes

 

Classes e Tabelas

A adoção das linguagens de programação orientadas a objeto é inquestionável. Linguagens tradicionalmente não orientadas a objeto, por exemplo, Visual Basic ou Cobol, hoje já apresentam versões que usufruem desta técnica, disseminando tal tecnologia para um público antes restrito a práticas consideradas ultrapassadas.  Uma forma comum de um sistema orientado a objetos resolver um problema, é através do projeto de classes ou hierarquias de classes, definindo os relacionamentos corretos entre as instancias destas classes e finalmente persistindo as informações armazenadas nestas instancias em tabelas num banco de dados relacional. Mover os dados do mundo orientado a objeto para o mundo relacional pode parecer uma tarefa trivial, mas na realidade é um antigo problema que pode apresentar alta complexidade. O .Net Framework tornou este problema além de complexo, comum, já que orientação a objetos é o conceito fundamental no código gerenciado. É muito fácil encontrarmos profissionais de informática com dúvidas do gênero, por onde começo o projeto de um sistema multicamadas, pela modelagem das classes ou pela modelagem das tabelas do banco de dados. Independente de onde você começar, com certeza terá que gastar um bom tempo fazendo o mapeamento de um modelo para o outro. E qual o mapeamento adequado entre as classes e tabelas; uma classe para cada tabela ou várias tabelas para cada classe? Será que as regras de normalização de um banco de dados relacional devem ser mantidas?

 

Não seria interessante se existisse uma camada de software que encapsulasse esta complexidade de mapear classes e tabelas, e que proporcionasse ao programador fazer mudanças radicais no mapeamento, sem que o código cliente sofresse algum impacto. A Microsoft vem trabalhando pesado para disponibilizar esta infra-estrutura para o desenvolvedor e a linguagem de consulta para interagir com esta camada será OPath.

 

OPath

OPath é a forma pela qual você expressa critérios de seleção para a camada de persistência de objetos e como resultado recebe os objetos que satisfazem tal critério. Para os que conhecem a linguagem XPath, OPath será fácil de ser aprendida, pois foi baseada nos conceitos de navegação da linguagem XPath, já que as arvores semi-estruturadas XML são semelhantes aos grafos de objetos.

Veja um exemplo: imagine o seguinte conjunto de classes apresentado na Listagem 2 em C#. Suponha que você queira recuperar todos os clientes que possuem ordens de compra. Em OPath você escreve a seguinte expressão:

 

Exists(Clientes.Compras)

 

Vamos restringir ainda mais a seleção para os clientes que possuem compras entre 10 e 20 de fevereiro.

 

Exists(Clientes.Compras[DataCompra>=’10/02/2004’ and DataCompra<=’20/02/2004’])

 

Podemos restringir ainda mais os clientes para apenas aqueles clientes que compraram produtos com preço superior a 100 reais.

 

Exists(Clientes.Compras[DataCompra>=’10/02/2004’ and DataCompra<=’20/02/2004’].Items[Preco>100])

 

As três expressões são exemplos básicos que não exigiram nenhuma construção mais complexa. Para acessar a propriedade de um objeto o desenvolvedor deve utilizar o operador ‘.’, ou seja, para acessar a lista de compras dos clientes escreve-se a expressão Clientes.Compras. Uma vez selecionada a lista desejada, podemos adicionar critérios de seleção, conhecidos também como predicados, utilizando os colchetes.  Todas as expressões dentro dos colchetes tem como escopo o objeto especificado a esquerda do colchetes esquerdo.  Quando escrevemos Clientes.Compras[DataCompra =’17/02/2004’] a propriedade DataCompra se refere ao objeto especificado à esquerda do colchetes, neste caso a lista de objetos do tipo OrdemCompra.  Portanto são dois os conceitos essenciais que você precisa apreender para escrever expressões OPath; o primeiro é como navegar a partir de um objeto para outro, utilizando o operador ‘.’; e o segundo é como descrever critérios de seleção para filtrar apenas os objetos desejados, utilizando os predicados dentro dos colchetes.

 

Agora vamos traduzir estas expressões OPath para a linguagem SQL. Veremos que os comandos SQL equivalentes não são tão simples assim.  Como nosso modelo de classe é simples, adotaremos o mapeamento de um para um, conforme mostrado na Figura 1. Cada classe será armazenada em uma tabela.

 

Figura 1. Mapeamento da tabela

 

O primeiro filtro pode ser traduzido para SQL como:

 

Select Clientes.* From Clientes

Where exists(

  select 1 from Compras

  Where Clientes.ClienteID=Compras.ClienteID)

 

Para o segundo filtro temos:

 

Select Clientes.* From Clientes

Where exists(

  select 1 from Compras

  where Clientes.ClienteID=Compras.ClienteID

  and Compras.DataCompra between ‘10/02/2004

  and ‘20/02/2004’)

 

E para o terceiro filtro temos:

 

 

Select Clientes.* From Clientes

Where exists(

  select 1 from Compras

  join Items on Compras.OrdemID = Items.OrdemID

  where Clientes.ClienteID=Compras.ClienteID

  and Compras.DataCompra between ‘10/02/2004

  and ‘20/02/2004’ and Item.Preco > 100)

 

Estes comandos SQL podem ser reescritos de outra forma equivalente ao exposto. Observe o terceiro filtro e compare com a expressão OPath equivalente. A expressão OPath é bem mais simples, devido ao fato de ter escondido a complexidade de fazer os joins entre as três tabelas envolvidas e colocar os critérios de seleção na posição correta.  Será responsabilidade da camada de persistência de objetos traduzir as expressões OPath nos comandos SQL equivalentes, não apenas semanticamente equivalentes, mas também da maneira mais otimizada possível, eliminando a necessidade de se escrever manualmente tais comandos SQL. Para traduzir uma expressão OPath, a camada de persistência necessita do mapeamento entre as classes e seus relacionamentos, e as tabelas e seus relacionamentos. O fato deste mapeamento poder ser alterado durante o ciclo de desenvolvimento, sem nenhum ou com mínimo impacto no código cliente, proporciona ao desenvolvedor a rapidez e agilidade necessárias para atender as contantes mudanças nos requisitos de um projeto.

 

Listagem 2. Classes da tabela

Public class Cliente

{

  Public string Nome;

  Public Nullable<Endereco> Endereco;

  Public Collection<OrdemCompra> Compras;

}

 

Public class Endereco

{

  Public string Rua;

  Public string Cidade;

  Public string Estado;

  Public string Cep;

  Public string Pais;

}

 

Public class OrdemCompra

{

  Public DateTime DataCompra;

  Public Nullable<Endereco> EnderecoEnvio;

  Public Collection<ItemCompra> Items;

}

 

Public class ItemCompra

{

  Public string Produto;

  Public decimal Preco;

  Public int Quantidade;  

}

 

Conclusão

Este artigo apresentou os conceitos fundamentais da nova linguagem de consulta OPath, sua relação com outras linguagens tais como SQL e exemplos básicos de sua sintaxe. Saber escrever consultas em OPath é requisito básico para desfrutar dos benefícios do novo sistema de arquivos denominado WinFS, um dos pilares do próximo sistema operacional da Microsoft, codename Longhorn.  O cronograma do sistema operacional Longhorn prevê o lançamento da versão Beta ainda no ano de 2004 e a versão final no final do ano de 2005.

6/14/2004 10:11:32 PM (E. South America Standard Time, UTC-03:00)  #    Disclaimer  |   |  Trackback
Tracked by: