{"id":383,"date":"2019-01-10T00:30:37","date_gmt":"2019-01-09T21:30:37","guid":{"rendered":"http:\/\/fdavid.com.br\/blog\/?p=383"},"modified":"2021-03-13T04:22:35","modified_gmt":"2021-03-13T01:22:35","slug":"postgresql-em-c","status":"publish","type":"post","link":"https:\/\/fdavid.com.br\/blog\/postgresql-em-c\/","title":{"rendered":"Como criar uma conex\u00e3o do banco de dados PostgreSQL com a linguagem C"},"content":{"rendered":"\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.postgresql.org\/media\/img\/about\/press\/slonik_with_black_text_and_tagline.gif\" alt=\"\"\/><\/figure>\n\n\n<p><strong>Introdu\u00e7\u00e3o<\/strong><\/p>\n<p align=\"justify\">O <a href=\"https:\/\/www.postgresql.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">PostgreSQL<\/a> \u00e9 um poderoso banco de dados open source, relacional, com gerenciamento multiusu\u00e1rio e compat\u00edvel com as plataformas Linux, FreeBSD, Solaris, Microsoft Windows e Mac OS X. Ele \u00e9 utilizado em pequenas, m\u00e9dias e grandes aplica\u00e7\u00f5es de diferentes tipos de solu\u00e7\u00f5es. Por ele ser capaz de suportar o gerenciamento de dados de grandes sistemas, muitas IDEs (<i>Integrated Development Environment<\/i>) e ambientes de desenvolvimento j\u00e1 possuem m\u00e9todos de comunica\u00e7\u00e3o com este banco.<\/p>\n<p align=\"justify\">Entretanto, hoje n\u00e3o \u00e9 comum ver solu\u00e7\u00f5es desenvolvidas na linguagem C e integradas com o PostgreSQL. Aqui, vou demonstrar como \u00e9 simples realizar a comunica\u00e7\u00e3o entre um programa escrito em C e uma base de dados criada no PostgreSQL.<\/p>\n<p>\u00a0<\/p>\n<p><strong>Objetivo<\/strong><\/p>\n<p align=\"justify\">Na internet e na documenta\u00e7\u00e3o do PostgreSQL voc\u00ea vai encontrar muitos exemplos de programas em C que usam API para realizar a comunica\u00e7\u00e3o com o Postgres. Mas todos eles, por terem uma finalidade did\u00e1tica, deixam a implementa\u00e7\u00e3o dessa comunica\u00e7\u00e3o na fun\u00e7\u00e3o<i> main<\/i> e processos como conectar, criar, selecionar ou fechar a conex\u00e3o n\u00e3o s\u00e3o separados em fun\u00e7\u00f5es, o que pode dificultar um pouco a implanta\u00e7\u00e3o para quem tem menos experi\u00eancia em C.<\/p>\n<p align=\"justify\">Organizar seu software em fun\u00e7\u00f5es e, consequentemente em bibliotecas (ou classes), \u00e9 o b\u00e1sico a se fazer para manter um c\u00f3digo organizado, claro e de f\u00e1cil manuten\u00e7\u00e3o, principalmente quando falamos de programa\u00e7\u00e3o em C, j\u00e1 que se torna muito mais f\u00e1cil de entender. Por isso, esse artigo tem o objetivo de mostrar como criar um pequeno programa em C (de forma estruturada) fazendo uso da <em>include<\/em> libpq para se comunicar com o PostgreSQL.<\/p>\n<p align=\"justify\">O ponto mais complicado nessa tarefa \u00e9 criar estruturas que possam ser dimencionadas din\u00e2micamente e essa tarefa n\u00e3o tem como ser feita sem algum dominio na manipula\u00e7\u00e3o de ponteiros.<\/p>\n<p><!--more--><\/p>\n<p>\u00a0<\/p>\n<p><strong>Situa\u00e7\u00e3o problema<\/strong><\/p>\n<p>Estou desenvolvendo um projeto para coleta de dados de um medidor de energia, s\u00e3o dados de gera\u00e7\u00e3o, consumo, tens\u00e3o e corrente e at\u00e9 que esses dados possam ser enviados ao webservice\u00a0 ou se for necess\u00e1rio fazer algum tipo de pr\u00e9-processamento ficam gravados em um banco de dados <a href=\"https:\/\/www.sqlite.org\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">SQLite3<\/a>.<\/p>\n<p>O SQLite \u00e9 um banco de dados voltado para pequenos aplica\u00e7\u00f5es e apesar de possuir menos recursos que um SGDB convencional, \u00e9 de f\u00e1cil implata\u00e7\u00e3o e nativo em v\u00e1rias linguagens, tamb\u00e9m esta presente em software como o Firefox que utiliza ele <a href=\"https:\/\/support.mozilla.org\/pt-BR\/kb\/perfis-onde-firefox-armazena-dados-usuario\" target=\"_blank\" rel=\"noopener noreferrer\">para organizar<\/a> os favoritos, senhas e outros dados do usu\u00e1rio.\u00a0 At\u00e9 o momento nenhuma novidade, pois j\u00e1 desenvolvi <a href=\"http:\/\/fdavid.com.br\/blog\/index.php\/category\/databases\/sqlite\/\">outros projetos<\/a> utilizando o SQLite que \u00e9 muito pr\u00e1tico e r\u00e1pido para pequenas aplica\u00e7\u00f5es (no site tem uma rela\u00e7\u00e3o de <a href=\"https:\/\/www.sqlite.org\/whentouse.html\" target=\"_blank\" rel=\"noopener noreferrer\">limita\u00e7\u00f5es ou indica\u00e7\u00f5es<\/a>).<\/p>\n<p>Por\u00e9m, com o SQLite sinto falta de alguns recursos, como por exemplo, PROCEDURES, vari\u00e1veis ou campos CALCULATE. Mas nada que utilizando as alternativas do pr\u00f3prio banco ou da linguagem de programa\u00e7\u00e3o n\u00e3o pudessem ser contornados, at\u00e9 mesmo porque o que\u00a0 falta de recursos nele, surpreende em outros pontos.<\/p>\n<p>A coisa ficou complicada quando precisei programar com o framework <a href=\"https:\/\/www.djangoproject.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Django. <\/a>Pelo fato do SQLite ser mono usu\u00e1rio e o projeto necessitar que o banco de dados fosse acessado por um <a href=\"https:\/\/pt.wikipedia.org\/wiki\/Daemon_(computa%C3%A7%C3%A3o)\" target=\"_blank\" rel=\"noopener noreferrer\">daemon<\/a> (software que executa como um processo em plano de fundo) que fica coletando dados e o pr\u00f3prio Django respons\u00e1vel pelos cadastro, altera\u00e7\u00f5es, relat\u00f3rios de log etc, a chance de ocorrer travamentos quando estivesse em produ\u00e7\u00e3o seria grande.<\/p>\n<p align=\"justify\">Isso porque o daemon tem prioridade de acesso o Django n\u00e3o iria conseguir acessar o banco de dados, fazendo com que a aplica\u00e7\u00e3o fique praticamente todo tempo fora do ar. Mas, ap\u00f3s algum tempo procurando uma solu\u00e7\u00e3o para isso, decidi usar o PostgreSQL, j\u00e1 que o Django tamb\u00e9m suporta PostgreSQL e existe uma extensa documenta\u00e7\u00e3o da API para utilizar o PostgreSQL com diversas linguagens.<\/p>\n<p>\u00a0<\/p>\n<p><strong>Disclaimer<\/strong><\/p>\n<p>Mas porque fa\u00e7o isso em C se com Python, por exemplo, \u00e9 muito mais f\u00e1cil e r\u00e1pido?<\/p>\n<ol>\n<li>\u00a0C ainda \u00e9 uma linguagem relevante para o desenvolvimento de software embarcado, como mostrado no\u00a0<a href=\"https:\/\/www.embarcados.com.br\/linguagens-ieee-spectrum-2018\/\" target=\"_blank\" rel=\"noopener noreferrer\" data-wpel-link=\"internal\">Ranking das Linguagens de Programa\u00e7\u00e3o mais usadas em 2018 (IEEE Spectrum)<\/a>.<\/li>\n<li>\u00a0Porque eu gosto.<\/li>\n<\/ol>\n<p>Os passos que vou descrever ou exemplos que constam nesse artigo foram feitos no Linux (Slackware 14.1, eu sei ja passou da hora de desapegar) com o compilador GCC v4.8.2 mas nos exemplos n\u00e3o tem nenhum header que n\u00e3o seja comum a outros compiladores.<\/p>\n<p>\u00a0<\/p>\n<p><strong>Escovando bits<\/strong><\/p>\n<p>N\u00e3o vou entrar em detalhes de como instalar, configurar, criar um banco de dados ou usu\u00e1rios no PostgreSQL, os dois primeiros passos variam de acordo com o sistema operacional utilizado, entretanto, faz parte da instala\u00e7\u00e3o a biblioteca libpq.h que \u00e9 utilizada para acessar o PostgreSQL em C.<\/p>\n<pre><code>\n\/*\n * helloworld.c\n *\/\n#include &lt;stdio.h&gt;\n#include &lt;libpq-fe.h&gt; \n\nint main() \n{   \n    int lib_ver = PQlibVersion();\n\n    printf(\"Versao libpq: %d\\n\", lib_ver);\n    \n    return 0;\n}\n<\/code><\/pre>\n<p align=\"justify\">Esse programa ir\u00e1 imprimir a vers\u00e3o da libpq e para compil\u00e1-lo \u00e9 necess\u00e1rio indicar o local dos headers do PostgreSQL utilizando o par\u00e2metro -lpq durante a compila\u00e7\u00e3o:<\/p>\n<pre><code> \n$ gcc -o helloworld helloworld -lpq\n$ .\/helloworld \nVersao libpq: 90309\n<\/code><\/pre>\n<p>Se voc\u00ea conseguiu compilar e executar esse exemplo, \u00e9 sinal que instalou e configurou o PostgreSQL corretamente, a partir de agora nosso foco ser\u00e1 os comandos e estruturas necess\u00e1rias para estruturar os exemplos.<\/p>\n<p>Para fazer uma conex\u00e3o com o servidor de banco de dados voc\u00ea deve utilizar a fun\u00e7\u00e3o <em>PQconnectdb<\/em> que recebe uma string com os par\u00e2metros de conex\u00e3o, veja:<\/p>\n<p>&#8220;password=masterkey user=postgres dbname=concrete&#8221;<\/p>\n<p align=\"justify\">Essa string voc\u00ea pode gerar dinamicamente, lendo as configura\u00e7\u00f5es de um arquivo ou recebendo como par\u00e2metro. No exemplo deixei est\u00e1tico para ficar mais simples.<\/p>\n<pre><code>\n\/*\n * connect.c\n *\/\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;libpq-fe.h&gt; \n\nint main() \n{   \n    PGconn *conn = PQconnectdb(\"password=masterkey user=postgres dbname=concrete\");\n   \n    if (PQstatus(conn) == CONNECTION_BAD) {\n        fprintf(stderr, \"Connection to database failed: %s\\n\", PQerrorMessage(conn));\n        PQfinish(conn);\n        exit(1);\n    }\n\n    printf(\"Database connected!\\n\");\n    printf(\"User: %s\\n\", PQuser(conn));\n    printf(\"Database name: %s\\n\", PQdb(conn));\n    printf(\"Password: %s\\n\", PQpass(conn));\n\n    PQfinish(conn);\n    return 0;\n}\n<\/code><\/pre>\n<p>\u00a0<\/p>\n<p>Uma vez que a aplica\u00e7\u00e3o j\u00e1 esta conectando com o banco de dados \u00e9 hora de criar uma tabela, inserir registros, fazer a sele\u00e7\u00e3o e processar os dados recebidos. Deixei o <a href=\"https:\/\/github.com\/fdavidgithub\/learn_c\/blob\/master\/postgres.c\" target=\"_blank\" rel=\"noopener noreferrer\">software completo<\/a> e comentado em meu <a href=\"https:\/\/github.com\/fdavidgithub\" target=\"_blank\" rel=\"noopener noreferrer\">github<\/a>.<\/p>\n<p align=\"justify\">Com esses exemplos espero ter contribu\u00eddo para que possa montar as suas pr\u00f3prias bibliotecas de acesso. Fique a vontade para utilizar ou modificar os c\u00f3digos aqui apresentados e\/ou sugerir melhorias.<\/p>\n\n\n<p><strong>Agradecimentos<\/strong><\/p>\n\n\n\n<p>Ellayne Cristin (Revis\u00e3o texto) <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Introdu\u00e7\u00e3o O PostgreSQL \u00e9 um poderoso banco de dados open source, relacional, com gerenciamento multiusu\u00e1rio e compat\u00edvel com as plataformas Linux, FreeBSD, Solaris, Microsoft Windows e Mac OS X. Ele \u00e9 utilizado em pequenas, m\u00e9dias e grandes aplica\u00e7\u00f5es de diferentes tipos de solu\u00e7\u00f5es. Por ele ser capaz de suportar o gerenciamento de dados de grandes &hellip; <a href=\"https:\/\/fdavid.com.br\/blog\/postgresql-em-c\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Como criar uma conex\u00e3o do banco de dados PostgreSQL com a linguagem C&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[65,67,66],"tags":[],"class_list":["post-383","post","type-post","status-publish","format-standard","hentry","category-articles","category-c-articles","category-postgres"],"_links":{"self":[{"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/posts\/383","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/comments?post=383"}],"version-history":[{"count":2,"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/posts\/383\/revisions"}],"predecessor-version":[{"id":447,"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/posts\/383\/revisions\/447"}],"wp:attachment":[{"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/media?parent=383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/categories?post=383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fdavid.com.br\/blog\/wp-json\/wp\/v2\/tags?post=383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}