Esse artigo faz parte da revista SQL Magazine edição 52. Clique aqui para ler todos os artigos desta edição

d; FONT-FAMILY: Verdana">PostgreSQL

Menus dinâmicos a partir de funções em PostgreSQL 8

 

 

Uma das mais importantes classes de estruturas de dados em computação são as árvores. Uma árvore é uma estrutura de dados que se caracteriza por uma relação de hierarquia entre os elementos que a compõem. Aproveitando-se desta estrutura, este artigo mostrará a criação de alguns exemplos de menus dinâmicos, montados a partir do resultado de uma consulta SQL. Esta consulta listará os registros obedecendo à hierarquia baseada na relação pai-filho.

Através da implementação de uma função recursiva no PostgreSQL 8 é possível retornar esta estrutura de registros de forma rápida e organizada, tendo em vista que este banco, ainda, não possui em seu código nativo nenhuma solução pronta. O banco de dados Oracle, por exemplo, possui as cláusulas START WITH e CONNECT BY que facilitam o processo de criação de consultas hierárquicas.

Assim, convido-os a compreender a implementação desta função hierárquica e de outras funções que formatarão estes registros para serem utilizados como parâmetro em componentes que criam menus. Mãos à obra!

Árvores

Uma árvore é constituída de elementos chamados nó (node), interligados com outros elementos que estão em níveis diferentes. O nível é a distância que um nó está até chegar ao topo da árvore (nó raiz).

Cada nó possui uma ligação com outro nó de nível superior (nó-pai), com exceção do nó que está no topo, chamado de root ou nó raiz. Os elementos que estão ligados ao mesmo nó-pai são nomeados irmãos (siblings). Já os nós que não possuem nós-filhos, isto é, não estão ligados com outros nós de nível inferior, são chamados de folhas (leaf). 

As árvores dividem-se em dois grupos, como mostra a Figura 1. No grupo de árvores binárias, os nós da árvore podem conter no máximo dois nós-filhos. Já no grupo de árvores genéricas, o número de nós-filhos torna-se ilimitado, sendo este o grupo que mais se enquadra em uma estrutura de menus.

 

Figura 1. Exemplos de grupos de árvores

Iniciando a construção do menu

  Para uma melhor compreensão sobre como proceder para a criação de uma estrutura para geração de menus, montei um escopo das etapas necessárias, conforme Figura 2, mostrando a ordem de criação e a forma como cada etapa interage com a outra.

  A primeira e a segunda etapa consiste na criação da tabela e na inserção de alguns registros que são os itens do menu. Na terceira etapa, definiremos o tipo de dado “tpmenu” para ser utilizado no retorno da função hierárquica “fnc_monta_menu”. Logo em seguida, implementaremos esta função que servirá de base para as funções de formatação vistas na quinta etapa.

A etapa 6 indica que uma linguagem de programação executará as funções de formatação, enviando o resultado produzido para um componente de menu. A última etapa mostrará na tela o respectivo menu.

A Listagem 1 mostra o script das etapas 1 e 2. A tabela possui um auto-relacionamento evidenciado pela coluna IDMENUPAI na linha 6, que está referenciando um outro registro da mesma tabela. Coloquei um número razoável de registros para que possamos visualizar de forma clara o resultado. O primeiro registro será o topo da árvore, identificado por não possuir nenhum registro pai e, portanto, não será mostrado no menu.  A Figura 3 mostra a tabela com os dados inseridos.

 

Figura 2. Etapas para construção do menu

 

 

Listagem 1. Definição do esquema e da tabela

1        CREATE SCHEMA artigo;

2       

3        CREATE TABLE artigo.TBMENU

4        (

5                 IDMENU         SERIAL      NOT NULL,   -- CHAVE PRIMÁRIA

6                 IDMENUPAI    INT4,                       -- CHAVE ESTRANGEIRA

7                 MENU           VARCHAR(50) NOT NULL,   -- NOME DO ITEM DO MENU

8                 HREF            VARCHAR(50),            -- ARQUIVO DE CHAMADA

9                 ORDEM          INT2        NOT NULL,   -- ORDEM DOS ITENS DE MESMO PAI

10                PRIMARY KEY(IDMENU),

11                FOREIGN KEY(IDMENUPAI) REFERENCES artigo.TBMENU(IDMENU),

12                CHECK  (IDMENUPAI <> IDMENU),              -- UM ITEM FILHO NÃO PODE SER PAI

                                                                               DE SI MESMO

13                CHECK  (ORDEM > 0),                              -- VALORES POSITIVOS PARA A

                                                                              COLUNA ORDEM

14                UNIQUE (IDMENUPAI, ORDEM)                   -- VALIDAR DUPLICIDADE PARA

                                                                              ORDEM E PAI DE MESMO VALOR

15      );

16     

17      insert into artigo.tbmenu(menu, ordem) values('Início', 1);

18      insert into artigo.tbmenu(idmenupai, menu, href, ordem) values(1, 'Cadastros',  NULL, 1);

19      insert into artigo.tbmenu(idmenupai, menu, href, ordem) values(1, 'Operações',  NULL,

            2); ...

Quer ler esse conteúdo completo? Tenha acesso completo