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.