acadêmico: fabiano bendercampeche.inf.furb.br/tccs/2012-ii/tcc2012-2-10-ap-fabianobender.p… ·...
TRANSCRIPT
Acadêmico: Fabiano BenderOrientadora: Joyce Martins
FURB 2012/2
� Introdução� Objetivos� Fundamentação teórica� Desenvolvimento do aplicativo� Resultados� Resultados� Conclusão� Extensões
� Ampla utilização dos SGBDs
� Dificuldades da utilização da linguagem PL/PgSQL
� Necessidade da utilização de um depurador� Necessidade da utilização de um depurador
O objetivo principal este trabalho é desenvolver uma ferramenta para depuração de funções PL/PgSQL.
Os objetivos específicos são:� Efetuar as análises léxica, sintática e semântica das � Efetuar as análises léxica, sintática e semântica das funções, para detectar erros de compilação, bem como extrair as informações necessárias para a depuração� Depurar as estruturas sintáticas procedurais de algumas funções internas disponíveis no banco de dados� Disponibilizar uma interface para mostrar os valores das variáveis da função depurada
� Sistemas Gerenciadores De Banco de Dados� SGBD PostgreSQL� Linguagem SQL� Linguagem Procedural� PL/PgSQL� PL/PgSQL
� Sistemas Gerenciadores De Banco de Dados� PL/PgSQL
--Cabeçalho da funçãoCREATE OR REPLACE FUNCTION nome_da_funcao (nome_do_p arametro_de_entrada
TIPO_DE_DADO_DO_PARAMETRO) RETURNS TIPO_DE_DADO_DE_RETORNO AS $$ -- Escopo principal da função-- Escopo principal da funçãoDECLARE--Declaração de variáveis utilizadas no escopo prin cipal
nome_da_variavel 1 TIPO_DE_DADO;nome_da_variavel 2 TIPO_DE_DADO;
BEGIN--Código da função--...RETURN conteudo_do_tipo_de_dado_de_retorno; --opcio nal
END;--Rodapé da função$$LANGUAGE plpgsql;
� Compiladores e Depuradores
� Compiladores e Depuradores� Análise léxica
#biblioteca para operações com expressões regulares>>> import re>>> token = "Fabiano 123 Bender"
#pesquisa pelo caractere 'a' na variável token>>> re .findall( 'a' , token )[ 'a' , 'a' ]
#pesquisa por uma sequência de dígitos na variável token>>> re .findall( ' \d+' , token )[ '123' ]
#pesquisa por uma sequência de letras na variável token>>> re .findall( '[a-zA-Z \_]+' , token )[ 'Fabiano' , 'Bender' ]
� Compiladores e Depuradores� Análise sintática
<expressão> ::= <expressão> + <termo>| <expressão> - <termo>| <termo>
<termo> ::= <termo> * <fator>| <termo> / <fator>
� Análise semântica
| <termo> / <fator>| <fator>
<fator> ::= ( <expressão> )| identificador
� Trabalhos Correlatos� PL SQL Developer (Sun Software)
� Trabalhos Correlatos� SQL Navigator (Quest Software)
� Trabalhos Correlatos� PostgreSQL Maestro (SQL Maestro Group)
� Trabalhos Correlatos� Protótipo de um compilador para a linguagem PL/SQL (Hiebert)
� Permitir depurar comando a comando as funções que estão no banco de dados� Analisar léxica, sintática e semanticamente funções PL/PgSQL
Requisitos Funcionais
PL/PgSQL� Permitir inserir no banco de dados funções PL/PgSQL� Permitir conectar em um banco de dados PostgreSQL� Possuir uma tela para edição e para depuração de funções PL/PgSQL� Permitir inserir no banco de dados funções que estão sendo depuradas
� Executar no sistema operacional Windows e Linux� Ser implementada utilizando a linguagem de programação Python� Utilizar a ferramenta Qt Designer para desenho da
Requisitos Não Funcionais
� Utilizar a ferramenta Qt Designer para desenho da interface gráfica� Utilizar a biblioteca PyQt para interligação da interface com a ferramenta� Utilizar a biblioteca PLY para geração dos analisadores léxico e sintático
� Tipos de dados suportados
Definição da gramática da linguagem PL/PgSQL
Tipo SQL Tipo SQL
bigint interval
bigserial numericbigserial numeric
boolean serial
bytea smallint
date text
double precision timestamp
integer
� Funções internas suportadas
Definição da gramática da linguagem PL/PgSQL
Função Função Função
avg length round
coalesce lower substrcoalesce lower substr
count max to_char
current_date min trim
current_time now trunc
current_timestamp r_pad upper
l_pad r_trim
l_trim replace
Especificação: Diagrama de Diagrama de
Casos de Uso
Especificação: Diagrama de Diagrama de
Classes
� Python
� Qt Designer
Implementação: Ferramentas Utilizadas
� PyQt
� PLY
Implementação: Analisador léxico
#Método com a expressão regular que identifica se o token é um tipodef t_TYPE ( self , t ) :
r 'bigint|bigserial|boolean|bytea|date|double \precision|integer|interval|numeric|serial|smallint| text|timestamp|void|time'
if self . var_flag :self . variavel[ self . var_id] = [ t. value , None]return treturn t
#Método com a expressão regular que identifica se o token é um identificadordef t_ID ( self , t ) :
r '[a-zA-Z \_][a-zA-Z0-9 \_]*'if self . var_flag :
self . var_id = t. value . strip()return t
#Método com a expressão regular que identifica se o token é um decimaldef t_DECIMAL( self , t ) :
r ' \d+( \.\d+)?'return t
Implementação: Analisador sintático#Regra inicialdef p_statement_assign ( self , p) :
"""statement : CREATE OR REPLACE FUNCTION ID LPAREN expression_typeRPAREN RETURNS TYPE LANGUAGE PLPGSQL AS DOLLAR DECLARE expression_variavel BEGIN expression_comando END SEM ICOLON DOLLAR empty"""
pass
#Regra que define um tipo de regra sintática#Regra que define um tipo de regra sintáticadef p_expression_type ( self , p) :
"""expression_type : TYPE| TYPE COMMA expression_type"""
pass
#Regra que define um tipo de regra sintáticadef p_expression_where ( self , p) :
"""expression_where : ID OPERADOR ID| DECIMAL OPERADOR ID| expression_where OR expression_where"""
pass
def p_empty( self , p): "empty :"pass
Implementação: Analisador Semânticodef testa_tipo_dado ( self , k, v) :
v = str ( v)if v:
tipo = self . tipo_dado[ self . variavel[ k][ 0]]dado = "%s(%s)" % ( tipo , v)if self . debug : print " ==> %s - %s - %s" % ( v, tipo , dado )try:
if tipo == 'int' and v. find( '.' ) > - 1:raise
elif tipo == 'date' and '0000-00-00' != re . sub( ' \d' , '0' , v) :raise
elif tipo == 'time' and '00:00:00' != re . sub( ' \d' , '0' ,v[ : 8]) :
raiseelif tipo == 'datetime' and '0000-00-00 00:00:00' !=
re . sub( ' \d' , '0' , v[ : 19]) :raise
return Trueexcept Exception, e:
print ereturn False
Implementação: Depuradordef analisa_expressao ( self , linha , comando) :
if comando. startswith( 'if' ) :if not self . cmd_if :
self . ret_if =self . DepuradorBase . executa_comando_if( comando)
self . cmd_if = Trueelse:
self . cmd_if = False
if comando. startswith( 'select' ) :k, v = self . DepuradorBase . executa_select( comando)self . token_valor . append( ( linha , k, v) )self . variavel[ k][ 1] = v or 'None‘ret_teste = self . testa_tipo_dado( k, v)
if comando. find( ':=' ) > - 1:k, v = self . DepuradorBase . executa_atribuicao( comando)self . token_valor . append( ( linha , k, v) )self . variavel[ k][ 1] = vret_teste = self . testa_tipo_dado( k, v)
Implementação: Operacionalidade (Debugres)
� Objetivos propostos atingidos� Delimitação da gramática� Python� PLY� PLY� PyQt� Qt Designer
� Delimitação da gramática
� Facilidade na utilização de um depurador
� Vantagens da ferramenta Debugres
� Aperfeiçoar a gramática, não restringindo os tipos de dados e os comandos disponíveis para o SGBD PostgreSQL
� Melhorar as mensagens dos erros identificadas pelos � Melhorar as mensagens dos erros identificadas pelos analisadores, deixando mais específicas as correções a serem efetuadas
� Integrar o depurador diretamente ao SGBD PostgreSQL, eliminando a parte gráfica e facilitando a depuração das funções