Clipper On Line • Ver Tópico - LetoDb e Harbour, como usar.
Página 1 de 14

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jun 2014 16:12
por Itamar M. Lins Jr.
Ola!
O LetoDb é um motor "DAEMON" que funciona com características similares aos bancos de dados MySQL, Postgree SQL, MSSQL...
Em outras palavras, ele serve de ponte (ligação) entre seu aplicativo e o banco de dados. É para ele que fazemos a requisição dos dados, solicitamos ao DAEMON (motor), os dados, assim sendo não existe mais o tráfego de todos os arquivos pela rede, não precisamos mapear tão pouco compartilhar a pasta, e os perigos dos travamentos(rlock(),flock()) são minimizados. Aumentando assim a velocidade da aplicação que usa DBF.

Baixe o LetoDb da sessão de download aqui do forum.
http://www.pctoledo.com.br/forum/filebase.php?d=1&id=218&c_old=0&what=c&page=1

Primeiro verificar(editar) o arquivo letodb.ini e colocar o DATAPATH de acordo onde se encontra os seus arquivos DBF´s, pode conter subpastas não precisa direcionar para as subpastas apenas para pasta raiz.

Port = 2812              
Logfile = "letodb.log"   
DEFAULT_DRIVER = CDX     
DATAPATH = c:\dados\
ENABLEFILEFUNC = 1
CRYPT_TRAFFIC = 0
PASS_FOR_LOGIN = 0
PASS_FOR_MANAGE = 0
PASS_FOR_DATA = 0
Share_Tables  = 0
Cache_Records = 50
[DATABASE]
DataPath = c:\dados\
Driver = CDX


Para instalar o serviço no windows XP ou 7 ou 8 use:
c:>\pasta_com_letodb\letodb install //minusculo mesmo
net start letodb_service


Pronto o letodb está rodando e "apontado" para a pasta onde estão os seus DBF´s apenas faça os ajustes se for CDX ou NTX.
Dica firewall!
Não esquecer de liberar pelo firewall a porta 2812.
1)Dica para acesso externo!
No modem ADSL na opção NAT direcionar a PORTA 2812 para o IP do servidor que está instalado o LetoDB
2)Dica, use um programa gratuito p/ acesso externo!
Use o serviço(programa) www.no-ip.com ou outro melhor para achar seu computador em uma rede WAN.

Testando:

#require "sddodbc" //opcional se for usar MySql com LetoDb
#require "sddfb"  //opcional se for usar Firebird com Letodb
#include "rddleto.ch"

REQUEST DBFCDX, DBFFPT, DBFDBT, LETO
REQUEST HB_LANG_PT, HB_CODEPAGE_PTISO, HB_CODEPAGE_PT850

REQUEST  SQLMIX, SDDODBC //opcional se for usar MySQL ou Firebird etc...

Function Main
Local cPATH := "//localhost:2812/" //não precisa informar o caminho dos DBF´s porque já foi informado(configurado) no arquivo leotdb.ini

//Conectando com o servidor LetoDb.

      nConect := leto_Connect( cPath)
      IF nConect == -1
          nRes := leto_Connect_Err()
         IF nRes == LETO_ERR_LOGIN
            alert( "Falha ao Logar" )
         ELSEIF nRes == LETO_ERR_RECV
           alert( "Error ao conectar" )
         ELSEIF nRes == LETO_ERR_SEND
            alert( "Erro de envio" )
         ELSE
            alert( "Não connectado ao servidor: " + cPath )
         ENDIF
         Return .F.
      ENDIF

cIndex  := cPATH+"meu_arquivo.cdx"

cDbf := cPATH+"meu_aquivo.dbf"

DbUseArea(.t.,'LETO',cDbf,"alias_xyz",.T.,.F.,'PTISO')
If leto_file(cIndex)
   DBSETINDEX( cIndex )
Else
   index on ...//seu código
   index on ... //seu código
EndIf



E quando compilar sua aplicação, não esquecer de ligar a lib!
Colocar em um arquivo com a extensão letodb.hbc
{win}incpaths=c:\pasta_com_letodb\include;
{win}libpaths=c:\pasta_com_letodb\lib;

{win}libs=rddleto

E no arquivo "seu_projeto.hbp" adicionar a linha:
letodb.hbc 

Depois compilar:
:>hbmk2 seu_projeto.hbp


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jun 2014 16:43
por Duda 'Sgluber'
Estas informações serão muito úteis pra mim, em breve.

Muito obrigado, Itamar! Imagem

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jun 2014 17:00
por Itamar M. Lins Jr.
Ps.
Esqueci de agradecer ao Alexander Kresin e ao Pavel Tsarenko por terem feito o LetoDb!

t+

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jun 2014 17:03
por lugab
Obrigado, Itamar...

Estou cheio de esperança de fazer funcionar essa sua contribuição no meu aplicativo Dbf/CDX

Tentei antes usar o LetoDB baseado em postagens de outros tópicos e não consegui sequer compilar...

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jun 2014 22:22
por Maurício Elias
Grande Itamar, esse é o cara...
Fechou a questão, amanhã mesmo já começo os estudos.
Valew cara, muito obrigado.
Só me fala uma coisa: Para o caso do servidor Linux e teminais Win XP e 7, estou tendo travamentos no ato dos "Confirma Gravação?" ( HB32+DBF+NTX )
Será que o LetoDB resolve essa questão tb? Ou é outro problema ?

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jun 2014 23:04
por Itamar M. Lins Jr.
Teste ai antes. Depois, pode remover o Linux+SAMBA e usar o win7 mesmo. Lembrando que essa compilação é 32Bits!

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jun 2014 23:43
por janio
Preciso do leto compilado para xharbour 1.2

Alguem?????

LetoDb e Harbour, como usar.

MensagemEnviado: 04 Jun 2014 07:54
por Toledo
Janio, faça você mesmo a compilação, copie os códigos fontes do LetoDb e veja os arquivos Readme.txt e readme_pt_br.txt (obrigado Leonardo - sygecom pela tradução).

http://letodb.cvs.sourceforge.net/viewvc/letodb/letodb/?view=tar&pathrev=rel-1-mt

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 04 Jun 2014 18:04
por janio
Ok,
- baixei o leto
- fiz os ajustes necessários
- executei sem erros o arquivo make_b32.bat
- foram geradas as lib's leto.lib e rddleto.lib

Mas o executavel num gerado em lugar nenhum! Como gero o executavel letodb.exe????

LetoDb e Harbour, como usar.

MensagemEnviado: 04 Jun 2014 22:02
por janio
Vi um negocio estranho aqui no makefile.bc
#
# Our default target
#

!if $d(XHARBOUR)
PROJECT = \
   $(CLIENT_RDD_LIB) \
   $(CLIENT_LIB)
!else
PROJECT = \
   $(CLIENT_RDD_LIB) \
   $(CLIENT_LIB) \
   $(SERVER_EXE)
!endif


Quando é para xHarbour o executado do leto (letodb.exe) não é gerado??? Somente as lib's????
Estou sem entender...
como gero esse executavel no xharbour, meu Deus?

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jun 2014 08:45
por Toledo
janio escreveu:como gero esse executavel no xharbour, meu Deus?

Janio, pelo jeito você não leu o arquivo readme_pt_br.txt completo.

2.3 xHarbour Builder(Comercial)

Execute o make_xhb.bat para construir binários com este compilador.
Provavelmente, você precisará alterar o caminho para sua cópia Construtor
de expressões na make_xhb.bat xHarbour. O valor padrão é:

set XHB_PATH=c:\xhb

Então se o seu xHarbour estiver em outra pasta (c:\xhb), basta editar o arquivo make_xhb.bat e procurar a linha set XHB_PATH=c:\xhb e informar a pasta correta. Depois é só executar o make_xhb.bat.

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jun 2014 09:25
por janio
Toledo,

Eu li o arquivo readme_pt_br.txt. Ocorre que esse item refere-se ao xHarbour COMERCIAL, que não é o meu caso, por isso ignorei-o!

Vou fazer os testes que vc sugeriu!

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jun 2014 09:37
por Itamar M. Lins Jr.
Janio, você pode usar o executável que postei mesmo.
Use somente a lib p/ xHb.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jun 2014 09:51
por janio
Hummmmm é mesmo! Como não pensei nisso!!!

#-) :%

Executável é executavel e não importa em que linguagem foi compilado!
:-´

Janio

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jun 2014 11:43
por Minduim
bom dia senhores;

estou testando as informações deste tópico e esta aparecendo a mensagem abaixo no arquivo letodb.log;

06/05/14 11:01:16: Error BASE/1001  Undefined function: DESCRIPT Arguments: ( [ 1] = Type: C Val:       )


no mesmo momento, o executável também retorna o erro abaixo, na função:
dbUseArea( .T., "LETO", "//localhost:2812/ARQ20670.DBF", "ARQ20270", .F.)

Subsystem Call......: LETO
System Code.........: 1021
Default Status......: .F.
Description.........: Tipo incorreto de dado
Operation...........:
Arguments...........:
Involved File.......: //localhost:2812/ARQ20670.DBF
Dos Error Code......: 0


todos os arquivos de banco de dados estão criptografados pelas rotinas: cript/descript (função de usuário), mas o arquivo de banco de dados e index não chegam serem abertos;

DEFAULT_DRIVER = CDX

o sistema funciona perfeitamente em "DBFNTX" ou "DBFCDX"

alguma luz?

em tempo, baixei o letodb pelo caminho indicado pelo TOLEDO
http://letodb.cvs.sourceforge.net/viewv ... v=rel-1-mt

e utilizando o arquivo bat abaixo:
set path=c:\hb32\bin

hbmk2 letodb.hbp

hbmk2 rddleto.hbp

hbmk2 leto.hbp

hbmk2 letodyn.hbp


aparecem os erros abaixo:

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jun 2014 17:19
por Itamar M. Lins Jr.
Vc fez uma salada ai.
Bem pelo que vc mostrou você conseguiu rodar o letodb e compilar.
Depois você mostra uma tela de erros que não conseguiu.

Você está usando Harbour ou xHb ?
no mesmo momento, o executável também retorna o erro abaixo, na função:
dbUseArea( .T., "LETO", "//localhost:2812/ARQ20670.DBF", "ARQ20270", .F.)

Testou assim?
dbUseArea( .T., "LETO", "ARQ20670.DBF")
ou assim ?
use ARQ20670 via "LETO"

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jun 2014 21:59
por janio
Itamar,

Ha um tempo vc reportou um bug na função leto_fRename.

Esse bug ainda persiste??

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 00:32
por janio
Ah, so para esclarecer... o make_xhb.bat deve ser mesmo para xharbour COMERCIAL! Mesmo ajustando aqui o path da uma porrada de erros! Ele reclama da falta de alguns exe's (xcc.exe, xhb.exe, xlink.exe, etc)... que so podem ser do xh comercial.

Conclusão: Para xharbour (free) apenas as lib's são geradas... o executavel não!

Quem tiver contato com o russo, favor reportar esse negocio pra a gente saber como fazer!

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 10:12
por Itamar M. Lins Jr.
O xHarbour comercial ou não, tem uma serie de bugs no modo MT, motivo pelo qual foi abandonado pelo Pavel Tsareko, essa versão que postei é a dele, a antiga foi abandonada por esses motivos, tinha muitos problemas. Como a LIB pode ser usada inclusive em PHP, tém até exemplos, o melhor é usar somente a LIB e pegar o executável que postei.
O Alexander e Pavel usam o Harbour ele adicionou esse make em 2008, como ninguém na Russia e no Brasil reclamou, esse arquivo foi esquecido.
Esse arquivo make_xhb.bat deve ter sido enviado p/ ele por algum Brasileiro.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 11:05
por janio
Ok Itamar!

Ja estou usando o executavel postado por vc e tem funcionado muito bem! Estou fazendo umas mudanças no meu sistema de modo que eu possa usar ou não o leto apenas lendo uma chave num arquivo ini. Ta ficando muito bom!

O ruim de o xharbour não gerar o executavel é que vamos ficar sempre na dependencia de alguem compilar pra gente. Mas num tem problema... vamos no virando.

Qnto a função leto_fRename()... ja ta tudo ok???

Janio

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 11:29
por Minduim
agradeço a colaboração;

caro Itamar, bom dia a todos nos;
perdoe a demora em retornar;

1 - iniciei os meus testes utilizando a versão compilada indicada por você:
"http://www.pctoledo.com.br/forum/filebase.php?d=1&id=218&c_old=0&what=c&page=1"
em tempo: esta faltando rddleto.ch;

utilizo harbour 3.2 + mingw

fiz os testes com as observações apontadas por você:
1 - não esta mais aparecendo mensagem de erro no arquivo letodb.log;
2 - mas continua aparecendo mensagem de erro no executável = "tipo incorreto de dado";

2 - infelizmente ontem não houve salada (sou vegetariano);
depois de muitos testes infrutíferos e de muitos cabelos a menos, resolvi dar um tempo e
baixei o letodb indicado pelo Toledo:
"http://letodb.cvs.sourceforge.net/viewvc/letodb/letodb/?view=tar&pathrev=rel-1-mt"
ao compilá-lo notei os erros, na realidade apenas um;
nas rotinas LetoDbCreateTable e LetoDbOpenTable contidas no arquivo letocl em letodb/souce/cliente
a linha de comando:
pTable->uiDriver = LETO_NTX; (linhas 114 e 242)
pelo que notei, não existe nenhuma referencia a LETO_NTX, mas também não sei como corrigir pois não entendo desta linguagem;

mais alguma luz?

HB_EXPORT LETOTABLE * LetoDbCreateTable( LETOCONNECTION * pConnection, char * szFile, char * szAlias, char * szFields, unsigned int uiArea )
{

   LETOTABLE * pTable;

   char * szData, * ptr = szFields, szTemp[14];

   unsigned int ui, uiFields = 0;

   while( *ptr )

   {

      for( ui=0; ui<4; ui++ )

      {

         while( *ptr && *ptr++ != ';' );

         if( !(*ptr) && ( *(ptr-1) != ';' || ui < 3 ) )

         {

            s_iError = 1;

            return NULL;

         }

      }

      uiFields ++;

   }

   szData = (char *) malloc( (unsigned int) uiFields * 24 + 10 + _POSIX_PATH_MAX );

   if( LetoCheckServerVer( pConnection, 100 ) )

      sprintf( szData,"creat;%s;%s;%d;%s\r\n", szFile, szAlias, uiFields, szFields );

   else

      sprintf( szData,"creat;01;%d;%s;%s;%d;%s\r\n", uiArea, szFile, szAlias, uiFields, szFields );

   if( !leto_DataSendRecv( pConnection, szData, 0 ) )

   {

      s_iError = 1000;

      free( szData );

      return NULL;
   }

   free( szData );

   ptr = leto_getRcvBuff();
   if( *ptr == '-' )

   {

      if( ptr[4] == ':' )

         sscanf( ptr+5, "%u-%u-", &ui, &s_iError );

      else

         s_iError = 1021;

      return NULL;

   }

   pTable = (LETOTABLE*) malloc( sizeof(LETOTABLE) );

   memset( pTable, 0, sizeof( LETOTABLE ) );

   pTable->uiConnection = pConnection - letoConnPool;

   pTable->iBufRefreshTime = -1;

   pTable->uiSkipBuf = 0;

   pTable->fShared = pTable->fReadonly = 0;

   pTable->pLocksPos  = NULL;

   pTable->ulLocksMax = pTable->ulLocksAlloc = 0;

   leto_AddFields( pTable, uiFields, szFields );

   pTable->pRecord = ( unsigned char * ) malloc( pTable->uiRecordLen+1 );

   ptr = leto_firstchar();
   LetoGetCmdItem( &ptr, szTemp );
ptr ++;

   sscanf( szTemp, "%lu" , &(pTable->hTable) );

   if( *ptr == '1' )

     pTable->uiDriver = LETO_NTX;

   ptr ++;
ptr++;

   leto_ParseRecord( pTable, ptr, 1 );

   /*
   if( LetoCheckServerVer( pConnection, 100 ) )

   {

      ptr += HB_GET_LE_UINT24( ptr ) + 3;
      leto_ReadMemoInfo( pTable, ptr );

   }

   */

   return pTable;

}

HB_EXPORT LETOTABLE * LetoDbOpenTable( LETOCONNECTION * pConnection, char * szFile, char * szAlias, int iShared, int iReadOnly, char * szCdp, unsigned int uiArea )

{

   char szData[_POSIX_PATH_MAX + 16], * ptr, szTemp[14];
   LETOTABLE * pTable;

   unsigned int uiFields;

   if( szFile[0] != '+' && szFile[0] != '-' )

   {
      if( LetoCheckServerVer( pConnection, 100 ) )

         sprintf( szData,"open;%s;%s;%c%c;%s;\r\n", szFile,

             szAlias, (iShared)? 'T':'F', (iReadOnly)? 'T':'F', szCdp );

      else

         sprintf( szData,"open;01;%d;%s;%s;%c%c;%s;\r\n", uiArea, szFile,

             szAlias, (iShared)? 'T':'F', (iReadOnly)? 'T':'F', szCdp );

      if( !leto_DataSendRecv( pConnection, szData, 0 ) )

      {
         s_iError = 1000;

         return NULL;

      }
      ptr = leto_getRcvBuff();

      if( *ptr == '-' )

      {

         if( *(ptr+3) == '4' )

            s_iError = 103;

         else

            s_iError = 1021     return NULL;

      }

      pTable = (LETOTABLE*) malloc( sizeof(LETOTABLE) );

      memset( pTable, 0, sizeof( LETOTABLE ) );

      pTable->uiConnection = pConnection - letoConnPool;

      ptr = leto_firstchar();

   }

   else

   {

      if( ( ptr = strchr( szFile + 1, ';' ) ) == NULL )

         return NULL;

      pTable = (LETOTABLE*) malloc( sizeof(LETOTABLE) );

      ptr ++;

   }

   pTable->fShared = iShared;

   pTable->fReadonly = iReadOnly;

   pTable->iBufRefreshTime = -1;

   pTable->uiSkipBuf = 0;

   pTable->pLocksPos  = NULL;

   pTable->ulLocksMax = pTable->ulLocksAlloc = 0;

   LetoGetCmdItem( &ptr, szTemp );
ptr ++;

   sscanf( szTemp, "%lu" , &(pTable->hTable) );

   if( *ptr == '1' )

     pTable->uiDriver = LETO_NTX;

   ptr ++;
ptr++;

   if( LetoCheckServerVer( pConnection, 100 ) )

   {

      // Read MEMOEXT, MEMOTYPE, MEMOVERSION

      ptr = leto_ReadMemoInfo( pTable, ptr );

      // for DBI_LASTUPDATE

      if( LetoCheckServerVer( pConnection, 208 ) )

      {

         LetoGetCmdItem( &ptr, szTemp );
ptr ++;

         pTable->lLastUpdate = leto_dateEncStr( szTemp );

      }

   }

   // Read number of fields

   LetoGetCmdItem( &ptr, szTemp );
ptr ++;

   sscanf( szTemp, "%d" , &uiFields );

   ptr = leto_AddFields( pTable, uiFields, ptr );

   pTable->pRecord = ( unsigned char * ) malloc( pTable->uiRecordLen+1 );

   if( s_uiAutOpen )

      ptr = leto_ParseTagInfo( pTable, ptr );

   else

      ptr = leto_SkipTagInfo( pConnection, ptr );

   leto_ParseRecord( pTable, ptr, 1 );

   return pTable;

}

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 11:58
por janio
"tipo incorreto de dado" quer dizer que vc não está setando o rdd correto!

Colocou no inicio do seu sistema

REQUEST LETO
RDDSETDEFAULT("LETO")

?????

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 12:31
por Itamar M. Lins Jr.
Ola!
Minduim coloca um pequeno PRG com o teste que vc está fazendo. Inclusive como está seu LETODB.INI

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 12:41
por Itamar M. Lins Jr.
Ola!
Esqueci de colocar o arquivo rddleto.ch
Segue anexo com correção.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 13:42
por Minduim
agradeço a colaboração de todos

Janio - suas observações constam do meu .prg

Itamar - fiz rapidinho um .prg de teste

arquivo teste.prg
********************************
PROCEDURE MAIN(npa)

   local cPath, nConnect, nRes

   REQUEST DBFNTX
   REQUEST DBFCDX
   REQUEST LETO

   RDDSETDEFAULT( "DBFCDX" )

   #include "rddleto.ch"

   #include "inkey.ch"
   #include "hbgtinfo.ch"

   REQUEST HB_LANG_PT
   REQUEST HB_CODEPAGE_PT850
   REQUEST HB_CODEPAGE_PTISO
   HB_LANGSELECT("PT")
   HB_CDPSELECT("PT850")

   REQUEST HB_GT_WVG_DEFAULT

   hb_gtinfo( HB_GTI_SELECTCOPY,.T.)
   hb_gtinfo( HB_GTI_RESIZABLE, .F.)
   hb_gtinfo( HB_GTI_CLOSABLE, .T.)
   hb_gtinfo( HB_GTI_CODEPAGE, 255)
   hb_gtinfo( HB_GTI_MOUSESTATUS, 0)
   hb_gtinfo( HB_GTI_FONTNAME, "Courier New")     
   hb_gtinfo( HB_GTI_FONTQUALITY, HB_GTI_FONTQ_DRAFT) // _DRAFT _NORMAL _HIGH

   SetMode(32, 120)
   do case
      case hb_gtinfo( HB_GTI_DESKTOPWIDTH) > 1023
           hb_gtinfo( HB_GTI_SCREENWIDTH, 960)
           hb_gtinfo( HB_GTI_SCREENHEIGHT, 512)
           hb_gtinfo( HB_GTI_FONTWIDTH, 10)
           hb_gtinfo( HB_GTI_FONTSIZE,  22)
      case hb_gtinfo( HB_GTI_DESKTOPWIDTH) > 799
           hb_gtinfo( HB_GTI_SCREENWIDTH, 640)
           hb_gtinfo( HB_GTI_SCREENHEIGHT, 400)
           hb_gtinfo( HB_GTI_FONTWIDTH, 12)
           hb_gtinfo( HB_GTI_FONTSIZE,  27)
      otherwise
           hb_gtinfo( HB_GTI_FONTWIDTH, 8)
           hb_gtinfo( HB_GTI_FONTSIZE, 17)
   endcase

   cPath:= "//localhost:2812/"
   nConect := leto_Connect( cPath )
   if nConect == -1
      nRes := leto_Connect_Err()
      if nRes == LETO_ERR_LOGIN
         alert( "Falha ao Logar" )
      elseif nRes == LETO_ERR_RECV
         alert( "Error ao conectar" )
      elseif nRes == LETO_ERR_SEND
         alert( "Erro de envio" )
      else
         alert( "Nao conectado ao servidor: " + cPath )
      endif
   endif

   dbUseArea( .T., "LETO", "ARQ2070.DBF", "ARQ20670", .F. )

   browse()

   dbCloseArea()

   return .t.

EXIT PROCEDURE MAIN_SAIR
   quit

   return


arquivo letodb.ini
Port = 2812              
Logfile = "letodb.log"   
DEFAULT_DRIVER = CDX     
DATAPATH = d:\arq00001\
ENABLEFILEFUNC = 1
CRYPT_TRAFFIC = 0
PASS_FOR_LOGIN = 0
PASS_FOR_MANAGE = 0
PASS_FOR_DATA = 0
Share_Tables  = 0
Cache_Records = 50
[DATABASE]
DataPath = d:\arq00001\
Driver = CDX


arquivo .hbp
#
# $Id: hbmain.hbp $
#

-lrddleto

-lhbtip

-lxhb

-lhbcomm

-lhbct

-lhbwin

-lgtwvg

-oteste

-gui

-inc

-mt

-es2

-strip

-quiet

-compr

-workdir=d:\grlsis\r_apoio\teste_leto\temp

d:\grlsis\r_apoio\teste_leto\teste.prg



arquivo .bat para executar o letodb
letodb install
net start letodb_service

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 14:50
por Itamar M. Lins Jr.
Diminui ai o exemplo:
Function Main
LOCAL cPath

REQUEST LETO
RDDSETDEFAULT( "LETO" )
SET DATE FORMAT "dd/mm/yy"

cPath := "//127.0.0.1:2812/"
dbCreate( cPath+"test1", { {"NOME","C",10,0}, {"NUMERO","N",4,0}, {"DESCRICAO","C",40,0}, {"DATA","D",8,0} } )

? "Arquivo criado"
USE ( cPath+"test1" ) New
? "Arquivo aberto"
aStru := dbStruct()
? "Campos:", Len( aStru )
FOR i := 1 TO Len( aStru )
      ? i, aStru[i,1], aStru[i,2], aStru[i,3], aStru[i,4]
NEXT
close all
//Fim

Criar um arquivo com o nome rddleto.hbc
incpaths=\lugar_do_\include
libpaths=\lugar_do\lib

libs=rddleto

Criar um arquivo com o nome hbmk.hbm //Esse é um arquivo padrão que o hbmk2 procura automaticamente, e dentro colocar.
rddleto.hbc


Depois é compilar assim:
hbmk2 teste.prg //só isso!!!


Ps. Teste p/ ver se o motor do letodb está rodando antes.
C:\devl\LetoDB\tests>net stop letodb_service
.
O serviço de LetoDB Service foi finalizado com êxito.
C:\devl\LetoDB\tests>net start letodb_service
O serviço de LetoDB Service está sendo iniciado.
O serviço de LetoDB Service foi iniciado com êxito.

Aqui rodou sem problema!
C:\devl\LetoDB\tests>notepad testx.prg

C:\devl\LetoDB\tests>hbmk2 testx
hbmk2: Processando script local make: hbmk.hbm
Harbour 3.4.0dev () (2014-05-30 23:24)
Copyright (c) 1999-2014, http://harbour-project.org/
Compiling 'testx.prg'...
Lines 20, Functions/Procedures 1
Generating C source output to 'C:\Users\Itamar\AppData\Local\Temp\hbmk_pafawe.di
r\testx.c'... Done.

C:\devl\LetoDB\tests>testx

Arquivo criado
Arquivo aberto
Campos:          4
         1 NOME C         10          0
         2 NUMERO N          4          0
         3 DESCRICAO C         40          0
         4 DATA D          8          0


Um detalhe neste exemplo, é que não preciso conectar com o letodb via comando:
nConect := leto_Connect( //localhost:2812/ )

Porquê ?, porque o letodb(servidor) está rodando na mesma máquina, no caso meu notebook.
Se o letodb estiver em outra máquina ai sim é necessário conectar via leto_Connect

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 06 Jun 2014 15:29
por Minduim
Itamar;
agradeço a atenção, a paciência e a boa vontade de ajudar;
não sei o que seria de nós sem a pronta ajuda de vocês;
sem literatura específica e com poucos textos em outra língua, tendo que ficar traduzindo, é muito frustante;

vou testar suas sugestões e depois retorno;
depois, agora já estou estressado;

LetoDb e Harbour, como usar.

MensagemEnviado: 08 Jun 2014 14:23
por Minduim
caro Itamar, muita boa tarde;
nada como uma boa noite de sono...

me corrija se eu estiver errado;

sua postagem de teste funcionou perfeitamente, então onde esta o erro...

entendo que não demos a devida importância a uma postagem anterior:
arquivo letodb.log
06/05/14 11:01:16: Error BASE/1001  Undefined function: DESCRIPT Arguments: ( [ 1] = Type: C Val:       )


analisando o arquivo letodb.prg, entendi que que quando estamos executando o letodb algumas funções não são mais executadas pelo
nosso executável e sim pelo Letodb;

então compilei o letodb acrescentando minhas funções de usuário CRIPT e DESCRIPT e o sistema deu sinais de vida;

agora inicialmente me deparo com algumas dificuldades, onde não encontrei referencia:
- não encontrei referencia as novas funções introduzidas pelo Letodb;

- na libleto existem muitas funções mas não encontrei referências de como utilizá-las;

- as funções que entendo que são de baixo nível: FOPEN, FWRITE, FCLOSE, FERASE, etc não funcionaram, existe alguma outra opção;

- como criar, abrir e apagar um arquivo em um diretório diferente do padrão:
-- cParh:= "//localhost:2812/"
-- carqu:= "temp\teste.dbf"
-- cinde:= "temp\teste.cdx"

- executando o meu aplicativo, tenho como mudar o RDD padrão:
-- de DBFCDX para DBFNTX

- existe alguma função para capturar no meu executável o diretório padrão;

alguma luz?

LetoDb e Harbour, como usar.

MensagemEnviado: 08 Jun 2014 17:41
por Itamar M. Lins Jr.
sua postagem de teste funcionou perfeitamente, então onde esta o erro...

Beleza então! O feedback é importante. Agora fica fácil!
- não encontrei referencia as novas funções introduzidas pelo Letodb;

No arquivo readme.txt tem os comandos, porque o que está em português está defasado.
O problema é que as variáveis do lado cliente e até o alias não é visto do lado do servidor. Como resolver ?
Simples vc pode usa o &(comercial), por exemplo:
Function teste
Local minha_var_date := date()
use xyz alias "xy" new via "LETO"

index on cliente //Não pode "index on xy->cliente" uso de alias... o servidor não sabe que o alias é xy
index on cliente for data > minha_var_date //também não pode. porque o servidor não sabe. É uma variavel LOCAL. Como resolver ?
A mesma técnica que usamo em SQL veja.
cTemp  := "rec002"+dtos(hb_datetime())

cQuery := " dtos(emissao) >= '"+DToS(dIni)+"' .and. dtos(emissao) <= '"+DToS(dFim)+"' .and. cod_venda == " + "'" + cCodVenda + "'"
OrdBy  := "cliente"
Index on &OrdBy to &cTemp for &cQuery temporary

Então se voce criptografa o BD você precisa além de adicionar as funções do lado do servidor, eliminar as VARIÁVEIS.
O letodb tem outros recursos mais interessantes, não precisa vc recompilar o LetoDb p/ adicionar suas funções, se bem que é possível isso.
Crie um arquivo de nome letoudf.prg e coloque lá dentro suas funções.
Compilar usando hbmk2 letodbudf -gh //Vair gerar um arquivo de nome letoudf.hrb
O motor letodb procura este arquivo(letoudf.hrb) automaticamente, quando inicializado.
Quanto as variáveis serem vistas do lado do servidor, o letodb tem como fazer, porém eu não as uso.

      7.9 Server variable management functions

      LETO_VARSET( cGroupName, cVarName, xValue[, nFlags[, @xRetValue]] ) --> lSuccess

This function assign value <xValue> to variable <cVarName> from group <cGroupName>
Optional parameter <nFlags> defines function mode:
LETO_VCREAT    - if variable doesn't exist, it's created;
LETO_VOWN      - own user variable (free after user disconnect);
LETO_VDENYWR   - write deny for other users;
LETO_VDENYRD   - read deny for other users;
LETO_VPREVIOUS - retusn previos value to <xRetValue> parameter.

      LETO_VARGET( cGroupName, cVarName )                  --> xValue

Function return value of variable <cVarName> from group <cGroupName>

      LETO_VARINCR( cGroupName, cVarName )                 --> nValue

Function increment value of variable <cVarName> from group <cGroupName>

      LETO_VARDECR( cGroupName, cVarName )                 --> nValue

Function decrement value of variable <cVarName> from group <cGroupName>

      LETO_VARDEL( cGroupName, cVarName )                  --> lSuccess

Function delete variable <cVarName> from group <cGroupName>

      LETO_VARGETLIST( [cGroupName [, nMaxLen]] )          --> aList

Function return two-dimensional array with variables: { {<cVarName>, <value>}, ...}

      7.10 Calling udf-functions on the server

      LETO_UDF( cSeverFunc, xParam1, ... )                 --> xResult
This function is called from client application. A string
<cServerFunc> contains a server connection string and name
of udf function:
//ip_address:port/funcname
A <funcname> function should be defined on the letodb server.
The first parameter of udf function is nUserStru.
Udf function can return result (any type) to client.
Examples of udf-functions are in the tests/letoudf.prg

      LETO_UDFEXIST( cSeverFunc )                          --> lExist
leto_udfExist check the existance of udf-function at the letodb server.
<cSeverFunc> parameter is the same as for leto_udf().

      LETO_PARSEREC( cRecBuf )                             --> nil
This function is necessary for calling, if udf-function returns as
result the buffer of record which should be current after of it
works.

      LETO_PARSERECODRS( cRecBuf )                         --> nil
This function is necessary for calling to fill the skip-buffer as a result
of udf-function UDF_dbEval. After calling this function, the data from the
skip-buffer can be received by dbSkip() calls. See sample in comments for
UDF_dbEval() in tests/letoudf.prg


Funções de baixo nível, fopen, etc.
      7.6 File functions

The <cFileName> parameter of all file functions can contain a connection string
to the letodb server in a format:
//ip_address:port/data_path/file_name.
If the connection string is omitted, the current active connection is used:
/data_path/file_name.
All files is searching at the DataPath catalog on the server. The ".."
symbols are disabled.

      LETO_FILE( cFileName )                               --> lFileExists
Determine if file exist at the server, analog of File() function

      LETO_FERASE( cFileName )                             --> -1 if failed
Delete a file at the server.

      LETO_FRENAME( cFileName, cFileNewName )              --> -1 if failed
Rename a file: <cFileName> --> <cFileNewName>. <cFileNewName> should be without
connection string.

      LETO_MEMOREAD( cFileName )                           --> cStr
Returns the contents of file at the server as character string, analog of
MemoRead() function.

      Leto_MemoWrite( cFileName, cBuf )                    --> lSuccess
Writes a character string into a file at the server, analog of
MemoWrit() function.

      LETO_MAKEDIR( cDirName )                             --> -1 if failed
Creates a directory at the server

      LETO_FERROR()                                        --> nError
Returns an error code of last file function.

      Leto_FileRead( cFileName, nStart, nLen, @cBuf )      --> -1 if failed
Read a content of file at the server from <nStart> offset and <nLen> length

      Leto_FileWrite( cFileName, nStart, cBuf )            --> lSuccess
Write <cBuf> character string to a file at the server from <nStart> offset and <nLen> length

      Leto_FileSize( cFileName )                           --> -1 if failed
Returns a length of filt at the server

      Leto_Directory( cDir[, cAttr] )                      --> aDirectory
Returns a content of directory at the server in the same format as Directory() function

- existe alguma função para capturar no meu executável o diretório padrão;

Do aplicativo:
cPasta    := LEFT(hb_argv(0), RAT(HB_OSPathSeparator(), hb_argv(0)))

Mudar o PATH do LETODB
      LETO_PATH( [<cPath>], [cConnString | nConnection] )  --> cOldPath

Leia o arquivo readme.txt
      /* $Id: Readme.txt,v 1.33.2.37 2014/03/14 15:25:30 ptsarenko Exp $ */

      Leto DB Server is a multiplatform database server or a database
management system, chiefly intended for client programs, written on Harbour,
be able to work with dbf/cdx files, located on a remote server.

Contents
--------

1. Directory structure
2. Building binaries
   2.1 Borland Win32 C compiler
   2.2 Linux GNU C compiler
   2.3 xHarbour Builder
   2.4 Mingw C compiler
   2.5 Building letodb with hbmk
   2.6 Addition functions support
3. Running and stopping server
4. Server configuration
   4.1 letodb.ini
   4.2 Authentication
5. Features of work with the letodb server
   5.1 Connecting to the server from client programs
   5.2 Filters
6. Variables management
7. Functions list
   7.1 Connection management functions
   7.2 Transaction functions
   7.3 Additional functions for current workarea
   7.4 Additional rdd functions
   7.5 Setting client paramenter
   7.6 File functions
   7.7 Management functions
   7.8 User account management functions
   7.9 Server variable management functions
   7.10 Calling udf-functions on the server
   7.11 Functions for bitmap filters
8. Management utility
9. Server-side functions

      1. Directory structure

      bin/          -    server executable file
      doc/          -    documentation
      include/      -    source header files
      lib/          -    rdd library
      source/
          client/   -    rdd sources
          common/   -    some common source files
          client/   -    server sources
      tests/        -    test programs, samples
      utils/
          manage/   -    server management utilities

      2. Building binaries

      The letodb server can be compiled only by the Harbour compiler, and client
library - both Harbour, and xHarbour. For OS Windows the letodb server can be
compiled as Windows service (the macro by __WIN_SERVICE__ should be initialized),
or as the daemon (process) for what it's necessary to set a macro __WIN_DAEMON__.
For Linux it is necessary to set a macro __LINUX_DAEMON__.
The server and the client library can be built with the support of the driver BMDBFCDX/BMDBFNTX.
In this case, the basic rdd letodb server will be used instead DBFCDX/DBFNTX
driver BMDBFCDX/BMDBFNTX, and supported the same functionality that BMDBF*.
To build on this mode, in build scripts (letodb.hbp, rddleto.hbp for hbmk2
and makefile.* for other compilers) it's need to set a macro __BM.

      2.1 Borland Win32 C compiler

      An environment variable HB_PATH, which defines a path to the Harbour
directory, must be set before compiling. This can be done, for example,
by adding a line in a make_b32.bat:

          SET HB_PATH=c:\harbour

If you use xHarbour, uncomment a line 'XHARBOUR = yes' in makefile.bc.
Then run the make_b32.bat and you will get server executable file letodb.exe in a bin/
directory and rdd library rddleto.lib in a lib/ directory.

      2.2 Linux GNU C compiler

      An environment variable HB_ROOT, which defines a path to the Harbour
directory, must be set before compiling. Or just change the value of HRB_DIR
in the Makefile.linux.

Then run the make_linux.sh and you will get server executable file letodb in a bin/
directory and rdd library librddleto.a in a lib/ directory.

      2.3 xHarbour Builder

      Run the make_xhb.bat to build binaries with this compiler. Probably,
  you will need to change the path to your xHarbour Builder copy in the
  make_xhb.bat. Default value is:

          set XHB_PATH=c:\xhb

      2.4 Mingw C compiler

      An environment variable HB_PATH, which defines a path to the Harbour
directory, must be set before compiling. This can be done, for example,
by adding a line in a make_mingw.bat:

          SET HB_PATH=c:\harbour

If you use xHarbour, uncomment a line 'XHARBOUR = yes' in makefile.gcc.
Then run the make_mingw.bat and you will get server executable file letodb.exe in a bin/
directory and rdd library librddleto.a in a lib/ directory.

      2.5 Building letodb with hbmk

      Now there is a possibility to build letodb with a Harbour make utility, provided by
Viktor Szakats. The command line syntax is:

      hbmk2 [-hb10|-xhb] rddleto.hbp letodb.hbp [-target=tests/test_ta.prg]

Optional parameters: -hb10 - Harbour version is 1.0 or 1.0.1,
                      -xhb - xHarbour,
                      -target="blank"\test_ta.prg - build the test, too.

      2.6 Addition functions support

      LetoDB use Harbour expression engine for evaluating index expressions and filters,
and allows a call of the following functions:

      ABS, ALLTRIM, AT, CHR, CTOD, DATE, DAY, DELETED, DESCEND, DTOC, DTOS,
      EMPTY, I2BIN, L2BIN, LEFT, LEN, LOWER, LTRIM, MAX, MIN, MONTH, PAD, PADC,
      PADL, PADR, RAT, RECNO, RIGHT, ROUND, RTRIM, SPACE, STOD, STR, STRZERO,
      SUBSTR, REPLICATE, TIME, TRANSFORM, TRIM, UPPER, VAL, YEAR,
      hb_ATokens, hb_WildMatch

      If it's necessary to add this set of functions, in the source/server.prg module
it's necessary to add a line:

      REQUEST <cFName1>[, ...]

      And then rebuild server.

      3. Running and stopping server

      Just run it:
     
      letodb.exe                    ( under Windows )
      ./letodb                      ( under Linux )

      To shutdown the server, run the same executable with a 'stop' parameter:

      letodb.exe stop               ( under Windows )
      ./letodb stop                 ( under Linux )

      To reload letoudf.hrb module, run the same executable with a 'reload' parameter:

      letodb.exe reload             ( under Windows )
      ./letodb reload               ( under Linux )

      For windows service (server should be compiled with __WIN_SERVICE__ flag):

      To install and uninstall service, you must have administrative privileges.
      To install service, run letodb with 'install' parameter:

      letodb.exe install

      To uninstall service, run letodb with 'uninstall' parameter:

      letodb.exe uninstall

      To start and stop server, run service manager.

      4. Server configuration

      4.1 letodb.ini

      You may provide configuration file letodb.ini if you isn't satisfied with
default parameters values. Currently following parameters exists ( default
values are designated ), they should be written in section [MAIN]:

      [MAIN]
      Port = 2812              -    server port number;
      TimeOut = -1             -    connection timeout;
      DataPath =               -    path to a data directory on a server;
      LogPath = letodb.log     -    path and name of a log file;
      Default_Driver = CDX     -    default RDD to open files on server ( CDX/NTX );
      Memo_Type =              -    memo type ( FPT/DBT ). Default: FPT for DBFCDX, DBT for DBFNTX;
      Lower_Path = 0           -    if 1, convert all paths to lower case;
      EnableFileFunc = 0       -    if 1, using of file functions ( leto_file(),
                                    leto_ferase(), leto_frename() is enabled;
      EnableAnyExt = 0         -    if 1, creating of data tables and indexes with
                                    any extention, other than standard ( dbf,cdx,ntx )
                                    is enabled;
      Pass_for_Login = 0       -    if 1, user authentication is necessary to
                                    login to the server;
      Pass_for_Manage = 0      -    if 1, user authentication is necessary to
                                    use management functions ( Leto_mggetinfo(), etc. );
      Pass_for_Data = 0        -    if 1, user authentication is necessary to
                                    have write access to the data;
      Pass_File = "leto_users" -    the path and name of users info file;
      Crypt_Traffic = 0        -    if 1, the data passes to the network encrypted;
      Share_Tables = 0         -    if 0 (default, this mode server was the only from the
                                    start of a letodb project), the letodb opens all
                                    tables in an exclusive mode, what allows to increase
                                    the speed. If 1 (new mode, added since June 11, 2009),
                                    tables are opened in the same mode as client
                                    applications opens them, exclusive or shared, what
                                    allows the letodb to work in coexistence with other
                                    types of applications.
      No_Save_WA = 0           -    When this mode is set, each dbUseArea() will cause
                                    a real file open operation and creating a new
                                    workarea on the server ( in default mode each file
                                    is opened only one time and have only one real
                                    workarea for all users ).
                                    Theoretically this new mode may increase the speed
                                    in case of a big number of active users. It isn't
                                    properly tested yet, so for production use default
                                    mode is recommended.
      Cache_Records            -    The number of records to read into the cache
      Max_Vars_Number = 10000  -    Maximum number of shared variables
      Max_Var_Size = 10000     -    Maximim size of a text variable
      Trigger = <cFuncName>    -    Global function letodb RDDI_TRIGGER
      PendingTrigger = <cFuncName>- Global function letodb RDDI_PENDINGTRIGGER
      Tables_Max  = 5000       -    Number of tables
      Users_Max = 500          -    Number of users
      Debug = 0                -    Debug level
      Optimize = 0             -    if 1, SET HARDCOMMIT OFF
      AutOrder = 0             -    SET AUTORDER setting
      ForceOpt = 0             -    _SET_FORCEOPT setting

      It is possible to define [DATABASE] structure if you need to have a
directory, where files are opened via other RDD:

      [DATABASE]
      DataPath =               -    (mandatory option)
      Driver = CDX             -    ( CDX/NTX )

      You can define as many [DATABASE] sections, as needed.

      In Windows environment the letodb.ini must be placed in a directory, from
where server is started.
      In Linux the program looks for it in the directory from where the server
is started and, if unsuccessfully, in the /etc directory.

      4.2 Authentication

      To turn authentication subsystem on you need to set one of the following
letodb.ini parameters to 1: Pass_for_Login, Pass_for_Manage, Pass_for_Data. But before
you need to create, at least, one user with admin rights, because when authentication
subsystem works, only authenticated users with admin rights are able to add/change users
and passwords.
      To add a user, you need to include a call of LETO_USERADD() in your client side
program, for example:

      LETO_USERADD( "admin", "secret:)", "YYY" )

where "YYY" is a string, which gives rights to admin, manage and write access. You may
also use the utils/manager/console.prg program to set or change authentication data.

To connect to a server with an authentication data ( username and password ) you need to
use LETO_CONNECT() function.

      5. Features of work with the letodb server

      5.1 Connecting to the server from client programs

      To be able to connect to the server you need to link the rddleto library
to your aplication and add at start of a main source file two lines:

      REQUEST LETO
      RDDSETDEFAULT( "LETO" )

      To open a dbf file on a server, you need to write in a SET PATH TO
statement or in the USE command directly a path to the server in a standard
form //ip_address:port/data_path/file_name.

      If a 'DataPath' parameter of a server configuration file is set to a non
empty value, you need to designate not the full path to a file on the server,
but only a relative ( relatively the 'DataPath' ).
      For example, if the you need to open a file test.dbf, which is located on
a server 192.168.5.22 in a directory /data/mydir and the 'DataPath' parameter
value ( of a letodb.ini server configuration file ) is '/data', the syntax
will be the following:

      USE "//192.168.5.22:2812/mydir/test"

      If the server doesn't run or you write a wrong path, you'll get open error.
It is possible to check accessibility of a server before opening files by using
the leto_Connect( cAddress ) function, which returns -1 in case of unsuccessful
attempt:

      IF leto_Connect( "//192.168.5.22:2812/mydir/" ) == -1
         Alert( "Can't connect to server ..." )
      ENDIF

     At connection with the server the client send to it information about codepage,
which the server then uses for operations of indexation, a filtration and for some
other operations. The client codepage should be established before connection with
the letodb server.

      5.2 Filters

      The filter is established usually: by the SET FILTER TO command or by a call
dbSetFilter() function. The filter which can be executed on the server, is called optimized.
If the filter can't be executed on the server, it is not optimized. Such filter
is slow as from the server all records, which are all the same requested then
are filtered on the client. To set the optimized filter, it is necessary, that in logical
expression for the filter there were no variables or the functions defined on the client.
To check, whether the filter is optimized, it is necessary to caall the LETO_ISFLTOPTIM()
function.

      6. Variables management

      Letodb allows to manage variables, which are shared between applications, connected
to the server. Variables are separated into groups and may be of logical, integer or
character type. You can set a variable, get it, delete or increment/decrement
( numerical, of course ). All operations on variables are performed consecutively by
one thread, so the variables may work as semaphores. See the functions list for a syntax
of appropriate functions and tests/test_var.prg for a sample.
      Letodb.ini may contain lines to determine the maximum number of variables and a
maximum size of a text variable.

      7. Functions list

      7.1 Connection management functions

      Below is a full ( at least, for the moment I write it ) list of functions,
available for using in client applications with RDD LETO linked.

      LETO_CONNECT( cAddress, [ cUserName ], [ cPassword ], [ nTimeOut ], [ nBufRefreshTime ] )
                                                           --> nConnection, -1 if failed
nBufRefreshTime defines the time interval in 0.01 sec. After this
time is up, the records buffer must be refreshed, 100 by default (1 sec)

      LETO_CONNECT_ERR()                                   --> nError
      LETO_DISCONNECT( [ cConnString | nConnection ] )     --> nil
      LETO_SETCURRENTCONNECTION( nConnection )             --> nil
      LETO_GETCURRENTCONNECTION()                          --> nConnection
      LETO_GETSERVERVERSION()                              --> cVersion
      LETO_GETLOCALIP()                                    --> IP address of client station
      LETO_ADDCDPTRANSLATE(cClientCdp, cServerCdp )        --> nil
      LETO_PATH( [<cPath>], [cConnString | nConnection] )  --> cOldPath

      7.2 Transaction functions

      LETO_BEGINTRANSACTION( [ nBlockLen ] )
Parameter <nBlockLen> can be used for set memory allocation block size.
For big transaction it can improve transaction speed at the client side.

      LETO_ROLLBACK()

      LETO_COMMITTRANSACTION( [ lUnlockAll ] )             --> lSuccess

      LETO_INTRANSACTION()                                 --> lTransactionActive

      7.3 Additional functions for current workarea

      LETO_COMMIT()
This function can be used for current workarea instead of calls:

dbCommit()
dbUnlock()

The client sends to the server 3 packages: for record updating
on the server, for commit record and area unlock. Leto_Commit sends
only one package for all these operations

      LETO_SUM( <cFieldNames>|<cExpr>, [ cFilter ], [xScope], [xScopeBottom] )
                                                           --> nSumma if one field or expression passed, or
                                                               {nSumma1, nSumma2, ...} for several fields
The first parameter of leto_sum if comma separated fields or expressions:
leto_sum("Sum1,Sum2", cFilter, cScopeTop, cScopeBottom) return
an array with values of sum fields Sum1 and Sum2.

If "#" symbol passed as field name, leto_sum returns a count of
evaluated records, f.e:
leto_sum("Sum1,Sum2,Sum1+Sum2,#", cFilter, cScopeTop, cScopeBottom) -->
{nSum1, nSum2, nSum3, nCount}

  If only one field name or expression is passed, leto_sum() returns a numeric value

      LETO_GROUPBY(cGroup, <cFields>|<cExpr>, [cFilter], [xScopeTop], [xScopeBottom]) --> aValues
                                                               {{xGroup1, nSumma1, nSumma2, ...}, ...}

This function return two-dimensional array. The first element of each row is
a value of <cGroup> field, elements from 2 - sum of comma separated fields or
expressions, represented in <cFields>. If "#" symbol passed as field name in cFields,
leto_groupby return a count of evaluated records in each group

      LETO_ISFLTOPTIM()                                    --> lFilterOptimized

      dbInfo( DBI_BUFREFRESHTIME[, nNewVal])               --> nOldVal
  Setting new value for area skip and seek buffers refresh time in 0.01 sec.
  If -1: using connection setting. If 0 - buffers are used anyway.

      dbInfo( DBI_CLEARBUFFER )
  This command cleared skip buffer.

      7.4 Additional rdd functions

      leto_CloseAll( [ cConnString | nConnection ] )       --> nil
Close all workareas for specified or default connection

      7.5 Setting client paramenter

      LETO_SETSKIPBUFFER( nSkip )                          --> nCount (buffer statistic using)
This buffer is intended for optimization of multiple calls of skip.
This function set size in records of skip buffer for current workarea.
By default, the size of skip buffer is 10 records. Skip buffer is bidirectional.
Skip buffer is refreshed after BUFF_REFRESH_TIME (1 sec)
If parameter <nSkip> is absent, function returns bufferr statictic (number of buffer shooting)

      LETO_SETSEEKBUFFER( nRecsInBuf )                     --> nCount (buffer statistic using)
This buffer is intended for optimization of multiple calls of seek.
This function set size in records of seek buffer for current index order.
If record is found in seek buffer on dbSeek(), it's not loaded from server.
Like skip buffer, seek buffer is refreshed after BUFF_REFRESH_TIME (1 sec)
If parameter <nRecsInBuf> is absent, function returns bufferr statictic
(number of buffer shooting)
By default, seek buffer is turned off.

      LETO_SETFASTAPPEND( lFastAppend )                    --> lFastAppend (previous value)
If the fast append mode isn't set, record is added on the server at once
after a dbAppend() function call. If this mode is set, record is added
by dbCommit() call, or after a call of functions of navigation. By default
a mode fast append isn't set. The switch working on all workareas.

      RddInfo( RDDI_REFRESHCOUNT, <lSet>,, [nConnection] )
By default, the RDDI_REFRESHCOUNT flag is set to true.  If this flag is set,
RecCount() function retrieve records count from server, if doesn't set -
use last value from server.  If other applications are appending records
to the table, new value of records count won't be immediately received.
If RDDI_REFRESHCOUNT flag is cleared, dbGoto(0) cleared record buffer and
set eof and other flags instead of server request.

      RddInfo( RDDI_BUFKEYCOUNT, <lSet>,, [nConnection] )
By default, the RDDI_BUFKEYCOUNT flag is set to false.  If this flag isn't set,
ordKeyCount() function retrieve key count from server, if set -
use last value from server.

      RddInfo( RDDI_BUFKEYNO, <lSet>,, [nConnection] )
By default, the RDDI_BUFKEYNO flag is set to false.  If this flag isn't set,
ordKeyNo() function retrieve value from server, if set - use last value from server.

      7.6 File functions

The <cFileName> parameter of all file functions can contain a connection string
to the letodb server in a format:
//ip_address:port/data_path/file_name.
If the connection string is omitted, the current active connection is used:
/data_path/file_name.
All files is searching at the DataPath catalog on the server. The ".."
symbols are disabled.

      LETO_FILE( cFileName )                               --> lFileExists
Determine if file exist at the server, analog of File() function

      LETO_FERASE( cFileName )                             --> -1 if failed
Delete a file at the server.

      LETO_FRENAME( cFileName, cFileNewName )              --> -1 if failed
Rename a file: <cFileName> --> <cFileNewName>. <cFileNewName> should be without
connection string.

      LETO_MEMOREAD( cFileName )                           --> cStr
Returns the contents of file at the server as character string, analog of
MemoRead() function.

      Leto_MemoWrite( cFileName, cBuf )                    --> lSuccess
Writes a character string into a file at the server, analog of
MemoWrit() function.

      LETO_MAKEDIR( cDirName )                             --> -1 if failed
Creates a directory at the server

      LETO_FERROR()                                        --> nError
Returns an error code of last file function.

      Leto_FileRead( cFileName, nStart, nLen, @cBuf )      --> -1 if failed
Read a content of file at the server from <nStart> offset and <nLen> length

      Leto_FileWrite( cFileName, nStart, cBuf )            --> lSuccess
Write <cBuf> character string to a file at the server from <nStart> offset and <nLen> length

      Leto_FileSize( cFileName )                           --> -1 if failed
Returns a length of filt at the server

      Leto_Directory( cDir[, cAttr] )                      --> aDirectory
Returns a content of directory at the server in the same format as Directory() function

      7.7 Management functions

      LETO_MGGETINFO()                                     --> aInfo
This function returns parameters of current connection as 17-element array
of char type values:
1 - count of active users
2 - max count of users
3 - opened tables
4 - max opened tables
5 - time elapsed
6 - count of operations
7 - bytes sent
8 - bytes read
9 - opened indexes
10 - max opened indexes
11 - data path
12 - max day wait
13 - ulWait
14 - count of transactions
15 - count successfully of transactions
16 - current memory used
17 - max memory used

      LETO_MGGETUSERS( [<cTableId>|<nTable>] )                        --> aInfo
Function returns two-dimensional array, each row is info about user:
aInfo[i,1] - user number
aInfo[i,2] - ip address
aInfo[i,3] - net name of client
aInfo[i,4] - program name
aInfo[i,5] - timeout

      LETO_MGGETTABLES( [<cUserId>|<nUser>] )                         --> aInfo
Function returns two-dimensional array, each row is info about opened tables:
aInfo[i,1] - table number
aInfo[i,2] - table name

      LETO_MGGETTIME()                                     --> aDateTime
Function returns array {<dDate>, <nSeconds>}:
dDate - server date;
nSeconds - seconds after midnight.
Convert this values to datetime variable (Harbour):
hb_DTOT( aDateTime[1], aDateTime[2] )

      LETO_MGKILL( <nUser>|<cUserId> )
Kill user number <nUser>

      LETO_LOCKCONN( lOnOff )                              --> lSuccess
After leto_lockconn( .t. ) request new connections are blocked by server, until
leto_lockconn( .f. ) called

      LETO_LOCKLOCK( lOnOff, nSecs )                       --> lSuccess
This function wait until any updates are closed, commit all changes and
trying to lock server from any updates from clients.
It returns True, if lock is succesfull.

      7.8 User account management functions

      LETO_USERADD( cUserName, cPass [, cRights ] )        --> lSuccess
      LETO_USERPASSWD( cUserName, cPass )                  --> lSuccess
      LETO_USERRIGHTS( cUserName, cRights )                --> lSuccess
      LETO_USERFLUSH()                                     --> lSuccess
      LETO_USERGETRIGHTS()                                 --> cRights

      7.9 Server variable management functions

      LETO_VARSET( cGroupName, cVarName, xValue[, nFlags[, @xRetValue]] ) --> lSuccess

This function assign value <xValue> to variable <cVarName> from group <cGroupName>
Optional parameter <nFlags> defines function mode:
LETO_VCREAT    - if variable doesn't exist, it's created;
LETO_VOWN      - own user variable (free after user disconnect);
LETO_VDENYWR   - write deny for other users;
LETO_VDENYRD   - read deny for other users;
LETO_VPREVIOUS - retusn previos value to <xRetValue> parameter.

      LETO_VARGET( cGroupName, cVarName )                  --> xValue

Function return value of variable <cVarName> from group <cGroupName>

      LETO_VARINCR( cGroupName, cVarName )                 --> nValue

Function increment value of variable <cVarName> from group <cGroupName>

      LETO_VARDECR( cGroupName, cVarName )                 --> nValue

Function decrement value of variable <cVarName> from group <cGroupName>

      LETO_VARDEL( cGroupName, cVarName )                  --> lSuccess

Function delete variable <cVarName> from group <cGroupName>

      LETO_VARGETLIST( [cGroupName [, nMaxLen]] )          --> aList

Function return two-dimensional array with variables: { {<cVarName>, <value>}, ...}

      7.10 Calling udf-functions on the server

      LETO_UDF( cSeverFunc, xParam1, ... )                 --> xResult
This function is called from client application. A string
<cServerFunc> contains a server connection string and name
of udf function:
//ip_address:port/funcname
A <funcname> function should be defined on the letodb server.
The first parameter of udf function is nUserStru.
Udf function can return result (any type) to client.
Examples of udf-functions are in the tests/letoudf.prg

      LETO_UDFEXIST( cSeverFunc )                          --> lExist
leto_udfExist check the existance of udf-function at the letodb server.
<cSeverFunc> parameter is the same as for leto_udf().

      LETO_PARSEREC( cRecBuf )                             --> nil
This function is necessary for calling, if udf-function returns as
result the buffer of record which should be current after of it
works.

      LETO_PARSERECODRS( cRecBuf )                         --> nil
This function is necessary for calling to fill the skip-buffer as a result
of udf-function UDF_dbEval. After calling this function, the data from the
skip-buffer can be received by dbSkip() calls. See sample in comments for
UDF_dbEval() in tests/letoudf.prg

      7.11 Functions for bitmap filters

If letodb compiled with rdd BMDBFCDX/BMDBFNTX, then there is support
the following functions:

      LBM_DbGetFilterArray()                               --> aFilterRec
      LBM_DbSetFilterArray( aFilterRec )                   --> nil
      LBM_DbSetFilterArrayAdd( aFilterRec )                --> nil
      LBM_DbSetFilterArrayDel( aFilterRec )                --> nil

Purpose and the parameters of these functions is the same as for the
corresponding functions BM_*.

      LBM_DbSetFilter( [<xScope>], [<xScopeBottom>], [<cFilter>] ) -> nil
This function set bitmap filter by current index order and for condition,
defined in <xScope>, <xScopeBottom>, <cFilter> parameters.
The current record after LBM_DbSetFilter() is the first record satisfying
filter condition.

      8. Management utility

      There are two management utilities, GUI and console, the sources are in
utils/manage directory.

      GUI utility, manage.prg, is made with the HwGUI library. If you have HwGUI,
just write in the line 'set HWGUI_INSTALL=' in utils/manage/bld.bat a path
to your HwGUI directory and run the bld.bat, it will build manage.exe for you.
   
      For those, who doesn't use HwGUI, there is a console mode utility,
console.prg. Build a console.exe with a make/bat files, which you use to build
Harbour single-file programs, you just need to add rddleto.lib to the libraries
list. Run the console.exe with a server name or ip and port as a parameter:

      console.exe server_name:nPort
      console.exe ip_address:nPort

The server_name and ip_address in a command line must be without leading
slashes ( '//' ), because Clipper/Harbour interprets them in a special way.

      9. Server-side functions

      These functions can be run from the client by function leto_udf,
and also from the functions defined in a file letoudf.hrb.
The first parameter such function always nUserStru

      leto_Alias( nUserStru, cClientAlias )                --> cRealAlias
This function return server alias for client alias <cClientAlias>.
The server alias then can be user in usial rdd-operations

      leto_RecLock( nUserStru [, nRecord] )                --> lSuccess
  leto_Reclock function locked record with <nRecord> number, or a current record.

      leto_RecUnLock( nUserStru [, nRecord] )              --> Nil
  leto_RecUnlock function unlocked record with <nRecord> number, or a current
  record.

      leto_RecLockList( nUserStru, aRecNo )                --> lSuccess
  leto_ReclockList function locked records with number in the <aRecNo> array.
  If any record isn't locked, all records are unlocked, and function returns
  .F. result.
  This function can be used at the server from letoodf.prg module, or from
  client by a call leto_UDF( "leto_RecLockList", aRecNo ).

      leto_TableLock( <nUserStru>, [<nFlag>], [<Secs>])    --> lSuccess
      leto_TableUnLock( <nUserStru>, [<nFlag>])

      nFlag - parameter from 1 to 32, nSecs - seconds for wait locking (1 by default)
      These functions are intended for concurrent access to the table for
      actions except updating of the data.

      leto_SelectArea( nUserStru, nAreaId )                --> lSuccess

      leto_areaID( nUserStru )                             --> nAreaId
Function return internal id of current workarea

      letoUseArea( nUserStru, cFileName, cAlias, lShared, lReadOnly, cdp ) --> nAreaId
      letoOrdListAdd( nUserStru, cBagName )                --> Nil
      letoOrdCreate( nUserStru, cBagName, cKey, cTagName,
                     lUnique, cFor, cWhile, lAll, nRecNo,
                     nNext, lRest, lDesc, lCustom,
                     lAdditive )                           --> Nil
      letoCloseArea( nUserStru )                           --> Nil

The functions letoUseArea, letoOrdListAdd, letoOrdCreate, letoCloseArea,
leto_RecLock, leto_RecLock is intended for using in udf-functions instead
of rdd functions: dbUseArea, OrdListAdd, OrdCreate, dbCloseArea, RLock, dbUnlock

      LETO_VARSET( nUserStru, cGroupName, cVarName, xValue[, nFlags )
                                                           --> lSuccess
      LETO_VARGET( nUserStru, cGroupName, cVarName )       --> xValue
      LETO_VARINCR( nUserStru, cGroupName, cVarName )      --> nValue
      LETO_VARDECR( nUserStru, cGroupName, cVarName )      --> nValue
      LETO_VARDEL( nUserStru, cGroupName, cVarName )       --> lSuccess
      LETO_VARGETLIST( nUserStru, [cGroupName, [lValue]] ) --> aList



Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jun 2014 08:43
por Minduim
caro Itamar, bom dia para todos nós;

agradeço sua colaboração;

creio que entendi suas observações;

entendo que terei re-escrever grande parte do dos meus .prg;

bem, mãos a obra;

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jun 2014 15:15
por Minduim
Itamar;
em harbour utilizo a função hb_DirExist() para verificar se um diretório existe;

ao tentar criar uma rotina em Letodb com a função Leto_Directory() para fazer esta verificação, noto que o retorno da função é
sempre o mesmo, independente do parametro utilizado;

estou fazendo algo errado?, tem outra opção?

arquivo teste.prg
********************************
Function Main
LOCAL cPath, aDir

REQUEST LETO
RDDSETDEFAULT( "LETO" )

cPath := "//127.0.0.1:2812/"
@  1, 2 say "Leto_Directory( cPaTH, cParam )    Arquivos"

aDir:= Leto_Directory( cPath )
@  2, 2 say "cParam = ' '" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "D" )
@  3, 2 say "cParam = 'D'" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "H" )
@  4, 2 say "cParam = 'H'" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "S" )
@  5, 2 say "cParam = 'S'" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "V" )
@  6, 2 say "cParam = 'V'" + space(25) + str(len( aDir ), 6)

inkey(0)

return .T.
//Fim

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jun 2014 17:18
por Itamar M. Lins Jr.
Tem um BUG na leto_directory()
Só está vindo os arquivos. Não vem as subpastas.
Já mandei em email, vamos aguardar a resposta.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Jun 2014 15:56
por filizola
Itamar, seguindo os seus passos. acontece este erro.

Pode me ajudar ?

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Jun 2014 18:01
por Itamar M. Lins Jr.
Ola!
Pulou algo na leitura.
O hbmk2 não achou a lib rddleto!
Volte 3 casas. E leia novamente sobre o arquivo hbmk.hbm!
Quando postar coloque o conteúdo do seu arquivo acesso.hbp
Seguiu esses passos ?
http://www.pctoledo.com.br/forum/viewtopic.php?f=42&t=15108&start=15#p88946

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 12 Jun 2014 15:17
por filizola
Desculpe mas realmente estou voltando os olhos para o letodb agora.

o make_b32.bat nao roda -> "make' nao e conhecido como um comando interno ou externo.

compilando diretamente os arquivos de extensao .hbp ger a extensaõ .a na pasta lib

utilizo o harbour nigthly (32)

conteudo do meu arquivo acesso.hbp

letodb.hbc
acesso.prg

conteudo do meu arquivo letodb.hbc

{win}incpaths=c:\letodb\include;
{win}libpaths=c:\letodb\lib;

{win}libs=rddleto

Desde já, agradeço

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Jun 2014 09:31
por Minduim
Itamar, bom dias a todos nós;

em harbour me utilizo da função SetFAttr() para modificar o atributo de um arquivo oculto de disco, para que as funções de tratamento de arquivo possam visualizá-lo;
- se o arquivo esta oculto ( atributo 'H' ), executo:
SetFAttr( arquivo, 0 ) // modifica o atributo para: sem atributo
- o arquivo esta visível para a funções de tratamento de arquivo;
- faço as operações necessárias e executo:
SetFAttr( arquivo, 2 ) // modifica o atributo para: oculto

como as funções LETO são análogas as do harbour, entendo que também terei que modificar os atributos do arquivo para ficarem visíveis para as funções do LETO, mas não encontrei uma função em LETO que trabalhe este parâmetro;
também não posso testar esta teoria enquanto a função LETO_DIRECTORY() não for corrigida;

alguma luz?

arquivo teste
********************************
Function Main
LOCAL cPath, aDir, cArq, cRet

REQUEST LETO
RDDSETDEFAULT( "LETO" )

cPath:= "//127.0.0.1:2812/"
cArq:= "TESTE.TXT" // arquivo com atributo 'H' (hidden/oculto)

aDir:= Leto_Directory( cPath, "H" )

if len( aDir ) > 0 .AND. ascan( aDir, { |_a| Upper( alltrim( _a[1] ) ) == cArq } ) > 0

  cRet:= Leto_MemoRead( cPath + cArq )

else

   cRet:= "ARQUIVO NAO ENCONTRADO"

endif

@  0, 0 say cRet
inkey(0)

return .T.


em tempo: também não encontrei uma função em LETO para a função em harbour "HB_DISKSPACE()"

LetoDb e Harbour, como usar.

MensagemEnviado: 17 Jun 2014 11:12
por Minduim
Itamar, bom dia a todos nós;

creio que identifiquei mais um erro na função LETO_DIRECTORY();

se chamamos a função em outro diretório que o padrão, este outro diretório existe e com um nome de pesquisa com mais de 11 caracteres aparece o erro na execução;

arquivo teste
********************************
Function Main
LOCAL cPath, aDir

REQUEST LETO
RDDSETDEFAULT( "LETO" )

cPath := "//127.0.0.1:2812/teste/xxxxxxxx.xxx"

@  1, 2 say "Leto_Directory( cPaTH, cParam )    Arquivos"

aDir:= Leto_Directory( cPath )
@  2, 2 say "cParam = ' '" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "D" )
@  3, 2 say "cParam = 'D'" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "H" )
@  4, 2 say "cParam = 'H'" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "S" )
@  5, 2 say "cParam = 'S'" + space(25) + str(len( aDir ), 6)

aDir:= Leto_Directory( cPath, "V" )
@  6, 2 say "cParam = 'V'" + space(25) + str(len( aDir ), 6)

inkey(0)

return .T.

LetoDb e Harbour, como usar.

MensagemEnviado: 18 Jun 2014 19:30
por Toledo
Amigos, teria como incluir no LetoDb alguma função para retornar informações sobre o servidor, como: versão do Sistema Operacional, número de serie do HD, data e hora no servidor,etc?

Outra dúvida, existe algum site onde se pode baixar a última versão do LetoDb já compilados para Windows e/ou Linux?

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 19 Jun 2014 08:19
por Minduim
bom dia Toledo;

não sei se sou a melhor fonte de informação para você, mas vou compartilhar minhas informações:

- estou utilizando a versão do site abaixo e creio que é a ultima versão disponibilizada:
http://sourceforge.net/projects/letodb/

-data e hora no servidor:
      LETO_MGGETTIME()                                     --> aDateTime
Function returns array {, }:
dDate - server date;
nSeconds - seconds after midnight.
Convert this values to datetime variable (Harbour):
hb_DTOT( aDateTime[1], aDateTime[2] )


das suas dúvidas, é só o tenho para compartilhar.

LetoDb e Harbour, como usar.

MensagemEnviado: 19 Jun 2014 09:30
por Toledo
Minduim escreveu:- estou utilizando a versão do site abaixo e creio que é a ultima versão disponibilizada:
http://sourceforge.net/projects/letodb/

Se você observar, esta versão é de 28/11/2012, então as atualizações feitas recentemente não estão neste binário.

Neste link tem a versão mais recente, com todas atualizações, mas é o código fonte. O que eu queria era se não tem algum site que já vem com o executável do LetoDb (atualizado) compilado para Windows e/ou Linux.
No caso das LIB's ai não tem jeito, tem que baixar o código fonte e compilar mesmo (veja como compilar aqui), mas o executável do LetoDb não importa como foi compilado. A versão para Windows fica até fácil compilar, mas uma versão Linux do LetoDb atualizada e já compilada seria muito bom.

Sobre a data e hora, muito obrigado!

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 23 Jun 2014 11:08
por Itamar M. Lins Jr.
Ola!
Amigos, teria como incluir no LetoDb alguma função para retornar informações sobre o servidor, como: versão do Sistema Operacional, número de serie do HD, data e hora no servidor,etc?

Data e hora:
   aDH := LETO_MGGETTIME()
   If DToS(aDH[1]) <> DToS(DATE())
      Hwg_MsgStop("Corrija a data do computador.")
      Leto_Commit()
      Close all
      Cancel
   EndIf

Sistema operacional, Numero de serie do HD, etc,etc...
Criar um arquivo de nome letoudf.prg e colocar dentro suas funções.
Veja o exemplo na pasta tests\letoudf.prg
/*  $Id: letoudf.prg,v 1.1.2.15 2013/03/21 18:53:35 ptsarenko Exp $  */

#include "dbinfo.ch"
#include "set.ch"

#ifdef __LINUX__
   #define DEF_SEP      '/'
   #define DEF_CH_SEP   '\'
#else
   #define DEF_SEP      '\'
   #define DEF_CH_SEP   '/'
#endif

/*
* File version
*/
FUNCTION UDF_Version
   RETURN "1.08"

FUNCTION UDF_Init
/*
* This function called immediately after loading letoudf.hrb, if exist
*/
   SET AUTORDER TO 1
   RETURN Nil

/*
* This sample function demonstrates how to use udf function on Letodb server
*
* Function Call from client:
*
* cRecBuf := Leto_Udf("UDF_AppendRec", <cFieldName>, [<cOrder>|<nOrder>], [<xMin>])
*
* The function return buffer of appended record. After call of Leto_ParseRec
*
* Leto_ParseRec( cRecBuf )
*
* Internal data of rddleto is filled from record buffer.
*/

FUNCTION UDF_AppendRec( nUserStru, cFieldName, xOrder, xMin )
   LOCAL nPos := FieldPos( cFieldName )
   LOCAL xKey, lApp, lOver := .F.

   IF ! Empty( xOrder )
      OrdSetFocus( xOrder )
   ENDIF
   IF leto_TableLock( nUserStru, 1 )

      dbGoBottom()
      xKey := FieldGet( nPos )
      IF Empty(xKey) .and. ! Empty(xMin)
         xKey := xMin
      ENDIF

      IF ValType( xKey ) == "N"
         xKey ++
         IF hb_FieldType(nPos) $ 'NF'
            lOver := xKey > Val( Replicate( "9", hb_FieldLen( nPos ) ) )
         ELSEIF hb_FieldLen( nPos ) == 2
            lOver := xKey > 0x7FFF
         ELSEIF hb_FieldLen( nPos ) == 4
            lOver := xKey > 0x7FFFFFFF
         ENDIF
      ELSEIF ValType( xKey ) == "C"
         xKey := StrZero( Val(xKey) + 1, Len(xKey) )
         lOver := (xKey = '*')
      ENDIF

      IF lOver
         lApp := .F.
      ELSE
         lApp := ( UDF_Append( nUserStru ) != Nil )
      ENDIF

      IF lApp
         FieldPut( nPos, xKey )
         dbCommit()
      ENDIF
      leto_TableUnLock( nUserStru, 1 )
   ELSE
      lApp := .F.
   ENDIF

   RETURN if( lApp, leto_rec( nUserStru ), Nil )

FUNCTION UDF_Append( nUserStru )
   LOCAL lApp, lSetDel

   lSetDel := Set( _SET_DELETED, .f. )
   dbGoTop()
   Set( _SET_DELETED, lSetDel )
   IF Deleted() .and. Empty( OrdKeyVal() )
      IF( lApp := leto_RecLock( nUserStru ) )
         dbRecall()
      ENDIF
   ELSE
      dbAppend()
      IF ( lApp := ! NetErr() )
         leto_RecLock( nUserStru, RecNo() )
      ENDIF
   ENDIF
   RETURN if( lApp, leto_rec( nUserStru ), Nil )

/*
* This sample function delete records on scope xScope, xScopeBottom and filter <cFilter>
*/
FUNCTION UDF_DeleteRecs( nUserStru, xScope, xScopeBottom, xOrder, cFilter, lDeleted )
   LOCAL aRecs := {}, n

   leto_SetEnv( xScope, xScopeBottom, xOrder, cFilter, lDeleted )
   dbEval({|| AADD(aRecs, RecNo())})
   leto_ClearEnv( xScope, xScopeBottom, cFilter )

   FOR EACH n in aRecs
      dbGoto(n)
      IF leto_RecLock( nUserStru, n )
         ClearRec()
         leto_RecUnlock( nUserStru, n )
      ENDIF
   NEXT
   dbCommit()

   RETURN leto_rec( nUserStru )

STATIC FUNCTION ClearRec
   LOCAL nCount := FCount(), nLoop, xValue

   dbDelete()
   FOR nLoop := 1 to nCount
      xValue := Nil
      SWITCH HB_FIELDTYPE( nLoop )
         CASE "C"
         CASE "M"
            xValue := ""
            EXIT
         CASE "N"
         CASE "F"
         CASE "I"
         CASE "Y"
         CASE "Z"
         CASE "2"
         CASE "4"
         CASE "8"
         CASE "B"
            xValue := 0
            EXIT
         CASE "L"
            xValue := .F.
            EXIT
         CASE "D"
         CASE "T"
            xValue := CTOD( "" )
            EXIT
      ENDSWITCH
      IF xValue != Nil
         FieldPut( nLoop, xValue )
      ENDIF
   NEXT
   RETURN Nil

/*
* UDF_UpdCascade - cascade update key fields in main and relation table
* Parameters:
*   nRecNo       - record number in the main table
*   cKeyField    - field name in the main table (primary key)
*   xKeyNew      - new value of key field
*   cClientAlias - client alias of the relation table
*   cKeyField2   - field name in the relation table (foreign key)
*   xOrder       - order name or order number in the relation table
*
* This function return array of record buffer in two tables
* Call from client:
*
* aRecBuf := Leto_Udf("UDF_UpdCascade", ... )
* (table1)->( leto_ParseRec( aRecBuf[1] ) )
* (table2)->( leto_ParseRec( aRecBuf[2] ) )
*/
FUNCTION UDF_UpdCascade( nUserStru, nRecNo, cKeyField, xKeyNew, cClientAlias, cKeyField2, xOrder )
   LOCAL xKeyOld, cLetoAlias, cArea := Alias()
   LOCAL nPos := FieldPos( cKeyField ), nPos2
   LOCAL cRecBuf1, cRecBuf2

   dbGoto( nRecNo )
   xKeyOld := FieldGet( nPos )
   IF xKeyOld != xKeyNew .and. leto_RecLock( nUserStru, nRecNo )
      FieldPut( nPos, xKeyNew )
      leto_RecUnlock( nUserStru, nRecNo )
      cRecBuf1 := leto_rec( nUserStru )

      cLetoAlias := leto_Alias( nUserStru, cClientAlias )
      dbSelectArea( cLetoAlias )
      IF Empty( cKeyField2 )
         cKeyField2 := cKeyField
      ENDIF
      nPos2 := FieldPos( cKeyField2 )
      IF ! Empty( xOrder )
         ordSetFocus( xOrder )
      ENDIF
      WHILE dbSeek( xKeyOld )
         IF leto_RecLock( nUserStru, RecNo() )
            FieldPut( nPos2, xKeyNew )
            leto_RecUnlock( nUserStru, RecNo() )
         ELSE
            EXIT
         ENDIF
      ENDDO
      dbSeek( xKeyNew )
      cRecBuf2 := leto_rec( nUserStru )

      dbSelectArea( cArea )

   ENDIF
   RETURN { cRecBuf1, cRecBuf2 }

/*
* UDF_FilesExist - check files existence at the specified path
* Parameters:
* cPaths - list of directories, delimited with comma
* aFiles - array of filenames without path to check
*
* This function return array of path for each file or "-" symbol,
* if file doesn't exist
*/
FUNCTION UDF_FilesExist( nUserStru, cPaths, aFiles)
   LOCAL aRet := {}, cFile, lFound, cPath
   LOCAL cDataPath := leto_GetAppOptions( 1 )
   LOCAL aPath := leto_getPath( cPaths )

   for each cFile in aFiles
      lFound := .f.
      for each cPath in aPath
         if File( StrTran( cDataPath + cPath + cFile, DEF_CH_SEP, DEF_SEP ) )
            AADD( aRet, cPath )
            lFound := .t.
            exit
         endif
      next
      if ! lFound
         AADD( aRet, "-" )
      endif
   next

   RETURN aRet

STATIC FUNCTION leto_getPath( cPaths )
   LOCAL aPath := hb_ATokens( cPaths, "," ), nI
   for nI := 1 to len( aPath )
      if ! ( Right( aPath[ nI ], 1) $ DEF_CH_SEP + DEF_SEP )
         aPath[ nI ] += DEF_CH_SEP
      endif
   next
   RETURN aPath

/*
* UDF_Locate function locate record on scope xScope, xScopeBottom and filter <cFilter>
   If lLast parameter specified, function locate the last occurence of record.
   If record isn't found, UDF_Locate returns eof() value.
*/
FUNCTION UDF_Locate( nUserStru, xScope, xScopeBottom, xOrder, cFilter, lDeleted, lLast )

   leto_SetEnv( xScope, xScopeBottom, xOrder, cFilter, lDeleted )

   IF lLast == Nil
      GO TOP
   else
      GO BOTTOM
   endif

   leto_ClearEnv( xScope, xScopeBottom, cFilter )

   RETURN leto_rec( nUserStru )

/*
* UDF_dbEval function returns buffer with records by order <xOrder>, and for condition,
* defined in <xScope>, <xScopeBottom>, <cFilter>, <lDeleted> parameters
* Function call from client:
   
   leto_ParseRecords( leto_Udf('UDF_dbEval', <xScope>, <xScopeBottom>, <xOrder>, <cFilter>, <lDeleted> ) )
   while ! eof()
      ...
      skip
   enddo
   dbInfo( DBI_CLEARBUFFER )

*/
FUNCTION UDF_dbEval( nUserStru, xScope, xScopeBottom, xOrder, cFilter, lDeleted )
   LOCAL cRecs

   leto_SetEnv( xScope, xScopeBottom, xOrder, cFilter, lDeleted )
   GO TOP
   cRecs := leto_dbEval( nUserStru )
   leto_ClearEnv( xScope, xScopeBottom, cFilter )

   RETURN cRecs

FUNCTION UDF_Trans( nUserStru, cTo )
/*
* UDF_Trans copy all records from current area to area with <cTo> client alias
   with conversion between numeric and character fields.
*/
   LOCAL cArea := Alias()
   LOCAL cAliasTo := leto_Alias( nUserStru, cTo )
   LOCAL lSetDel
   LOCAL lRes := .T., oError

   dbSelectArea( cArea )
   IF ! Empty( cAliasTo )
      lSetDel := Set( _SET_DELETED, .f. )
      BEGIN SEQUENCE WITH { |e|break( e ) }
         OrdSetFocus( 0 )
         GO TOP
         WHILE ! eof()
            UDF_TransRec( cAliasTo )
            SKIP
         ENDDO
         (cAliasTo)->(dbCommit())
      RECOVER USING oError
         WrLog('UDF_Trans error: ' + cArea + '-->' + cTo + ' ' +;
oError:description + if(!Empty(oError:operation), ':' + oError:operation,'') +;
' recno ' + LTrim(Str(RecNo())))
         lRes := .F.
      END SEQUENCE
      Set( _SET_DELETED, lSetDel )
   ENDIF
   RETURN lRes

STATIC FUNCTION UDF_TransRec( cAliasTo )
   LOCAL nPos1, nPos2, xVal, cFName, ct1, ct2

   (cAliasTo)->( dbAppend() )
   IF ! NetErr()
      FOR nPos1 := 1 to FCount()
         cFName := FieldName( nPos1 )
         IF (nPos2 := (cAliasTo)->(FieldPos(cFName))) # 0 .and. ! (cAliasTo)->(hb_FieldType(nPos2)) $ '+^'
            xVal := (cAliasTo)->(FieldGet(nPos2))
            ct2 := ValType( xVal )
            xVal := FieldGet( nPos1 )
            IF ! Empty( xVal )
               ct1 := ValType( xVal )
               IF ct2 = ct1
                  IF ct1 == "C"
                     xVal := RTrim( xVal )
                  ENDIF
                  (cAliasTo)->(FieldPut( nPos2, xVal ))
               ELSEIF ct1 = 'C' .and. ct2 = 'N'
                  (cAliasTo)->(FieldPut( nPos2, Val(xVal)))
               ELSEIF ct1 = 'N' .and. ct2 = 'C'
                  (cAliasTo)->(FieldPut( nPos2, Str(xVal, hb_FieldLen(nPos2), hb_FieldDec(nPos2))))
               ENDIF
            ENDIF
         ENDIF
      NEXT
      IF Deleted()
         (cAliasTo)->( dbDelete() )
      ENDIF
   ENDIF
   RETURN Nil

FUNCTION UDF_OpenTables( nUserStru, aTables, cPaths )
/*
* UDF_OpenTables open a tables, described in aTables array,
   and return to client an array with structure of opened tables
   Each table described with array of (at least) 1 to 5 elements:
   {<cFileName>, [<cAlias>], [<lShared>], [<lReadOnly>], [<cdp>]}
   Tables are opened on the server by one request from the client,
   the server returns information on open tables in the array,
   and then elements of array is transferred to the "use" command.
   The "use" command opens tables without the request to the server.
   The <alias> in the "use" command is mandatory parameter.

   Example of usage UDF_OpenTables from client:

   if leto_UDFExist( "UDF_OpenTables" )

      aAreas := leto_UDF( ""UDF_OpenTables"", {{"table1",, .t.}, {"table2",, .t.}, {"table3",, .t.}} )
      use (aAreas[1]) alias table1 shared new
      use (aAreas[2]) alias table2 shared new
      use (aAreas[3]) alias table3 shared new

   else

      use table1 alias table1 shared new
      use table2 alias table2 shared new
      use table3 alias table3 shared new

   endif

*/
   LOCAL aOpen := {}, aItem, nLen, cTable
   LOCAL cDataPath, aPath, cPath, cOpen

   IF cPaths != nil
      cDataPath := leto_GetAppOptions( 1 )
      aPath := leto_getPath( cPaths )
   ENDIF

   FOR EACH aItem IN aTables
      cTable := aItem[1]
      IF ! Empty( aPath )
         FOR EACH cPath IN aPath
            IF File( StrTran( cDataPath + cPath + cTable + ".dbf", DEF_CH_SEP, DEF_SEP ) )
               cTable := cPath + cTable
               exit
            ENDIF
         NEXT
      ENDIF
      nLen := len( aItem )
      cOpen := leto_Use( nUserStru, cTable,;
                         IIF( nLen >=2, aItem[2], ),;
                         IIF( nLen >=3, aItem[3], ),;
                         IIF( nLen >=4, aItem[4], ),;
                         IIF( nLen >=5, aItem[5], ) )
      AADD( aOpen, "+" + cTable + ";" + Substr( cOpen, Asc( Left( cOpen, 1 ) ) + 2 ) )
   NEXT

   RETURN aOpen


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 23 Jun 2014 11:25
por Itamar M. Lins Jr.
Ola!
Foi corrigido o BUG do leto_directory

2014-06-20 17:20 UTC+0300 Pavel Tsarenko (tpe2/at/mail.ru)
* source/server/server.prg
* reverted last change
* source/client/leto1.c
* checking for empty tag name moved to the client side

2014-06-19 18:25 UTC+0300 Pavel Tsarenko (tpe2/at/mail.ru)
* source/client/letomgmn.c
! fixed typo in LETO_DIRECTORY()

2014-06-17 17:40 UTC+0300 Pavel Tsarenko (tpe2/at/mail.ru)
* source/server/server.prg
* allow empty tag name in index creation, for compatibility with DBFCDX


Anexo letodb atualizado.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Jun 2014 10:39
por Toledo
Itamar, obrigado pela informação, já criei o meu arquivo letoudf.prg com as funções que eu precisava. Deu um pouco de trabalho para entender como iria funcionar estas novas funções com o server letodb, mas consegui, deu certo.

Então, para quem precisar que o server letodb execute alguma função específica, segue o que tem que ser feito:

1 - Crie o seu arquivo letoudf.prg com as funções que você precisa, veja modelo que está em \tests\letoudf.prg.

2 - Compile o arquivo letoudf.prg da seguinte forma:

harbour letoudf.prg -gh -n -w -i\hb32\include

3 - No comando acima será criado o arquivo letoudf.hrb, que você deve copiar para a pasta \BIN do LetoDb.

4 - Abra o arquivo server.prg que está na pasta \source\server do LetoDb e observe que no início deste arquivo existe vários comandos REQUEST chamando várias funções do Harbour. Então verifique se as funções do Harbour, que você usou nas funções que você criou no arquivo letoudf.prg, estão relacionadas em um destes REQUEST. As funções que não estiverem, você terá então que incluir em algum destes REQUEST.

Então, se você incluiu alguma função no REQUEST, você terá que compilar novamente o LetoDb, para isto basta entrar na pasta do LetoDb e digitar:

hbmk2 letodb.hbp

Atenção: se for necessário, você terá que incluir no arquivo letodb.hbp as LIB's que tem as funções que foram incluídas no REQUEST. Por exemplo, se no arquivo letoudf.prg você usou alguma função que está na LIB hbct e incluiu esta função lá no REQUEST do server.prg, então no arquivo letodb.hbp você terá que incluir uma linha com: -lhbct

5 - No seu programa para chamar as funções que você criou no letoudf.prg, use a seguinte função:
PathServ   :=  "//localhost:2812/"
cRet := Leto_Udf(PathServ+"UDF_NomeFunc",param1,...)

A expressão UDF_NomeFunc é o nome da função que você quer executar.
A expressão ,param1,... são os parâmetros da função, se for necessário.

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Jun 2014 16:49
por Minduim
Toledo, muito boas as suas explicações e obrigado por compartilhar a utilização do arquivo letoudf;

Itamar;
agradeço sua atenção;

fiz os testes com as modificações do letodb;
a função "Leto_DirExist" entendo que esta ok;
mas percebo que a função "Leto_Directory" ainda não esta retornando corretamente conforme os parametros;


arquivo teste
********************************
Function Main
LOCAL cPath, aDir

REQUEST LETO
RDDSETDEFAULT( "LETO" )

cPath := "//127.0.0.1:2812/teste/"

if Leto_DirExist( cPath )
   @  1, 2 say "Leto_Directory( cPaTH, cParam )    Arquivos"

   aDir:= Leto_Directory( cPath )
   @  2, 2 say "cParam = ' '" + space(25) + str(len( aDir ), 6)

   aDir:= Leto_Directory( cPath, "D" )
   @  3, 2 say "cParam = 'D'" + space(25) + str(len( aDir ), 6)

   aDir:= Leto_Directory( cPath, "H" )
   @  4, 2 say "cParam = 'H'" + space(25) + str(len( aDir ), 6)

   aDir:= Leto_Directory( cPath, "S" )
   @  5, 2 say "cParam = 'S'" + space(25) + str(len( aDir ), 6)

   aDir:= Leto_Directory( cPath, "V" )
   @  6, 2 say "cParam = 'V'" + space(25) + str(len( aDir ), 6)
else
   @  1, 2 say "Diretorio " + cPath + " nao encontrado"
endif

inkey(0)

return .T.

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jun 2014 14:49
por Minduim
Itamar;

fiz um pequeno estudo da função 'directory' com e sem o 'leto';

na 'imagem 001' traz o retorno da função sem utilizar o 'leto';
observe que o retorno só é correto com a sintaxe 'disk:\', contrariando a informação do 'harbour' conforme a 'imagem 003';

na 'imagem 002' traz o retorno da função utilizando o 'leto';
observe que o retorno é sempre com se utilizando a sintaxe 'disk:';

Toledo;

no post anterior, entendo que você implementou a função 'volserial' no 'leto' de sua aplicação;
observe na 'imagem 001' e 'imagem 002' que o retorno da função é sempre em relação ao driver 'C';
você também observa isto ou estou fazendo algo errado?

arquivo letoudf
********************************
function UDF_VOLSERIAL( cLabel )

   return VolSerial( cLabel )

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jun 2014 15:17
por Toledo
Minduim escreveu:Toledo;

no post anterior, entendo que você implementou a função 'volserial' no 'leto' de sua aplicação;
observe na 'imagem 001' e 'imagem 002' que o retorno da função é sempre em relação ao driver 'C';
você também observa isto ou estou fazendo algo errado?

Amigo, nas funções que você criar no arquivo letoudf.prg, obrigatoriamente o primeiro parâmetro em cada função (mesmo que a função não tenha nenhum parâmetro) tem que ser nUserStru, então a sua função ficaria assim:
function UDF_VOLSERIAL( nUserStru, cLabel )

Agora, quando for chamar a função com Leto_Udf(), não precisar passar este parâmetro nUserStru, por exemplo:
PathServ   :=  "//localhost:2812/"
nSerial := Leto_Udf(PathServ+"UDF_VOLSERIAL","C:\")

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jun 2014 16:06
por Minduim
Toledo;

agradeço sua pronta atenção;
segue abaixo a 'imagem 002' corrida

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jun 2014 20:17
por Itamar M. Lins Jr.
Ola!
A função Leto_directory() só funciona no PATH do LetoDb. Só "enxerga" através do LetoDb.

Se no LetoDb está assim:
cPath := "//localhost:2812/MeuDB/"

Não adianta pedir p/ ele enxergar fora Leto_Directory("//localhost:2812/User/Documents/"...)

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jul 2014 10:26
por Minduim
bom dia colegas;

a implementação do letodb em meu sistema esta quase pronta;
agora estou tentando juntar os programas 'LETOTRAY.PRG' E 'MANAGE.PRG' que estão na pasta '\LETODB\UTILS' e estou encontrando alguma dificuldade;

1 - ao clicar em 'STAR SERVER', no arquivo de log aparece a mensagem:
LetoDB service has had some problems:       1063


2 - ao clicar em 'USERSINFO', apresenta a mensagem de erro:
Error BASE/1004  No exported method: HIDE
Called from ->HIDE(0)
Called from letotray_manage.prg->USERSINFO(80)
Called from letotray_manage.prg->(b)MAIN(30)
Called from source\winapi\hwindow.prg->ONCOMMAND(528)
Called from source\winapi\hwindow.prg->(b)HMAINWINDOW(231)
Called from source\winapi\hwindow.prg->HMAINWINDOW:ONEVENT(317)
Called from ->HWG_ACTIVATEMAINWINDOW(0)
Called from source\winapi\hwindow.prg->HMAINWINDOW:ACTIVATE(306)
Called from letotray_manage.prg->MAIN(37)

HWGUI 2.18 Build 1
Date:07/03/14
Time:10:19:39


arquivo letotray+manage
#include "hwgcompat.ch"
#include "hbclass.ch"  // manage.prg
#include "hwgui.ch"  // manage.prg
#include "hxml.ch"  // manage.prg
#include "rddleto.ch"  // manage.prg

Static cPath
Static cIp := '127.0.0.1'
Static nPort := 2812

Function Main
Local oMainWindow, oTrayMenu, oIcon := HIcon():AddResource("ICON_1")
Private oApp  // manage.prg

   oApp := HApp():New() // manage.prg

   cPath := DiskName() + ":\" + CurDir() + "\"

   IF ! File( cPath + "letodb.exe" )
      MsgInfo("letodb.exe not found")
      Return nil
   ENDIF

   INIT WINDOW oMainWindow MAIN TITLE "LetoDB server"

   CONTEXT MENU oTrayMenu
      MENUITEM "Start letodb" ACTION StartServer()
      MENUITEM "Stop letodb"  ACTION StopServer()
      MENUITEM "UsersInfo"    ACTION UsersInfo( cIp )  // manage.prg
      SEPARATOR
      MENUITEM "Exit"         ACTION EndWindow()
   ENDMENU

   oMainWindow:InitTray( oIcon,, oTrayMenu, "LetoDB server" )

   ACTIVATE WINDOW oMainWindow NOSHOW
   oTrayMenu:End()
   Return Nil

Function StartServer
  ShellExecute( cPath + "letodb.exe",,, cPath )
  Return nil

Function StopServer
  ShellExecute( cPath + "letodb.exe",, "stop", cPath )
  Return nil

Static func Connect
   Return Leto_Connect("//" + cIp + ":" + LTrim(Str(nPort)) + "/") != -1

Static Function UsersInfo( cAddress )  // manage.prg
   oApp:nItemCurr := 0
   IF cAddress != Nil
      IF ( arr := GetIpFromPath( "//" + cAddress + "/" ) ) != Nil
         cIp := arr[1]
         nPort := arr[2]
         oApp:nItemCurr := Ascan( oApp:aServers, cIp )
      ENDIF     
   ENDIF

   INIT WINDOW oApp:oMainWnd MAIN TITLE "Server management utility" ;
     AT 200,0 SIZE 600,400 FONT HFont():Add( "Georgia",0,-15,,204 )

   InfoUsers()
   
   oApp:oBtnKill:Hide()
   IF oApp:nItemCurr > 0
      oApp:oCombo:SetItem( oApp:nItemCurr )
   ENDIF
   ACTIVATE WINDOW oApp:oMainWnd
   Return Nil

Static Function InfoUsers() // manage.prg
   Local aInfo, i, nUsers
   IF oApp:lSend
      oApp:nRequest = 2
      Return .T.
   ENDIF

   oApp:lSend := .T.
   IF ( aInfo := leto_MgGetUsers() ) == Nil
      oApp:lSend := .F.
      Return .F.
   ENDIF
   oApp:lSend := .F.

   oApp:oBtnLock:Hide()
   oApp:oBtnKill:Show()
   nUsers := Len( aInfo )
   oApp:oBrw1:aArray := Array( nUsers, 5 )
   FOR i := 1 TO nUsers
      oApp:oBrw1:aArray[i,4] := aInfo[i,1]
      oApp:oBrw1:aArray[i,1] := aInfo[i,2]
      oApp:oBrw1:aArray[i,2] := aInfo[i,3]
      oApp:oBrw1:aArray[i,3] := aInfo[i,4]
      oApp:oBrw1:aArray[i,5] := Padl(Ltrim(Str(Int((Val(aInfo[i,5])%86400)/3600))),2,'0') ;
         +":"+ Padl(Ltrim(Str(Int((Val(aInfo[i,5])%3600)/60))),2,'0') +":"+ ;
         Padl(Ltrim(Str(Int(Val(aInfo[i,5])%60))),2,'0')
   NEXT

   IF oApp:nInfoType != 2
      oApp:nInfoType := 2
      oApp:oBrw1:aColumns := {}
      oApp:oBrw1:AddColumn( HColumn():New( "Ip",{|v,o|o:aArray[o:nCurrent,1]},"C",16,0 ) )
      oApp:oBrw1:AddColumn( HColumn():New( "Host",{|v,o|o:aArray[o:nCurrent,2]},"C",18,0 ) )
      oApp:oBrw1:AddColumn( HColumn():New( "Module",{|v,o|o:aArray[o:nCurrent,3]},"C",18,0 ) )
      oApp:oBrw1:AddColumn( HColumn():New( "Timeout",{|v,o|o:aArray[o:nCurrent,5]},"C",15,0 ) )
      oApp:oBrw1:bPosChanged := Nil
      oApp:oBrw1:bPosChanged := {||Tables4User()}
      oApp:oBrw1:lChanged := .T.
      oApp:oBrw1:nCurrent := oApp:oBrw1:rowPos := 1
   ENDIF
   oApp:oBrw1:Refresh()
   Tables4User()
   Return .T.

Static Function Tables4User() // manage.prg
   Local aInfo, i, nTables
   IF !Empty( oApp:oBrw1:aArray ) .AND. ;
         Len( oApp:oBrw1:aArray ) >= oApp:oBrw1:nCurrent .AND. ;
         Valtype( oApp:oBrw1:aArray[oApp:oBrw1:nCurrent] ) == "A" .AND. ;
         Len( oApp:oBrw1:aArray[oApp:oBrw1:nCurrent] ) >= 4
      oApp:lSend := .T.
      IF ( aInfo := leto_MgGetTables( oApp:oBrw1:aArray[oApp:oBrw1:nCurrent,4] ) ) == Nil
         oApp:lSend := .F.
         oApp:oBrw2:aArray := {}
      ELSE
         oApp:lSend := .F.

         nTables := Len( aInfo )
         oApp:oBrw2:aArray := Array( nTables,2 )
         FOR i := 1 TO nTables
            oApp:oBrw2:aArray[i,2] := aInfo[i,1]
            oApp:oBrw2:aArray[i,1] := aInfo[i,2]
         NEXT
      ENDIF
   ELSE
      oApp:oBrw2:aArray := {}
   ENDIF

   IF oApp:oBrw2:aColumns == Nil .OR. Len(oApp:oBrw2:aColumns) == 3
      oApp:oBrw2:aColumns := {}
      oApp:oBrw2:AddColumn( HColumn():New( "Name",{|v,o|o:aArray[o:nCurrent,1]},"C",24,0 ) )
      oApp:oBrw2:lChanged := .T.
   ENDIF
   oApp:oBrw2:Refresh()
   Return Nil

Static Function GetIpFromPath( cPath ) // manage.prg
   Local nPos1, nPos2, nPos3, cSub
   IF Left( cPath,2 ) != "//" .OR. ( nPos1 := At( ":",cPath ) ) == 0
      Return Nil
   ENDIF
   cSub := Substr( cPath, nPos1 + 1 )
   nPos2 := At( "/",cSub )
   nPos3 := At( "\",cSub )
   IF nPos2 == 0 .AND. nPos3 == 0
      Return Nil
   ENDIF
   IF nPos2 == 0 .OR. ( nPos3 != 0 .AND. nPos3 < nPos2 )
      nPos2 := nPos3
   ENDIF
   nPos3 := Max( RAt( "/",cSub ), RAt( "\",cSub ) )
   Return { Substr(cPath,3,nPos1-3), Val(Left(cSub,nPos2-1)), Iif(nPos3==0,"",Substr(cSub,nPos2,nPos3-nPos2+1)) }

Static Function ReadOptions( oApp )  // manage.prg
   Local oOptions := HXMLDoc():Read( "manage.xml" )
   Local oNode, i1, cIp, cPort, cUser, cPass
   IF !Empty( oOptions ) .AND. !Empty( oOptions:aItems ) .AND. oOptions:aItems[1]:title == "init"
      FOR i1 := 1 TO Len( oOptions:aItems[1]:aItems )
         oNode := oOptions:aItems[1]:aItems[i1]
         IF oNode:title == "server"
            cIp := oNode:GetAttribute("ip")
            cPort := oNode:GetAttribute("port")
            cUser := oNode:GetAttribute("user")
            Aadd( oApp:aServers, cIp )
            Aadd( oApp:aParams, { Iif(cPort==Nil,"2812",cPort), cUser } )
         ENDIF
      NEXT
   ENDIF
   IF Empty( oApp:aServers )
      Aadd( oApp:aServers, "127.0.0.1" )
      Aadd( oApp:aParams, { "2812", Nil } )
   ENDIF
   Return Nil

CLASS HApp  // manage.prg
   DATA oMainWnd
   DATA oTool
   DATA oCombo
   DATA oGetPort
   DATA oGetRefr
   DATA oSayServer
   DATA oBtnGo
   DATA oBtnKill
   DATA oBtnLock
   DATA oBrw1
   DATA oBrw2
   DATA oSplit

   DATA aServers
   DATA aParams
   DATA nItemCurr  INIT 0
   DATA lUpdList   INIT .F.

   DATA oTimer
   DATA lSend      INIT .F.

   DATA nInfoType  INIT 0
   DATA nRequest   INIT 0

   DATA lLocked    INIT .F.

   METHOD New
ENDCLASS

METHOD New CLASS HApp  // manage.prg
   ::aServers := {}
   ::aParams  := {}
   ReadOptions( Self )
   Return Self


alguma luz?

LetoDb e Harbour, como usar.

MensagemEnviado: 03 Jul 2014 10:55
por filizola
Bom dia galera, consegui fazer rodar o leto, muito bom mesmo. porém em um cliente, quando tento instalar. "letodb install" o letodb.log vem com a ms "Error installing letodb service: 1073".

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Jul 2014 10:28
por filizola
resolvido. bastou eu desinstalar o letodb e pronto.

letodb uninstall

LetoDb e Harbour, como usar.

MensagemEnviado: 12 Jul 2014 11:26
por Minduim
Itamar bom dia;

esta faltando somente mais algumas pendências;

quanto ao erro abaixo, apresentado anteriormente, entendo que nenhum colega sabe resolver ou não passou por esta dificuldade;
LetoDB service has had some problems:       1063


agora, como configurar o comando 'SET PRINT TO';

se escrevo o comando: 'SET PRINT TO //127.0.0.1:2812/TEXTO.PRN', apresenta o erro:
'Error TERM/2014 Erro de Criação //127.0.0.1:2812/TEXTO.PRN (Dos Error 53)' // servidor não encontrado

se crio a função no arquivo letoudf.prg:
********************************
function UDF_SETPRINTER( nUserStru, cArq )

   if !Empty( cArq )
      Set Printer to ( cArq )
   else
      Set Printer to
   endif
   return Nil


e chamo pela função: 'Leto_Udf( "127.0.0.1.:2812/" + "UDF_SetPrinter", "TEXTO.PRN" )',
não apresenta mensagem de erro e o arquivo é criado;
mas ao gerar o relatório, o arquivo 'TEXTO.PRN' permanece vazio;

estou fazendo algo errado ou este comando não é compatível com o letodb?

observação: com mapeamento de rede, a rotina de impressão funciona perfeitamente;

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Jul 2014 16:46
por Minduim
em tempo;
terminei a fusão dos programas letotray e manage e fiz o primeiro teste de conexão fora da minha rede;
pedi para um colega, distante uns 100 km se conectar e funcionou perfeitamente;
verifiquei uns pequenos gargalos de processamento que terei que corrigir no meu aplicativo e ainda tentar (...) resolver as pendências do post anterior;
estou muito contente...

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Jul 2014 18:21
por Toledo
Amigos, estou tentando fazer um teste com o LetoDB com acesso remoto. Para isto, fiz um cadastro no noip e instalei o DUC do noip no meu computador. Executei ele, informei minha conta e senha, depois selecionei o host e tudo parece estar certo. Mas se tento dar um ping no endereço, nenhuma das tentativas da certo, são todas perdidas.

No meu modem (NET), tem um roteador (D-LINK Dir 600), então tentei configurar um Virtual Server para redirecionar a porta 2812 para o IP do computador onde está o letoDB, mas isto também não adiantou.

Pensei que poderia estar faltando instalar alguma coisa no computador onde está o DUC do noip, IIS por exemplo, mas no Painel de Controle não tem o IIS para fazer a instalação. O Windows é o 8 Pro.

A minha intenção é só fazer o acesso ao LetoDB, então o que mais tenho que fazer?

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Jul 2014 19:09
por filizola
insira o ip da maquina na "DMZ" e libera a porta 2812 no firewall e redirecione a porta 2812 para o ip.

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Jul 2014 20:33
por Toledo
Feito, mas continua na mesma... não consigo conexão com o LetoDB usando o endereço ou IP no meu noip.

O estranho, é que se eu abrir meu navegador (Firefox, Chrome, Opera,etc) e digitar o endereço do meu noip, abre o programa do roteador (D-LINK Dir 600).

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Jul 2014 20:55
por filizola
tente primeiro fazer uma conexao pelo mstsc so pra testar.

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 07:56
por Minduim
toledo, em meus testes, somente efetuei o registro da imagem em anexo no roteador e liberei a porta 2812 no firewall do windows;
entendo que o programa do seu roteador, se não é o mesmo, é muito parecido;
entendo também que o no-ip + duc associam o endereço de ip externo da maquina servidor a um endereço na internet;
exemplo: xxx.xx.xx.xxx => servidor.ddns.net;
assim o endereço na internet permanecera fixo, mas o ip externo do servidor sofrera alteração, e como a conexão com o letodb é feito pelo endereço de ip e não por um endereço na internet, ainda não entendi com utilizar este recurso para uma conexão estavel com o letodb;

espero ter ajudado o amigo;

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 09:24
por Itamar M. Lins Jr.
Ola!
Eu tenho feito isso, em muitas maquinas por aqui.
E é dessa forma que você está fazendo, não esqueça de liberar no FIREWALL o LetoDb, não use DMZ é perigoso.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 09:31
por filizola
Itamar, o problema é que eu não tinha utilizado o DMZ num roteador d-link e nao conseguia entrar na maquina. só depois de ter liberado o ip no dmz que funcionou. fiz bastante busca a respeito, e só assim consegui. o risco seria de ataques ?

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 09:34
por Itamar M. Lins Jr.
Isso!
Fica muito vulnerável.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 09:53
por Toledo
filizola escreveu:tente primeiro fazer uma conexao pelo mstsc so pra testar.

Bom, não sei se estou fazendo certo, tentei da seguinte forma:

mstsc /v:192.168.0.122:2812

Esta tentativa foi usando o IP do computador na rede local, mas deu a seguinte mensagem:
mstsc2.jpg


Depois tentei usando o IP externo que aparece no DUC do noip, que é o mesmo que aparece quando dou um ping no meu endereço do noip, e também tentei usando o endereço do meu noip, por exemplo:

mstsc /v:179.216.254.10:2812

ou

mstsc /v:pctoledo.noip.me:2812

Nas duas tentativas retornou:
mstsc.jpg


Minduim escreveu:somente efetuei o registro da imagem em anexo no roteador e liberei a porta 2812 no firewall do windows; entendo que o programa do seu roteador, se não é o mesmo, é muito parecido;

A versão do programa do roteador é outra, mas a configuração é bem parecida.
d_link.jpg


Mas continua na mesma, não consigo conectar usando o endereço ou IP do noip.

Uma dúvida, neste caso de conexão remota pelo noip, o sistema operacional do computador onde está o LetoDB tem que ser algum Windows Server ou pode ser Windows 8 (que é o meu caso)?

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 10:14
por Itamar M. Lins Jr.
Está errado ai via mstsc.
O terminal server usa 3389 a porta. A porta 2812 é do LetoDb.
Você está tentando conectar o terminal server na porta do letodb ! Nunca irá funcionar.

Para saber se o letodb está rodando Use:
Function Main
Local cServidor := "//192.168.0.122:2812/" //seuservidor.no-ip.info aqui!

      nConect := leto_Connect( cServidor )
      IF nConect == -1
          nRes := leto_Connect_Err()
         IF nRes == LETO_ERR_LOGIN
            hwg_MsgStop( "Falha ao Logar" )
         ELSEIF nRes == LETO_ERR_RECV
            hwg_MsgStop( "Error ao conectar" )
         ELSEIF nRes == LETO_ERR_SEND
            hwg_MsgStop( "Erro de envio" )
         ELSE
            hwg_MsgStop( "Não connectado ao servidor: " + cServidor )
         ENDIF
         Return .F.
      ENDIF

hwg_MsgInfo( "Conectado ao servidor: " + cServidor )
Leto_disconect()


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 10:22
por filizola
Exato. quando disse para tentar fazer uma conexão via mstsc é pela porta 3389, só pra ver se consegue chegar na máquina. porque se a maquina servidora estiver te bloqueando no mstsc, é muito provável que estará te bloqueando no letodb também.

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Jul 2014 10:32
por Minduim
toledo;
utilizo windows 7 e provedor net
os arquivos letodb.exe, leudbf.hrb e letodb.ini estão junto com os dbfs;
a chamada para iniciar o letldb_service tem que partir de onde esta o letodb.exe, caso você verifique no firewall do windows que o letodb_service foi iniciado em outro diretorio, desative o serviço e comece do zero ( no prompt do dos digite : sc delete letodb_service );
para iniciar o letodb_service, no prompt do dos ou um arquivo bat, digite:
letodb install
net start letodb_service

para desativar o letodb_service, no prompt do dos ou arquivo bat, digite:
letodb desconnect
net stop letodb_service

como postei anteriormente, ainda não aprendi a conectar/desconectar de outra forma;

espero ter ajudado o amigo;

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jul 2014 13:30
por Toledo
Itamar M. Lins Jr. escreveu:Para saber se o letodb está rodando Use:
...
Local cServidor := "//192.168.0.122:2812/" //seuservidor.no-ip.info aqui!

Itamar, se eu usar cServidor := "//192.168.0.122:2812/" funciona certinho. O problema é com o endereço do meu noip, assim cServidor := "//pctoledo.noip.me:2812/" não funciona de jeito nenhum.

filizola escreveu:Exato. quando disse para tentar fazer uma conexão via mstsc é pela porta 3389

Filizola, agora sim, consegui conectar usando: mstsc /v:192.168.0.122:3389, mas se tento com o endereço noip, ai não vai, continua apresentado a mensagem que postei na minha mensagem anterior.

Minduim escreveu:os arquivos letodb.exe, leudbf.hrb e letodb.ini estão junto com os dbfs;
a chamada para iniciar o letldb_service tem que partir de onde esta o letodb.exe, caso você verifique no firewall do windows que o letodb_service foi iniciado em outro diretorio, desative o serviço e comece do zero

A pasta para os DBF está em uma pasta diferente de onde o LetoDB estava instalado, então fiz a alteração para a mesma pasta do LetoDB.
Como disse acima, fazendo a conexão usando o IP local do computador onde está o LetoDB, funciona normal, tanto com os DBF na pasta do LetoDB ou em outra pasta qualquer. O problema é com o endereço do meu noip.

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jul 2014 15:52
por Itamar M. Lins Jr.
Tem que ver se o noip deixa pingar.
ping pctoledo.noip.me
Deve retorna apenas 1 com o ip depois voltam 2 ou 3 com falha é normal.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jul 2014 19:01
por Itamar M. Lins Jr.
Outo detalhe é que na própria maquina usando yxz.no-ip.info não funciona!!!
Tem que usar //localhost:2812/ ou o IP da placa de rede 192.168.X.XXX:2812

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Jul 2014 19:27
por Toledo
Amigos, pedi por MP para o Itamar fazer um teste no meu noip e deu tudo certo. Obrigado Itamar pela ajuda!

Itamar M. Lins Jr. escreveu:Outo detalhe é que na própria maquina usando yxz.no-ip.info não funciona!!!
Tem que usar //localhost:2812/ ou o IP da placa de rede 192.168.X.XXX:2812

Eu já tinha imaginado que seria assim, então os testes que fiz foram em outros micros na rede local, mas também pelo jeito não funciona.

Mas se os seus testes deu certo, ótimo. Depois vou fazer mais alguns testes usando um outro micro, fora da minha rede local.

Obrigado a todos pela ajuda.

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Jul 2014 16:18
por Toledo
Amigos, qual é o procedimento para abrir o DBF em modo compartilhado com o LetoDB?

DbUseArea(.T.,"LETO", PathLeto + "NOMES.DBF","Nomes", .T. )

Apenas isto ou tem que ser feito mais algum coisa? No INI do LetoDB por exemplo!

Qual o procedimento de uso dos comandos RLOCK, UNLOCK e COMMIT com o LetoDB? Todos estes comandos são necessários com o LetoDB em um Sistema Multiusuário?

Algum exemplo de como usar estes comandos para Incluir, Alterar e Excluir registros no DBF com o LetoDB.

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Jul 2014 17:31
por rochinha
Amiguinhos,

Algum exemplo de como usar estes comandos para Incluir, Alterar e Excluir registros no DBF com o LetoDB.


Tenho pra mim que se voce tem um aplicativo que faz acesso a .DBFs de forma padrão, tipo USE, APPEND, REPLACE, etc e voce deseja que este aplicativo acesse as tabelas via LetoDB a unica diferença reside no fato de que voce incluiu uma linha que faz a ligação do motor do LetoDB com as tabelas.

Depois o código deve correr da mesma forma que voce programou na sintaxe xBase.

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Ago 2014 11:54
por Dudu_XBase
Bom Dia Itamar.
Não sei o que falta conferi o passo a passo tá dando erro para "linkeditar" num tá achando a rdd leto e a criatura ta no diretório.....kkkkk

Rodo o hbmk2 testex.prg e dá o erro

Imagem
image free hosting

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Ago 2014 13:12
por janio
Dudu,

Meu letodb.hbc está assim:
{win}incpaths=c:\letodb\include;
{win}libpaths=c:\letodb\lib;

{win}libs=rddleto


Meu comp.hbp esta assim:

#---------------------------
# Nome do Execut vel
# ---------------------------
-oSysLoja
-run

# ---------------------------
# hbc
# ---------------------------

letodb.hbc

# ---------------------------
# Prg(s) e Rc(s)
# ---------------------------

menu.prg


compilo assim:

hbmk2 comp.hbp

Toledo,

Qndo passei a usar o leto, alterei minha função de abertura dos dbf's para:

******************************************
// usar assim: AbreDb( [A16CLI],[CLIENTE] )
Function AbreDB( cArquivo, cAlias, lModo )
Local lRet := .t.
Local xArq := cArquivo

lModo := IIf( lModo == nil , .t. , .f. )
cArquivo := IIf( At( ".", xArq ) > 0 , cArquivo, cArquivo + ".dbf" )

If Leto

   If Leto_File( PathServ + cArquivo  )
                  //*** PathServ = "//192.168.0.1:2812/"
      DbUseArea(.t.,'LETO', PathServ + cArquivo,cAlias,lModo )
   Else
      MSG( 'LetoDB Não Foi Localizado: ' + PathServ + cArquivo )
      lRet := .f.
   EndIf

Else
   DbUseArea(.t.,'DBFCDX',cArquivo,cAlias,lModo )
EndIf
Return lRet


Todos os outros comandos continuaram do mesmo jeito (RLOCK, UNLOCK e COMMIT)

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Ago 2014 15:37
por Dudu_XBase
Mesmo erro o gcc não acha a lib olha q tá igual ao seu tem q fazer alguma configuração no linkeditor como fazia antes no Borland o "BCC" ?

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Ago 2014 15:57
por Dudu_XBase
Consegui salvei a lib na pasta lib do gcc e foi bora continuar os testes harbour 3.4 dev e letodb compilado do svn....

Obrigado a todos. :)Pos

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Abr 2015 16:23
por FFreire
Prezados...

Estou implementando o LetoDB, consegui compilar, gerar as libs, tanto para MinGw, como para Minigui Extended (pois tenho 2 projetos, um console e outro Gui), mas estou me TRAVANDO no FILE(), configurei no letodb.ini, EnableFileFunc = 0, portanto não estou usando leto_FILE, mas insiste em dizer que a tabela tal, não existe...minha tabela se chama ADMIN.ADM, dai também configurei no letodb.ini, EnableAnyExt = 1, o que mais tenho que fazer... segui os passos e parei aqui... portanto, peço ajuda...

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Abr 2015 17:02
por FFreire
O engraçado é que retiro o FILE...e dou sequencia...ele abre o arquivo ADMIN.ADM, pois vejo no manager, que esta aberto, mas não funciona se checar se o arquivo existe...segue como estou fazendo...

Aqui ele da msg que o arquivo não existe !!
// onde _PathAdm = "//127.0.0.1:2812/"
IF !FILE( _PathAdm + 'ADMIN.ADM' )
   TONE( 321, 2 )
   MSGBOX1( 'Arquivo Admin.ADM nÆo existe !!!', 'Erro...',,'&OK' )
   RETURN( .F. )
END


Mas aqui abre o arquivo normalmente
// na função NETUSE... esta ajustado para o leto ser o RDD

IF !NETUSE( _PathAdm + 'ADMIN.ADM', 'Adm', SHARE )
   MSGBOX1( Erro na abertura do arquivo...', 'Erro...',,'&OK' )
   RETURN( .F. )
END


O arquivo letodb.ini (que esta na pasta, onde esta o letodb.exe)
[Main]
; server port number;
Port = 2812

; connection timeout;
; TimeOut = -1

; path to a data directory on a server;
DataPath = c:\teste

; path and name of a log file;
Logpath = letodb.log

; default RDD to open files on server ( CDX/NTX );
Default_Driver = CDX

; memo type ( FPT/DBT ). Default: FPT for DBFCDX, DBT for DBFNTX;
; Memo_Type = FPT

; if 1, convert all paths to lower case;
Lower_Path = 0

; if 1, using of file functions ( leto_file(),
; leto_ferase(), leto_frename() is enabled;
EnableFileFunc = 0

; if 1, creating of data tables and indexes with
; any extention, other than standard ( dbf,cdx,ntx )
; is enabled;
EnableAnyExt = 1

; if 1, user authentication is necessary to
; login to the server;
Pass_for_Login = 0

; if 1, user authentication is necessary to
; use management functions ( Leto_mggetinfo(), etc. );
Pass_for_Manage = 0

; if 1, user authentication is necessary to
; have write access to the data;
Pass_for_Data = 0

; the path and name of users info file;
; Pass_File = "leto_users"

; if 1, the data passes to the network encrypted;
; Crypt_Traffic = 0

; if 0 (default, this mode server was the only from the
; start of a letodb project), the letodb opens all
; tables in an exclusive mode, what allows to increase
; the speed. If 1 (new mode, added since June 11, 2009),
; tables are opened in the same mode as client
; applications opens them, exclusive or shared, what
; allows the letodb to work in coexistence with other
; types of applications.
Share_Tables = 1

; The number of records to read into the cache
; Cache_Records = 10

; Maximum number of shared variables
; Max_Vars_Number = 10000

; Maximim size of a text variable
; Max_Var_Size = 10000

; Global function letodb RDDI_TRIGGER
; Trigger = <cFuncName>

; Global function letodb RDDI_PENDINGTRIGGER
; PendingTrigger = <cFuncName>

; Number of tables
; Tables_Max = 5000

; Number of users
; Users_Max = 500

; Debug level
; Debug = 0

; if 1, SET HARDCOMMIT OFF
; Optimize = 0

; SET AUTORDER setting
; AutOrder = 0

; _SET_FORCEOPT setting
; ForceOpt = 0

;[DATABASE]
Datapath = c:\teste
driver = cdx


F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Abr 2015 18:55
por Itamar M. Lins Jr.
Está correto.
File() não vai funcionar mesmo.
use: ENABLEFILEFUNC = 1, IF !LETO_FILE( _PathAdm + 'ADMIN.ADM' )

Se está no mesmo servidor use: FILE("c:\teste\admin.adm") sem o IP.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Abr 2015 18:57
por FFreire
Mas ja usei leto_file, da forma que vc colocou e também não funciona...habilitando EnableFileFunc = 1 em letodb.ini....

Ou tenho que quando for localhost...usar o caminho (c:\teste\...) para checar se o arquivo existe, e quando os dados estiverem em outra maquina/ip...dai posso usar o ip...é isso ?

LetoDb e Harbour, como usar.

MensagemEnviado: 05 Abr 2015 20:05
por Itamar M. Lins Jr.
Não.
Leto_File("//127.0.0.1:2812/adm.adm") tem que funcionar ai. Aqui funciona muito bem.

Aqui eu uso toda hora, e funciona.
Onde está o arquivo 'ADMIN.ADM' ?
O Leto só enxerga onde estiver configurado o arquivo.

; path to a data directory on a server;
DataPath = c:\teste

Coloque mais uma barra: DataPath = c:\teste\

E teste p/ ver se é isso.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Abr 2015 20:53
por FFreire
Nobre colega...

Batendo muita cabeça ainda com o Letodb...

Eu notei que onde esta o letodb.exe, é gerado um arquivo de log... dai percebi que quando carrego o serviço do leto... ele grava o seguinte no log...

04/09/15 20:45:00: Leto DB Server has been started.

Leto DB Server v.2.15 ! INIT: DataPath=, ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10

04/09/15 20:45:00: C:\FFSoft\DESENV\hmg\letodb\bin\letoudf.hrb has been loaded.


Veja que o DataPath, esta em branco... mas no letodb.ini esta configurado C:\FF\, dai não entendi nada, o letodb.ini, esta no mesmo diretório do letodb.exe...

Se esta configurado DataPath = C:\FF\ e também ShareTables=1... pq esta lendo em branco e 0... onde tem que ficar o letodb.ini ??

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Abr 2015 21:58
por FFreire
Outra dúvida....

Porque assim funciona...
x := leto_udf("UDF_CRIPTO",Nome,"R")
ALERT(X)


e assim não...dá ERROR LETO/1001 Função indefinida

zLetoDB := //127.0.0.1:2812/
_Chave   := 'LETO_UDF("UDF_CRIPTO",Nome,"R")'
_Tag     := ALLTRIM( (_ANtx)->Tag )
_NomeInd := zLetoDB+"Teste"

INDEX ON &(_Chave) TAG &(_Tag) TO &(_NomeInd)


Os 2 códigos no mesmo sistema...portanto, tudo que carrega para um, carrega para o outro...

To ficando mais careca do que ja sou !!!! kkkk

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Abr 2015 22:32
por FFreire
Opa... baixei a versão 2.13 e apareceu conforme o letodb.ini... será que a versão 2.15 tem problemas ???

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Abr 2015 22:41
por Itamar M. Lins Jr.
Estou usado a versão de hoje do SVN.
Coloque dessa forma seu letodb.ini

[MAIN]
Port = 2812             
Logfile = "letodb.log"   
DEFAULT_DRIVER = CDX     
DATAPATH = c:\clientes\xyz\
ENABLEFILEFUNC = 1
CRYPT_TRAFFIC = 0
PASS_FOR_LOGIN = 0
PASS_FOR_MANAGE = 0
PASS_FOR_DATA = 0
Share_Tables  = 1
Cache_Records = 100
[DATABASE]
DataPath = c:\clientes\xyz\
Driver = CDX

Leto DB Server v.2.15 ! INIT: DataPath=c:\clientes\xyz, ShareTables=1
, MaxUsers=500, MaxTables=5000, CacheRecords=100


Minúsculos/maiúsculos, etc... deixa da forma que está esse e teste. Aqui funciona.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Abr 2015 22:59
por Itamar M. Lins Jr.
...Função indefinida

O funcionamento é o mesmo de um motor SQL.
Use & ou () antes de indexar.

cQuery := " cod_client == '" + cCodCl + "' .and. dtos(vencimento) >= '"+dtos(dIni)+"' .and. dtos(vencimento) <= '"+dtos(dFim)+"'"
cOrdBy := " dtos(emissao) + cod_venda "

Index on &cOrdBy Tag re99  for &cQuery temporary eval {||oBar:Step(),.t.}

ou

cQuery := ""
If !empty(cCodFornecedor)
   cQuery += "'" + cCodFornecedor + "' == cod_fornec .AND. "
EndIf
If !Empty(cLoja)
   cQuery += " '" + cLoja + "' == loja .AND. "
EndIf
cQuery += " dtos(data_vcto) >= ["+DToS(dIni)+"] .AND. dtos(data_vcto) <= ["+DToS(dFim)+"] .AND. empty(data_pgto) "
cOrdBy := " dtos(data_vcto)+duplicata "
Index on &cOrdBy TAG pg99 FOR &cQuery temporary additive eval {||oBar:Step(),.T.}



Não pode ter função nenhuma, nem variáveis nas strings enviadas. Há não ser que tenha declarado elas no servidor.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Abr 2015 23:02
por FFreire
Sobre o letodb.ini... acabei de copiar conforme me passou e funcionou... devia ser alguma coisa no arquivo...tenho que habilitar alguma opção para enxergar as tabelas dentro do DATAPATH, pois por enquanto, estou tendo que copiar tudo na pasta principal, ou seja, se eu configurar DATAPATH=C:\TESTE\, esta lendo apenas o que esta em C:\TESTE\..... o que esta dentro das sub-pastas, não acha...alguma sugestão ?

Sobre o que relatei da função CRIPTO, agi assim:

Em um arquivo chamado LETOUDF.PRG ficou assim:

FUNCTION UDF_CRIPTO( nUserStru, aString, vTipo, Serie )

// aString  -- String a ser criptografada/descriptografada
// vTipo    -- Tipo 'C' Criptografa - 'R' Descriptografa
// Serie    -- Utilizada como base no calculo

LOCAL  cWord, cChave, nPos := 1, vChave := 0, nCnt, Chave := ""
LOCAL  cString := aString, nSerie, cRetr := ""

nSerie := STRZERO( Serie, 6 )
nSerie := VAL( SUBSTR( nSerie, 1, 1 ) ) + VAL( SUBSTR( nSerie, 2, 1 ) ) +;
          VAL( SUBSTR( nSerie, 3, 1 ) ) + VAL( SUBSTR( nSerie, 4, 1 ) ) +;
          VAL( SUBSTR( nSerie, 5, 1 ) ) + VAL( SUBSTR( nSerie, 6, 1 ) )

FOR nCnt = 10 TO 60
    Chave += CHR( nCnt + nSerie )
NEXT nCnt

DO WHILE nPos <= LEN( cString )
   cWord  := SUBSTR( cString, nPos, 1 )
   cChave := SUBSTR( Chave,   nPos, 1 )
   IF vTipo = "C"
      vChave := vChave + ASC( cChave )
      cRetr  := cRetr  + CHR( ASC( cWord ) + vChave )
   ELSEIF vTipo = "R"
      vChave := vChave - ASC( cChave )
      cRetr  := cRetr  + CHR( ASC( cWord ) + vChave )
   ENDIF
   nPos++
ENDDO

RETURN( cRetr )


Dai compilei dessa forma:
harbour letoudf.prg -gh -n -w -iC:\HARBOUR\INCLUDE


Gerou o arquivo letoudf.hrb, que coloquei na pasta que esta o letodb.exe... baixo o serviço e carrego novamente o serviço... consequentemente ele lê o arquivo com as funções e coloca no log assim:

04/09/15 23:16:12: Leto DB Server has been started.

Leto DB Server v.2.15 ! INIT: DataPath=c:\ff, ShareTables=1, MaxUsers=500, MaxTables=5000, CacheRecords=100

04/09/15 23:16:12: C:\FFSoft\DESENV\hmg\letodb\bin\letoudf.hrb has been loaded.


Dai como demonstrei acima, executando o LETO_UDF("UDF_CRIPTO",NOME."C")...funciona normal...só da erro quando tento gerar um indice.......o que poderia ser ???

Segui o que o TOLEDO, informou uns posts atrás, será que não fiz alguma coisa ???

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Abr 2015 01:04
por Itamar M. Lins Jr.
C:\TESTE\..... o que esta dentro das sub-pastas, não acha...alguma sugestão ?


O leto enxerga as subpastas.
DATAPATH = c:\dados\

Ele vai enxergar por exemplo,
c:\dados\2015\

   if Leto_file(dServidor+mAno+"\"+ArqInv) //-> "MeuIp:2812\2015\inventario2015.dbf"

Atenção! Não coloque MeuIp:2812\c:\dados\2015\inventario2015.dbf, desta forma está errado!

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Abr 2015 08:22
por Toledo
FFreire escreveu:executando o LETO_UDF("UDF_CRIPTO",NOME."C")...funciona normal...só da erro quando tento gerar um indice

Resta saber se é possível usar a função LETO_UDF() em uma macro na criação de índices.

Abraços,

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Abr 2015 09:12
por FFreire
Ok... sobre ver nas sub-pastas, entendi, que devo informar ao letodb que o arquivo esta em determinado lugar, tinha entendido que era só apontar para a pasta principal e ele se encarregava de procurar os arquivos, da pasta principal indicada em diante... mas ficou claro.......Obrigado !

Sobre a questão de usar macro, gostaria de saber se alguém ja usou dessa forma, se não tiver jeito terei que fazer de outra forma... mas enfim... vamos ver se tem alguma utilização... fico no aguardo.....

Muito obrigado a todos... e vamos em frente !!!

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Abr 2015 11:08
por FFreire
Prezados...

Novamente, venho solicitar ajuda, pois estou tentando o seguinte...

Como não esta funcionando. o esquema da macro na geração do indices, fiz isso:

// Atribuo ao leto a variavel
LETO_VARSET( "Main", "_Chave","Codigo", LETO_VCREAT )

// Se eu mandar exibir, ok também...
x := leto_varGet( "Main","_Chave" )
alert(x) // Exibe "Codigo" que é o que foi atribuido...

// Dai mando indexar...
zLetoDB := "//127.0.0.1:2812/"
INDEX ON LETO_UDF(zLetoDB+"UDF_CRIPTO",(_Chave),"R") TAG &_Tag TO &_NomeIndFim

E da erro...LETO/1003 Variável não existe...

Por favor... alguma luz ??? rs rs

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 12 Abr 2015 11:10
por FFreire
Achei a solução, com a ajuda do nobre Minduim...

Peguei a minha função de criptografia e compilei ela junto com o letodb, portanto o letodb.exe tem a função internamente, dai posso chamar ela que vai funcionar ok ! :))

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 12 Abr 2015 12:46
por Itamar M. Lins Jr.
Já tinha respondido isso.
Não pode ter função nenhuma, nem variáveis nas strings enviadas. Há não ser que tenha declarado elas no servidor.


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 12 Abr 2015 15:58
por FFreire
Opa...Itamar, desculpe por não ter te citado, mais é que o foco era tão grande em resolver, que passou despercebido !!!

Ufa... superei os problemas iniciais... agora esta rodando sem problemas... mas como nem tudo é flores... vejam...

Estou rodando o leto em uma maquina e esta funcionando certinho... dai vou testar em rede agora, o que fiz...

- Compartilhei o meu C:\ e mapeei na mesma maquina para G:\ (ou seja, se eu executar, é local)
- Fui no letodb.ini e acertei o DATAPATH de C:\ para G:\, STOP e START no serviço LETODB_SERVICE
- Entrei no sistema...e da erro LETO/1021..Tipo incorreto de dados:.....se executo o sistema em c:\, funciona normal...

Ai nem pude mapear em outra maquina para testar o funcionamento em rede...

Qual o bicho agora ???

Obs: Talvez irei escutar que não precisa mapear, pois é só usar o IP da maquina servidor... mas eu tenho que mapear, pois meu sistema utiliza algumas coisas em locais especifico...então o mapeamento é necessário para utilização do sistema...
Vale também lembrar que estou testando com o manager, tanto no local, quanto em outro terminal e esta acessando o letodb normalmente, então não é firewall bloqueando...
Outra colocação, eu fiz de uma forma, que só alterando o meu arquivo .ini, eu uso ou não o letodb... testando localmente, percebi que sem o letodb, é mais rápido...

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 13 Abr 2015 11:49
por FFreire
Prezados...

Vejam que quando tento iniciar o serviço, na unidade mapeada...da isso:
erro na inicialização do serviço.png


Observem que o serviço foi instalado, da unidade Y:...é quando vai iniciar é que dá isso...

Se instalar/iniciar na unidade c:...normal.... o que será ??

Acredito que pelo mesmo motivo, estou com problemas que relatei no ultimo post...

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 13 Abr 2015 12:09
por janio
NÃO PRECISAR MAPEAR!

No computador que for o servidor vc acessa com 'localhost' e nas estação da rede vc põe o IP DO SERVIDOR em vez de 'localhost'

LetoDb e Harbour, como usar.

MensagemEnviado: 13 Abr 2015 13:06
por FFreire
Janio, obrigado pela atenção...

Eu preciso mapear, pois o meu sistema esta no servidor e não na maquina local, além de ter outras pastas que precisam estar mapeadas, para o funcionamento do sistema...

Alguma sugestão ??

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 13 Abr 2015 22:54
por Itamar M. Lins Jr.
Ola!
Eu não entendi nada do que vc está querendo.
Para quê ficar mexendo no letodb ?
Porque chamar o letodb na y: ?
Se vc quer rodar duas instâncias do letodb, tem mudar nos fontes do letodb o nome do serviço e recompilar novamente. Tem que ter dois EXE´s com nomes de serviços diferentes.

LetoDb não é a resposta p/ tudo. Mas com outros comandos do Harbour hb_vf* functions, podem resolver uma serie de problema sem a necessidade de mapear a rede(compartilhar a unidade c:\)

// copy remote file located on the NETIO server to virtual
   // memory filesystem
   hb_fsCopy( "NET:192.168.0.1:/data/test.dbf", "mem:test.dbf" )

   // open DBF file copied to memory FS
   use mem:test

   // export it to file ont the server
   COPY TO "NET:192.168.0.1:/data/result.dbf"


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Abr 2015 12:05
por FFreire
Desculpe...eu que fiz uma grande confusão... natural de quem esta tentando entender o funcionamento de uma determinada ferramenta, sem nenhum tipo de manual...enfim... eu estava achando que tinha que instalar o letodb na unidade mapeada e fazer ele enxergar a unidade mapeada... na verdade, fazendo testes depois, entendi que tenho que instalar o letodb no servidor (c:) e configurar ele para enxergar na pasta do servidor..(c:\dados\)... dai depois se vou mapear ou não é outro problema... pois uma vez rodando no servidor ele irá monitorar a pasta que configurei e na estação vou colocar o ip do servidor... estava fazendo uma grande salada... que ja resolvi...AGRADEÇO PELA ATENÇÃO QUE FOI ME DADA, e fico a disposição para maiores esclarecimentos, conforme eu for evoluindo na ferramenta...

Só um detalhe, executando tudo no servidor... ainda não notei ganho de velocidade, mas vou fazer outros testes, do tipo...exe na estação e tabelas no servidor, para ver como fica e reporto aqui depois !!!

Obrigado !!!

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Abr 2015 12:58
por Itamar M. Lins Jr.
ainda não notei ganho de velocidade, mas vou fazer outros testes, do tipo...exe na estação e tabelas no servidor, para ver como fica e reporto aqui depois !!!


No servidor, não há nada para observar, agora, pendura 20 Maquinas ai na rede e chama tudo via Letodb, para ver o poder de fogo desta maravilhosa ferramenta. Segurança dos DBF´s, e não há mais problema de corrupção de dados.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 13 Mai 2015 09:48
por paiva
BOM dia.

não sei se já comentaram....

com o letodb pode-se usar comando TIPO Sql ?

select ................

ou é querer demais...

se permite o resultado do select vem para dbf ou Vetor .....

COMO funciona ex:

em rede se eu abrir um dbf e for lendo reg a reg para gerar um relatório a base e os índices trafegam pela rede para o Programa no PC-terminal selecionar ou Não o registro. SE for um browser acredito ser a mesma coisa e se precisar de + registros seriam buscado no servidor e trazidos para o pc-terminal.

COMO ficaria usando o letodb ? da mesma forma ? a não ser que em COMANDOS especiais eu FORCE o servidor resolver lá e NAO trazer para o PC-terminal ????

quando se manda executar um reindex on (criar os índices do sistemas (rs) demora uma vida se for de um pc-terminal..
no letodb ele se vira sozinho e não trafega os dados ?

desde já agradeço

PAiva

LetoDb e Harbour, como usar.

MensagemEnviado: 18 Mai 2015 11:15
por paiva
BOM dia

fuçando na NET Tiver uma ideia do Objetivo do Letodb.

Fazer o processamento no Servidor, Pack, filter, re-index etc. passando para PC basicamente os reg solicitado. Com isso diminui sensivelmente o trafego. a GROSSO modo seria como se fosse TS(ele só manda tela) em rede.

estão usando em produção normalmente ? ou ainda é arriscado ?

pode ter a mesma aplicação usando letodb e DBF Puro ? ou causaria conflito ?

minha aplicação é xhb + wvw + hwgui o EXE do lettdb pode ser em harbour ? comandos como recno() etc NAo seriam afetados ?t

desde já agradeço

PAiva

LetoDb e Harbour, como usar.

MensagemEnviado: 18 Mai 2015 15:42
por frazato
Tenho um projeto usado o Gtwvw com harbour e LetoDB funciona perfeitamente junto com o meu sistema atual usando os mesmos DBFs compartilhado, só não mudei meu programa inteiro devido a alguns problemas que tive pra montar rotinas de criação de indice temporário, mais de resto perfeito.

Segue um exemplo de uso!

Fornecedor : 1632
Senha := 1

Qq coisa me avise,

Frazato

LetoDb e Harbour, como usar.

MensagemEnviado: 19 Mai 2015 10:53
por Itamar M. Lins Jr.
estão usando em produção normalmente ? ou ainda é arriscado ?
pode ter a mesma aplicação usando letodb e DBF Puro ? ou causaria conflito ?


Como assim, arriscado ? Eu uso e outras pessoas usam desde alguns anos.
Como assim DBF puro ? É DBF com CDX ou NTX. E tem outro tipo de DBF ? E pode usar com outro programa sem letodb em paralelo, até com Foxpro.
      It is possible to define [DATABASE] structure if you need to have a
directory, where files are opened via other RDD:

      [DATABASE]
      DataPath =               -    (mandatory option)
      Driver = CDX             -    ( CDX/NTX )

      You can define as many [DATABASE] sections, as needed.


com o letodb pode-se usar comando TIPO Sql ?

Não tem. Mas vc pode usar qualquer função do lado do servidor para fazer o que desejar, parecido com STORED PROCEDURES.

a base e os índices trafegam pela rede para o Programa no PC-terminal selecionar ou Não o registro.

Não existe isso. É cliente/servidor, usa TCP/IP, a base e nem os indices trafegam pela rede. TODO o processo é do lado do servidor.

Para entender mais só usando. É a mesma coisa do ADS que custa uma fortuna!

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 20 Mai 2015 10:08
por paiva
Obrigado, entendi (ACHO rs)

só uma duvida ALEM de ter que alterar o sistema no INICIO do sistema

precisa mexer em + lugares ?

tipo: Abertura de arquivos, Append, replace, delete ??

ou funciona como um RDD o mínimo de alterações ?

SEM contar que se trocar while de leitura por um filter antes ou um Indice com FOR DIMINUIRIA o numero
de registro trafegados na rede correto ? porque o servidor seleciona o reg manda para o PC ele que vai verificar se o registro ATENDE e processar ou ignorar e mandar buscar o proximo, ENTAO se já houver uma pre-seleção no server agilizaria estou correto ?

e como NÂO existe select o procedimento seria por Índices ou Filtros

ob

PAiva

LetoDb e Harbour, como usar.

MensagemEnviado: 28 Mai 2015 20:21
por FFreire
Nobres...

Estou com um probleminha que não consigo resolver ou pelo menos enxergar onde esta o problema...

Estou rodando letodb e inclusive muito satisfeito, pois resolveu meu problema de lentidão com N terminais, parece até que ressuscitou a velha novell, pois se não estiver melhor, esta bem parecido em termos de velocidade...

Mas vamos ao problema, por enquanto ainda estou levando 2 versões do sistema, uma em console e outra em gui... que vou aos poucos convertendo... fiz os ajustes para funcionar o letodb e na versão console esta tudo ok... na versão gui... quando vai criar um determinado arquivo, ele esta dando esse erro que esta em anexo... o que poderia ser, sendo que o código tanto do gui, quanto do console são idênticos... alguém vê alguma diferença ???

FUNCTION CriaStr( _CodCria, _ArqCria, __Str, __StrI, __AStr, __Recria, __Caminho )

// _CodCria  --  Codigo para pesquisa no arq. de Estrutura
// _ArqCria  --  Nome do arquivo a ser criado
// __Str     --  Arquivo de Estruturas dos arquivos
// __StrI    --  Arquivo de Indices da estruturas
// __AStr    --  Alias da Estrutura
// __Recria  --  Se cria o arquivo mesmo que existir

LOCAL _StrDef, aChou, xOpErro
LOCAL _AbreS := .F., __CaminhoLeto

_StrDef  := {}
__Recria := IIF( __Recria = NIL, .F., __Recria )

IF EMPTY( SELECT( __AStr ) )
   // Tenta abrir arquivo de (estruturas) em modo compartilhado
   IF NETUSE( __Str, (__AStr), SHARE )
      DBSETINDEX( __StrI )
   ELSE
      MsgMenu('Arq.' + __Str + ' não pode ser aberto !!! Verifique os terminais !!!',{'OK'},,IM__ERRO,'ERRO',,,'32 ERR CAN',,,_branco_)
      RETURN( FALSE )
   END
   _AbreS := .T.
END

(__AStr)->( DBSEEK(_CodCria) )
WHILE (__AStr)->Codigo == _CodCria
   AADD( _StrDef, { ALLTRIM((__AStr)->Nome), (__AStr)->Tipo, (__AStr)->Tamanho, (__AStr)->Decimal } )
   (__AStr)->( DBSKIP() )
END

IF EMPTY( _StrDef )
   RETURN( FALSE )
ELSE
   xOpErro = 1
   IF FILE(__Caminho+_ArqCria) .AND. !__Recria
      xOpErro :=  MsgMenu('Arq.' + __Caminho +_ArqCria + ' já existe !!! Cria novamente ???',{'&Sim','&Não'},,IM__PERGUNTA,'Atenção',,,'42 ASK',,,_branco_) = 1
   END
   IF xOpErro = 1
      __CaminhoLeto := zLetoDB + SUBSTR(__Caminho,4,LEN(__Caminho)-3)
      DBCREATE( IIF(EMPTY(zLetoDB),__Caminho,__CaminhoLeto)+_ArqCria, _StrDef )
      HB_FCOMMIT()
   END
END

IIF( _AbreS, (__AStr)->( DBCLOSEAREA() ), '' )

RETURN( TRUE )

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Mai 2015 08:49
por janio
"Error SIXCDX" ????????????

Vc esta setando rdd LETO corretamente??

Janio

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Mai 2015 10:17
por FFreire
Sim... esta ok, pois esse erro esta dando, quando vou criar o DBF, quando crio os CDX esta ok !

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Mai 2015 13:21
por FFreire
Alguém saberia dizer onde posso encontrar o significado dos códigos de retornos de erro do letodb.exe...ja sei que a função letowin_GetLastError() é a que retorna tais códigos, mas quais seriam eles... ficaria mais fácil de interpretar o problema quando aparecer os código e tivermos a informação deles...

por exemplo: Error installing LetoDB service: 5 -> O que siginifica isso...

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 31 Mai 2015 15:48
por FFreire
Opa... venho relatar uma diferença... postei acima que quando ia criar um arquivo com o minigui extended estava dando um erro de criação... realmente persistiu esse erro, até eu dar uma olhada na sintaxe do dbcreate()... vejam...

Usando harbour+minigui+mingw+letodb...eu uso o dbcreate assim: DBCREATE( _ArqCria, _StrDef ), onde _Arqcria é o caminho + o nome do arquivo que vou criar e _strdef é uma matriz com a estrutura, uso a muito tempo e sempre funcionou sem problema, tanto que na versão console, não alterei nada e ta funcionando... seja usando letodb ou dbfcdx.

Dai quando uso harbour+minigui extended+bcc+letodb...usando dbfcdx, sem problemas, funcionando jóia, mas quando fui usar da forma acima com o letodb dava erro..erro de criação, dos error 67 e por ai vai... dai acertei dessa forma... DBCREATE( _ArqCria, _StrDef, IIF(EMPTY(zLetoDB),"DBFCDX","LETO") ), funcionou na hora... parou de dar o erro... ou seja, se forem usar o letodb com minigui extended tem que informar o RDD, ja no minigui clássico (digamos assim), não precisa...o estranho é que uso o mesmo harbour para os dois...para mim dbcreate() é do harbour...então o que tem a ver, seria o linker (mingw/bcc) a diferença... mas enfim... novamente bati bastante cabeça, mas esta funcionando...

E só para animar o pessoal com o letodb, o ganho de performance na rede local é maravilhoso... coloquei em um cliente com 20 estações e win server 2008... acabou a lentidão que tanto reclamavam... tive alguns probleminhas, por exemplo... se a maquina da uma travadinha na placa de rede, cabo, etc... as vezes fica travado os arquivos no servidor... mas dai resolvi, da seguinte forma, depois de conectar ao leto, verifico se aquele ip não esta conectado, se estiver, mato as conexões e digo para o usuário entrar novamente do sistema... outro problema que tive é com relação aos browses... em algumas situações ele não atualiza na hora, mas dai forço uma leitura, usando o posicionamento dos ponteiro e beleza... no mais só alegria... estou quase pronto para colocar no meu maior cliente, que tem 60 terminais locais e uns 20 usando TS... vamos ver o que dá...

Enfim... aos poucos vou ficando pronto para poder colaborar aqui com a minha vivência nas ferramentas...

Ei... ninguém tem uma resposta para aquela ultima pergunta ali... sobre os retornos do letodb.exe... mandei até um e-mail para o russo... quem sabe ele retorna com o significado dos números, quando executamos letodb install... alguns ja entendi... agora tem uns que não faço a mínima da causa !!! Dei uma olhada nos fontes, mas lá não tem nada, que posso informar...

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 31 Mai 2015 17:46
por janio
se a maquina da uma travadinha na placa de rede, cabo, etc... as vezes fica travado os arquivos no servidor... mas dai resolvi, da seguinte forma, depois de conectar ao leto, verifico se aquele ip não esta conectado, se estiver, mato as conexões e digo para o usuário entrar novamente do sistema


Nao entendi esta parte! Vc entra no sistema e ja constar q essa estação ja estava conectada vc mata o sistema e pede pra entrar novamente?

Um problema que enfrento eh qndo a estação perde a conexão com o servidor e logo em seguida recupera novamente. Ocorre que mesmo que caia a conexao e no segundo seguinte a conexão se restabeleça... mesmo assim o leto acusa erro e o sistema eh abortado! Nao sei como resolver isso...

Pra testar fiz o seguinte:
1- Entro no sistema abrindo uma tabela;
2- paro em algum get;
3- deconecto o cabo de rede;
4- conecto o cabo novamente;
5- volto ao sistema e tento fechar a tabela (aqui dah o erro)

Mesmo a conexão ja estando ativa, da erro...

Janio

LetoDb e Harbour, como usar.

MensagemEnviado: 31 Mai 2015 18:36
por FFreire
Acho que nas 2 situações é o mesmo problema... se perder a conexão com o leto, seja por, falta de energia, problema no cabo, problema na placa de rede, hibernação, desligamento por inatividade... o sistema irá travar em qualquer situação... pois o meio físico parou, não tem o que fazer, mesmo que fosse com dbfcdx... o lado bom da história é que o leto, garante/gerencia a conexão, evitando problemas em bases e índices... Mas dai quando vc entrar novamente no sistema, irá gerar uma nova conexão... veja isso pelo manager... dai eu tenho problemas, pois uso arquivos temporários com o numero da estação de trabalho em modo exclusivo... quando conecta novamente, ele tenta usar o arquivo e não abre, pois eles ja se encontram aberto em uma outra conexão... dai resolvi assim...
// Conexao ao servidor de dados LETODB
IF !EMPTY(zLetoDB)
   xLeto := LETO_CONNECT(zLetoDB) // efetuo a conexão ao leto
   IF xLeto == -1
      MsgMenu('Não conectado ao servidor: '+zLetoDB,{'OK'},,IM__ERRO,'ERRO',,,'32 ERR CAN',,,_branco_)
      RELEASE WINDOW Principal
   END
   // Verifica se ja esta conectado no letodb
   xiplocal := GetIp() // função que retorna o ip local
   xipcnx   := leto_MgGetUsers() // retorna matriz com informações das conexões (1-sequencia / 2-ip / 3-host / 4-exe que gerou a conexao / 5 - timeout)
   IF LEN(xipcnx) > 1 // se houver mais de 1 usuario
      nCntCnx := 0
      FOR nCnt = 1 TO LEN(xipcnx)
         IF xipcnx[nCnt,2] == xiplocal .AND. UPPER(xipcnx[nCnt,4]) == 'SAGRIO.EXE' // se existir alguma conexão com o iplocal e no meu sistema, incrementa
            nCntCnx++
         END
      NEXT
      IF nCntCnx > 1 // se tem mais de 1 sistema conectado
         FOR nCnt = 1 TO LEN(xipcnx)
            IF xipcnx[nCnt,2] == xiplocal .AND. UPPER(xipcnx[nCnt,4]) == 'SAGRIO.EXE' // mato a conexão
               leto_MgKill( xipcnx[nCnt,1] )
            END
         NEXT
         MsgMenu('Conexão anterior não finalizada corretamente !!!'+SALTO_LINHA+SALTO_LINHA+'Entre novamente no sistema...',{'OK'},,IM__ERRO,'ERRO',,,'32 ERR CAN',,,_branco_)
         RELEASE WINDOW Principal
      END
   END
END

****************
FUNCTION GetIp()
****************
LOCAL aHosts
LOCAL cEstacao := NETNAME(.F.)

HB_InetInit()
aHosts := HB_InetGetHosts( cEstacao )
IF aHosts == NIL
   aHosts := HB_InetGetAlias( cEstacao )
END
IF EMPTY(aHosts)
   aHosts := HB_InetGetAlias( cEstacao )
END
HB_InetCleanup()
RETURN aHosts[1]

Outra coisa a ser dita, é conectar em base de dados com wifi, eita coisa, para oscilar...passou qualquer tipo de sinal do lado, ja oscila o sinal, quando vejo que o usuário não usa cabo, simplesmente coloco no TS, pronto ta resolvido...

Pensando aqui agora... poderia ao invés de sair do sistema... poderia conectar novamente...

Espero ter ajudado...

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 31 Mai 2015 18:47
por janio
Esse tipo de problema so acontece qndo conectamos o sistema via ip. Qndo eh mapeado, mesmo q a conexao com o servidor caia e volte novamente, não da erro nenhum!

Chato isso pq se o servidor estiver indisponível... blz, nao ha o que fazer. Mas se a perca da conexão se deu de forma mometanea e no momento da requisição o servidor ja estava disponível novamente... nao vejo pq ocorrer esses erros.

Estava pensando numa solução de em vez de abortar a aplicação, tentar uma reconectar novamente. Pelo errorsys daria pra tratar isso. Mas não sei se as tabelas JA ABERTAS continuariam visiveis para a NOVA CONEXÃO!

Janio

LetoDb e Harbour, como usar.

MensagemEnviado: 31 Mai 2015 18:59
por FFreire
Entendi... vc esta falando de conexão, onde a base se encontra em outro local remoto, que não é a rede local... mas dai daria para aplicar no errorsys, o mesmo esquema, mata a conexão e tenta novamente, se houver conexão, vc reiniciaria apenas o modulo onde vc estava... tem que aprimorar, mas acho que é por ai !

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Jun 2015 13:30
por masteragm
Hola :
Estoy trabajando con letodb y estoy haciendo un browse sobre una base de datos de 7000 reg. ,
pero se demora alrededor de 10 minutos !!!!
Si alguien puede ayudarme , estare muy agradecido .
este es el codigo :

x_inicio:=diario.desde.value
x_final :=diario.hasta.value
x_ord:="XXD9"
select det
ORDSETFOCUS(x_ord)
det->(OrdScope( 0,x_inicio))
det->(OrdScope( 1,x_final))
det->( dbSetFilter( { || Field->dvfecvou >= diario.desde.value .and. Field->dvfecvou <= diario.hasta.value }, 'Field->dvfecvou >= diario.desde.value .and. Field->dvfecvou <= diario.hasta.value' ) )
DBGOTOP()
diario.browse_1.refresh
diario.browse_1.value := det->(recno())
diario.browse_1.refresh

Atte.Alejandro Gonzalez

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Jun 2015 13:47
por Itamar M. Lins Jr.
Ola!
Abra um novo tópico! Aloo moderadores!

OrdScope e SET FILTER juntos... estranho.

Use índice temporário.
det->( dbSetFilter( { || Field->dvfecvou >= diario.desde.value .and. Field->dvfecvou <= diario.hasta.value }, 'Field->dvfecvou >= diario.desde.value .and. Field->dvfecvou <= diario.hasta.value' ) ) 

Troque por:
cOrdBy := ??? //
cQuery :=  "Field->dvfecvou >= diario.desde.value .and. Field->dvfecvou <= diario.hasta.value"
Index on &cOrdBy TAG MyTmpTagX FOR &cQuery temporary additive


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Jun 2015 20:16
por masteragm
gracias , voy a probar con este codigo , serias tan amable
de explicarme el uso de las instrucciones :

LETO_BEGINTRANSACTION( [ nBlockLen ] )
LETO_ROLLBACK()
LETO_COMMITTRANSACTION( [ lUnlockAll ] )

Saludos

Alejandro Gonzalez

LetoDb e Harbour, como usar.

MensagemEnviado: 08 Jul 2015 16:37
por FFreire
Olá...

Como resolver essa situação...

Tenho um cliente que usa um servidor windows server 2008, ele tem 2 empresas, cada uma com seu cnpj, usando meu sistema no mesmo servidor...

Como faço isso... no C: do servidor, crio 2 pastas \empresa1, \empresa2... ai dentro de cada pasta instalo meu sistema e depois mapeio 2 unidades (F: para \empresa1 e G: para \empresa2), consequentemente 2 atalhos... tudo perfeito, sem problemas... funcionando a bastante tempo, agora estou usando o letodb, ja coloquei em quase todos os clientes e esta funcionando perfeito, mas como fazer nessa situação... pois tenho que instalar 1 serviço (letodb_service), consequentemente, irá monitor apenas 1 lugar... alguém ja passou por isso... qual seria o caminho a seguir ???

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 08:33
por janio
Vc tem os fontes do leto...

Recompile o servidor mudando o nome do serviço e o arquivo .ini monitorado!

Um será o leto normal e o outro sera o leto com serviço diferente

Janio

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 18:07
por FFreire
Ok Janio... vou tentar isso para ver o que acontece...retorno o resultado...obrigado !

Só uma dúvida, será que irá afetar a lib que uso adicionada ao sistema ou apenas o letodb.exe ?

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 19:18
por Itamar M. Lins Jr.
Tem algumas possibilidades.
Na minha opinião usar:
c:\DataBase\EmpresaX
c:\DataBase\EmpresaY
[code]
No letodb.ini configurar a pasta [DATAPATH ]= c:\DataBase\
Porque ele irá enxergar as subpastas.

Ou usar o LetoDb.exe em diretórios diferentes não instalando como serviço!
[code]c:\EmpresaX\Letodb.exe
c:\EmpresaY\Letodb.exe


Ou como foi explicado pelo Janio.

Prefiro a primeira opção das subpastas.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 19:19
por FFreire
Não funciona... :(Neg

Troquei o nome para letodb_service0 E letodb0.ini, instala ok, inicia... tranquilo... fico com 2 serviços letodb no servidor.....o letodb_service e o letodb_service0, carregados e funcionando, mas quando o sistema conecta, ele conecta no letodb_service...e o mais interessante, derruba o letodb_service0... dai eu tento subir o serviço, da uma mensagem, dizendo que o windows paraliza serviços que estão ociosos (resumindo)...

Dai tentei uma coisa, só para ver o que acontece... peguei as libs que foram geradas como letodb_service0 e linkei com o sistema... continua lendo letodb_service... portanto não resolve...

Dai fiquei imaginando, se eu quiser colocar um servidor meu, para que clientes menores, que não tem infra-estrutura, acessar meu sistema não consigo..., pois a idéia seria instalar um sistema para cada cliente... cada um com seus dados, etc, etc... não dá, pois só consigo monitorar uma pasta...

Claro que posso resolver isso, via sistema, que é determinar qual pasta irá acessar, a partir da pasta monitorada pelo leto... mas vai complicar um pouco...

Será que não tem outra solução, será que ninguém passou por isso ??? :'(

Vamos aguardar para ver o que aparece !

F.Freire

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 19:22
por Itamar M. Lins Jr.
Tem algumas possibilidades.
Na minha opinião usar:
c:\DataBase\EmpresaX
c:\DataBase\EmpresaY


No letodb.ini configurar a pasta [DATAPATH ]= c:\DataBase\
Porque ele irá enxergar as subpastas.

Ou usar o LetoDb.exe em diretórios diferentes não instalando como serviço!
c:\EmpresaX\Letodb.exe
c:\EmpresaY\Letodb.exe


Ou como foi explicado pelo Janio.

Prefiro a primeira opção das subpastas.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 19:24
por Itamar M. Lins Jr.
Mudando o nome do serviço funciona 100%
Tem que mudar a porta também.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 19:26
por FFreire
Opa... bem pensado...Itamar...

O que vc esta dizendo é para usar:

c:\SISTEMA\EMPRESA1
c:\SISTEMA\EMPRESA2

No leto...no datapath = c:\sistema\

dai mapeio f:... c:\sistema\empresa1, vai aparecer o que tiver aqui dentro...

e mapeio g:... c:\sistema\empresa2, vai aparecer o que tiver ai dentro... resolvendo o problema e usando o mesmo serviço...

vou testar e reporto aqui...

Só mais um detalhe que ainda não entendi, como não usar o letodb, sem ser um serviço....

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 19:28
por FFreire
Eu mudei o nome do serviço... mas não mudei a porta... pode ser isso então... vou testar... mas não preciso linkar a lib com o nome do serviço mudado ?

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 20:27
por Itamar M. Lins Jr.
Tem que mudar duas linhas no letodb.hbp

2. Building binaries

The letodb server can be compiled only by the Harbour compiler, and client
library - both Harbour, and xHarbour. For OS Windows the letodb server can be
compiled as Windows service (the macro by __WIN_SERVICE__ should be initialized),
or as the daemon (process) for what it's necessary to set a macro __WIN_DAEMON__.
For Linux it is necessary to set a macro __LINUX_DAEMON__.


Olhando o letodb.hbp
#-prgflag={win}-D__WIN_DAEMON__
-prgflag={win}-D__WIN_SERVICE__

Trocar para
-prgflag={win}-D__WIN_DAEMON__
#-prgflag={win}-D__WIN_SERVICE__


E compilar novamente.
Dai:
3. Running and stopping server

Just run it:

letodb.exe ( under Windows )
./letodb ( under Linux )

To shutdown the server, run the same executable with a 'stop' parameter:

letodb.exe stop ( under Windows )
./letodb stop ( under Linux )



Isso está no readme.txt e no letodb.hbp
Assim vc pode ter n letodb.exe´s, um em cada diretório com suas respectivas pastas e lógico monitorando portas diferentes.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Jul 2015 20:55
por FFreire
Blz... ficou bem claro com relação ao letodb daemon...

Mas optei, por enquanto, em trocar o nome do serviço, pois usando como serviço, dispensa a questão manual... realmente o problema era a porta, estava usando a mesma, deu certinho... posso dai gerar quantos serviços necessitar que vai atender !

Agradeço, Janio e Itamar, pelas dicas... muito obrigado !

LetoDb e Harbour, como usar.

MensagemEnviado: 16 Jul 2015 10:33
por Concentra
Bom dia !

Preciso de alguma ajuda com o Leto.
Estou convertendo uma aplicação antiga e relativamente grande para o Leto.
A princípio foi relativamente fácil, visto que não precisava mudar muita coisa, basicamente a conexão inicial ao Leto.

Com os índices já criados e funcionando com o DBFCDX vai que é uma maravilha, ficou muito mais rápido em rede.
Mas estou a 5 dias tentando criar os índices com o Leto e nada...
Os índices triviais sem problemas, mas tenho alguns índices "estranhos" e preciso de ajuda !!!

Por exemplo, tenho um índice ordenando uma tabela de pedidos pela descrição da tabela de produtos, estando as tabelas relacionadas.
Na tabela de pedidos eu tenho o código do produto que relaciona com a tabela de produtos, que tem a descrição.

O exemplo abaixo funciona normalmente com DBFCDX, mas o LETO gera um erro "Error BASE/1002 Alias does not exist: PRODUTOS" :

PROCEDURE Main()

   REQUEST LETO
   LOCAL I

   SETMODE(25,80)
   CLS
   IF Leto_Connect(ALLTRIM(MEMOREAD("LETODB.FLG"))) <> -1
      RDDSETDEFAULT( "LETO" )
   ELSE
      Alert("Not connected")
      QUIT
   ENDIF

   DBCREATE( "PRODUTOS", { { "PROD_ID", "C",  10, 0 },;
                           { "DESC"   , "C",  50, 0 } } )

   DBCREATE( "VENDAS",   { { "PROD_ID", "C",  10, 0 },;
                           { "PRECO"  , "N",  12, 2 } } )

   USE PRODUTOS NEW
   INDEX ON FIELD->PROD_ID TAG "ID"

   APPEND BLANK
   REPLACE FIELD->PROD_ID WITH "0000000001"
   REPLACE FIELD->DESC    WITH "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
   APPEND BLANK
   REPLACE FIELD->PROD_ID WITH "0000000002"
   REPLACE FIELD->DESC    WITH "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

   USE VENDAS NEW

   APPEND BLANK
   REPLACE FIELD->PROD_ID WITH "0000000002"
   REPLACE FIELD->PRECO   WITH 2.00

   SET RELATION TO FIELD->PROD_ID INTO PRODUTOS

   INDEX ON PRODUTOS->DESC TAG "DESCRIPT"

   SEEK "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

   ALERT( VENDAS->PROD_ID + " " + PRODUTOS->DESC )

   Return


Eu entendo que a área de trabalho PRODUTOS é algo que pertence ao escopo do cliente, não do servidor, mas como eu faço algo assim no LETO ?
Quais as alterações necessárias no meu exemplo ?

[[]] Maurício Ventura Faria

LetoDb e Harbour, como usar.

MensagemEnviado: 16 Jul 2015 13:33
por janio
USE PRODUTOS NEW alias PRODUTOS
INDEX ON FIELD->PROD_ID TAG "ID"

LetoDb e Harbour, como usar.

MensagemEnviado: 17 Jul 2015 08:16
por Concentra
janio escreveu:USE PRODUTOS NEW alias PRODUTOS
INDEX ON FIELD->PROD_ID TAG "ID"

Isso não resolve o problema, o Leto retorna o mesmo erro.
Quando o ALIAS não é referenciado, por padrão, o nome do arquivo é assumido como ALIAS.

[[]] Maurício Ventura Faria

LetoDb e Harbour, como usar.

MensagemEnviado: 17 Jul 2015 09:58
por janio
Function Main( cPath )
   LOCAL I

   REQUEST LETO
   RDDSETDEFAULT( "LETO" )

   SETMODE(25,80)
   CLS

   IF Empty( cPath )
      cPath := "//127.0.0.1:2812/temp/"
   ELSE
      cPath := "//" + cPath + Iif( Right(cPath,1) $ "/\", "", "/" )
   ENDIF

   DBCREATE( cPath+"PRODUTOS", { { "PROD_ID", "C",  10, 0 },;
                              { "DESC"   , "C",  50, 0 } } )

   DBCREATE( cPath+"VENDAS",   { { "PROD_ID", "C",  10, 0 },;
                           { "PRECO"  , "N",  12, 2 } } )
   USE (cPath+"PRODUTOS") NEW alias PRODUTOS
   INDEX ON PROD_ID TAG "ID"

   APPEND BLANK
   REPLACE FIELD->PROD_ID WITH "0000000001"
   REPLACE FIELD->DESC    WITH "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
   APPEND BLANK
   REPLACE FIELD->PROD_ID WITH "0000000002"
   REPLACE FIELD->DESC    WITH "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

   USE (cPath+"VENDAS") NEW

   APPEND BLANK
   REPLACE FIELD->PROD_ID WITH "0000000002"
   REPLACE FIELD->PRECO   WITH 2.00

   SET RELATION TO FIELD->PROD_ID INTO PRODUTOS

   Select Produtos
   INDEX ON DESC TAG "DESCRIPT"
   SEEK "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"

   ALERT( VENDAS->PROD_ID + " " + PRODUTOS->DESC )

   Return

LetoDb e Harbour, como usar.

MensagemEnviado: 17 Jul 2015 13:26
por Concentra
janio escreveu: Select Produtos
INDEX ON DESC TAG "DESCRIPT"

Jânio, eu preciso indexar a tabela de vendas, não a de produtos...

[[]] Maurício Ventura Faria

LetoDb e Harbour, como usar.

MensagemEnviado: 17 Jul 2015 17:58
por janio
Tabela VENDAS não tem o campo DESC. como vc quer indexar por um campo q não existe na tabela?

LetoDb e Harbour, como usar.

MensagemEnviado: 18 Jul 2015 01:59
por Concentra
janio escreveu:Tabela VENDAS não tem o campo DESC. como vc quer indexar por um campo q não existe na tabela?

As tabelas estão relacionadas, toda vez que um registro na tabela de vendas é posicionado o registro correspondente na tabela de produtos é posicionado automaticamente , então, é possível ordenar a tabela de vendas pela descrição da tabela de produtos.
Faço esse tipo de relacionamento em várias situações em meus sistemas e preciso fazer com o LETO mas não descobri como...

LetoDb e Harbour, como usar.

MensagemEnviado: 18 Ago 2015 15:06
por esbasso
Baixei fontes recentes do leto
Leto Server 2.15 b3 ou 2.15 Funciona normal

Mas o lib cliente RDDLETO.LIB gerada não funciona, não conecta de forma alguma
USANDO XHARBOUR 1.23 ...
Tentei de tudo

Só funciona usando uma LIB cujo leto VERSÃO eu só tinha esta por ultimo
/* $Id: leto1.c,v 1.166.2.63 2013/06/24 09:33:44 ptsarenko Exp $ */
/* $Id: letocl.c,v 1.1.2.23 2014/01/15 10:57:57 alkresin Exp $ */ ultima que tenho que funciona

NÃO FUNCIONA
/* $Id: leto1.c,v 1.166.2.120 2015/03/04 12:49:39 alkresin Exp $ */

/* $Id: letocl.c,v 1.1.2.45 2015/08/01 20:23:30 ptsarenko Exp $

Se alguém tiver uma versão de LIB para xharbour lado cliente RDDLETO.LIB poste aqui

LetoDb e Harbour, como usar.

MensagemEnviado: 18 Ago 2015 19:19
por esbasso
Consegui resolver o problema verificando o arquivo letocl.c

No que funcionava a conexão LETOCONNECTION tinha a seguinte linha
hSocket = hb_ipConnect( szAddr, htons( iPort ), iTimeOut );

Na atual versão esta linha foi alterada para
hSocket = hb_ipConnect( szAddr, iPort, iTimeOut );

Troquei a linha e voltou a funcionar.

htons( iPort ) e iPort eis a diferença

LetoDb e Harbour, como usar.

MensagemEnviado: 19 Ago 2015 21:44
por asimoes
Esbasso,

Já foi resolvido este problema?

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Set 2015 22:03
por asimoes
Prezados,

Como é definido usuário e senha para acesso
ex.
Onde é informado o usuário admin e senha admin?

Tem algum exemplo?

IF Leto_Connect( cServidorDB, 'admin', 'admin' ) == -1
ENDIF

LetoDb e Harbour, como usar.

MensagemEnviado: 16 Set 2015 01:09
por asimoes
Pessoal,

PASS_FILE tem algum exemplo, eu queria testar a autenticação no letodb, tá dificil! não tem nenhum exemplo?

Quero testar esse arquivo, eu não sei o que informar.

; the path and name of users info file;
PASS_FILE = "LETO_USERS"

LetoDb e Harbour, como usar.

MensagemEnviado: 16 Set 2015 09:46
por asimoes
Não sei como se faz, mas acredito que não funciona.
Com o netio consigo definir a segurança de acessso. No letodb tá dificil!

Pass_for_Login = 1
Pass_File = "leto_users"

Alguém me diz ao contrário com exemplo?

LetoDb e Harbour, como usar.

MensagemEnviado: 04 Nov 2015 12:51
por asimoes
Caros,

Estou com este erro, quando faço indexação com o rddleto, o problema está em month(d_nasc) = nMes, com netio ou dbfcdx indexa sem problemas, alguém sabe como contornar este problema?
O letodb não está gostando da variável nmes

Error LETO/1003 Variavel nao existe
Called from ->ORDCREATE(0)
Called from REL_ANI.PRG->REL_ANI(57)
Called from ->(b)MAIN(849)
Called from ->MAIN(849)

INDEX ON NOME TAG INDICE01 FOR !Left(Classe_Pg,2) $ "06,07,08,09,10,11,12,13" .AND. Month(D_Nasc) = nMes  .AND. Empty(D_Faleci) .AND. !Deleted() TEMPORARY ADDITIVE

LetoDb e Harbour, como usar.

MensagemEnviado: 13 Nov 2015 21:38
por asimoes
Pessoal,

O letoudf.prg que eu tenho tem uma função nova que eu gostaria de usar (UDF_Eventos).
Só que ao executar o letodb (versão daemon) dá a seguinte mensagem no letodb.log:

11/13/15 22:26:20: Error BASE/6101 Unknown or unregistered symbol: DOEVENTS
ERROR! SETHRBERROR - pUStru not found!!!!!!!!!!!!!!!!!!!!

FUNCTION UDF_Eventos( nUserStru )
   DoEvents()
RETURN .T.

#pragma BEGINDUMP
#include <windows.h>

HB_FUNC( DOEVENTS )
{
   MSG Msg;

   while( PeekMessage( ( LPMSG ) &Msg, 0, 0, 0, PM_REMOVE ) )
   {
      TranslateMessage( &Msg );
      DispatchMessage( &Msg );
   }
}
#pragma ENDDUMP

LetoDb e Harbour, como usar.

MensagemEnviado: 30 Nov 2015 14:01
por Itamar M. Lins Jr.
Ola!
Não pode, use da mesma forma que usamos no SQL.

..."Month(d_nasc) = " +str(nMes,2)+"...

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 30 Nov 2015 14:21
por asimoes
Itamar,

O letodb não gostou do uso código em c no letoudf.prg

11/13/15 22:26:20: Error BASE/6101 Unknown or unregistered symbol: DOEVENTS
ERROR! SETHRBERROR - pUStru not found!!!!!!!!!!!!!!!!!!!!

Você sabe como resolver?

FUNCTION UDF_Eventos( nUserStru )
DoEvents()
RETURN .T.

#pragma BEGINDUMP
#include <windows.h>

HB_FUNC( DOEVENTS )
{
MSG Msg;

while( PeekMessage( ( LPMSG ) &Msg, 0, 0, 0, PM_REMOVE ) )
{
   TranslateMessage( &Msg );
   DispatchMessage( &Msg );
}
}
#pragma ENDDUMP


LetoDb e Harbour, como usar.

MensagemEnviado: 30 Nov 2015 14:33
por Itamar M. Lins Jr.
Ola!
Uma dica! Não sei se irá resolver, mas usando o httpd recompilo ele junto com o letodb.hbc e a hbwin.hbc usando REQUEST.

#require "rddleto"
REQUEST __HB_EXTERN__
REQUEST LETO, LETO_CONNECT, LETO_CONNECT_ERR, LETO_DISCONNECT, LETO_FILE, LETO_COMMIT
REQUEST LETO_GETCURRENTCONNECTION, LETO_SETCURRENTCONNECTION, LETO_GETSERVERVERSION
REQUEST WIN_PRINTERLIST,WIN_PRINTERGETDEFAULT,WIN_PRINTFILERAW
REQUEST HB_MEMOWRIT, __BREAKBLOCK, ISDEC, WIN_PRN


Ou vc pode colocar a função lá no \source\server\letofunc.c e recompilar... Boa sorte!

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 13 Abr 2016 18:28
por JAIR RANGEL
Olá a todos!

Estou compilando um programa para testar o leto e uma série de erros aparece.
Baixei o leto e pelo que vi parece estar completo.
Tem o executável do servidor, pois vejo que ele carrega do serviço e com o Manager posso verificar que ele está no ar.
No entanto, quando compilo, ao link-editar, surge as mensagens de Erro.
Acho que não está reconhecendo o rddleto.lib, mesmo estando configurado.

Uso MiniGUI/Harbour, BCC32

Por outra, tentei compilar o leto com o meu ambiente de desenvolvimento, mas não tive sucesso.

Se alguém puder dar uma dica, seria show.

Vlw

LetoDb e Harbour, como usar.

MensagemEnviado: 30 Jun 2016 10:33
por jelias
Olá amigos,

Estou terminando a migração para o uso do LETODB e estou com as seguintes dúvidas.

a) Ao sair do sistema devo utilizar o comando LETO_DISCONNECT(). O que realmente faz este comando?
b) Através de alguns relatos que li, existe algum "bug" com relação ao comando QUIT ao sair do sistema?
c) O erro relatado pelos colegas ASIMOES e WAGNERARAGÃO, "leto_errInternal!!!!!!!!!!!!!!!!!!" foi resolvido?

Desde já agradeço aos amigos pela colaboração,

Saudações,

Júlio.

LetoDb e Harbour, como usar.

MensagemEnviado: 19 Ago 2016 15:57
por jelias
Olá Amigos,

Estou usando o LETODB e estou acompanhando no site https://sourceforge.net/projects/letodb/ onde está sendo "comitado" algumas atualizações!

Como faço para baixar estas atualizações?
É através do programa TORTOISE CVS? Já tentei atualizar através do mesmo e aparece a seguinte mensagem de erro!

CVSROOT: cvs -d:pserver:anonymous@letodb.cvs.sourceforge.net:/cvsroot/letodb checkout -r rel-1-mt letodb

Desde já agradeço pela colaboração!

Saudações,

Júlio.

LetoDb e Harbour, como usar.

MensagemEnviado: 19 Ago 2016 16:57
por wagner aragao
OLá

Alguém poderia me passa o link da última versão estável do LetoDB ????

Funciona bem com windows 2008 e 2010 ???

t+

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Ago 2016 11:01
por elrosa
Hello,

does anyone knows what the following error means?

C:/hb30/lib/win/mingw/librddleto.a(letomgmn.o):letomgmn.c:(.text+0xc20): undefined reference to `hb_extIsNil'
C:/hb30/lib/win/mingw/librddleto.a(letomgmn.o):letomgmn.c:(.text+0xc46): undefined reference to `hb_extIsNil'
C:/hb30/lib/win/mingw/librddleto.a(letomgmn.o):letomgmn.c:(.text+0xeee): undefined reference to `hb_extIsNil'
C:/hb30/lib/win/mingw/librddleto.a(letomgmn.o):letomgmn.c:(.text+0x1844): undefined reference to `hb_extIsNil'
C:/hb30/lib/win/mingw/librddleto.a(letomgmn.o):letomgmn.c:(.text+0x19ca): undefined reference to `hb_extIsNil'
C:/hb30/lib/win/mingw/librddleto.a(letomgmn.o):letomgmn.c:(.text+0x19fd): more undefined references to `hb_extIsNil' follow
C:/hb30/lib/win/mingw/librddleto.a(letocl.o):letocl.c:(.text+0xaf5): undefined reference to `__chkstk_ms'
C:/hb30/lib/win/mingw/librddleto.a(leto1.o):leto1.c:(.text+0x8d2a): undefined reference to `hb_extIsNil'
C:/hb30/lib/win/mingw/librddleto.a(leto1.o):leto1.c:(.text+0xa138): undefined reference to `hb_extIsNil'
C:/hb30/lib/win/mingw/librddleto.a(blowfish.o):blowfish.c:(.text+0x375): undefined reference to `__chkstk_ms'
C:/hb30/lib/win/mingw/librddleto.a(blowfish.o):blowfish.c:(.text+0x497): undefined reference to `__chkstk_ms'
collect2: ld returned 1 exit status
hbmk2: Error: Running linker. 1
gcc.exe OBJ/overige.o OBJ/rk.o OBJ/ag.o OBJ/rd.o OBJ/hs.o OBJ/conver.o OBJ/fax.o OBJ/print.o OBJ/browse.o OBJ/getsys.o OBJ/errorsy.o OBJ/rddsys.o OBJ/oops.o OBJ/tn.o OBJ/tn1.o OBJ/tn2.o OBJ/pr.o OBJ/pr2.o OBJ/pr_toep.o OBJ/toep_br.o OBJ/callrap.o OBJ/rl.o OBJ/rl2.o OBJ/rl3.o OBJ/or0.o OBJ/or1.o OBJ/or2.o OBJ/or3.o OBJ/or4.o OBJ/or5.o OBJ/nc_ver.o OBJ/nc_aan.o OBJ/ems.o OBJ/ems2.o OBJ/prspec.o OBJ/euro.o OBJ/budget.o OBJ/html.o OBJ/menuto.o OBJ/div1.o OBJ/div2.o OBJ/div3.o OBJ/hmenu.o OBJ/kostpr.o OBJ/snelcalc.o OBJ/prbudget.o OBJ/brutow.o OBJ/monsters.o OBJ/alloc.o OBJ/pr_overz.o OBJ/pdf.o OBJ/vis.o OBJ/combi.o OBJ/combi2.o OBJ/log_dien.o OBJ/dien_log.o OBJ/levtar.o OBJ/zeevrach.o OBJ/st.o OBJ/reach.o OBJ/harbour.o OBJ/pdfprint.o OBJ/hbmk_yrchxg.o    -mwindows -Wl,--start-group -lhbrtl -lhbvm -lhbcommon -lhbmacro -lhbrdd -lhbsix -lrddntx -lrddfpt -lrddcdx -lxhb -lhbwin -lhbct -lhbnf -lhmg -lhbmzip -lrddleto -lhbextern -lhbdebug -lhbvm -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 -lwinspool -lcomctl32 -lcomdlg32 -lshell32 -luuid -lole32 -loleaut32 -lmpr -lwinmm -lmapi32 -limm32 -lmsimg32 -lwininet -lhbpcre -lhbzlib   -Wl,--end-group -oems.exe  -LC:/hb30/lib/win/mingw -LC:/hb30/bin


Thank you!

Maarten

LetoDb e Harbour, como usar.

MensagemEnviado: 30 Ago 2016 10:50
por Jairo Maia
Hi elrosa,

These errors mean that are missing these functions. I don't know LetoDb, but I know that you need Harbour version 3.2 or 3.4. You are using the Harbour 3.0.

See this topic too: Letodb no linux ubuntu 12.04.

LetoDb e Harbour, como usar.

MensagemEnviado: 08 Mar 2018 03:58
por lugab
Bom dia, everybody...

Quando o executável está no cliente a aula aqui ministrada pelo prof.Itamar transformou o Letodb em algo bem fácil, pois o próprio programa no PC do cliente seta as variáveis necessárias...
Function Main
LOCAL cPath
request leto
rddsetdefault( "LETO" )
set date format "dd/mm/yy"
cPath:= "//25.77.144.122:2812/"
carq="CLIE01"
use (cpath+carq) new
browse()
close
RETU

A pergunta é: Como usar o Letodb se o executavel estiver no servidor, juntamente com os dados e não no PC do cliente ?

Grato pela atenção...

LetoDb e Harbour, como usar.

MensagemEnviado: 08 Mar 2018 06:39
por Itamar M. Lins Jr.
Ola!
É por isso que precisamos aprender outras coisas, antes. O BASICÃO!
TCP/IP o que é isso ? O que é LOCALHOST ? O que é IP FIXO o que é IP DINAMICO ? O que é PORTA TCP ? O que é protocolo UDP e protocolo TCP ?...

A pergunta é: Como usar o Letodb se o executavel estiver no servidor, juntamente com os dados e não no PC do cliente ?

Todo PC "com placa de rede e com protocolo TCP/IP versão 4 ativado" possui um número e um nome. Você pode setar ou com número ou com nome o Letodb.

C:\fontes\SCI_WIN>ping google.com

Disparando google.com [172.217.2.174] com 32 bytes de dados:
Resposta de 172.217.2.174: bytes=32 tempo=619ms TTL=53
Resposta de 172.217.2.174: bytes=32 tempo=600ms TTL=53
Resposta de 172.217.2.174: bytes=32 tempo=612ms TTL=53
Resposta de 172.217.2.174: bytes=32 tempo=572ms TTL=53

Estatísticas do Ping para 172.217.2.174:
    Pacotes: Enviados = 4, Recebidos = 4, Perdidos = 0 (0% de
             perda),
Aproximar um número redondo de vezes em milissegundos:
    Mínimo = 572ms, Máximo = 619ms, Média = 600ms

Como pode ver o nome "google.com" é convertido para 172.217.2.174
Como o letodb tanto faz vc usar "google.com" ou "172.217.2.174"
Então, cPath:= "//25.77.144.122:2812/"
ou cPath := "172.217.2.174:2812" ou cPath := "google.com:2812"


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 08 Mar 2018 13:37
por lugab
Itamar, o que te fiz pra merecer uma resposta prepotente e que não tinha como objetivo responder diretamente a minha pergunta ?
Eu admito que não sou da área, que conheço pouquíssimo sobre o quesito conexões, que o pouco que sei e que aprendi aqui no fórum ,
foi "consertar e atualizar para harbour um antigo sistema em clipper" que eu herdei qdo assumi uma loja da família..

Então, eu vou insistir na pergunta, pra ver se eu ganho uma ajuda real, uma resposta direta...
Aqui nesse tópico eu aprendi a acessar os DBFs via LetdoDB quando o "Teste.exe" se encontra no meu PC de cliente. Nesse caso,
o próprio teste.exe apresenta as linhas de conexão.
A minha questão é "quando além dos DBFs, o "Teste.exe" também está instalado no servidor Letodb"

Eu gostaria de executar esse Teste.exe do servidor a partir do meu PC ( eu acho q não é possível, mas...) eu peço a ajuda de quem possa responder de forma direta....

LetoDb e Harbour, como usar.

MensagemEnviado: 08 Mar 2018 18:42
por Itamar M. Lins Jr.
Ola!
É qui nois é meio assim "acavalado". Mas veja que eu disse "precisamos" eu também não sei. E estou aprendendo.
Agora é que caiu a ficha aqui... eu acho.

No seu executável vc vai ler um arquivo qualquer com a configuração. Pode passar o IP via arquivo ".ini" ou via parâmetro.
c:\xyz>teste.exe //192.168.1.20:2812/

No .PRG vc faz assim ou como achar melhor.
function main(cPath)
hb_default(@cPath,"localhost")


Ou lendo o arquivo .ini com as funções do harbour, eu uso Hwgui, então faço assim:
cServidor := Hwg_GetIni('Config','Servidor'      ,,cIniFile)

Se cServidor for "empty" então eu faço acesso local mesmo.

  //Fragmento de código para dar uma ideia.
   BEGIN SEQUENCE WITH {| oErr | Break( oErr ) }
      If lRddLeto
          If Leto_File(cServidor+cDB)             
             DbUseArea(.T.,"LETO",cServidor+cDB,Apel,.T.,.F.,'PTISO')
          Else
             hwg_Msgstop('LetoDb Não Localizou o Arquivo: ' + cServidor + cDB)
             lRet := .F.
          EndIf
      Else
          DbUseArea(.T.,'DBFCDX',dDados+cDB,Apel,.T.,.F.,'PTISO')
      EndIf


Desculpa ai os coices...
Porque vc compila no seu executável o IP(cPath), não faça assim porque vc está engessando o seu .exe.
Tive que fazer uma analise, reprocessar, loop etc...para entender a sua pergunta. E ainda estou com dúvida se entendi.
Vc até pode fazer da forma que vc usa, mas precisa usar algum nome ao invés de usar números(192.168.0.10) por exemplo uma rede com 5 maquinas.
"servidor", "cpu1', "cpu2", "cpu3" ...
Se vc compilar o teste.exe para abrir a maquina de nome "servidor", vai dar certo também.
cPath:="//servidor:2812/"


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Mar 2018 12:03
por lugab
Ta esclarecido, obrigado

LetoDb e Harbour, como usar.

MensagemEnviado: 09 Mar 2018 13:24
por Itamar M. Lins Jr.
Ola!
Só mais umas coisinhas...
Um computador tem no mínimo 2(DOIS) IP's o que identifica ela na rede que pode ser local "LAN" (Local Area Network) ou a Internet "mundial" que é WAN (Wide Area Network) e mais outro localhost.

O Primeiro IP é ela mesma (não passa pela placa de REDE) pode até desligar a placa ou 127.0.0.1(loopbak) ou podemos usar a palavra "localhost". Para testar qualquer serviço que está usando o protocolo TCP/IP usamos a palavra localhost ou o número 127.0.0.1 que são a mesma coisa. Quando usamos algum NOME é para identificar ela na REDE LOCAL(LAN) e quando queremos acessar ela ou disponibilizar algo tipo servidor Apache ou MYSQL ou os DBF'´s via LetoDbf na WAN temos que criar o DOMÍNIO no nível mundial, usamos o NO-IP, DynDNS que irão gerar o NOME aceito na grande rede(internet). Assim, cpu1casa.ddns.net será atribuído a algum IP válido na Internet e este IP é fornecido por algum provedor de internet ao nosso MODEM. Atrás do modem pode ter "n" IP's na faixa 192.167.... na frente do modem só tem 1 IP.
Para compartilhar ou disponibilizar, criar aplicações "for qualquer coisa", algo na internet, precisamos ter essas noções e quem manda na internet são os navegadores, quase a totalidade que acessamos é via algum navegador ou serviços similares ao WTS (Windows Terminal Service).
Quero saber se o LetoDB está rodando na minha maquina ?
IF ( leto_Connect( "localhost",,,30000 ) ) < 0 //Default is 120.000 aka 2 minutes.
//ou
IF ( leto_Connect( "127.0.0.1",,,30000 ) ) < 0 //Default is 120.000 aka 2 minutes.
...


Isso vai funcionar mesmo se o FIREWALL do windows estiver barrando o LetoDB.
Agora se o LetoDB está em outro CPU tanto faz ser LAN ou WAN ai temos que ABRIR no firewall do windows a porta 2812(em questão) e/ou "se for o caso" ABRIR no MODEM a porta TCP/IP 2812 e direcionar ela para o IP LAN da maquina servidora tanto faz ser Letodb, MySql...

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Mai 2018 13:23
por vcatafesta
Olá pessoal,

Alguém tem idéia de como resolver esse erro no letodb?

Error TERM/2014  Create error: //127.0.0.1:2812/TEXTO.TXT
                       (OS Error 123)


ou deste

 Error TERM/2014  Create error: TESTE.TXT
               (OS Error 3)

         Quit    Retry    Default


att

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Mai 2018 18:58
por Itamar M. Lins Jr.
Ola!
Já procurou na internet que erro é esse ?
Se é do LETO ou do OS ? Permissões, nomes errados... de pastas...arquivos...

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 10 Mai 2018 19:37
por vcatafesta
Olá Itamar,

Esse erro TERM/2014 se dá no ambiente do Letodb.

quanto ao erro 3 - Doserror 3 - Path not found.
SET(24, "TESTE.TXT", .F.)

quanto ao erro 23 - Doserror 123 - 123 Illegal character or invalid file-system name.
SET(24, cPath + "TESTE.TXT", .F.)

O arquivo dbleto.ini está adequadamente configurado, inclusive tudo funciona normal no ambiente leto, criação de tabelas, indice, etc.

Não encontrei qualquer menção na internet a respeito da resolução desse erro:
(SET(24, (xarquivo), .F.) ou SET PRINT TO (xArquivo) no ambiente Leto.

Acredito eu, que seja a mesma situação que ocorre com Fcreate() no ambiente Leto, função essa
que foi substituida, no ambiente Leto pela Leto_Fcreate().

Examinando os fontes do Leto, observei que Leto_Set(), retorna Set(), sem qualquer outro tratamento de criação de arquivo TERM no ambiente Leto.

//server.prg
FUNCTION leto_Set( nSet, xPar1, xPar2 )
   RETURN Set( nSet, xPar1, xPar2 )


no Harbour a função em C, para SET_PRINTFILE

static void open_handle( PHB_SET_STRUCT pSet, const char * file_name,
                         HB_BOOL fAppend, HB_set_enum set_specifier )
{
   HB_STACK_TLS_PRELOAD
   PHB_ITEM pError = NULL;
   PHB_FILE handle, * handle_ptr;
   HB_ERRCODE uiError;
   const char * szDevice = NULL, * def_ext;
   char * szFileName = NULL;
   char ** set_value;
   HB_BOOL fPipe = HB_FALSE, fStripEof;

   HB_TRACE( HB_TR_DEBUG, ( "open_handle(%p, %s, %d, %d)", ( void * ) pSet, file_name, ( int ) fAppend, ( int ) set_specifier ) );

   switch( set_specifier )
   {
      case HB_SET_ALTFILE:
         uiError = 2013;
         set_value = &pSet->HB_SET_ALTFILE;
         handle_ptr = &pSet->hb_set_althan;
         def_ext = ".txt";
         break;
      case HB_SET_PRINTFILE:
         uiError = 2014;
         set_value = &pSet->HB_SET_PRINTFILE;
         handle_ptr = &pSet->hb_set_printhan;
         def_ext = ".prn";
         break;
      case HB_SET_EXTRAFILE:
         uiError = 2015;
         set_value = &pSet->HB_SET_EXTRAFILE;
         handle_ptr = &pSet->hb_set_extrahan;
         def_ext = ".prn";
         break;
      default:
         return;
   }

   if( file_name && file_name[ 0 ] != '\0' )
   {
#if defined( HB_OS_UNIX )
      fPipe = file_name[ 0 ] == '|';
      if( fPipe )
         szFileName = hb_strdup( file_name );
      else
#endif
      {
         szDevice = is_devicename( file_name );
         if( szDevice )
         {
            szFileName = hb_strdup( szDevice );
            def_ext = NULL;
#if defined( HB_OS_WIN ) || defined( HB_OS_DOS )
            fAppend = HB_TRUE;
#endif
         }
         else
            szFileName = hb_strdup( file_name );
      }
   }

   /* free the old value before setting the new one (CA-Cl*pper does it).
    * This code must be executed after setting szFileName, [druzus]
    */
   close_handle( pSet, set_specifier );
   if( *set_value )
   {
      hb_xfree( *set_value );
      *set_value = NULL;
   }

   if( ! szFileName )
      return;

   fStripEof = fAppend && szDevice == NULL && ! fPipe;

   /* Open the file either in append (fAppend) or truncate mode (! fAppend), but
      always use binary mode */

   /* QUESTION: What sharing mode does Clipper use ? [vszakats] */

   do
   {
      if( fPipe )
         handle = hb_filePOpen( szFileName + 1, "w" );
      else
         handle = hb_fileExtOpen( szFileName,
                                  hb_stackSetStruct()->HB_SET_DEFEXTENSIONS ? def_ext : NULL,
                                  ( ! fStripEof || set_specifier == HB_SET_PRINTFILE ? FO_WRITE : FO_READWRITE ) |
                                  FO_DENYWRITE | FXO_SHARELOCK |
                                  ( fAppend ? FXO_APPEND : FXO_TRUNCATE ) |
                                  ( szDevice ? 0 : FXO_DEFAULTS ),
                                  NULL, pError );

      if( handle == NULL )
      {
         pError = hb_errRT_FileError( pError, HB_ERR_SS_TERMINAL, EG_CREATE, uiError, szFileName );
         if( hb_errLaunch( pError ) != E_RETRY )
            break;
      }
   }
   while( handle == NULL );

   if( pError )
      hb_itemRelease( pError );

   if( handle != NULL && fStripEof )
   {
      /* Position to EOF */
      if( hb_fileSeek( handle, 0, FS_END ) > 0 )
      {
         /* Special binary vs. text file handling - even for UN*X, now
            that there's an HB_SET_EOF flag. */

         /* PRINTFILE is always binary and needs no special handling. */
         if( set_specifier != HB_SET_PRINTFILE )
         {
            /* All other files are text files and may have an EOF
               ('\x1A') character at the end (both UN*X and non-UN*X,
               now that theres an HB_SET_EOF flag). */
            char cEOF = '\0';
            hb_fileSeek( handle, -1, FS_END );     /* Position to last char. */
            hb_fileRead( handle, &cEOF, 1, -1 );   /* Read the last char. */
            if( cEOF == '\x1A' )                   /* If it's an EOF, */
               hb_fileSeek( handle, -1, FS_END );  /* Then write over it. */
         }
      }
   }

   /* user RT error handler can open it too so we have to
    * close it again if necessary
    */
   if( handle == NULL )
   {
      hb_xfree( szFileName );
      szFileName = NULL;
   }

   close_handle( pSet, set_specifier );
   *handle_ptr = handle;
   if( *set_value )
      hb_xfree( *set_value );
   *set_value = szFileName;
}

int hb_setUpdateEpoch( int iYear )
{
   if( iYear >= 0 && iYear < 100 )
   {
      int iEpoch = hb_setGetEpoch();
      int iCentury = iEpoch / 100;

      if( iYear < iEpoch % 100 )
         ++iCentury;
      iYear += iCentury * 100;
   }
   return iYear;
}


Resultando que Set(24,..), não tem tratamento adequado no ambiente Leto.

LetoDb e Harbour, como usar.

MensagemEnviado: 14 Mai 2018 13:17
por vcatafesta
Ninguém?!?!?!

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 08:24
por Itamar M. Lins Jr.
Ola!
OOOOxi... que isso rapaz.... que está querendo ?
Resultando que Set(24,..), não tem tratamento adequado no ambiente Leto.

Quem disse que é da forma que vc está "entendendo" ?
Esses erros ai não tem nada a ver com o Letodbf.
No caso do SET ele o letodbf passa a bola para o harbour... não tem necessidade de reinventar a roda...
O SET(...) é do Harbour não do letodbf.
Mostre os seus códigos, como está fazendo...? e não como está entendendo.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 12:01
por vcatafesta
Justamente Itamar!

O codigo é simplesmente uma chamada para imprimir para arquivo.

Set(24, (xArquivo), .F.) ou Set Print to (xarquivo)


O Leto está passando a "bola" de todas as chamadas a SET() para o Harbour,
inclusive a Set(24, (xArquivo). .F.) ou Set Print To (xArquivo).

Ocorre que essa chamada é para TERM, e em ambiente leto gera erro, e como mencionei
anteriormente.

Penso eu, que para imprimir para arquivo em ambiente Leto, faltaria um tratamento
para o Set(24,...), da mesma forma que foi com o FCreate, agora em ambiente Leto Leto_Fcreate,
entendeu?

att

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 13:24
por asimoes
Olá, já verificou as permissões na pasta ?

Outra coisa mostra o seu letodb.ini pra gente dar uma comparada.

Deixa eu entender isso, você tá querendo gerar um arquivo no servidor letodb ? é isso ?

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 13:38
por Itamar M. Lins Jr.
Ola!
Não precisa do Letodbf para pegar o erro.
Set(24, (xArquivo), .F.) ou Set Print to (xarquivo)

Esse erro vai ocorrer sem uso do letodbf. Simule ele ai sem usar o Letodbf que vai ocorrer.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 13:44
por Itamar M. Lins Jr.
Ola!
Use as novas funções do harbour para trabalhar em rede.
hb_vf*
hbmk2 -find hb_vf*
Núcleo Harbour (instalado):
   hb_socketRecvFrom()
   hb_vfAttrGet()
   hb_vfAttrSet()
   hb_vfClose()
   hb_vfCommit()
   hb_vfConfig()
   hb_vfCopyFile()
   hb_vfDirectory()
   hb_vfDirExists()
   hb_vfDirMake()
   hb_vfDirRemove()
   hb_vfDirSpace()
   hb_vfEof()
   hb_vfErase()
   hb_vfExists()
   hb_vfFlush()
   hb_vfHandle()
   hb_vfLink()
   hb_vfLinkRead()
   hb_vfLinkSym()
   hb_vfLoad()
   hb_vfLock()
   hb_vfLockTest()
   hb_vfMoveFile()
   hb_vfOpen()
   hb_vfRead()
   hb_vfReadAt()
   hb_vfReadLen()
   hb_vfRename()
   hb_vfSeek()
   hb_vfSize()
   hb_vfTempFile()
   hb_vfTimeGet()
   hb_vfTimeSet()
   hb_vfTrunc()
   hb_vfUnlock()
   hb_vfWrite()
   hb_vfWriteAt()
   sx_VFGet()


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 14:18
por Itamar M. Lins Jr.
Ola!
você tá querendo gerar um arquivo no servidor letodb ? é isso ?

Eu entendi que ele está querendo imprimir no servidor ou em algum lugar via direcionamento.
cArq := "\\192..."
set printer to cArq

Isso não é erro do letodbf e ele também não faz isso, é preciso usar as funções hb_VF* do Harbour com as devidas permissões etc...
Melhor usar o servidor de impressão do windows mesmo na minha opnião.
Porque tem o leto_fcreate, etc... e não tem o leto_set_printer_to...? não tem necessidade nenhuma... basta gerar em qualquer maquina e jogar no gerenciador de impressão via printfileraw() por exemplo.

Bemmmm, foi isso que entendi até agora.(salvo engano)

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 14:39
por vcatafesta
Olá,

Pessoal, o erro somente ocorre no ambiente Leto.

Olá, já verificou as permissões na pasta ?

sim, todas as permissões OK, inclusive as tabelas e índices são criados normalmente no
servidor.

Deixa eu entender isso, você tá querendo gerar um arquivo no servidor letodb ? é isso ?

Sim, ao criar arquivo no servidor Leto o erro é gerado.

Não precisa do Letodbf para pegar o erro.

Claro que não! o erro somente ocorre ao tentar criar o arquivo no servidor. Ao gerar arquivo localmente o erro não ocorre.

Isso não é erro do letodbf e ele também não faz isso, é preciso usar as funções hb_VF* do Harbour com as devidas permissões etc...


Ok. Vou tentar com as funcões hb_vf*

Mas não deixa de ser um erro!

LetoDb e Harbour, como usar.

MensagemEnviado: 15 Mai 2018 15:00
por asimoes
Olá,

Você pode criar uma função de usuário pra ser usado pelo letodb pra fazer o que você quer, dá uma olhada em letoudf.prg

LetoDb e Harbour, como usar.

MensagemEnviado: 22 Out 2018 14:48
por porter
Olá pessoal,
Estou tentando executar o exemplo desse tópico para entender como funciona o letodb, mas está dando erro de compilação, dentro da pasta c:\letodb,
tenho os seguintes arquivos: Changelog, letocdp.ch, letocl.dll, letodb.exe, letodb.ini, letodb.log, libleto.a, librddleto.a, rddleto.ch.
executei o comando: net start letodb_service
O serviço LetoDB Service foi iniciado com êxito.

cannot find -lrddleto
collect2.exe error: ld returned 1 exit status
Erro de compilação: hbmk2[TESTE]: Erro: Executando linkeditor .1

letodb.ini na pasta c:\letodb
Port = 2812              
Logfile = "letodb.log"   
DEFAULT_DRIVER = CDX     
DATAPATH = c:\dados\
ENABLEFILEFUNC = 1
CRYPT_TRAFFIC = 0
PASS_FOR_LOGIN = 0
PASS_FOR_MANAGE = 0
PASS_FOR_DATA = 0
Share_Tables  = 0
Cache_Records = 50
[DATABASE]
DataPath = c:\dados\
Driver = CDX


teste.hbp na pasta c:\dados
-otesteleto  
-compr=yes
-quiet
-lxhb
-lhbwin
-lhbct
-prgflag=-b               
-strip
-compr
rddleto.hbc
-iC:\letodb
TESTLETO.PRG


compilar.bat
@echo off
CLS
set path=C:\hb32\bin;C:\hb32   
CLS
HBMK2 TESTE.HBP


rddleto.hbc na pasta c:\dados
{win}incpaths=c:\letodb\include;
{win}libpaths=c:\letodb\lib;
{win}libs=rddleto


hbmk.hbm na pasta c:\dados
rddleto.hbc


testleto.prg na pasta c:\dados
//  #require "sddodbc" //opcional se for usar MySql com LetoDb
//   #require "sddfb"  //opcional se for usar Firebird com Letodb
   #include "rddleto.ch"
   
     REQUEST DBFCDX, DBFFPT, DBFDBT, LETO
     REQUEST HB_LANG_PT, HB_CODEPAGE_PTISO, HB_CODEPAGE_PT850
     
     REQUEST  SQLMIX, SDDODBC //opcional se for usar MySQL ou Firebird etc...
     
     Function Main
     Local cPATH := "//localhost:2812/" //não precisa informar o caminho dos DBF´s porque já foi informado(configurado) no arquivo leotdb.ini
   
     REQUEST LETO
     RDDSETDEFAULT("LETO")
     
     //Conectando com o servidor LetoDb.
     
           nConect := leto_Connect( cPath)
           IF nConect == -1
               nRes := leto_Connect_Err()
              IF nRes == LETO_ERR_LOGIN
                 alert( "Falha ao Logar" )
              ELSEIF nRes == LETO_ERR_RECV
                alert( "Error ao conectar" )
              ELSEIF nRes == LETO_ERR_SEND
                 alert( "Erro de envio" )
              ELSE
                 alert( "Não connectado ao servidor: " + cPath )
              ENDIF
              Return .F.
           ENDIF
     
     cIndex  := cPATH+"PRODUTOS.cdx"
     
     cDbf := cPATH+"PRODUTOS.dbf"
     
     DbUseArea(.t.,'LETO',"PROD",.T.,.F.,'PTISO')
     If leto_file(cIndex)
        DBSETINDEX( cIndex )
     Else
*       index on ...//seu código
*       index on ... //seu código
       index on codmercad to codigo
     EndIf
   return


Harbour 3.2.0(dev)

LetoDb e Harbour, como usar.

MensagemEnviado: 22 Out 2018 18:27
por Itamar M. Lins Jr.
Ola!
Eu não uso "set PATH" mais, nem olho mais isso. o HBMK2 faz tudo!
Se vc informa que o arquivo a biblioteca está na pasta. c:\letodb\lib ? o hbmk2 vai procurar lá.
Mas pelo que vi não tens a tal pasta está tudo dentro do c:\letodb. Correto ? basta corrigir um dos dois.
{win}libpaths=c:\letodb\lib;


O hbmk2 está procurando ai.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 28 Out 2018 10:16
por porter
Bom dia Itamar,
Estou abrindo arquivo compartilhado conforme essa rotina, gostaria de saber se para abrir os índices, somente
funciona com o DBSETINDEX ou com o SET INDEX também da certo, com o SET INDEX está dando erro: Error LETO/1003 Open error: c:\dados\cIndex2.
Se conseguir abrir os índices com SET INDEX, não preciso mudar no sistema, outra dúvida, os índices tem que ser recriados ?

REQUEST LETO            
RDDSETDEFAULT("LETO")
cPATH     := "//localhost:2812/"
cIndex1   := cPATH + "codigo.cdx"
cIndex2   := cPATH + "desc.cdx"   
USE (cPath+"PRODUTOS") SHARED
SET INDEX TO cIndex2,cIndex1


Harbour 3.2.0(dev)

LetoDb e Harbour, como usar.

MensagemEnviado: 28 Out 2018 12:58
por Itamar M. Lins Jr.
Ola!
Oxi ??? e precisa de vários CDX's para um único DBF ? nunca vi.
Geralmente usamos TAG x, TAG y... o contrário, tudo dentro de um único CDX, vários INDICES dentro de 1 CDX.
Não precisa desse cPATH ai também não.
LOGOU/Conectou no LETODBf, o resto é como sempre usamos.
use produtos.dbf new shared
set index to ... // com "SET AUTOPEN ON", nem precisa disso o tal set index...


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Out 2018 10:06
por porter
Bom dia Itamar,
Estou tentando adaptar ao sistema, o exemplo do início desse tópico, compilei e executou normalmente,
se não usar o cPath, dá erro quando for abrir o arquivo: Error LETO/1021 Data Type Error: PRODUTOS.DBF,
estou conectando o LetoDb, não estou usando TAGS, crio vários CDX para o arquivo e abro com SET INDEX.

Harbour(3.2.0)dev
em modo console

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Out 2018 17:33
por Itamar M. Lins Jr.
Ola!
Olha eu estou usando o LetoDBf. Versão do GIT 2018-10-10 11:21. Harbour 3.4 GCC 7.3
É bom identificar qual LetoDB está usando versão etc...
Porque se der erro será sempre a que está no GIT que ele vai corrigir.
Vc pode postar seu código para tetarmos executar aqui, para ver se é um BUG e caso for um BUG, reportarmos ao Elch.
Precisa postar um exemplo enxuto que demostre o problema.

Eu uso assim:
      nConect := leto_Connect( cPath)


Esse post é velho de 2014, não uso mais o LetoDB, uso agora o LetoDBf.
Depois que conectar no LetoDBf, não precisa do: cPATH:="//192.168...:2812/".
Basta "use xyz.dbf"

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 29 Out 2018 18:10
por porter
Olá Itamar,
Resolvi fazer download do LetoDBF pelo GIT, porque pelo que li no fórum, está mais atualizado, então descompactei
e instalei o LetoDBF, eu até havia conseguido compilar o LetoDB, mas o LetoDBF, não estou conseguindo
compilar, o procedimento para compilar o LetoDBF é o mesmo do LetoDB, são os mesmos arquivos usados no LetoDB ?

Obrigado.

LetoDb e Harbour, como usar.

MensagemEnviado: 30 Out 2018 11:05
por Jairo Maia
Para compilar o LtoDBf, use Hbmk2 letodb.hbp. Será gerado o executável na pasta bin.

LetoDb e Harbour, como usar.

MensagemEnviado: 21 Nov 2018 09:11
por bwr2018
Bom dia, sou novo aqui no forum perdoem se estou postando algo de forma errada. Estou com o seguinte problema:
1 - Eu consigo me conectar com o letodb.
2 - Eu consigo me conectar com o banco de dados na rede.
3 - Eu consigo manipular os campos do banco na rede.
4 - O banco de dados da rede é atualizado com dbcommitall().

Tudo parece perfeito, mas as maquinas tanto a servidora quanto as estações não me mostram os valores atualizados na tela rsrs.
Segue as funções de conexão, gravação, update e amostragem.

Função de conexão
procedure connect_server
local iSecs2
local iFalha := 0
local iSecs1 := abs( seconds() )
do while abs( seconds() - iSecs1 ) < 300
   //se conseguimos conectar
   if leto_Connect( "//192.168.0.1:2812/" ) <> -1
      //se enxerguei o banco vamos tentar nos conectar
      if leto_file( FILE_SERVER )
         //vamos dizer ao programa que estamos conectado
         bConected := .t.
         //seleciono a area de trabalho com numero 6
         select 6
         //e vamos abrir o banco de dados do servidor no modo compartilhado
         USE FILE_SERVER SHARED NEW ALIAS LAN
         //se chegamos até aqui, se não houve erro na abertura do arquivo só resta sair do loop
         if !neterr() .and. !empty( alias() )
            exit
         else
            ? "Erro ao abrir banco de dados"
            inkey(0)
            quit
         endif
      //se não conseguimos
      else
         //vamos dizer ao programa que ainda não nos conectamos
         //mostramos na tela que estamos tentando
         ? "Tentativa de conexao com o banco de dados ",alltrim(str(++iFalha))," -> falha"
         ? "Proxima tentativa em 1 minuto"
         ? "Procurando...",FILE_SERVER
         bConected := .f.
      endif
   //se não enxerguei o banco
   else
      //mostramos na tela que estamos tentando
      ? "Tentativa de conexao com o servidor ",alltrim(str(++iFalha))," -> falha"
      ? "Proxima tentativa em 1 minuto"
   endif
   if abs( seconds() - iSecs1 ) < 300
      //aguardamos 1 minuto aqui
      iSecs2 := abs( seconds() )
      do while abs( seconds() - iSecs2 ) < 60
         if inkey() == 27
            quit
         endif
      enddo
   else
      exit
   endif
enddo
//se ficamos aqui tentando por mais de 5 minutos
//e não conseguimos nos conectar
if abs( seconds() - iSecs1 ) >= 300
   ? "Fim das tentativas inciando local..."
   //então dizemos ao programa que não conseguimos portanto tudo sera local
   bConected := .f.
   inkey(5)
endif
return


Função de gravação
procedure dbxput_server(cField, xValor)
do while !dbrlock()
enddo
field->&cField := xValor
dbunlockall()
return


Função de update
procedure update_dbf
dbcommitall()
return


Amostragem simples
@ 10,10 say "INCREMENTO REG 1: "+alltrim(str(LAN->REG1))
@ 11,10 say "INCREMENTO REG 2: "+alltrim(str(LAN->REG2))
@ 12,10 say "INCREMENTO REG 3: "+alltrim(str(LAN->REG3))
@ 13,10 say "INCREMENTO REG 4: "+alltrim(str(LAN->REG4))
@ 14,10 say "INCREMENTO REG 5: "+alltrim(str(LAN->REG5))
@ 15,10 say "INCREMENTO REG 6: "+alltrim(str(LAN->REG6))
@ 16,10 say "INCREMENTO REG 7: "+alltrim(str(LAN->REG7))


Agora o mais intrigante de tudo isso, é que se eu ficar abrindo e fechando o banco ai sim eu consigo os valores atualizados.
Meu conhecimento é bem raso sobre banco de dados. Mas o que da entender é que o programa só mostra os valores de incremento da própria estação e não o que realmente está gravado no banco de dados do servidor.
Enfim não tenho mais para onde correr rsrs, então recorri ao forum. Agradeço desde já aqueles que puderem me ajudar nessa questão.

LetoDb e Harbour, como usar.

MensagemEnviado: 21 Nov 2018 11:49
por Jairo Maia
Olá bwr2018,

Seja bem vindo ao fórum.

Não tenho esse problema, inclusive, se alguma estação estiver aberta com o TBrowse no arquivo clientes por exemplo, e alguma estação cadastrar algum cliente, meu TBrowse faz um refresh a cada 15 segundos se estiver parado, e já aparece o novo cadastro na tela de todas estações.

Como você disse que após algumas tentativas consegue ver os dados atualizados, uma pergunta: Você está encerrando o LetoDBf ao encerrar a aplicação? Não sei se é o caso, mas apenas para verificar se pode ser isso, coloque em qualquer arquivo .PRG a função EXIT PROCEDURE, e se já existir, acrescente a desconexão do LetoDBF nela. Exemplo:
Exit Func Encerrar()  // chamada automaticamente quando o sistema é fechado.

Leto_DisConnect()    // desconecta a conexão LetoDBf (Local ou não)...

Return Nil
Isso é a única coisa que me ocorre no momento.

Isso não quer dizer que tenha que fechar o aplicativo para ver as atualizações, isso significa apenas que não haverá conflito de conexões do Leto.

LetoDb e Harbour, como usar.

MensagemEnviado: 21 Nov 2018 12:17
por Jairo Maia
bwr2018, veja tambem se isso ajuda:

Acrescente em seu arquivo letodb.ini o comando: HardCommit = 1, e reinicie o serviço LetoDbf Service para isso ter efeito.

Ativando esse comando (colocando 1 ao invés de deixar zero - padrão) fará com que os dados sejam salvos imediatamente em disco, ignorando o cache do sistema operacional. Pode ser que ajude.

HardCommit = 0 - if 0, SET HARDCOMMIT OFF, this is now DEFAULT.
It is recommended for UNSTABLE running server to set it to <1>,
which means that each change at data tables are immedeate written to
harddrive bypassing the OS cache.

LetoDb e Harbour, como usar.

MensagemEnviado: 21 Nov 2018 12:46
por bwr2018
Olá Jairo, a função exit procedure existe sim, e já esta com o leto_disconnect(). Mas a sua segunda opção é uma boa. Não tinha me atentado para isso. Vou implementar e testar. Mais um detalhe que deixei escapar. Esse banco não uso nenhum tipo de index nele, não vi a necessidade disso pois se trata de um banco com apenas um registro. Varios campos para ser exato 12 campos onde eu os incremento. Será que é por isso? Eu devo criar o index?

LetoDb e Harbour, como usar.

MensagemEnviado: 22 Nov 2018 07:31
por Jairo Maia
bwr2018 escreveu:Esse banco não uso nenhum tipo de index nele, [...]. Será que é por isso?
Creio que não. Mas como você está em fase de testes, seria interessante se você indexasse esse arquivo e repetisse os testes, e reportasse aqui. Reporte também se funcionou ou não o comando HardCommit,assim ficaria para registro a outros que venham ter esse problema.

NOTA: lembrando que só é recomendado usar HardCommit se houver instabilidade do servidor, ou em outras palavras, se houver demora para gravar os dados em disco.

LetoDb e Harbour, como usar.

MensagemEnviado: 22 Nov 2018 12:46
por bwr2018
Perfeito Jairo, vou fazer esses testes no sábado e retorno aqui. Muito obrigado por enquanto!

LetoDb e Harbour, como usar.

MensagemEnviado: 23 Nov 2018 18:00
por bwr2018
Bem, disse no sábado mas a ansiedade não me deixou rsrs. Primeiro que fiz o que o colega Jairo falou mudei HardCommit = 0, para 1. O problema ainda persiste. Vou postar aqui o código completo dos testes que estou fazendo, para os amigos que se interessarem em ajudar. Lembrando que a forma que vou postar é a forma que fiz funcionar. Abrindo e fechando o banco. Mas creio que não seja a mais correta. Bom esse é um problema contornado em partes. Agora surgiu outro, que é quando cai a conexão do servidor. No caso simulei aqui somente removi o cabo da rede, o programa que rodava na estação travou e eu não consegui fazer mais nada. Somente após conectar o cabo novamente ele conseguiu restabelecer a conexão. E então o programa ficou disponível novamente. Ainda nesse teste o servidor continuou operando normal mesmo sem estar conectado a rede. Segue o codigo.

Programa
#define FILE_LOCAL  "/home/bruno/server/banco.dbf"
#define FILE_LETODB "/usr/local/bin/letodb"
#define FILE_SERVER "banco.dbf"
#define NETSERVER   "192.168.0.1"
#define NETPORT     "2812"

request RDDLETO
memvar getlist

field INCSERV1
field INCSERV2
field INCSERV3
field INCSERV4
field INCSERV5
field INCSERV6
field INCSERV7
field INCLOCAL1
field INCLOCAL2
field INCLOCAL3
field INCLOCAL4
field INCLOCAL5
field INCLOCAL6
field INCLOCAL7

procedure main(param1)
local secs,tk
set date british
set date format "dd/mm/yyyy"
set century on

init_database()

if ( empty( param1 ) )
   cls
   ? "./browse 0 - para iniciar como servidora"
   ? "./browse 1 - para iniciar como estacao"
   quit
endif
if ( param1 == '0' )
   init_service_leto()
endif

if leto_Connect( "//"+NETSERVER+":"+NETPORT+"/" ) == -1
   alert("Sem conexao")
   clear all
   close all
   quit
endif

cls
secs := abs(seconds())
do while .t.

   tk := inkey(0.1)

   if tk == 27
      quit
   endif

   if tk == 13

      dbselectarea("W")

      dbxput( "INCLOCAL1", INCLOCAL1 + 1 )
      dbxput( "INCLOCAL2", INCLOCAL2 + 1 )
      dbxput( "INCLOCAL3", INCLOCAL3 + 1 )
      dbxput( "INCLOCAL4", INCLOCAL4 + 1 )
      dbxput( "INCLOCAL5", INCLOCAL5 + 1 )
      dbxput( "INCLOCAL6", INCLOCAL6 + 1 )
      dbxput( "INCLOCAL7", INCLOCAL7 + 1 )
     
      USE FILE_SERVER SHARED NEW ALIAS LAN
      if neterr() .or. empty( alias() )
         alert("Erro ao abrir banco de dados")
      else
         dbselectarea("LAN")
      endif

      dbxput_server( "INCSERV1", INCSERV1 + 1 )
      dbxput_server( "INCSERV2", INCSERV2 + 1 )
      dbxput_server( "INCSERV3", INCSERV3 + 1 )
      dbxput_server( "INCSERV4", INCSERV4 + 1 )
      dbxput_server( "INCSERV5", INCSERV5 + 1 )
      dbxput_server( "INCSERV6", INCSERV6 + 1 )
      dbxput_server( "INCSERV7", INCSERV7 + 1 )

      update_dbf()

      LAN->( dbclosearea() )

   endif

   if abs( seconds() - secs ) > 0.3

      dbselectarea("W")     

      @ 0,43 say "BANCO LOCAL"
      @ 2,41 say "INCREMENTO 1: "+alltrim(str(INCLOCAL1))
      @ 3,41 say "INCREMENTO 2: "+alltrim(str(INCLOCAL2))
      @ 4,41 say "INCREMENTO 3: "+alltrim(str(INCLOCAL3))
      @ 5,41 say "INCREMENTO 4: "+alltrim(str(INCLOCAL4))
      @ 6,41 say "INCREMENTO 5: "+alltrim(str(INCLOCAL5))
      @ 7,41 say "INCREMENTO 6: "+alltrim(str(INCLOCAL6))
      @ 8,41 say "INCREMENTO 7: "+alltrim(str(INCLOCAL7))
     
      USE FILE_SERVER SHARED NEW ALIAS LAN
      if neterr() .or. empty( alias() )
         alert("Erro ao abrir banco de dados")
      else
         dbselectarea("LAN")
      endif

      @ 0,3 say "BANCO SERVIDOR"
      @ 2,1 say "INCREMENTO 1: "+alltrim(str(INCSERV1))
      @ 3,1 say "INCREMENTO 2: "+alltrim(str(INCSERV2))
      @ 4,1 say "INCREMENTO 3: "+alltrim(str(INCSERV3))
      @ 5,1 say "INCREMENTO 4: "+alltrim(str(INCSERV4))
      @ 6,1 say "INCREMENTO 5: "+alltrim(str(INCSERV5))
      @ 7,1 say "INCREMENTO 6: "+alltrim(str(INCSERV6))
      @ 8,1 say "INCREMENTO 7: "+alltrim(str(INCSERV7))

      LAN->( dbclosearea() )

      secs := abs( seconds() )
   endif

enddo
leto_disconnect()
quit

procedure init_service_leto
cls
? "Iniciando letodb..."
hb_run(FILE_LETODB)
? "Letodb iniciado...."
inkey(3)
return

procedure init_database
local cDbf_File := "banco.dbf"
if file(cDbf_File)
   dbusearea(.t., NIL, cDbf_File, "W", NIL, .f.)
else
   cls
   alert(cDbf_File+" nao encontrada!")
   quit
endif
return

procedure dbxput(local1,local2)
field->&local1 := local2
return

procedure dbxput_server(cField, xValor)
do while .t.
   if ( LAN->( dbrlock() ) )
      field->&cField := xValor
      LAN->( dbunlock() )
      exit
   else
      alert("Sem conexao")
      exit
   endif
enddo
return

procedure update_dbf
dbcommitall()
return


Make para compilação
-obrowse
-w3
-es2

-lrddleto

browse.prg


Banco
//REQUEST DBFCDX
memvar getlist

procedure main
local aDbf := {}
set date british
set date format "dd/mm/yyyy"
setcancel(.f.)
set century on

aadd(aDbf,{"INCSERV1"   , "N",  12,  4})
aadd(aDbf,{"INCSERV2"   , "N",  12,  4})
aadd(aDbf,{"INCSERV3"   , "N",  12,  4})
aadd(aDbf,{"INCSERV4"   , "N",  12,  4})
aadd(aDbf,{"INCSERV5"   , "N",  12,  4})
aadd(aDbf,{"INCSERV6"   , "N",  12,  4})
aadd(aDbf,{"INCSERV7"   , "N",  12,  4})
ferase("base.dbf")             
//dbCreate( "base.dbf", aDbf, "DBFCDX", .T., "W" )
DbCreate("base.dbf", aDbf,,.t.,"W")
W->(dbAppend())
W->INCSERV1 := 0
W->INCSERV2 := 0
W->INCSERV3 := 0
W->INCSERV4 := 0
W->INCSERV5 := 0
W->INCSERV6 := 0
W->INCSERV7 := 0
commit
clear all
close all
quit


Bom pessoal é isso, o caso de não atualizar se não tiver solução tudo bem. Agora esse caso do travamento caso a conexão com o servidor seja perdida isso é bem ruim acaba inviabilizando o uso da ferramenta. Será que existe algum tratamento para isso alguma maneira de esta sempre verificando se a conexão ainda esta ativa? Fico no aguardo muito obrigado por enquanto.

LetoDb e Harbour, como usar.

MensagemEnviado: 23 Nov 2018 19:48
por asimoes
Olá eu trocaria:

leto_Connect( "//"+NETSERVER+":"+NETPORT+"/" )

Por

leto_Connect( "//"+NETSERVER+":"+NETPORT+"/", , , -1 )

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Nov 2018 09:47
por bwr2018
Olá, e qual é a diferença amigo?

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Nov 2018 11:02
por asimoes
bwr2018 escreveu:Olá, e qual é a diferença amigo?


Olá,

Eu tinha alguns problemas com acesso a tabelas, modifiquei o parâmetro de timeout para -1 e nunca mais tive problemas.

Agora as respostas para as suas perguntas estão no arquivo ChangeLog.txt pra saber das correções/novidades e no readme.txt que é o manual.

Outra coisa importante mantenha sempre atualizada a versão do letodbf, eu faço assim antes de atualizar faço uma cópia da versão em uso (backup) qq comportamento fora do normal uso a versão anterior.

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Nov 2018 22:44
por Itamar M. Lins Jr.
Ola!
Agora esse caso do travamento caso a conexão com o servidor seja perdida isso é bem ruim acaba inviabilizando o uso da ferramenta.

E é para acontecer o quê neste caso ? Eu não estou entendendo.

      HardCommit = 0           -    if 0, SET HARDCOMMIT OFF, this is now DEFAULT.
                                    It is recommended for UNSTABLE running server to set it to <1>,
                                    which means that each change at data tables are immedeate written to
                                    harddrive bypassing the OS cache.
                                    Expect significant reduced performance with setting '1'.

Será que existe algum tratamento para isso alguma maneira de esta sempre verificando se a conexão ainda esta ativa?

No caso da pergunta acima, a resposta está no capitulo 7.1 do arquivo Readme.txt do LetoDbf.
Mas continuo sem entender nada. A Conexão tem ficar ativa o tempo TODO mesmo, se cair congela a aplicação! Não é assim com qualquer programa ?
Qual é o programa que "em usando" a rede e a conexão cair, continua funcionando ?
      LETO_DETECT( [ cService ],[ nNrOfPossible ],[ nPort ] )  ==> cServerIP
This functions sends a broadcast into the local network, to all available interfaces,
(virtual) interfaces loopback (lo) and other without MAC address are excluded from that.
Default <cService> is "letodb", and this is correlating to the server side:
see in example letodb.ini for config option: BC_Services = letodb;
Such configured LetoDBf server then will respond to this query with its IP/Port,
where <cServerIP> is in the format: "//9.9.9.9:2812/" to be used i.e. to connect
to the server: Leto_Connect( Leto_Detect() ),
With <nNrOfPossible> can be selected between multiple server responding to same service name.
Alternative to new build-in at server was before a standalone exe: 8.2. 'Uhura'


Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Nov 2018 22:46
por Itamar M. Lins Jr.
Ola!
Uhura é uma homenagem ao personagem de Jornada Nas Estrelas.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 24 Nov 2018 23:21
por Jairo Maia
bwr2018 escreveu: Agora esse caso do travamento caso a conexão com o servidor seja perdida isso é bem ruim acaba inviabilizando o uso da ferramenta. Será que existe algum tratamento para isso alguma maneira de esta sempre verificando se a conexão ainda esta ativa?
Para verificar se a conexão está ativa basta usar a dica do Itamar acima, já para evitar o "travamento", basta NÃO usar TimeOut = -1.

Assim, quando perder a conexão com o servidor o comportamento será como qualquer outro sistema, como sua internet por exemplo, ou seja, "morre tudo".

TimeOut = -1 - Connection timeout in seconds, -1 means infinite wait.
This timeout determine, how long a write to network/ wait for requested workarea
will wait to succeed, before the thread for the connection give up.
If used: Zombie_Check, this value shell be shorter than that.

LetoDb e Harbour, como usar.

MensagemEnviado: 25 Nov 2018 10:59
por asimoes
Por acaso trabalha com plugin de banco ? gaspro ou outro ?, antivirus também interfere, isso acontece em mais de uma estação ?

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Nov 2018 11:17
por bwr2018
Itamar M. Lins Jr. escreveu:Ola!
Agora esse caso do travamento caso a conexão com o servidor seja perdida isso é bem ruim acaba inviabilizando o uso da ferramenta.

E é para acontecer o quê neste caso ? Eu não estou entendendo.

      HardCommit = 0           -    if 0, SET HARDCOMMIT OFF, this is now DEFAULT.
                                    It is recommended for UNSTABLE running server to set it to <1>,
                                    which means that each change at data tables are immedeate written to
                                    harddrive bypassing the OS cache.
                                    Expect significant reduced performance with setting '1'.

Será que existe algum tratamento para isso alguma maneira de esta sempre verificando se a conexão ainda esta ativa?

No caso da pergunta acima, a resposta está no capitulo 7.1 do arquivo Readme.txt do LetoDbf.
Mas continuo sem entender nada. A Conexão tem ficar ativa o tempo TODO mesmo, se cair congela a aplicação! Não é assim com qualquer programa ?
Qual é o programa que "em usando" a rede e a conexão cair, continua funcionando ?
      LETO_DETECT( [ cService ],[ nNrOfPossible ],[ nPort ] )  ==> cServerIP
This functions sends a broadcast into the local network, to all available interfaces,
(virtual) interfaces loopback (lo) and other without MAC address are excluded from that.
Default <cService> is "letodb", and this is correlating to the server side:
see in example letodb.ini for config option: BC_Services = letodb;
Such configured LetoDBf server then will respond to this query with its IP/Port,
where <cServerIP> is in the format: "//9.9.9.9:2812/" to be used i.e. to connect
to the server: Leto_Connect( Leto_Detect() ),
With <nNrOfPossible> can be selected between multiple server responding to same service name.
Alternative to new build-in at server was before a standalone exe: 8.2. 'Uhura'


Saudações,
Itamar M. Lins Jr.


E é para acontecer o quê neste caso ? Eu não estou entendendo.
R: Eu penso que eu tinha que ter pelo menos a chance de interceptar esse travamento.

A Conexão tem ficar ativa o tempo TODO mesmo, se cair congela a aplicação!
R: Não em entendi o seu "TODO"

Não é assim com qualquer programa ?
R: Não, ou pelo menos algo que informe que a conexão caiu.

Qual é o programa que "em usando" a rede e a conexão cair, continua funcionando ?
R: Qualquer programa que façamos um tratamento para isso. Visto que eu tenho o mesmo banco no servidor o no local. Acho que o amigo não leu meu codigo ou passou despercebido. Pois eu faço o mesmo incremento no servidor e no local. Então se a conexão com o servidor cair eu sigo usando o banco local. Desde que eu tenha a CHANCE de perceber ou detectar que a conexão caiu.

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Nov 2018 11:22
por bwr2018
Jairo Maia escreveu:
bwr2018 escreveu: Agora esse caso do travamento caso a conexão com o servidor seja perdida isso é bem ruim acaba inviabilizando o uso da ferramenta. Será que existe algum tratamento para isso alguma maneira de esta sempre verificando se a conexão ainda esta ativa?
Para verificar se a conexão está ativa basta usar a dica do Itamar acima, já para evitar o "travamento", basta NÃO usar TimeOut = -1.

Assim, quando perder a conexão com o servidor o comportamento será como qualquer outro sistema, como sua internet por exemplo, ou seja, "morre tudo".

TimeOut = -1 - Connection timeout in seconds, -1 means infinite wait.
This timeout determine, how long a write to network/ wait for requested workarea
will wait to succeed, before the thread for the connection give up.
If used: Zombie_Check, this value shell be shorter than that.


Olá Jairo, vou verificar o TimeOut, confesso editei muito pouco o meu letodb.ini e tbm meu conhecimento em rede é muito mas muito raso. Então agradeço demais toda ajuda de vcs.

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Nov 2018 11:26
por bwr2018
asimoes escreveu:Por acaso trabalha com plugin de banco ? gaspro ou outro ?, antivirus também interfere, isso acontece em mais de uma estação ?


Ola asimoes, não cara estou em fase de testes ainda usando um distro linux slackware 13.1 até bem antiga mas sempre me dei bem com ela. Confesso que nem sei o que são esses plugins que vc citou. E sim, acontece em todas estações. Se eu desconectar o cabo da servidora todas outras congelam.

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Nov 2018 11:35
por bwr2018
Segue como está meu letodb.ini, não mudei nada do original a não ser [Server], [Port] e [DataPath].

Server = 192.168.0.1
Port = 2812
DataPath = /home/bruno/server
;LogPath = /tmp
Default_Driver = CDX
;Lock_Scheme = 6
;Memo_Type = FPT
Share_Tables = 0
No_Save_WA = 1
Lower_Path = 0
EnableFileFunc = 1
EnableAnyExt = 1
Allow_UDF = 1
Pass_for_Login = 0
Pass_for_Manage = 0
Pass_for_Data = 0
;Pass_File = leto_users
Cache_Records = 21
;Max_Vars_Number = 1000
;Max_Var_Size = 67108864
;Tables_Max = 999
;Users_Max = 99
Debug = 1
Optimize = 1
;AutOrder = 0
;ForceOpt = 0
;TimeOut = 360
;Zombie_Check = 0
;Server_User = advantage
;Server_UID = 1000
;Server_GID = 4
;BC_Services = letodb;
;BC_Interface = eth2
;BC_Port = 2812
;SMB_SERVER = 1
DataBase = /
Backup = /tmp/backup
Mask = *.dbf,*.dbt,*.ntx
Lock = 1
Seconds = 30
Wait = 1
ArcCmd = tar -cvzf /tmp/backup/leto.tar.gz /tmp/backup/*

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Nov 2018 19:06
por Itamar M. Lins Jr.
Ola!
R: Não, ou pelo menos algo que informe que a conexão caiu.

Vai aparecer uma msg de erro.
O quê informa quando a conexão cai é o ícone do windows ai de rede no canto inferior direito.
A conexão nunca cai. Se cair será por outros problemas, fio, hub, etc... e o windows irá informar isso, mesma coisa quando sai do ar a internet.
Se vc conectar no letodb pela manha quando chegar a noite vai está conectado da mesma forma, mesmo que não faça nada. Não desliga quando fica ocioso.
O servidor verifica processos ZUMBIS e fecha os arquivos sozinho se não houver resposta do cliente. Nisso tem um comando para mexer nesse "tempo" de verificação dos processos ZUMBIS.

Mas ainda não estou entendendo, se vc tem uma cópia LOCAL, para quê usar o LetoDbf ?
Acho que o amigo não leu meu codigo ou passou despercebido.

Li e acho que vc não está entendendo o seu próprio código.
#define FILE_LOCAL  "/home/bruno/server/banco.dbf"

Se esta pasta está em outra máquina, se a conexão cair não vai acessar o arquivo banco.dbf com ou sem Letodbf
Se está na mesma máquina e vc tira o cabo usando "192.168.0.1" não vai achar pelo LetoDbf, porque vc está usando o endereço da conexão física.
Se deseja arrancar o cabo e a conexão ficar funcionando use //127.0.0.1:2812/ ai até sem rede vai funcionar.
Sua maquina tem dois IPs, o da rede física "192..." e outro loopbak -> "//localhost:2812/" ou "//127.0.0.1:2812/".

Mesmo assim fica a dúvida de quantas maquinas irão acessar o DBF, já que vc tem copia local, não precisa de sincronicidade ?
Antes sua pasta era mapeada ? Não tô entendendo isso, tem uma cópia em cada computador ?

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 26 Nov 2018 19:17
por Itamar M. Lins Jr.
Ola!
R: Eu penso que eu tinha que ter pelo menos a chance de interceptar esse travamento.

Neste caso com "error block", "Begin Sequence" nos comandos que manipule os arquivos. Append, skip, rlock, unlock...
Ai chamando o leto_detect...
Porque o erro reportado pelo sistema será do RDD do Harbour, não do LetoDbf.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 07:32
por bwr2018
Vai aparecer uma msg de erro.
O quê informa quando a conexão cai é o ícone do windows ai de rede no canto inferior direito.

Não uso windows como citado na msg anterior.

Mas ainda não estou entendendo, se vc tem uma cópia LOCAL, para quê usar o LetoDbf ?

Justamente, para que se por algum motivo o servidor sair do ar eu tenha como opção partir de onde parou localmente.

Li e acho que vc não está entendendo o seu próprio código.

kkkk desculpe como todo respeito acho que não estou perdido no meu código.

Se esta pasta está em outra máquina, se a conexão cair não vai acessar o arquivo banco.dbf com ou sem Letodbf
Se está na mesma máquina e vc tira o cabo usando "192.168.0.1" não vai achar pelo LetoDbf, porque vc está usando o endereço da conexão física.

Amigo é bem simples de entender, não estou entendendo o por que de tantos "por que's" da sua parte embora estou aqui pedindo ajuda mas vou tentar explicar ponto a ponto aqui abaixo.

Sistema utilizado: Slackware 13.1
Maquinas na rede: No maximo 10
IP servidor: 192.168.0.1
Ip's clientes: 192.168.0.2 até o 10
Internet: Não
Como estou fazendo: Na maquina com o ip servidor eu inicio o serviço letodb, em seguida me conecto com a mesma. E então abro os 2 bancos, o do servidor e o local.
./usr/local/bin/letodb
leto_connect("//192.168.0.1:2812/")
USE BCLOCAL.DBF EXCLUSIVE NEW ALIAS W
USE BANCO.DBF SHARED NEW ALIAS LAN

Na primeira maquina cliente com o ip 192.168.0.2, não iniciou o letodb somente me conecto a ela e abro o banco de dados no servidor e o banco local.
leto_connect("//192.168.0.1:2812/")
USE BCLOCAL.DBF EXCLUSIVE NEW ALIAS W
USE BANCO.DBF SHARED NEW ALIAS LAN

Blz? A esse ponto ja estou com 2 maquinas funcionando compartilhando o mesmo banco de dados.
Agora em um loop nas duas maquinas eu faço os incrementos dos campos. Tanto no banco do servidor quanto no local.
Por que tbm no local? Explicando, por que foi uma maneira que pensei em fazer o sistema partir de onde parou quando estava conectado ao servidor continuar trabalhando localmente.

Se deseja arrancar o cabo e a conexão ficar funcionando use //127.0.0.1:2812/ ai até sem rede vai funcionar.

Eu não pretendo arrancar o cabo! Isso foi apenas um teste. Foi quando notei o problema de travar a estação. E então resolvi perguntar aqui no forum se isso era normal, se tinha alguma solução etc etc.

Sua maquina tem dois IPs, o da rede física "192..." e outro loopbak -> "//localhost:2812/" ou "//127.0.0.1:2812/".

Não desejo usar o loopback. Não vejo sentido em usar letodb com loopback.

Mesmo assim fica a dúvida de quantas maquinas irão acessar o DBF, já que vc tem copia local, não precisa de sincronicidade ?

Maximo 10 maquinas, como citado acima eu fiz isso pq achei essa maneira de se por acaso o servidor sair do ar eu continuo trabalhando localmente, e na proxima sincronização com o servidor eu cruzo os dados, vejo quanto tem no local e quanto tem no servidor. Sendo assim o local vai ser maior eu apenas pego a diferença e atualizo o servidor.

Antes sua pasta era mapeada ? Não tô entendendo isso, tem uma cópia em cada computador ?

Não sei o que quer dizer "mapeada" talvez seja um local pré definido? Se for isso, sim sempre definido esse local para o banco do servidor. E sim tem uma copia em cada computador.

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 07:36
por bwr2018
Neste caso com "error block", "Begin Sequence" nos comandos que manipule os arquivos. Append, skip, rlock, unlock...
Ai chamando o leto_detect...
Porque o erro reportado pelo sistema será do RDD do Harbour, não do LetoDbf.


Eu não sei fazer isso, se te for possível postar um exemplo fico imensamente grato!

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 08:53
por asimoes
bwr2018 escreveu:
Neste caso com "error block", "Begin Sequence" nos comandos que manipule os arquivos. Append, skip, rlock, unlock...
Ai chamando o leto_detect...
Porque o erro reportado pelo sistema será do RDD do Harbour, não do LetoDbf.


Eu não sei fazer isso, se te for possível postar um exemplo fico imensamente grato!


Perguntas, você herdou esse sistema ? tem alguma experiência na linguagem ? esses comandos que o Itamar mostrou são básicos do clipper/harbour, exceto o leto_*

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 10:00
por Itamar M. Lins Jr.
Ola!
embora estou aqui pedindo ajuda mas vou tentar explicar ponto a ponto aqui abaixo.

A AJUDA para estar correta vai depender de informações BÁSICAS.

Pq as informações vem a conta gotas. Se tivesse descrito todo o seu cenário, teríamos avançado mais.
usando um distro linux slackware 13.1
Realmente não lembro de ter lido esta parte, li as outras que posta seu código.

a) As outras máquinas estão rodando windows ?
a.b) Vc compartilha o DBF com SAMBA ?
c) Se usa PUTTY ou outro tipo de terminal nas estações se tem alguma com windows ?
Como vc vai copiar/sincronizar o DBF para o servidor no caso de queda da rede ? Pq o LetoDbf Só vai cair se derrubarem ele via KILL ou falha física da rede

Eu estou entendendo o seguinte: Atualizar o DBF no Servidor via LetoDb e atualizar no Servidor na pasta \home\... e puxar o DBF para cada estação para ter a sincronicidade ok ?

Se a rede cair como vc vai saber onde está cada dado(informação) em cada estação ? Para depois aglutinar no servidor ?

Quando a rede cair, se for APENAS um TOTALIZADOR e vc precisar saber onde está a informação mais atualizada o maior contador de cada estação para depois copiar para o servidor, saber qual das 10 estações está com o DBF mais atualizado para gravar no servidor. Com a rede offline como faz isso ?

As perguntas que faço não são por curiosidade. E que cada uma traz uma informação para responder o problema apresentado.
A) LetoDBf com SAMBA precisa de configuração especial.
B) Se acessa via algum tipo de terminal não tem windows é tudo LINUX, não tem vantagem nenhuma usar LetoDBf.
Se está tudo na pasta \home... no servidor e acessa via SSH ou PUTTY ou qualquer das várias opções existentes (TERMINAL) tipo WTS (Windows Terminal Service) não vejo vantagem de usar LetoDbf.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 11:59
por Itamar M. Lins Jr.
Ola!
Seu código:
#define FILE_LOCAL "/home/bruno/server/banco.dbf"

Eu estou entendendo que nas 10 maquinas existe esta pasta. Acesso LOCAL.
Depois vc informa assim:

Na primeira maquina cliente com o ip 192.168.0.2, não iniciou o letodb somente me conecto a ela e abro o banco de dados no servidor e o banco local.
leto_connect("//192.168.0.1:2812/")
USE BCLOCAL.DBF EXCLUSIVE NEW ALIAS W
USE BANCO.DBF SHARED NEW ALIAS LAN


Aqui já outro cenário. Dois arquivos DBF´s diferentes. BCLOCAL.DBF e BANCO.DBF. Já fico sem entender, esse LOCAL está onde ? No servidor ou na estação ?
Se está na estação as atualizações da outras 9 máquinas como fica para saber quando ou o quê sincronizar em caso da rede esta off line ?
Seu letodb.ini tem isso:
DataPath = /home/bruno/server

Nisso eu entendo que ora LOCAL está tudo no próprio servidor (192.168.0.1) e vc acessa via SSH por exemplo, e ora LOCAL está espalhado pelas 10 estações.
Ou as 3 opções. 1 é o acesso com letodb, 2 é via SSH, etc.. e 3 tem uma cópia em cada estação no caso de queda de rede.

Saudações,
Itamar M. Lins Jr.

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 15:44
por bwr2018
asimoes escreveu:Perguntas, você herdou esse sistema ? tem alguma experiência na linguagem ? esses comandos que o Itamar mostrou são básicos do clipper/harbour, exceto o leto_*


1 - Não herdei.
2 - Sim, não tanto quanto vcs.

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 15:51
por bwr2018
Itamar M. Lins Jr. escreveu:Seu código:
#define FILE_LOCAL "/home/bruno/server/banco.dbf"

Eu estou entendendo que nas 10 maquinas existe esta pasta. Acesso LOCAL.
Depois vc informa assim:

Na primeira maquina cliente com o ip 192.168.0.2, não iniciou o letodb somente me conecto a ela e abro o banco de dados no servidor e o banco local.
leto_connect("//192.168.0.1:2812/")
USE BCLOCAL.DBF EXCLUSIVE NEW ALIAS W
USE BANCO.DBF SHARED NEW ALIAS LAN


Aqui já outro cenário. Dois arquivos DBF´s diferentes. BCLOCAL.DBF e BANCO.DBF. Já fico sem entender, esse LOCAL está onde ? No servidor ou na estação ?
Se está na estação as atualizações da outras 9 máquinas como fica para saber quando ou o quê sincronizar em caso da rede esta off line ?
Seu letodb.ini tem isso:
DataPath = /home/bruno/server

Nisso eu entendo que ora LOCAL está tudo no próprio servidor (192.168.0.1) e vc acessa via SSH por exemplo, e ora LOCAL está espalhado pelas 10 estações.
Ou as 3 opções. 1 é o acesso com letodb, 2 é via SSH, etc.. e 3 tem uma cópia em cada estação no caso de queda de rede.

Saudações,
Itamar M. Lins Jr.


Bem, se teve algumas divergências. Claro que sim pq apesar estar postando as duvidas aqui, eu não estou de braços cruzados esperando cair do céu o código em teste está em constante mudança aqui. Mas penso que são coisas tão pequenas que não deveria ser levado em consideração. Mas se ficar melhor eu vou postando aqui todo update. Enquanto isso vou tentando responder a duvida de todos vcs que estão dispostos a ajudar.

LetoDb e Harbour, como usar.

MensagemEnviado: 27 Nov 2018 16:17
por bwr2018
Itamar M. Lins Jr. escreveu:a) As outras máquinas estão rodando windows ?
a.b) Vc compartilha o DBF com SAMBA ?
c) Se usa PUTTY ou outro tipo de terminal nas estações se tem alguma com windows ?


a) As 3 maquinas que estou testando estão com o mesmo sistema.
a.b) Não.
c) Não
Itamar M. Lins Jr. escreveu:Como vc vai copiar/sincronizar o DBF para o servidor no caso de queda da rede ?

R: Eu não preciso copiar nada, enquanto a conexão esta viva eu tenho os mesmos registros tanto no servidor como no local. No código esta descrito isso.

Itamar M. Lins Jr. escreveu:Pq o LetoDbf Só vai cair se derrubarem ele via KILL ou falha física da rede.

R: Nem por falha fisica ele apenas desconecta o ip enquanto não dou um "letodb stop" ele realmente não para.

Itamar M. Lins Jr. escreveu:Eu estou entendendo o seguinte: Atualizar o DBF no Servidor via LetoDb e atualizar no Servidor na pasta \home\... e puxar o DBF para cada estação para ter a sincronicidade ok ?

R: Não, a atualização acontece nos dois bancos enquanto a conexão esta ativa. Se a conexão se perde é ai que entra o pulo do gato que estou querendo fazer. Eu preciso de alguma maneira fazer com que a estação enxergue que a conexão caiu sem travar. A partir do momento que ela enteder isso basta eu finalizar o banco aberto no servidor e dar select somente no banco local e tudo continura funcionando como se nada tivesse acontecido.

Itamar M. Lins Jr. escreveu:Se a rede cair como vc vai saber onde está cada dado(informação) em cada estação ? Para depois aglutinar no servidor ?

R: Todas estações estaram com os mesmos dados que o servidor tem. Quando a conexão voltar basta comparar o banco local com o do servidor e ver o que o servidor perdeu de incremento durante o tempo que ele ficou fora e gravar as diferenças.

Itamar M. Lins Jr. escreveu:Quando a rede cair, se for APENAS um TOTALIZADOR e vc precisar saber onde está a informação mais atualizada o maior contador de cada estação para depois copiar para o servidor, saber qual das 10 estações está com o DBF mais atualizado para gravar no servidor. Com a rede offline como faz isso?

R: A mesma resposta acima, pegando as diferenças. Se o servidor parou com 10 as estações seguiram digamos que uma foi ate o 20 a outra até o 30. A primeira vai iniciar e ja vai gravar no servidor sua diferença 20 - 10 = 10 logo o servidor estara com 20. Segunda inicia vai fazer a mesma coisa o servidor estará com 20 já que a primeira ja gravou sua diferença então 30 - 20 = 10 logo o servidor estara com 30 tbm.

Itamar M. Lins Jr. escreveu:As perguntas que faço não são por curiosidade. E que cada uma traz uma informação para responder o problema apresentado.
A) LetoDBf com SAMBA precisa de configuração especial.
B) Se acessa via algum tipo de terminal não tem windows é tudo LINUX, não tem vantagem nenhuma usar LetoDBf.
Se está tudo na pasta \home... no servidor e acessa via SSH ou PUTTY ou qualquer das várias opções existentes (TERMINAL) tipo WTS (Windows Terminal Service) não vejo vantagem de usar LetoDbf.

R: a) Não uso samba.
R: b) Bem eu não sei de outra maneira de acessar um banco de dados de outra maquina sem o leto, ou hbnetio que foi minha primeira tentativa.
R: c) Não sei, mas acho que precisa de internet né?