iGames V2.0

Últimos assuntos
» Reativação iGames V2.0 2016
Qua Out 19 2016, 22:04 por teilor

» MUDANÇAS iGAMES V2.0 Free & Vip
Qua Jun 10 2015, 18:11 por marcela

» Lançamento Lineage 2 Empire
Qua Dez 17 2014, 14:35 por teilor

» Reativação Staff
Dom Dez 14 2014, 18:42 por Viking

» Lineage 2 Empire
Sab Dez 13 2014, 17:39 por Viking

» GAME - Ultra Street Fighter IV ganha detalhes de lançamento
Sex Dez 06 2013, 02:59 por teilor

» GAME - Ajude a Konami a fazer o PES da próxima geração
Sex Dez 06 2013, 02:58 por teilor

» GAME - Abertura de Gran Turismo 6 é homenagem a Senna
Sex Dez 06 2013, 02:55 por teilor

» CINEMA - Equipe de Velozes faz vídeo para Paul Walker
Sex Dez 06 2013, 02:51 por teilor

» CINEMA - Eva Green em destaque no novo trailer de 300
Sex Dez 06 2013, 02:48 por teilor

» MUSICA - Ben Foster será o protagonista do filme Warcraft
Sex Dez 06 2013, 02:45 por teilor

» CINEMA - Diane Keaton receberá prêmio em nome de Woody Allen
Sex Dez 06 2013, 02:44 por teilor

» MUSICA - Daft Punk divulgou a prévia de seu novo clipe
Sex Dez 06 2013, 02:41 por teilor

» MUSICA - DJ Cassidy lança música com Jessie J e Robin Thicke
Sex Dez 06 2013, 02:40 por teilor

» Samsung inicia produção em massa de memórias DDR4
Dom Set 01 2013, 10:09 por teilor

» Archos cita dispositivos que deverão ser apresentados nesta IFA
Dom Set 01 2013, 10:07 por teilor

» CityNext: Microsoft lança programa para cidades inteligentes
Dom Set 01 2013, 10:05 por teilor

» Unity anuncia programa para desenvolvimento de jogos próprios
Dom Set 01 2013, 10:04 por teilor

» Como instalar addons em World of Warcraf
Sab Ago 31 2013, 06:29 por marcela

» Como criar macros em World of Warcraft
Sab Ago 31 2013, 06:25 por marcela

» [ Dicas ] de como jogar Real Racing 3 sem gastar nenhum dinheiro real
Sab Ago 31 2013, 06:13 por joaopaulo

» [dica] Como assistir arquivos de vídeo do computador na sua Apple TV
Sab Ago 31 2013, 06:10 por joaopaulo

» Steam Greenlight oferece promoção em seu aniversário
Sab Ago 31 2013, 06:05 por Leonardo

» Microsoft e Google juntam forças para processar governo dos EUA
Sab Ago 31 2013, 05:55 por Leonardo

» Pesquisadores do MIT desenvolvem processador com 110 núcleos
Sab Ago 31 2013, 05:53 por Leonardo

» Vai ao cinema? Apps para iPhone ajudam a escolher filme e comprar ingresso
Qui Ago 29 2013, 22:58 por 

» Serviço de videoclipes Vevo terá aplicativo para Apple TV, diz WSJ
Qui Ago 29 2013, 22:31 por 

» Como a Apple está transformando seu computador em um smartphone
Qui Ago 29 2013, 22:17 por 

» Os 11 melhores apps para iPhone, iPad e Mac, segundo a Apple
Qui Ago 29 2013, 13:56 por teilor

» iPhone 5S pode ter botão Home curvado para fora e leitor de digitais
Qui Ago 29 2013, 13:48 por teilor

» iPhone 5S e iPhone 5C serão lançados no dia 20 de setembro
Qui Ago 29 2013, 13:45 por teilor

» Crytek dedica esforços na melhoria da IA de Ryse: Son of Rome
Qui Ago 29 2013, 04:20 por teilor

» Atualização gratuita de The Last of Us traz novo modo ao multiplayer
Qui Ago 29 2013, 04:15 por teilor

» Novo trailer de GTA V amanhã ao meio-dia
Qui Ago 29 2013, 04:14 por teilor

» Killzone: Mercenary
Qui Ago 29 2013, 04:13 por teilor

Doação
Donation

Acessando PostgreSQL com C - Cursores

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

Acessando PostgreSQL com C - Cursores

Mensagem por Barbosa em Qui Ago 22 2013, 19:15

Veremos neste artigo como trabalhar com cursores através da libpq, utilizando a linguagem C.

Introdução
O PostgreSQL é um banco de dados extremamente eficiente, que não deixa a desejar se comparado com os grandes bancos de dados comerciais. Neste artigo iremos ver a recuperação de dados através da linguagem C, usando a libpq de uma forma alternativa para a recuperação de dados, com a utilização de cursores.

Criando o ambiente de testes

Primeiramente estamos levando em consideração que o PostgreSQL já está instalado e funcionando. Também presume-se que você tenha algum conhecimento utilizando a libpq, pelo menos como iniciar uma conexão com o banco de dados e como executar comandos.

Para os testes, usaremos aqui o mesmo ambiente criado no artigo




O PostgreSQL é um banco de dados extremamente eficiente, que não deixa a desejar se comparado com os grandes bancos de dados comerciais.

Neste artigo iremos ver, ainda que de forma bem simplificada, uma das muitas formas de interação com este banco de dados, que é usando a linguagem C, através de uma interface de programação disponibilizada pelo PostgreSQL.

Criando o ambiente de testes

Antes de começarmos, vamos partir do princípio que o PostgreSQL já funciona em seu computador e que você tem um banco de dados pronto para ser usado. Também iremos considerar que você já tem um leve conhecimento sobre comandos SQL.

No nosso caso, estamos usando um banco chamado 'TESTE'. Não entraremos em detalhes sobre esses assuntos, pois isto é material suficiente para um outro artigo.

Vamos criar o nosso ambiente de testes usando o psql, que é a ferramenta de linha de comando do PostgreSQL. Caso não saiba usá-la, é bem simples, basta digitar o comando "psql" na linha de comando, finalizando com um ponto-e-vírgula (Wink.

Para o nosso ambiente de testes, iremos precisar apenas de uma tabela. Iremos criá-la com o comando abaixo:

Código:
 CREATE TABLE contatos(
    email varchar(255),
    nome varchar(255)
);

Digitando no psql, teremos o seguinte (a palavra 'TESTE' que aparece é o nome do nosso banco de dados):

Código:
TESTE=> CREATE TABLE contatos
TESTE=> (
TESTE=>   email varchar(255),
TESTE=>   nome varchar(255)
TESTE=> );
note que o comando só é executado quando temos um ';'). Ao pressionar enter no final do comando acima, teremos o seguinte resultado:

teste=> CREATE TABLE

Pronto, nossa tabela está criada e pronta para ser usada.

Libpq
Antes de começarmos a nossa codificação, vamos dar uma olhada na biblioteca acima. Esta é a biblioteca do PostgreSQL que nos permite interagir com o banco de dados usando a linguagem C.

Basicamente, esta biblioteca vai nos permitir realizar conexões e disparar comandos no banco de dados.

Para usar as funções contidas nesta biblioteca, temos que:

a. Incluir o arquivo de cabeçalho libpq-fe.h

Isso é simples, basta utilizar a diretiva #include, como mostrado abaixo:

Código:
#include <libpq-fe.h>
b. Indicar ao gcc o diretório em que se encontra esta biblioteca;

Primeiro você vai precisar descobrir onde se encontra o arquivo libpq-fe.h (se você utilizar o comando "whereis libpq-fe.h", você vai conseguir descobrir onde se encontra este arquivo), depois, ao compilar o programa, passamos o diretório acima dentro da opção -I do gcc:

$ gcc -o programa -I/usr/include/pgsql programa.c -lpq

Isso supondo que a sua biblioteca está em /usr/include/pgsql. Altere para o diretório onde se encontra a sua. Talvez seja necessário utilizar a opção -L e o diretório, ao invés da opção -I.

No meu caso, para facilitar, copiei o arquivo para o diretório de include do meu Slackware (no meu caso, /usr/include), assim não preciso incluir a opção -I ao chamar o gcc.

Rotinas para conexão
O método mais usado para conexão com o PostgreSQL é o comando PQconnectdb (existem outras rotinas, mas focaremos apenas nesta), que tem a forma:

PGconn *PQconnectdb(const char *conninfo);

Esta função abre uma nova conexão usando os parâmetros passados na string conninfo. Esses parâmetros são passados separados por espaços, e podem ser:

   host: O nome do host que queremos nos conectar, neste exemplo, usaremos localhost;
   port: Porta de conexão com o PostgreSQL, como usaremos a porta padrão, podemos omitir este parâmetro;
   dbname: O nome do banco de dados que iremos nos conectar. Se deixado em branco, será usado o banco de nome igual ao usuário logado no Linux;
   user: O nome do usuário a realizar a conexão. Se omitido, o padrão é o mesmo usuário logado no Linux;
   password: A senha para o usuário a ser usado.


Cada um dos parâmetros acima é seguido de um sinal de igual ('=') e depois pelo valor que ele deve assumir. Parâmetros omitidos usarão o valor padrão.

Vejamos agora um exemplo para conexão com o nosso banco de dados TESTE criado anteriormente:

Código:
PGconn *conn = NULL;
conn = PQconnectdb("host=localhost dbname=TESTE");
Primeiro declaramos uma variável *conn, do tipo PGconn com o valor inicial NULL, em seguida, chamamos a função PQconnectdb passando como parâmetros o host, que será o localhost e o banco será o TESTE, que criamos acima.

A função PQconnectdb irá retornar NULL somente se houver falha na alocação de memória para o objeto de conexão. Mesmo que o retorno seja não-NULL, precisamos verificar se a conexão foi bem sucedida. Podemos fazer isso com a função PQstatus, que tem o protótipo:

ConnStatusType PQstatus(PGconn *conn);

Esta função recebe como parâmetro um objeto PGconn e retorna um tipo enumerado, que pode ter dois valores: CONNECTION_OK ou CONNECTION_BAD (os significados são bem óbvios).

Continuando o nosso exemplo, após chamar a função PQconnectdb, verificamos se a conexão foi bem sucedida:

Código:
if(PQstatus(conn) == CONNECTION_OK)
{
    printf("Conexão com efetuada com sucesso.");
}
else
{
    printf("Falha na conexão.");
    PQfinish(conn);
    return -1;
}



Não há muito o que se comentar sobre o código acima. Chamamos a função PQstatus passando como parâmetro o nosso objeto de conexão (conn) e verificamos o retorno. Se CONNECTION_OK, a conexão com o banco foi efetuada com sucesso, do contrário, mostramos a mensagem que nossa conexão falhou, e chamamos a função PQfinish que tem o seguinte protótipo:

void PQfinish(PGconn *conn);

Esta função encerra a conexão com o banco de dados e também libera a memória usada pelo objeto de conexão, e deve ser chamada mesmo que a conexão não tenha ocorrido com sucesso. Vale dizer que uma vez chamada esta função, não se deve tentar usar o objeto conn novamente.

Além de saber que a nossa conexão falhou, podemos querer saber qual foi a mensagem de erro retornada pelo PostgreSQL, podemos fazer isso com a função PQerrorMessage, que tem o seguinte protótipo:

char *PQerrorMessage(PGconn *conn);

Esta função retorna um ponteiro char, e recebe como parâmetro um objeto de conexão.

Vamos agora ver a listagem do código:

Código:
 #include <libpq-fe.h>

/*Objeto de conexão*/
PGconn *conn = NULL;

int main()
{
    /*realiza a conexão*/
    conn = PQconnectdb("host=localhost dbname=TESTE");
    
    if(PQstatus(conn) == CONNECTION_OK)
    {
        printf("Conexão com efetuada com sucesso. ");
    }
    else
    {
        printf("Falha na conexão. Erro: %s", PQerrorMessage(conn));
        PQfinish(conn);
        return -1;
    }
    
    /*Verifica se a conexão está aberta e a encerra*/
    if(conn != NULL)
        PQfinish(conn);
}

Pronto, agora, se a conexão falhar, podemos ter uma descrição melhor.

Inserindo, atualizando e removendo dados
A manipulação de dados no PostgreSQL é extremamente simples. Apenas a chamada a uma função para executar o comando e algumas outras para verificar os resultados são o suficiente.

A função a ser chamada para executar o comando é a PQexec, que tem o seguinte protótipo:

PGresult *PQexec(PGconn *conn, const char *sql_string);

Esta função recebe como parâmetro um objeto de conexão e uma string contendo o comando SQL a ser executado. O resultado pode ser um NULL em casos excepcionais, do contrário, receberemos um ponteiro que pode ser verificado chamando a função PQresultStatus, que receberá como parâmetro o ponteiro retornado por PQexec e irá retornar um enum do tipo ExecStatusType. A função PQresultStatus tem o seguinte protótipo:

ExecStatusType *PQresultStatus(PGresult *result);

Os valores da enum retornada por esta função são:

Código:

   PGRES_EMPTY_QUERY - Nada foi feito
    PGRES_COMMAND_OK - O comando foi bem sucedido, mas sem dados retornados.
    PGRES_TUPLES_OK - O comando foi bem sucedido e dados podem ter sido retornados.
    PGRES_COPY_OUT - Uma cópia para um arquivo externo estava em andamento.
    PGRES_COPY_IN - Uma cópia de um arquivo externo estava em andamento.
    PGRES_BAD_RESPONSE - Erro inesperado.
    PGRES_NONFATAL_ERROR - Erro não fatal.
    PGRES_FATAL_ERROR - Erro fatal.
Algumas observações quanto aos valores acima: PGRES_TUPLES_OK significa que um comando SELECT foi bem sucedido, mas não necessariamente que dados foram retornados. Os valores de PGRES_COPY_IN e PGRES_COPY_OUT estão relacionados com o banco de dados que está sendo carregado ou sendo feito o backup.

O valor de retorno da função PQresultStatus nos mostra apenas a ação ocorrida, se quisermos mais detalhes quanto ao resultado, podemos chamar uma outra função, PQresultErrorMessage, que tem o seguinte protótipo:

const char *PQresultErrorMessage(PGresult *result);

Esta função recebe o mesmo parâmetro que a função PQresultStatus, porém o retorno é uma string contendo a mensagem retornada pelo banco.

Uma outra função que pode ter alguma utilidade é a função PQcmdTuples, que retorna o número de linhas afetadas por comandos INSERT, DELETE e UPDATE (para descobrir a quantidade de linhas retornadas por um SELECT existe uma outra função). A função PQcmdTuples tem o seguinte protótipo:

const char *PQcmdTuples(PGresults *result);

O parâmetro de entrada desta função é o mesmo das funções acima, o ponteiro retornado por PQexec, e o retorno, uma string terminada com NULL contendo dígitos em formato de caracteres (atenção a isto, pois a função não retorna um inteiro, como seria mais óbvio).

Para finalizar esta seção, precisamos saber como liberar o objeto de resultado que obtivemos com a função PQexec. Para isso, usamos a função PQclear, que tem o seguinte protótipo:

void PQclear(PQresult *result);

Vamos agora ver na prática como usamos tudo isso:

Código:
#include <stdio.h>
#include <libpq-fe.h>

/*Objeto de conexão*/
PGconn *conn = NULL;

/*Ponteiro de resultado*/
PGresult *result;

int main()
{
    /*realiza a conexão*/
    conn = PQconnectdb("host=localhost dbname=TESTE");
    
    if(PQstatus(conn) == CONNECTION_OK)
    {
        printf("Conexão com efetuada com sucesso. ");
    }
    else
    {
        printf("Falha na conexão. Erro: %s", PQerrorMessage(conn));
        PQfinish(conn);
        return -1;
    }

    /*Executa o comando*/
    /*Aqui você substitui a query por outras. Colocamos apenas uma como exemplo.*/
    result = PQexec(conn, "INSERT INTO contatos (email, nome) VALUES ('Luiz Poleto', 'blah@hehe.com')");
    
    if(!result)
    {
        printf("Erro executando comando. ");
    }
    else
    {
        switch(PQresultStatus(result))
        {
            case PGRES_EMPTY_QUERY:
                printf("Nada aconteceu. ");
                break;
            case PGRES_FATAL_ERROR:
                printf("Error in query: %s ", PQresultErrorMessage(result));
                break;
            case PGRES_COMMAND_OK:
                printf("%s linhas afetadas. ", PQcmdTuples(result));
                break;
            default:
                printf("Algum outro resultado ocorreu. ");
                break;
        }
        
        /*Libera o nosso objeto*/
        PQclear(result);
    }

  
    /*Verifica se a conexão está aberta e a encerra*/
    if(conn != NULL)
        PQfinish(conn);
}
Projeto - Linux
Postagem - ADM_Barbosa
Edição - ADM_Barbosa
Teste - Equipe iGames

_________________




[Você precisa estar registrado e conectado para ver este link.]




Staff Plataforma iGames

Barbosa-Sugere:

do fórum e conheça a nossa equipe staff. [Você precisa estar registrado e conectado para ver este link.]
Aprenda com as nossas e veja nossos tutoriais e astúcias.[Você precisa estar registrado e conectado para ver este link.]
Mantenha o seu tópico ativo, ou ele será arquivado no prazo de três dias.
avatar
Barbosa
Fundador
Fundador

Respeito Respeito :
100 / 100100 / 100

Mensagens : 1026
Idade : 26
Localização : sao paulo

https://www.facebook.com/pages/Forum-IGames/246709752102045

Voltar ao Topo Ir em baixo

Re: Acessando PostgreSQL com C - Cursores

Mensagem por Leonardo em Qui Ago 22 2013, 21:14

Parabéns Barbosa fico muito bem explicado e bem editado.lol! 

_________________


avatar
Leonardo
Menbro VIP
Menbro VIP

Respeito Respeito :
100 / 100100 / 100

Mensagens : 45

Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum