FB++: BIBLIOTECA C++ PARA ACESSO AO GERENCIADOR DE BANCO DE DADOS FIREBIRD Renato Stocco Bonatto, Aedra Marciana Virgilio, Leacir Nogueira Bastos, Baulindo Gonçalves Leal. Resumo: Desenvolveu-se uma biblioteca em C++ com os recursos básicos para conecta-se ao gerenciador de banco de dados Firebird. Ela caracteriza-se por ser multiplataforma (Unix, Linux e Windows), muito simples e de fácil uso. Possuindo as duas classes fbDriver e fbQuery. A primeira conecta-se ao banco de dados e fornece serviços de acesso a segunda a qual executam, de modo controlado, comandos SQL. Possui ainda funções para a obtenção de dados do banco de dados. A sua licença de uso é a mesma que a do Firebird. A biblioteca foi testada e mostrou-se satisfatória e está disponível para download tanto o código fonte quanto um programa fonte para teste no site www.dpi.ufv.br/~lnb. PALAVRAS-CHAVE: biblioteca em C++, banco de dados, multiplataforma. FB++: LIBRARY C++ FOR ACCESS TO DATABASE FIREBIRD MANAGER Abstract: A library in C++ was developed with basic resources to connect the database manager Firebird. It’s characterized by being multi-platform (Unix, Linux and Windows), very simple and of easy use. It possesses two classes, fbDriver and fbQuery. The first is connected to the database and it supplies access services second which they execute, in a controlled way, commands SQL through functions, being obtained information starting from the database. It’s license of use is the same that the one of Firebird. The library was tested and revealed satisfactory and it is available for so much download the code source as a program source for test in the site www.dpi.ufv.br/~lnb. KEYWORDS: library in C++, database, multi-platform Introdução Bancos de dados, (ou bases de dados), são conjuntos de dados com uma estrutura regular que organizam informação, utilizadas para um mesmo fim. Um banco de dados é usualmente mantido e acessado por meio de um software conhecido como Sistema Gerenciador de Banco de Dados (SGBD). Normalmente um SGBD adota um modelo de dados, de forma pura, reduzida ou estendida. Muitas vezes o termo banco de dados é usado como sinônimo de SGDB. O Firebird, SGBD Relacional open-source, originou-se do Interbase 6. Ele é mantido por uma comunidade internacional de desenvolvedores, caracterizado por ser estável, seguro e robusto. Possui arquitetura multigeradora, commit automático em duas fases, sombreamento de banco de dados, replicação, admissão e tratamento de blobs, índices em mapa de bits disperso, colunas vetoriais multidimensionais, subsistema de eventos de alertas. Está em conformidade com os requisitos SQL-92 – ANSI (nível de entrada), com extensões próprias para gerenciamento de Generators, Triggers e Stored-Procedures. Suporta integridade referencial declarativa com operações em cascata, visões atualizáveis e outer joins. Provê bibliotecas que suportam desenvolvimento de aplicações cliente SQL e DSQL, e em todas as plataformas suportadas, aplicações cliente podem ser escritas para sua API que é uma biblioteca de funções pela qual se pode enviar requisições para operações no banco de dados no servidor. Suporta recursos estendidos da SQL, alguns dos quais antecipam o padrão ANSI – SQL3. Entre eles, stored procedures, triggers e suporte a Blob segmentado. É de simples administração e de aprendizagem fácil. O Firebird é um sistema gerenciador de banco de dados relacional (SGDBR) cliente/servidor que oferece muitas características do ANSI SQL-92, com versões para Linux, Windows e uma variedade de plataformas Unix. O Firebird oferece excelente concorrência, desempenho elevado e uma poderosa linguagem para se escrever stored procedures e triggers. Este SGDBR possui inúmeras características técnicas que podem ser obtidas junto ao seu site oficial: http://firebird.sourceforge.net. Outras referências complementares e igualmente importante são: a) o site da comunidade brasileira, http://www.firebase.com.br; b) o site da comunidade portuguesa, http://www.comunidade-firebird.org; e c) o site da comunidade internacional, http://www.ibphoenix.com. Materiais e Métodos Bancos de dados Firebird são criados e preenchidos com dados utilizandose de sentenças SQL (Inprise, 1999b). A linguagem SQL foi database is created and populated using SQL statements, which can be divided into two major categories: data definition language (DDL) - CREATE, ALTER e DROP.statements and data manipulation language (DML) - Podem-se encontrar na internet diversas bibliotecas para acessar o Firebird, disponíveis em várias linguagens. Para a linguagem C++ pode-se destacar a IBPP, uma biblioteca de código aberto (IBPP, 2004). O InterBase 6.0 vem com uma série de exemplos de softwares escritos em C++ que permite acessar banco de dados tanto do próprio InterBase quanto do Firebird. As aplicações DSQL podem declarar uma ou mais descritores extendidos de áreas SQL (XSQLDAs). XSQLDA são estruturas usadas para transferir dados de banco de dados quando se processa sentenças SQL. Um campo de XSQLDA é definido pela estrutura XSQLVAR que representa cada parâmetro de entrada ou coluna retornada Fonte: Inprise (1999a). isc_db_handle db ISC_STATUS *status isc_tr_handle trans isc_stmt_handle stmt XSQLDA *sqlda int size short columns handler da conexão com o SGDB Firebird um vetor de atributos da conexão handler da transação com o SGDB Firebird handler da sentença SQL estrutura que permite transferir dados da aplicação do e para o banco de dados tamanho em bytes do tipo de dado número de campos da tabela armazenada em sqlda Fonte: Inprise (1999a). API database functions Nome Propósito isc_attach_database Connects to a database and establishes initial parameters for database access, such as number of cache buffers to use; uses a previously declared and populated DPB isc_detach_database Disconnects from an attached database and frees system resources allocated to that attachment Fonte: Inprise (1999a). DSQL functions Function name isc_dsql_allocate_statement() isc_dsql_describe() isc_dsql_execute() isc_dsql_fetch() isc_dsql_free_statement() isc_dsql_prepare() Purpose Allocate a statement handle Fill in an XSQLDA with information about values returned by a statement Execute a prepared statement Retrieve data returned by a previously prepared and executed statement Free a statement handle, or close a cursor associated with a statement handle Prepare a statement for execution Fonte: Inprise (1999a). Resultados e Discussão Foram escritas duas classes em C++ para fazer o acesso ao SGDB Firebird, denominadas fbDriver e fbQuery. A classe fbDriver inicializa um handler (isc_db_handle db) e um vetor de atributos da conexão (ISC_STATUS status[20]). Estas duas variáveis definem a conexão e são utilizadas para parametrizar a classe fbQuery. A conexão com o banco de dados é feita com o método bool Attach(char* user, char* psw, char* name) que requer três parâmetros: nome do usuário (user), senha (psw) e nome do banco de dados (name), nesta ordem. Para desconectar-se do SGBD utiliza-se o método void Detach(void), . Tabela 1. Tabela 1 – Variáveis públicas fbDriver. isc_db_handle db ISC_STATUS status[20] bool Attach( char*, char*, char* ) void Detach( void ) handler da conexão com o SGDB Firebird um vetor de atributos da conexão função de conexão com o SGBD Firebird função de desconexão com o SGBD Firebird A rotina Attach é complexa e grande parte dela foi obtida a partir de Inprise(1999a), exemplos que acompanham o InterBase 6.0 e versões do Firebird (Firebird, 2004; Borland, 2004). A classe fbQuery possui os métodos privados. Estes métodos recebem um campo da tabela por meio da estrutura de dados XSQLVAR. Os campos da tabela ficam armazenados em sqlda e o n-ésimo campo de uma tabela é obtido pelo comando (XSQLVAR*) &sqlda->sqlvar[n]. O método Scale é utilizado apenas para campos com escala como é o caso de NUMERIC(p,s) e DECIMAL(p,s) pois estes campos são armazenados como inteiros sendo a posição do ponto decimal atribuída à variável sqlda->sqlvar[n]->sqlscale; A classe fbQuery possui os métodos públicos conforme descritas na Tabela 2. Tabela 2 – Métodos públicos da classe fbQuery. bool Open( ISC_STATUS*, isc_db_handle& ) bool Close( void ) bool Fetch( void ) int Columns( void ) bool SQL( string ) string asString( int ) string Text( int ) string String( int ) short Short( int ) int Int(int) long Long(int) float Float( int ) double Double( int ) string TimeStamp( int ) string Date( int ) string Time( int ) string Blob( int ) int Type( int ) int Size( int ) string Name( int ) Abre o banco de dados para acesso Fecha o banco de dados Retorna uma linha da consulta processada Retorna o número de colunas resultante da consulta Executa a SQL passada como string Retorna um dado do tipo string Retorna um dado do tipo text Retorna um dado do tipo string Retorna um dado do tipo short Retornar um dado do tipo inteiro Retorna um dado do tipo inteiro Retorna um dado do tipo float Retorna um dado do tipo double Retorna um dado do tipo data e hora Retorna um dado do tipo data Retorna um dado do tipo tempo Retorna um dado do tipo blob Retorna o tipo do dado Retorna o número de colunas resultante da consulta Retorna o nome da coluna da tabela Conclusão Desenvolveu-se uma biblioteca em C++ com os recursos básicos para conecta-se ao gerenciador de banco de dados Firebird. Ela caracteriza-se por ser multiplataforma (Unix, Linux e Windows), muito simples e de fácil uso. Possuindo as duas classes fbDriver e fbQuery. A primeira conecta-se ao banco de dados e fornece serviços de acesso a segunda a qual executam, de modo controlado, comandos SQL. Possui ainda funções para a obtenção de dados do banco de dados. A sua licença de uso é a mesma que a do Firebird. A biblioteca foi testada e mostrou-se satisfatória e está disponível para download tanto o código fonte quanto um programa fonte para teste. Referências Bibliográficas Firebird. Disponível em: www.firebird.com.br/ acesso em 06/09/2007. Firebird. Disponível em: http://firebird.sourceforge.net/ acesso em 07/09/2007 SILBERSCHATZ , Abraham; KORTH, Henry F. ; SUDARSHA, S. Sistemas de Banco de Dados,3° edição, Editora Makron Books, 1999 Anexo 1: Programa teste #include <stdio.h> #include <time.h> #include <cstdlib> //----------------------------------------------------------------------#define NBLOCO 20 #define BLOCO 1000000 //----------------------------------------------------------------------string itos( int x ) { char sz[22]; sprintf( sz, "%d", x ); return sz; } //---------------------------------------------------------------int main( void ) { time_t ini = time(NULL); int c ; fbDriver *db fbQuery *Query = new fbDriver(); = new fbQuery(); if(db->Attach("FB++","fb++","d:\\OpenSoft\\fb++\\fb++.FDB")) printf("\n :: error: 20\n"); Query->Open( db->status, db->db ); ini = time(NULL); FILE *f = fopen("insert.txt","w"); for( int k = 0; k < NBLOCO; k++ ) { for( int i = 0; i < BLOCO; i++ ) { Query->SQL("insert into A (A1,A2,A3,A4,A5,A6) values(1, 1.2,'aaaaa','aaaaa','11:11:11','23.09.2007')"); } fprintf(f,"\n%d;%9f",k+1, difftime(time(NULL),ini)); } fclose(f); c = 1; ini = time(NULL); f = fopen("select.txt","w"); for( int k = 0; k < NBLOCO; k++ ) { for( int i = 0; i < BLOCO; i++ ) { Query->SQL("select * from A where A0=" + itos(c) ); } fprintf(f,"\n%d;%9f",k+1, difftime(time(NULL),ini)); } fclose(f); c = 1; ini = time(NULL); f = fopen("update.txt","w"); for( int k = 0; k < NBLOCO; k++ ) { for( int i = 0; i < BLOCO; i++ ) { Query->SQL("update A set A1=1, A2=1.2 ,A3='aaaaa', A4='aaaaa', A5= '11:11:11', A6='23.09.2007' where A0=" + itos(c) ); } fprintf(f,"\n%d;%9f",k+1, difftime(time(NULL),ini)); } fclose(f); Query->Close(); delete Query; db->Detach(); delete db; system("pause"); return 0; } //-----------------------------------------------------------------------