Ensaio acerca de bibliotecas de código aberto para abstração de acesso a banco de dados em linguagem C++

Este estudo é um ensaio acerca das ferramentas de programação em linguagem C++ destinadas a fornecer uma camada de abstração para operar indistintamente bibliotecas clientes nativas de servidores de banco de dados.

[ Hits: 19.887 ]

Por: Renato Merli em 20/10/2011


GDAmm



1. Introdução

GDA [1], acrônimo para GNU Data Access, é a biblioteca para acesso a banco de dados que integra a plataforma GNU de desenvolvimento, que inclui também uma serie de bibliotecas de programação para diversas finalidades. Como acontece com todas as bibliotecas de programação da plataforma GNU, GDA é desenvolvida utilizando a linguagem C e são desenvolvidas ligações para as mais diversas linguagens de programação. Em nosso caso, faremos uso de GDAmm, que é a ligação em linguagem C++ para a biblioteca GDA.

GDAmm [8] é o que chamamos de wrapper, uma camada de abstração em linguagem C++ que faz uso de chamadas a uma biblioteca em linguagem C para realizar suas tarefas. Em outras palavras, GDAmm encapsula as chamadas a GDA, fornecendo acesso as funções da biblioteca em linguagem C através da semântica própria da linguagem C++. Essa arquitetura pode parecer estranha mas é bastante empregada. A ferramenta de abstração DBIxx, por exemplo, também faz uso da mesma arquitetura.

GDAmm esta integrado ao toolkit gráfico da plataforma GNU de desenvolvimento, o GTKmm, [4], fornecendo componentes gráficos como tabelas (grids) e formulários para apresentação e edição dos dados retornados das consultas ao SGBD de maneira facilitada, funcionalidade também presente na maioria das plataformas de desenvolvimento populares.

Uma questão relevante acerca da plataforma GNU é o fato de a mesma ser mantida pela Free Software Foundation, o que nos da alguma garantia de que essa ferramenta não será descontinuada, mas, pelo contrario, continuara a receber aperfeiçoamentos e correções por um longo período.

Como veremos, trata-se de uma biblioteca muito versátil e bastante completa.

2. Plataformas e backends

Oficialmente, GDAmm é compatível com as plataformas Windows, Linux, MacOS X e a maioria dos sistemas concordantes com Posix, mas é provável que possa ser utilizado em qualquer plataforma que ofereça um compilador compatível com ISO C++ e disponha da biblioteca STL.

Segundo seus manuais, os backends suportados no momento são os seguintes: MySQL, Oracle, PostgreSQL, Berkeley DB, arquivos .mdb (com recursos limitados), SQLite, SQLCipher, JDBC e Firebird. Versões anteriores também acessavam Microsoft SQL, servidores LDAP, Sybase SQL, Xbase e IBM DB2, mas a versão atual de GDA ainda não foi atualizada para operar junto a esses backends.

3. Principais componentes

Os principais componentes de GDAmm são os seguintes:

3.1 Gda::Value

Libgda é uma biblioteca nitidamente orientada a dados e baseada em um complexo mecanismo de tipagem dinâmica em linguagem C chamado GObject.

O recurso de tipagem dinâmica [5] [6], comum em linguagens interpretadas como Python e PHP, necessita de um método complicado e trabalhoso para uma implementação em linguagem C. Consulte documentação adicional sobre tipagem dinâmica para obter mais informações sobre o assunto.

Felizmente, a biblioteca GDAmm opera todos os tipos de dados de libGDA de forma facilitada através da classe Value, sem precisar lidar com o mecanismo de Gobject [6].

O uso correto de tipagem dinâmica pode ser muito útil para tratar dados operados junto aos SGBD's. O problema da arquitetura utilizada em GDA (na verdade, utilizada em todos os projetos que utilizam glib) diz respeito à intenção da biblioteca para tratamento de novos tipos de dados, que envolve a criação de objetos em C utilizando o complicado mecanismo da biblioteca gobject [7].

Value permite tratamento indistinto para diferentes tipos de dados, sendo capaz de realizar diversas conversões entre tipos de dados diferentes. Uma olhada na assinatura da classe nos da uma idéia precisa dos tipos de dados e conversões possíveis.

Os tipos dados utilizados são os presentes em glib, que em alguns casos são typedefs para tipos primitivos. Seus correspondentes em linguagem C podem ser deduzidos a partir de seu nome, por exemplo, gchar é um tipo char primitivo, gulong é um unsigned long primitivo, assim por diante.

Construtores:
  • Value (const Glib::ustring& as_string, GType type)
  • Value (guint val)
  • Value (guchar val)
  • Value (gchar val)
  • Value (const Timestamp& val)
  • Value (const Time& val)
  • Value (const char* val)
  • Value (const Glib::ustring& val)
  • Value (gulong val)
  • Value (gushort val)
  • Value (gshort val)
  • Value (float val)
  • Value (const GdaNumeric* val)
  • Value (const GdaValueList* val)
  • Value (int val)
  • Value (const GeometricPoint& val)
  • Value (double val)
  • Value (const Glib::Date& val)
  • Value (bool val)
  • Value (const GdaBlob* val)
  • Value (const guchar* val, long size)
  • Value (const Value& src)
  • Value (const GValue* castitem)
  • Value ()

Métodos:
  • const guchar* get_binary (long& size)
  • const const GdaBlob* get_blob ()
  • const bool get_boolean ()
  • const Glib::Date get_date ()
  • const double get_double ()
  • const float get_float ()
  • const Gtype get_g_type ()
  • const GeometricPoint get_geometric_point ()
  • const Glib::RefPtr<const Glib::Object> get_gobject ()
  • intget_int ()
  • const gint64 get_int64 ()
  • const const GdaValueList* get_list ()
  • const GdaNumeric* get_numeric ()
  • const gshort get_short ()
  • const Glib::ustring get_string ()
  • const Time get_time ()
  • const Timestamp get_timestamp ()
  • const guint get_uint ()
  • const guint64 get_uint64 ()
  • const gulong get_ulong ()
  • const gushort get_ushort ()
  • const Gtype get_value_type ()
  • const bool is_null () const bool is_number ()
  • const bool operator!= (const Value& src)
  • const Value& operator= (const Value& src)
  • bool operator== (const Value& src)
  • const void set (guint val)
  • void set (guchar val)
  • void set (gchar val)
  • void set (const Timestamp& val)
  • void set (const Time& val)
  • void set (const char* val)
  • void set (const Glib::ustring& val)
  • void set (gulong val)
  • void set (gushort val)
  • void set (gshort val)
  • void set (float val) void set (const GdaNumeric* val)
  • void set (const GdaValueList* val)
  • void set (int val)
  • void set (const Glib::RefPtr<Glib::Object>& val)
  • void set (const GeometricPoint& val)
  • void set (double val)
  • void set (const Glib::Date& val)
  • void set (bool val)
  • void set (const GdaBlob* val)
  • void set (const guchar* val, long size)
  • void set_g_type (GType val)
  • void set_int64 (gint64 val)
  • void set_uint64 (guint64 val)

É obrigação do programador utilizar operações coerentes para conversão de dados, já que uma grande quantidade de tipos de dados incompatíveis é operada.

Espera-se que objetos do tipo Value sejam usados em conjunto com os outros objetos de GDAmm para entrada e recuperação de dados, embora tipos primitivos também possam ser usados em muitos dos casos.

3.2 Gda::Query

A classe query permite a definição de consultas através do uso de objetos que definem de forma genérica as operações, condições e tabelas que compõe uma consulta, gerando como saída uma string contendo uma query otimizada para o backend (SGBD) em uso.

Seu propósito é fornecer uma interface de programação genérica para criação consultas apropriadas para as diferentes fontes de dados, lidando com limitações e diferenças na implementação da linguagem SQL de cada servidor em particular, gerar consultas otimizadas, assim como perimir acesso a fontes de dados incompatíveis com SQL.

Sua adoção favorece a portabilidade entre SGBDs e seu uso é recomendado, embora a biblioteca permita a especificação direta da string de consulta, sem o uso dos recursos dessa classe.

Os principais objetos para programação de uma query são: GdaQueryTarget, que representa as tabelas a serem operadas, QdaQueryJoin, que especifica a operação de mesmo nome (join), e GdaQueryCondition, que representa uma condição (clausula WHERE). Consulte a referencia de GDAmm para exemplos de uso dessas classes.

3.3 Gda::Conection

Objeto que realiza a conexão com o SGBD, realiza as operações no banco e controla as transações de forma transparente.

Tem métodos para especificação dos parâmetros de conexão com o banco, como set_username , set_password e set_dsn para especificação de usuário, senha e nome do banco, respectivamente.

Os métodos execute_select_command(string) e execute_nom_select_command(string) são os principais métodos para realizar operações no banco de dados.

Outras funcionalidades incluem acesso a alguns metadados e controle de transações.

Um recurso interessante e utilização das funcionalidades de libsig++ para implementar um sistema de sinais e slots para associação de tratadores dos eventos de conexão, desconexão ou abertura de novo banco de dados.

O objeto Gda::Connection retorna os dados da consulta em modelos de dados derivados de Gda::DataModel, estudados a seguir.

3.4 Gda::DataModel

A biblioteca cliente de cada SGBD em particular retorna dados estruturados de uma forma diferente, de modo que umas das funcionalidades mais importantes para permitir operação indistinta entre diferentes fontes de dados é um mecanismo que permita acessar os dados resultantes das consultas de uma forma genérica, independe do formato fornecido pela biblioteca cliente nativa do banco de dados em uso.

Gda implementa um modelo de dados bastante simples para representar dados de diferentes tipos em linhas e colunas (uma tabela), fornecendo dois métodos diferentes para recuperação de dados: através de seu índice ou através de um iterador.

Através do uso desse modelo de dados padrão, operamos os dados resultantes de operações no banco de uma forma única, seja qual for o formato nativo fornecido pela biblioteca cliente em uso.

3.5 Objetos gráficos (widgets)

O ambiente de desenvolvimento GNU oferece objetos de interface gráfica (visões) para visualização e manipulação dos dados em um modelo de dados Gda::DataModel usando arquitetura MVC. Essa funcionalidade é comum em ambientes de desenvolvimento populares.

Inicialmente, GDA era integrante da biblioteca GNOME-DB, que incluía também os componentes gráficos de visualização de dados. Recentemente foi criado um projeto separado para tratar do desenvolvimento dos objetos gráficos (widgets), o projeto libgda-uimm. No presente momento, nem todos os componentes presentes em gnome-db foram portados, e houve mudanças na API.

Os principais componentes gráficos são:
  • Gda::Grid: Um componente semelhante aos existentes em muitas plataformas de desenvolvimento, que recebe como argumento um modelo de dados resultante de uma consulta ao SGBD e os apresenta em um objeto gráfico na forma de tabela (linhas e colunas) de forma automática.
  • Gda::Form: Componente para representação de dados contidos em um Gda::DataModel, mas apresentando um registro por vez, na forma de um formulário.
  • Gda::DataEntry: Componente de edição de texto para entrada e edição de dados de diferentes tipos, como valores numéricos, booleanos, strings e data.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. GDAmm
   3. SOCI
   4. DBIxx
   5. Outras ferramentas e referências
Outros artigos deste autor

Introdução à plataforma GNU de desenvolvimento

Leitura recomendada

PostgreSQL - Embutindo comandos SQL no seu código C

Acessando PostgreSQL com C

Embutindo um banco de dados SQLite em sua aplicação C++

Usando MySQL na linguagem C

Acessando PostgreSQL com C - Cursores

  
Comentários
[1] Comentário enviado por julio_hoffimann em 20/10/2011 - 22:57h

Oi Renato,

Ótima coletânea!

Abraço!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts