Biblioteca VBMcgi: Crie aplicações Web CGI em C++ com acesso ao banco Interbase/Firebird sem mistério

VBMcgi é uma biblioteca multiplataforma para desenvolvimento de aplicações CGI, 100% open-source e muito fácil de ser utilizada. Com este recurso podemos criar aplicações web aproveitando todos os recursos da linguagem C++ sem misticismo.

[ Hits: 46.845 ]

Por: Alessandro de Oliveira Faria (A.K.A. CABELO) em 26/05/2004 | Blog: http://assuntonerd.com.br


Criando o CGI em C++



Abaixo encontra-se o código fonte CGI em C++. Em virtude da extensão do código fonte, irei disponibilizá-los para download no fim deste artigo. Para maiores detalhes no aspecto de aprendizado, consulte a documentação do Firebird/Interbase e da biblioteca VMBcgi.

O código abaixo é bem simples. Após receber a variável s_name da interface HTML, O select é executado no banco de dados usando a cláusula where do SQL. Concluída esta operação, o resultado é exibido em HTML construído pela nossa aplicação.

#include "vbmcgi.h"

#include "ibase.h"
#include "example.h"
#include <fstream>
#include <iostream>
#include <strstream>

using namespace std;

#define REGILEN         5
#define NOMELEN        60
#define DDDLEN          2
#define TELEFONELEN     8
#define TIPO           15
#define BUFLEN        512
#define SQL_VARCHAR(len) struct {short vary_length; char vary_string[(len)+1];}

int main(void)
{
   VBMcgi cgi;
   cgi.httpCompleteHeader();
   cgi.formDecode();

   string                      mTmpINIstr;
  
   char                         registro[REGILEN + 2];
   SQL_VARCHAR(NOMELEN)         nome;
   SQL_VARCHAR(DDDLEN)         ddd;
   SQL_VARCHAR(TELEFONELEN)     telefone;
   SQL_VARCHAR(TIPO)           tipo;
   string                            mNome;
   string                            mDDD;
   string                            mTelefone;
   string                            mTipo;

  
   ISC_QUAD                     blob_id;
   isc_blob_handle             blob_handle = NULL;
   short                       blob_seg_len;
   char                         blob_segment[512];
   isc_db_handle               DB = NULL;        
   isc_tr_handle               trans = NULL;    
   long                         status[20];      
   isc_stmt_handle             stmt = NULL;      
   XSQLDA ISC_FAR *             sqlda;
   long                         fetch_stat, blob_stat;
   short                       flag0 = 0,flag1 = 0;
   char                         empdb[128];
   char        user_name[31];
   char        password[31];
   char        sel_str[256];
   char ISC_FAR *        dpb = NULL, *d, *p, *copy;
   short        dpb_length = 0;
   long        l,sweep_interval = 16384;
   int grid;
   string mHTML,mSQL;
   VBString str_name = cgi.getVarContent("s_name");
   strcpy(sel_str,"SELECT codigo as registro,nome,ddd,telefone,tipo FROM telefones ");
   strcat(sel_str,"WHERE nome LIKE '%");
   strcat(sel_str,str_name.c_str() );
   strcat(sel_str,"%' ORDER BY nome");

    copy = dpb = (char *) malloc(7);
    p = dpb;
    *p++ = '\1';
    *p++ = isc_dpb_sweep_interval;
    *p++ = '\4';
    l = isc_vax_integer((char ISC_FAR *) &sweep_interval, 4);
    d = (char *) &l;
    *p++ = *d++;
    *p++ = *d++;
    *p++ = *d++;
    *p = *d;
    dpb_length = 7;

    strcpy(user_name, "SYSDBA");
    strcpy(password,  "masterkey");
  
    isc_expand_dpb(&dpb, (short ISC_FAR *) &dpb_length, isc_dpb_user_name, user_name, isc_dpb_password, password,  NULL);

    mTmpINIstr = "192.168.0.1:/servdad/secretaria.gdb";
    strcpy(empdb,mTmpINIstr.c_str());
  
    if (isc_attach_database(status, 0, empdb, &DB, dpb_length, dpb)) isc_print_status(status);

    if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL))
    {
        ERREXIT(status, 1)
    }
    
    sqlda = (XSQLDA ISC_FAR *) malloc(XSQLDA_LENGTH(5));
    sqlda->sqln = 5;
    sqlda->sqld = 0;
    sqlda->version = 1;

    if (isc_dsql_allocate_statement(status, &DB, &stmt))
    {
        ERREXIT(status, 1)
    }
    
    if (isc_dsql_prepare(status, &trans, &stmt, 0, sel_str, 1, sqlda))
    {
         ERREXIT(status, 1)
    }

    sqlda->sqlvar[0].sqldata = (char ISC_FAR *)registro;
    sqlda->sqlvar[0].sqltype = SQL_TEXT + 1;;
    sqlda->sqlvar[0].sqlind  = &flag0;
      
    sqlda->sqlvar[1].sqldata = (char *)&nome;
    sqlda->sqlvar[1].sqltype = SQL_VARYING  + 1;
    sqlda->sqlvar[1].sqlind  = &flag1;

    sqlda->sqlvar[2].sqldata = (char *)&ddd;
    sqlda->sqlvar[2].sqltype = SQL_VARYING  + 1;
    sqlda->sqlvar[2].sqlind  = &flag1;

    sqlda->sqlvar[3].sqldata = (char *)&telefone;
    sqlda->sqlvar[3].sqltype = SQL_VARYING  + 1;
    sqlda->sqlvar[3].sqlind  = &flag1;

    sqlda->sqlvar[4].sqldata = (char *)&tipo;
    sqlda->sqlvar[4].sqltype = SQL_VARYING  + 1;
    sqlda->sqlvar[4].sqlind  = &flag1;
    
    if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
    {
        ERREXIT(status, 1)
    }

std::cout << "<HTML><body>" << std::endl;

std::cout<<"<table border='0' width='100%' height='46'>"<<std::endl;
std::cout<<"  <tr>"<<std::endl;
std::cout<<"    <td  align='center' colspan='5' bgcolor='#FF9900'><b>"<<std::endl;
std::cout<<"    <font color='#FFFFFF' face='Tahoma' size='2'>NETi TECNOLOGIA - Agenda Telefonica </font></b></td>"<<std::endl;
std::cout<<"  </tr>"<<std::endl;
std::cout<<"  <tr>"<<std::endl;
std::cout<<"    <td width='6%' align='center'><b><font face='Tahoma' size='1'>Registro</font></b></td>"<<std::endl;
std::cout<<"    <td width='65%' align='center'><b><font face='Tahoma' size='1'>Nome</font></b></td>"<<std::endl;
std::cout<<"    <td width='2%' align='center'><b><font face='Tahoma' size='1'>DDD</font></b></td>"<<std::endl;
std::cout<<"    <td width='12%' align='center'><b><font face='Tahoma' size='1'>Telefone</font></b></td>"<<std::endl;
std::cout<<"    <td width='15%' align='center'><b><font face='Tahoma' size='1'>Tipo</font></b></td>"<<std::endl;
std::cout<<"  <tr>"<<std::endl;


    grid = 0;  
    while ((fetch_stat = isc_dsql_fetch(status, &stmt, 1, sqlda)) == 0)
    {
      registro[sqlda->sqlvar[0].sqllen] = '{TEXTO}';

      mNome = nome.vary_string;
      if (grid==0)
      { mHTML = "<TD>";
        grid = 1;
        }      
      else
      {mHTML = "<TD bgcolor='#FFECC6'>";
        grid = 0;}
            

std::cout<<mHTML<<"<font face='Tahoma' size='1'>"<<registro<<"</font></TD>"<<std::endl;
std::cout<<mHTML<<"<font face='Tahoma' size='1'>";
        printf("%-60.*s ", nome.vary_length, nome.vary_string);
        std::cout<<"</font></TD>"<<std::endl;

std::cout<<mHTML<<"<font face='Tahoma' size='1'>";
        printf("%-2.*s ", ddd.vary_length, ddd.vary_string);
        std::cout<<"</font></TD>"<<std::endl;

std::cout<<mHTML<<"<font face='Tahoma' size='1'>";
        printf("%-8.*s ", telefone.vary_length, telefone.vary_string);
        std::cout<<"</font></TD>"<<std::endl;

std::cout<<mHTML<<"<font face='Tahoma' size='1'>";
        printf("%-15.*s ", tipo.vary_length, tipo.vary_string);
        std::cout<<"</font></TD><tr>"<<std::endl;
                                  
      
   }

    if (fetch_stat != 100L)
    {
        ERREXIT(status, 1)
    }

    if (isc_dsql_free_statement(status, &stmt, DSQL_close))
    {
        ERREXIT(status, 1)
    }

    if (isc_commit_transaction (status, &trans))
    {
        ERREXIT(status, 1)
    }

    if (isc_detach_database(status, &DB))
    {
        ERREXIT(status, 1)
    }

    free(sqlda);

std::cout<<"</table>"<<std::endl;
std::cout<<"</body>"<<std::endl;
std::cout<<"</HTML>"<<std::endl;

    return 0;
}

Para compilarmos o programa, basta executar o seguinte comando:

# c++ sel_usu.cpp -o sel_usu -lvbmcgi -lgds -ldl -lcrypt

As bibliotecas a serem utilizadas, exceto a vbmcgi, deverão variar de acordo como a versão do banco de dados instalado. Para maiores informações, consulte a documentação.

Após a compilação, devemos copiar os arquivos select.html e logo_tel.jpg (imagem) para o diretório default do Apache e o binário sel_usu para o diretório cgi-bin.

Não esqueça de ajustar o caminho do banco de dados no fonte, o IP do servidor e a senha do SYDBA caso não seja masterkey.

Para facilitar a execução deste tutorial, segue abaixo o link para o download dos fontes.
Página anterior    

Páginas do artigo
   1. Introdução
   2. Download e instalação
   3. Criando o banco de dados
   4. Interface em HTML
   5. Criando o CGI em C++
Outros artigos deste autor

ePub - O MP3 dos livros

GNA: um Coprocessador para Aceleração Neural

Transforme seu celular em terminal sem fio SSH/Telnet

Transmitindo vídeo de eventos ao vivo via Internet com GNU/Linux

Programe em Python no jogo Minecraft com seu filho ou sozinho

Leitura recomendada

DotGNU: a resposta Open Source ao dotNET

Aplicativos web em C++ usando o Tufão

Criando aplicações RESTful com Qt e Cutelyst

Desenvolvendo um plugin de visualização para o XMMS (Parte 1)

GNA: um Coprocessador para Aceleração Neural

  
Comentários
[1] Comentário enviado por fabriciomoeller em 26/05/2004 - 11:13h

Beleza cabelo, meus parabens, estou baixando para testar e aprender com mais este teu tutorial. Vc sempre esta inovando meu amigo.

[2] Comentário enviado por removido em 25/04/2007 - 12:37h

Gostaria de saber se tem jeito de controlar a Porta Paralela do pc com C++ com base neste artigo?
Obs: já tenho os fontes do programa em C++.
Muito Obrigado!!!
O artigo está show!!!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts