Firebird no Xharbour

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Re: Firebird no Xharbour

Mensagem por gvc »

O download já se perdeu.
Vc poderia ver com o Toledo ou o Maligno para colocar neste sitio ou no Maligno para download?
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Re: Firebird no Xharbour

Mensagem por Toledo »

O arquivo exemplo já está no meu servidor... segue abaixo o link:

https://pctoledo.org/download/agenda.rar

Ramon, se você quiser, é só editar a sua mensagem e colocar o link acima.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar do usuário
RamonXHB
Usuário Nível 3
Usuário Nível 3
Mensagens: 159
Registrado em: 03 Mar 2007 14:55

Re: Firebird no Xharbour

Mensagem por RamonXHB »

Já editei o tópico que tem o endereço de download...
Ramon A. Körber Jr.
Harbour 3.2 MiniGUI Extended Edition
xDevStudio v0.70 - BCC 5.82 - Lazarus FreePascal
Firebird
AdoDB - ODBC
Windows - Linux
Linux User Number 404280
MSN - ramon15061959@hotmail.com
Skype - ramon15061959
ICQ - UIN 82580595
Avatar do usuário
viniciuspc
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 19 Dez 2006 17:18
Localização: Rio de Janeiro

Firebird no Xharbour

Mensagem por viniciuspc »

desenterrando o topico ! (A)

Precisamos utilizar um banco Firebird 1.5 que temos aqui, para exportação das tabelas DBF. Estamos usando o Harbour 3.0 com o MSVC (melhor performace) e acabei seguindo o exemplo do diretorio ..\contrib\hbfbird\tests\test.prg

Como já tinhamos o Firebird instalado, foi necessario apenas colocar o arquivo fbclient.dll na mesma pasta do executavel (se não tiver, ele nem entra...) e adaptamos o exemplo a nossa necessidade! funcionou perfeitamente.

Como temos uma possibilidade de alguns usuarios (temos em media mais de 5 mil usuarios no Brasil) não terem o Firebird instalado, então alteramos a conecção para o Firebird Embedded (Embarcado), bastou baixar o Firebird Embedded, copiar o arquivo fbembed.dll para fbclient.dll na pasta do executavel, e alteramos a variavel cServer do exemplo (test.prg)

Original LOCAL cServer := "localhost:"
Para LOCAL cServer := ""

A principio ficou OK, sem necessidade de instalação de ODBC e SGCD a parte.

Agora vem a parte dos testes... validar a aplicação nas demais plataformass Windows, mesmo com o Firebird instalado (2.0 ou 2.5) ou não.

Bom, fica ai a dica!

:xau
Clipper 5.2e + Blinker 5.10
Harbour 3.0.0 (Rev. 16951) + Microsoft Visual C++ 16.0.40219 (32-bit)
Avatar do usuário
RamonXHB
Usuário Nível 3
Usuário Nível 3
Mensagens: 159
Registrado em: 03 Mar 2007 14:55

Firebird no Xharbour

Mensagem por RamonXHB »

que tal você usar um exemplo ???
Ramon A. Körber Jr.
Harbour 3.2 MiniGUI Extended Edition
xDevStudio v0.70 - BCC 5.82 - Lazarus FreePascal
Firebird
AdoDB - ODBC
Windows - Linux
Linux User Number 404280
MSN - ramon15061959@hotmail.com
Skype - ramon15061959
ICQ - UIN 82580595
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Firebird no Xharbour

Mensagem por janio »

A velocidade é bem satisfatória, tanto em rede local como remota, é obvio e evidente que não se programa da mesma maneira que com os dbfs, não se concebe fazer uma query num SGBD que retorne milhares de registros, pois não há nada que justifique tal coisa...
Ja vi alguns colegas tocarem nessa questao "mostrar so os dados que interessam". Ocorre que ha situações que não vejo como aplicar a lógica disso! Se eu tenho um cadastro de produtos com 200.000 itens, por exemplo, e eu mostro um browse para o usuário procurar o produto q deseja... como de 200.000 produto eu irei mostrar apenas 10.000 se eu não sei qual produto o usuario deseja encontrar? O usuário pode querer encontrar qualquer um dos 200.000 cadastrados!

Pra pesquisa letra-a-letra como tenho no meu sistema, num vejo como aplicar essa lógica
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Firebird no Xharbour

Mensagem por Poka »

Olá a todos

Vinicius
Estou começando a mexer com Firebird agora. Usando o teste da contrib do harbour, consigo criar o arquivo , mas na linha da conexão dá o seguinte erro.


oServer := TFBServer():New( cServer + cDatabase, cUser, cPass, nDialect )


Error: Unresolved external '_HB_FUN_HB_DEFAULT' referenced from C:\MINIGUI\HARBOUR\LIB\HBFBIRD.LIB|tfirebrd

o que está faltando?

Janio, concordo plenamente contigo.
pra resolver o problema de tbrowse lento, fiz uma rotina que só mostro na tela num arquivo temporario, os registros que cabem na tela, aí sim resolve, praticamente não importa o tamanho do arquivo. Na empresa tava muito lento, agora até via romoto com TeamWiewer fica rápido, mesmo com pesquisa letra a letra.

Poka
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Firebird no Xharbour

Mensagem por sygecom »

Poka,
Você deve está usando Harbour, essa função está em RTL.LIB, quando se usa o hbmk2 para compilar ele já deve ir automaticamente.
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Firebird no Xharbour

Mensagem por Poka »

Leonardo, obrigado por responder.



Utilizo Harbour Minigui Extend Edition 2.1.1 – 2012-05-16
Harbour 3.2.0dev (rev. 17477)
Utilizo o xDevStudio para compilar.
O arquivo HBRTL já está relacionado na compilação.
Se tiver mais alguma informação, fico muito agradecido.

Poka
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Firebird no Xharbour

Mensagem por Hasse »

Boa noite Poka.

Uso a MiniGui 3.4.1, Harbour 3.2.0, IDE do Roberto Lopez V 1.0.8, compila com hbmk2.
Harbour 3.2.0dev (r1506261250)
Copyright (c) 1999-2015, http://harbour-project.org/
C:/Users/Padrao/AppData/Local/Temp/hbmk_wewqcg.dir/small_06.o:small_06.c:(.data+0x78): undefined reference to `HB_FUN_TFBSERVER'
collect2.exe: error: ld returned 1 exit status
hbmk2[Small_06]: Erro: Executando linkeditor. 1
gcc.exe C:/Users/Padrao/AppData/Local/Temp/hbmk_wewqcg.dir/small_06.o C:/Users/Padrao/AppData/Local/Temp/hbmk_wewqcg.dir/hbmk_v6uxe3.o G:/DEV2/DentalOff/_temp.o -mwindows -Wl,--start-group -lhmg -lcrypt -ledit -leditex -lgraph -lini -lreport -lhfcl -lmsvfw32 -lvfw32 -lhbct -lhbwin -lhbmzip -lminizip -lhbmemio -lhbmisc -lhbmysql -lmysql -lhbtip -lhbsqlit3 -lsddodbc -lrddsql -lsddmy -lhbodbc -lodbc32 -lhbhpdf -lhbfimage -lhbpgsql -lhbnetio -lxhb -lpng -llibhpdf -lhbvpdf -lhbzebra -lhbextern -lhbdebug -lhbvmmt -lhbrtl -lhblang -lhbcpage -lgtcgi -lgtpca -lgtstd -lgtwin -lgtwvt -lgtgui -lhbrdd -lhbuddall -lhbusrrdd -lrddntx -lrddcdx -lrddnsx -lrddfpt -lhbrdd -lhbhsx -lhbsix -lhbmacro -lhbcplr -lhbpp -lhbcommon -lhbmainwin -lkernel32 -luser32 -lgdi32 -ladvapi32 -lws2_32 -liphlpapi -lwinspool -lcomctl32 -lcomdlg32 -lshell32 -luuid -lole32 -loleaut32 -lmpr -lwinmm -lmapi32 -limm32 -lmsimg32 -lwininet -lhbpcre -lhbzlib -Wl,--end-group -oSmall_06.exe -LC:/hmg.3.4.1/harbour/lib/win/mingw -LC:/hmg.3.4.1/lib

hbmk2: Dica: Adicionar op‡Æo 'hbfbird.hbc' faltando nas fun‡äes: TFBServer()
Onde encontro a Função TFBServer e outras funções desta mesma classe.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Firebird no Xharbour

Mensagem por Poka »

Olá a todos

Hasse, desculpe estar só respondendo agora, estou enrolado com CT-e aqui, que nem deu tempo.
Essa função TFBServer, deve estar dentro hbfbird.lib.

Eu não isso essa função, eu a compilo somente para usar a criação de banco de dados fdb.
Se essa lib estivesse funcionando corretamente, talvez não precisaria do ODBC, aí sim ficaria nativo, alguém pode explicar melhor se estiver enganado.

Eu uso;

Harbour Minigui Extend 2.5.4 – 2015.10.21
Harbour 3.2.0dev (r1510132105)

Para compilar eu uso xDevStudio ( parabéns para quem desenvolveu essa ferramenta) nunca usei hbmk2.
Não entendo bem, acho que se alguém pode até explicar melhor do que eu. Tentei usar as funções da hbfbird.lib, mas dava muito erro, então uso Firebird + Odbc. Compilo essa lib somente para criar os arquivos mesmos. Para quem que mudar de banco de dados, acho que o caminho + fácil mesmo é esse, Firebird + Odbc. O firebird e o ODBC instala no “servidor” e nos terminais somente o ODBC, a instalação pode ser feita até pelo seu sistema mesmo, sem ter que entra na Internet, é rápido.


Não sou expert como os colegas daqui do fórum, apesar de estar programando há 25 anos, muita coisa que vocês dizem aqui foge do meu conhecimento, deixo de aprender muita coisa também, por causa do meu inglês que é zero. Mas vou fazendo o feijão com arroz mesmo.
Já coloquei um sistema pequeno com firebird, e está funcionando muito bem, estou passando o sistema maior agora, mas vai demorar uns meses ainda.

Quando tenho duvidas com comandos SQL pergunto aqui no fórum também, e assim vamos indo.
Sobre a velocidade do Firebird
Gostei bastante, fiz um teste com uma tabela de 1.000.000 de registros. No meu computador que é bem fraquinho, demorou 15 segundos (muito tempo), levei na empresa, 3 segundos, achei ótimo, isso procurando “SILVA” por exemplo no arquivo inteiro, aí mostro só os selecionados no
Uma coisa que gostei muito, é que qualquer terminal, por + ruim quem seja, a velocidade é igual a do servidor.

Sobre o Browser

Com um milhão de registros fica inaceitável, trazer todos os registros, nos dbs tinha feito uma paginação de dados onde só mostrava os registros que cabiam na tela, ficou super rápido , mas agora com firebird vou ter que fazer algo semelhante, O firebird pensando nisso já tem funções internas que facilita ainda mais essa rotina que são , First, Skip e Rows, não mexi nessa parte ainda,vou por o sistema para funcionar primeiro, depois altero essas rotinas, senão vou ficar o resto da vida terminando.

Porque escolhi o Firebird.

Quando fui sair do dbf para SQL, escolhi três opções.
MYSQL, POSTGRESQL, FIREBIRD
Não posso me dar ao luxo de aprender os três e ver o melhor, perde-se muito tempo, já tenho 62 anos e não posso dispender desse tempo. Então li muito na internet, sobre os esses bancos , opiniões, testes de velocidade, etc.
O MYSQL até onde entendi, embora muitos dizem o contrário, não é free, é free se vc for distribuir o seu sistema gratuitamente.
Entre os outros dois, acabei escolhendo o Firebird, e não me arrependi por isso, uma das coisas que influenciou no Firebird, não sei se esse seria o termo correto, a sua portabilidade.

Arquivo anexo:
Contém os arquivos exe do exemplo, e de intalação de Firebird e ODBC ( para WIn 32)
Descompacte em uma pasta qualquer esse exemplo.

Um abraço

Poka
Anexos
sistema.rar
(8.32 MiB) Baixado 228 vezes
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Firebird no Xharbour

Mensagem por Hasse »

Valeu meu caro.

Vou digerir todas as informações que você colocou.

Eu também escolhi o Firebird, mas não pelos mesmos motivos, mas por ter tido contatos anteriores com ele, e gostei.

Obrigado.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
Avatar do usuário
jairfab
Usuário Nível 3
Usuário Nível 3
Mensagens: 252
Registrado em: 21 Mai 2007 09:43
Localização: São Paulo, Região Leste - Suzano

Firebird no Xharbour

Mensagem por jairfab »

TFBServer realmente está escrito em harbour e não compatível com xharbour, mas tudo que tem nesta classe é feito utilizando funções em C que é compatível com harbour e xharbour, eu fiz um trabalho que precisava importar e exportar dados dbf para banco firebird nativo e tive este mesmo problema.

Foi então que fiz uma verificação na class TFBServer e vir que tudo que a classe faz é exatamente utilizar as funçôes que estar na lib ou seja apenas tratar os retorno da funções escritas em C.

Código: Selecionar todos


*** Utilizando a class TFBServer
 oServer := TFBServer():New( cServer + cDatabase, cUser, cPass, nDialect )

*** Utilizando a função  FBConnect o resultado seria o mesmo  
oServer := FBConnect( cServer + cDatabase, cUser, cPass )



Observe o que tem na lib alem da class TFBServer

Código: Selecionar todos

#include <time.h>

/* NOTE: Ugly hack to avoid this error when compiler with BCC 5.8.2 and above:
         Error E2238 C:\...\Firebird-2.1.1\include\ibase.h 82: Multiple declaration for 'intptr_t' */
#if ( defined( __BORLANDC__ ) && __BORLANDC__ >= 0x582 )
   /* Prevent inclusion of <stdint.h> from hbdefs.h */
   #define __STDINT_H
#endif

#include "hbapi.h"
#include "hbapierr.h"
#include "hbapiitm.h"

#include "ibase.h"

#ifndef ISC_INT64_FORMAT
   #define ISC_INT64_FORMAT PFLL
#endif

/* GC object handlers */

static HB_GARBAGE_FUNC( FB_db_handle_release )
{
   isc_db_handle * ph = ( isc_db_handle * ) Cargo;

   /* Check if pointer is not NULL to avoid multiple freeing */
   if( ph && * ph )
   {
      ISC_STATUS_ARRAY status;

      /* Destroy the object */
      isc_detach_database( status, ph );

      /* set pointer to NULL to avoid multiple freeing */
      * ph = 0;
   }
}

static void hb_FB_db_handle_ret( isc_db_handle p )
{
   if( p )
   {
      isc_db_handle * ph = ( isc_db_handle * )
            hb_gcAlloc( sizeof( isc_db_handle ), FB_db_handle_release );

      * ph = p;

      hb_retptrGC( ph );
   }
   else
      hb_retptr( NULL );
}

static isc_db_handle hb_FB_db_handle_par( int iParam )
{
   isc_db_handle * ph = ( isc_db_handle * ) hb_parptrGC( FB_db_handle_release, iParam );

   return ph ? * ph : 0;
}

/* API wrappers */

HB_FUNC( FBCREATEDB )
{
   if( hb_pcount() == 6 )
   {
      isc_db_handle newdb = ( isc_db_handle ) 0;
      isc_tr_handle trans = ( isc_tr_handle ) 0;
      ISC_STATUS status[ 20 ];
      char create_db[ 1024 ];

      const char *   db_name = hb_parcx( 1 );
      const char *   user    = hb_parcx( 2 );
      const char *   pass    = hb_parcx( 3 );
      int            page    = hb_parni( 4 );
      const char *   charset = hb_parcx( 5 );
      unsigned short dialect = ( unsigned short ) hb_parni( 6 );

      hb_snprintf( create_db, sizeof( create_db ),
                   "CREATE DATABASE '%s' USER '%s' PASSWORD '%s' PAGE_SIZE = %i DEFAULT CHARACTER SET %s",
                   db_name, user, pass, page, charset );

      if( isc_dsql_execute_immediate( status, &newdb, &trans, 0, create_db, dialect, NULL ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_retnl( 0 );
}

HB_FUNC( FBCONNECT )
{
   ISC_STATUS_ARRAY status;
   isc_db_handle    db = ( isc_db_handle ) 0;
   const char *     db_connect = hb_parcx( 1 );
   const char *     user = hb_parcx( 2 );
   const char *     passwd = hb_parcx( 3 );
   char             dpb[ 128 ];
   short            i = 0;
   int              len;

   /* TOFIX: Possible buffer overflow. Use hb_snprintf(). */
   dpb[ i++ ] = isc_dpb_version1;
   dpb[ i++ ] = isc_dpb_user_name;
   len = ( int ) strlen( user );
   if( len > ( int ) ( sizeof( dpb ) - i - 4 ) )
      len = ( int ) ( sizeof( dpb ) - i - 4 );
   dpb[ i++ ] = ( char ) len;
   hb_strncpy( &( dpb[ i ] ), user, len );
   i += ( short ) len;
   dpb[ i++ ] = isc_dpb_password;
   len = ( int ) strlen( passwd );
   if( len > ( int ) ( sizeof( dpb ) - i - 2 ) )
      len = ( int ) ( sizeof( dpb ) - i - 2 );
   dpb[ i++ ] = ( char ) len;
   hb_strncpy( &( dpb[ i ] ), passwd, len );
   i += ( short ) len;

   if( isc_attach_database( status, 0, db_connect, &db, i, dpb ) )
      hb_retnl( isc_sqlcode( status ) );
   else
      hb_FB_db_handle_ret( db );
}


HB_FUNC( FBCLOSE )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      ISC_STATUS_ARRAY status;

      if( isc_detach_database( status, &db ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}


HB_FUNC( FBERROR )
{
   char msg[ 1024 ];

   isc_sql_interprete( ( short ) hb_parni( 1 ) /* sqlcode */,
                       msg, sizeof( msg ) );

   hb_retc( msg );
}

HB_FUNC( FBSTARTTRANSACTION )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      isc_tr_handle trans = ( isc_tr_handle ) 0;
      ISC_STATUS_ARRAY status;

      if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retptr( ( void * ) ( HB_PTRDIFF ) trans );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBCOMMIT )
{
   isc_tr_handle trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 1 );

   if( trans )
   {
      ISC_STATUS_ARRAY status;

      if( isc_commit_transaction( status, &trans ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBROLLBACK )
{
   isc_tr_handle trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 1 );

   if( trans )
   {
      ISC_STATUS_ARRAY status;

      if( isc_rollback_transaction( status, &trans ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBEXECUTE )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      isc_tr_handle   trans = ( isc_tr_handle ) 0;
      const char *    exec_str = hb_parcx( 2 );
      ISC_STATUS      status[ 20 ];
      ISC_STATUS      status_rollback[ 20 ];
      unsigned short  dialect = ( unsigned short ) hb_parni( 3 );

      if( ISPOINTER( 4 ) )
         trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 4 );
      else
      {
         if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      if( isc_dsql_execute_immediate( status, &db, &trans, 0, exec_str, dialect, NULL ) )
      {
         if( ! ISPOINTER( 4 ) )
            isc_rollback_transaction( status_rollback, &trans );

         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      if( ! ISPOINTER( 4 ) )
      {
         if( isc_commit_transaction( status, &trans ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBQUERY )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      isc_tr_handle    trans = ( isc_tr_handle ) 0;
      ISC_STATUS_ARRAY status;
      XSQLDA *         sqlda;
      isc_stmt_handle  stmt = ( isc_stmt_handle ) 0;
      XSQLVAR *        var;

      unsigned short   dialect = ( unsigned short ) hb_parnidef( 3, SQL_DIALECT_V5 );
      int              i;
      int              num_cols;

      PHB_ITEM qry_handle;
      PHB_ITEM aNew;
      PHB_ITEM aTemp;

      if( ISPOINTER( 4 ) )
         trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 4 );
      else if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Allocate a statement */
      if( isc_dsql_allocate_statement( status, &db, &stmt ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Allocate an output SQLDA. Just to check number of columns */
      sqlda = ( XSQLDA * ) hb_xgrab( XSQLDA_LENGTH( 1 ) );
      sqlda->sqln = 1;
      sqlda->version = 1;

      /* Prepare the statement. */
      if( isc_dsql_prepare( status, &trans, &stmt, 0, hb_parcx( 2 ), dialect, sqlda ) )
      {
         hb_xfree( sqlda );
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Describe sql contents */
      if( isc_dsql_describe( status, &stmt, dialect, sqlda ) )
      {
         hb_xfree( sqlda );
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Relocate necessary number of columns */
      if( sqlda->sqld > sqlda->sqln )
      {
         ISC_SHORT n = sqlda->sqld;
         sqlda = ( XSQLDA * ) hb_xrealloc( sqlda, XSQLDA_LENGTH( n ) );
         sqlda->sqln = n;
         sqlda->version = 1;

         if( isc_dsql_describe( status, &stmt, dialect, sqlda ) )
         {
            hb_xfree( sqlda );
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      num_cols = sqlda->sqld;
      aNew = hb_itemArrayNew( num_cols );
      aTemp = hb_itemNew( NULL );

      for( i = 0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++ )
      {
         int dtype = ( var->sqltype & ~1 );

         switch( dtype )
         {
         case SQL_VARYING:
            var->sqltype = SQL_TEXT;
            var->sqldata = ( char * ) hb_xgrab( sizeof( char ) * var->sqllen + 2 );
            break;
         case SQL_TEXT:
            var->sqldata = ( char * ) hb_xgrab( sizeof( char ) * var->sqllen + 2 );
            break;
         case SQL_LONG:
            var->sqltype = SQL_LONG;
            var->sqldata = ( char * ) hb_xgrab( sizeof( long ) );
            break;
         default:
            var->sqldata = ( char * ) hb_xgrab( sizeof( char ) * var->sqllen );
            break;
         }

         if( var->sqltype & 1 )
            var->sqlind = ( short * ) hb_xgrab( sizeof( short ) );

         hb_arrayNew( aTemp, 7 );

         hb_arraySetC(  aTemp, 1, sqlda->sqlvar[ i ].sqlname );
         hb_arraySetNL( aTemp, 2, ( long ) dtype );
         hb_arraySetNL( aTemp, 3, sqlda->sqlvar[ i ].sqllen );
         hb_arraySetNL( aTemp, 4, sqlda->sqlvar[ i ].sqlscale );
         hb_arraySetC(  aTemp, 5, sqlda->sqlvar[ i ].relname );
         hb_arraySetNL( aTemp, 6, sqlda->sqlvar[ i ].aliasname_length ); /* support for aliases */
         hb_arraySetC(  aTemp, 7, sqlda->sqlvar[ i ].aliasname ); /* support for aliases */

         hb_arraySetForward( aNew, i + 1, aTemp );
      }

      hb_itemRelease( aTemp );

      if( ! sqlda->sqld )
      {
         /* Execute and commit non-select querys */
         if( isc_dsql_execute( status, &trans, &stmt, dialect, NULL ) )
         {
            hb_itemRelease( aNew );
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }
      else
      {
         if( isc_dsql_execute( status, &trans, &stmt, dialect, sqlda ) )
         {
            hb_itemRelease( aNew );
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      qry_handle = hb_itemArrayNew( 6 );

      hb_arraySetPtr( qry_handle, 1, ( void * ) ( HB_PTRDIFF ) stmt );
      hb_arraySetPtr( qry_handle, 2, ( void * ) ( HB_PTRDIFF ) sqlda );

      if( ! ISPOINTER( 4 ) )
         hb_arraySetPtr( qry_handle, 3, ( void * ) ( HB_PTRDIFF ) trans );

      hb_arraySetNL( qry_handle, 4, ( long ) num_cols );
      hb_arraySetNI( qry_handle, 5, ( int ) dialect );
      hb_arraySetForward( qry_handle, 6, aNew );

      hb_itemReturnRelease( qry_handle );
      hb_itemRelease( aNew );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );

}

HB_FUNC( FBFETCH )
{
   PHB_ITEM aParam = hb_param( 1, HB_IT_ARRAY );

   if( aParam )
   {
      isc_stmt_handle  stmt = ( isc_stmt_handle ) ( HB_PTRDIFF ) hb_itemGetPtr( hb_itemArrayGet( aParam, 1 ) );
      XSQLDA *         sqlda = ( XSQLDA * ) hb_itemGetPtr( hb_itemArrayGet( aParam, 2 ) );
      ISC_STATUS_ARRAY status;
      unsigned short   dialect = ( unsigned short ) hb_itemGetNI( hb_itemArrayGet( aParam, 5 ) );

      /* TOFIX */
      hb_retnl( isc_dsql_fetch( status,
                                &stmt,
                                dialect,
                                sqlda ) == 100L ? -1 : isc_sqlcode( status ) );
   }
   else
      hb_retnl( 0 );
}

HB_FUNC( FBFREE )
{
   PHB_ITEM aParam = hb_param( 1, HB_IT_ARRAY );

   if( aParam )
   {
      isc_stmt_handle  stmt = ( isc_stmt_handle ) ( HB_PTRDIFF ) hb_itemGetPtr( hb_itemArrayGet( aParam, 1 ) );
      XSQLDA *         sqlda = ( XSQLDA * ) hb_itemGetPtr( hb_itemArrayGet( aParam, 2 ) );
      isc_tr_handle    trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_itemGetPtr( hb_itemArrayGet( aParam, 3 ) );
      ISC_STATUS_ARRAY status;

      if( isc_dsql_free_statement( status, &stmt, DSQL_drop ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      if( trans )
      {
         if( isc_commit_transaction( status, &trans ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      /* TOFIX: Freeing pointer received as parameter? We should at least set the item NULL. */
      if( sqlda )
         hb_xfree( sqlda );

      hb_retnl( 1 );
   }
   else
      hb_retnl( 0 );
}

HB_FUNC( FBGETDATA )
{
   PHB_ITEM aParam = hb_param( 1, HB_IT_ARRAY );

   if( aParam )
   {
      XSQLVAR *        var;
      XSQLDA *         sqlda = ( XSQLDA * ) hb_itemGetPtr( hb_itemArrayGet( aParam, 2 ) );
      ISC_STATUS_ARRAY status;
      ISC_QUAD *       blob_id;

      int pos = hb_parni( 2 ) - 1;

      if( ! sqlda || pos < 0 || pos >= sqlda->sqln )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      var = sqlda->sqlvar + pos;

      if( ( var->sqltype & 1 ) && ( *var->sqlind < 0 ) )
      {
         hb_ret(); /* null field */
      }
      else
      {
         struct tm times;
         char date_s[ 25 ];
         char data[ 1024 ];

         short dtype = var->sqltype & ~1;

         switch( dtype )
         {
         case SQL_TEXT:
         case SQL_VARYING:
            hb_retclen( var->sqldata, var->sqllen );
            break;

         case SQL_TIMESTAMP:
            isc_decode_timestamp( ( ISC_TIMESTAMP * ) var->sqldata, &times );
            hb_snprintf( date_s, sizeof( date_s ), "%04d-%02d-%02d %02d:%02d:%02d.%04d",
                         times.tm_year + 1900,
                         times.tm_mon + 1,
                         times.tm_mday,
                         times.tm_hour,
                         times.tm_min,
                         times.tm_sec,
                         ( int ) ( ( ( ISC_TIMESTAMP * ) var->sqldata )->timestamp_time % 10000 ) );
            hb_snprintf( data, sizeof( data ), "%*s ", 24, date_s );

            hb_retc( data );
            break;

         case SQL_TYPE_DATE:
            isc_decode_sql_date( ( ISC_DATE * ) var->sqldata, &times );
            hb_snprintf( date_s, sizeof( date_s ), "%04d-%02d-%02d", times.tm_year + 1900, times.tm_mon + 1, times.tm_mday );
            hb_snprintf( data, sizeof( data ), "%*s ", 8, date_s );

            hb_retc( data );
            break;

         case SQL_TYPE_TIME:
            isc_decode_sql_time( ( ISC_TIME * ) var->sqldata, &times );
            hb_snprintf( date_s, sizeof( date_s ), "%02d:%02d:%02d.%04d",
                         times.tm_hour,
                         times.tm_min,
                         times.tm_sec,
                         ( int ) ( ( *( ( ISC_TIME * ) var->sqldata ) ) % 10000 ) );
            hb_snprintf( data, sizeof( data ), "%*s ", 13, date_s );

            hb_retc( data );
            break;

         case SQL_BLOB:
            blob_id = ( ISC_QUAD * ) var->sqldata;
            hb_retptr( ( void * ) blob_id );
            break;

         case SQL_SHORT:
         case SQL_LONG:
         case SQL_INT64:
            {
               ISC_INT64 value;
               short field_width;
               short dscale;

               switch( dtype )
               {
               case SQL_SHORT:
                  value = ( ISC_INT64 ) *( short * ) var->sqldata;
                  field_width = 6;
                  break;

               case SQL_LONG:
                  value = ( ISC_INT64 ) *( long * ) var->sqldata;
                  field_width = 11;
                  break;

               case SQL_INT64:
                  value = ( ISC_INT64 ) *( ISC_INT64 * ) var->sqldata;
                  field_width = 21;
                  break;

               default:
                  value = 0;
                  field_width = 10;
                  break;
               }

               dscale = var->sqlscale;

               if( dscale < 0 )
               {
                  ISC_INT64 tens = 1;
                  short     i;

                  for( i = 0; i > dscale; i-- )
                     tens *= 10;

                  if( value >= 0 )
                     hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d",
                                  field_width - 1 + dscale,
                                  ( ISC_INT64 ) value / tens,
                                  -dscale,
                                  ( ISC_INT64 ) value % tens );
                  else if( ( value / tens ) != 0 )
                     hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d",
                                  field_width - 1 + dscale,
                                  ( ISC_INT64 ) ( value / tens ),
                                  -dscale,
                                  ( ISC_INT64 ) -( value % tens ) );
                  else
                     hb_snprintf( data, sizeof( data ), "%*s.%0*" ISC_INT64_FORMAT "d",
                                  field_width - 1 + dscale,
                                  "-0",
                                  -dscale,
                                  ( ISC_INT64 ) -( value % tens ) );
               }
               else if( dscale )
                  hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d%0*d", field_width, ( ISC_INT64 ) value, dscale, 0 );
               else
                  hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d", field_width, ( ISC_INT64 ) value );
            }

            hb_retc( data );
            break;

         case SQL_FLOAT:
            hb_snprintf( data, sizeof( data ), "%15g ", *( float * ) ( var->sqldata ) );
            hb_retc( data );
            break;

         case SQL_DOUBLE:
            hb_snprintf( data, sizeof( data ), "%24f ", *( double * ) ( var->sqldata ) );
            hb_retc( data );
            break;

         default:
            hb_ret();
            break;
         }
      }
   }
}

HB_FUNC( FBGETBLOB )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      ISC_STATUS_ARRAY status;
      isc_tr_handle    trans = ( isc_tr_handle ) 0;
      isc_blob_handle  blob_handle = ( isc_blob_handle ) 0;
      short            blob_seg_len;
      char             blob_segment[ 512 ];
      ISC_QUAD *       blob_id = ( ISC_QUAD * ) hb_parptr( 2 );
      char             p[ 1024 ];
      ISC_STATUS       blob_stat;

      if( ISPOINTER( 3 ) )
         trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 3 );
      else
      {
         if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      if( isc_open_blob2( status, &db, &trans, &blob_handle, blob_id, 0, NULL ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Get blob segments and their lengths and print each segment. */
      blob_stat = isc_get_segment( status, &blob_handle,
                                   ( unsigned short * ) &blob_seg_len,
                                   sizeof( blob_segment ), blob_segment );

      if( blob_stat == 0 || status[ 1 ] == isc_segment )
      {
         PHB_ITEM aNew = hb_itemArrayNew( 0 );

         while( blob_stat == 0 || status[ 1 ] == isc_segment )
         {
            PHB_ITEM temp;

            hb_snprintf( p, sizeof( p ), "%*.*s", blob_seg_len, blob_seg_len, blob_segment );

            temp = hb_itemPutC( NULL, p );
            hb_arrayAdd( aNew, temp );
            hb_itemRelease( temp );

            blob_stat = isc_get_segment( status, &blob_handle,
                                         ( unsigned short * ) &blob_seg_len,
                                         sizeof( blob_segment ), blob_segment );
         }

         hb_itemReturnRelease( aNew );
      }

      if( isc_close_blob( status, &blob_handle ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      if( ! ISPOINTER( 3 ) )
      {
         if( isc_commit_transaction( status, &trans ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

Delpji 7, harbour 3.2, xharbour 1.2.3, Bcc7, Minigw, Minigui 19.11, hwgui 2.20, FiveWin 19.05 Gtwvw, Gtwvg, C# VS 2017
Avatar do usuário
jairfab
Usuário Nível 3
Usuário Nível 3
Mensagens: 252
Registrado em: 21 Mai 2007 09:43
Localização: São Paulo, Região Leste - Suzano

Firebird no Xharbour

Mensagem por jairfab »

Segue um pequeno exemplo utilizando firebird nativo

Código: Selecionar todos

#include "common.ch"
#include "Fileio.ch"  
#define CRLF CHR(13)+CHR(10)

FUNCTION MAIN 

LOCAL ndialect  := 3 
LOCAL cUser     := "SYSDBA"
LOCAL cPass     := "masterkey"

CLS
*      ? FBCreateDB( cServer + cDatabase, cUser, cPass, nPageSize, cCharSet, nDialect )
cls
RDDSetDefault("DBFCDX")
*cBanco='192.168.1.167:C:\DB\JAIR.FDB'
*cBanco='189.38.89.220:C:\JAIR.FDB'
cBanco:='C:\DB\JAIR.FDB'
db    := FBConnect(cBanco, "sysdba", "masterkey")

IF HB_ISNUMERIC( db )
  * MSGSTOP("Não foi possivel a conexão com o banco de dados :"+cBanco)
   RETURN .T.
ENDIF
IF ISNUMBER(db)
 *  MSGSTOP("Não foi possivel a conexão com o banco de dados :"+cBanco)
   RETURN .T.
ENDIF

trans := FBStartTransaction( db )
IF HB_ISNUMERIC( trans )
 *  MSGSTOP("Não foi possivel executar a transação")
   RETURN .T.
ENDIF
*                    1          2         3        4      5
cSql     := "SELECT CODCLI, CODEMPRESA, TIPOCLI, CONTA, CONTAFOR FROM V_CLI "
trans    := FBStartTransaction(db)
vPlanoCt := FBQuery(db, cSql, ndialect, trans)
*-----------------------------------------------------------------------*
* Carrega informações para a contabilização                             *
*-----------------------------------------------------------------------*


DO WHILE ( fetch_stat := FBFetch( vPlanoCt ) ) == 0
   V01 :=FBGetData( vPlanoCt, 1 )
   V02 :=FBGetData( vPlanoCt, 2 )
   V03 :=FBGetData( vPlanoCt, 3 )
   V04 :=FBGetData( vPlanoCt, 4 )
   V05 :=FBGetData( vPlanoCt, 5 )
   ? V01, V02, V03, V04, V05

ENDDO
*-----------------------------------------------------------------------*
* Fecha conexao com o banco de dados                                    *
*-----------------------------------------------------------------------*
FBFree(vPlanoCt)
FBClose(db)

return nil



Delpji 7, harbour 3.2, xharbour 1.2.3, Bcc7, Minigw, Minigui 19.11, hwgui 2.20, FiveWin 19.05 Gtwvw, Gtwvg, C# VS 2017
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Firebird no Xharbour

Mensagem por JoséQuintas »

Ja vi alguns colegas tocarem nessa questao "mostrar so os dados que interessam". Ocorre que ha situações que não vejo como aplicar a lógica disso! Se eu tenho um cadastro de produtos com 200.000 itens, por exemplo, e eu mostro um browse para o usuário procurar o produto q deseja... como de 200.000 produto eu irei mostrar apenas 10.000 se eu não sei qual produto o usuario deseja encontrar? O usuário pode querer encontrar qualquer um dos 200.000 cadastrados!
Pra pesquisa letra-a-letra como tenho no meu sistema, num vejo como aplicar essa lógica
Isso é relativo, justamente aí entra "não pensar igual DBF".

DBF:
200.000 produtos, registro de 2.000 bytes, numa tela cabendo 40 produtos, 80.000 bytes ( 80kb) pela rede.
Pelo menos 2 arquivos abertos e compartilhados (DBF + CDX), e terminal conversando com servidor.
Registros lidos um de cada vez, com várias consultas ao servidor durante a montagem do browse, e depois também.
Terminais talvez "brigando entre si", pra acessar os dados.
Mesmo numa rede de 100MB, são várias consultas.

Server:
O terminal pede pro servidor e vém pronto, consulta com código + descrição, 50 bytes, aonde o DBF gastava a rede pra 40 registros, agora cabem 1.600.
Ou que seja, 1MB pela rede para o arquivo inteiro.
Uma única consulta ao servidor, numa rede de 100MB, 1 segundo e servidor e rede estão liberados para os outros terminais.

As máquinas atuais vém com placa de rede de 1GB. Pra DBFs, o ganho é pequeno, porque continua sendo um registro por vez, já nessa consulta de 200.000 produtos em cliente/servidor...

Em termos de movimentação de dados/rede, a diferença entre DBF e cliente/server começa por aí.
Se avaliar só essa parte, que é o mínimo de tudo, já tem diferença.

Quem usa DBF se pergunta como fazem os que usam cliente/servidor, e vice-versa.
O estilo de uso é diferente, não dá pra comparar apenas determinada situação.

É por isso que usar cliente/servidor igual DBF acaba deixando tudo mais lento: acaba juntando as piores partes dos dois.
É repensar sobre como o aplicativo vai trabalhar com o banco de dados.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder