Página 2 de 3

Re: Firebird no Xharbour

Enviado: 26 Nov 2009 02:20
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?

Re: Firebird no Xharbour

Enviado: 26 Nov 2009 08:28
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,

Re: Firebird no Xharbour

Enviado: 26 Nov 2009 09:31
por RamonXHB
Já editei o tópico que tem o endereço de download...

Firebird no Xharbour

Enviado: 14 Mar 2013 09:27
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

Firebird no Xharbour

Enviado: 15 Mar 2013 16:42
por RamonXHB
que tal você usar um exemplo ???

Firebird no Xharbour

Enviado: 18 Mar 2013 09:49
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

Firebird no Xharbour

Enviado: 18 Mar 2013 15:01
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

Firebird no Xharbour

Enviado: 26 Mar 2013 14:49
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.

Firebird no Xharbour

Enviado: 27 Mar 2013 08:31
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

Firebird no Xharbour

Enviado: 29 Set 2016 21:11
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.

Firebird no Xharbour

Enviado: 06 Out 2016 10:31
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

Firebird no Xharbour

Enviado: 06 Out 2016 11:46
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.

Firebird no Xharbour

Enviado: 06 Out 2016 15:27
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 );
}


Firebird no Xharbour

Enviado: 06 Out 2016 15:37
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




Firebird no Xharbour

Enviado: 06 Out 2016 18:02
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.