Página 1 de 1

hbnetio

Enviado: 01 Dez 2014 12:57
por JoséQuintas
O hbnetio faz parte do Harbour, mas não vejo comentários sobre ele.
Algum problema nele?

hbnetio

Enviado: 01 Dez 2014 13:27
por Itamar M. Lins Jr.
Não, pelo que sei é muito bom, melhor até que o letodb, só que comecei a usar primeiro o letodb.
O Pritpal Bedi usa ele extensivamente, inclusive tem ele no HBQT.

Saudações,
Itamar M. Lins Jr.

hbnetio

Enviado: 01 Dez 2014 13:40
por Itamar M. Lins Jr.
HBNETIO - A Case Study by Pritpal Bedi

Código: Selecionar todos

Hello All

Here are the steps I took to convert my flagship application "Vouch" ( a mini ERP solutions for a variety of verticals ) to honor HBNETIO lib along-with normal execution as ususal.

BACKDROP

I use configuration file vouch.ini to set various parameters of the application, which beside setting extended protocols, sets the data paths too. So at any given point of execution every table/index/other file always contain fully qualified path.

This principal I adopted and implemented in my applications always made my efforts to switch to different RDD's which a minimum efforts and changes in the source code. Even mixing different RDDs for different parts of the application are made possible and been used successfully.

A table when used has this format:
  c:\creative.ram\checks.dbf  [ index: c:\creative.ram\checks.z01 ]
  ^^^^^^^^^^                                   ROOT FOLDER
                        ^^^^^^^                   TABLE
       =>
  net:checks.dbf

  c:\creative.ram\cac00001\vpn453za.dbf
  c:\creative.ram\caccomon\defaults.dbf   , etc
  ^^^^^^^^^^                                   ROOT FOLDER
                        ^^^^^^^                    AREA OF OPERATION
                                        ^^^^^^^    TABLE NAME
       =>
  net:caccomon\defaults.dbf

For HBNETIO protocol I just changed the root data path of any
supported file [ .dbf | .z01 (CDX) ] [ which must reside on the
data server ] with "net:" and that's it.

I executed the netiosrv.exe as:
  c:\creative.acp\netio\netiosrv.exe  63000  0.0.0.0  c:\creative.ram

And included in vouch.exe:

  #if 1   /* Net IO Client-Server Protocol */
     IF INIVLW( "NetIOEnabled" )
        cNetIOServer := IniValue( 'NetIOServer' )
        cNetIOPort   := IniValue( 'NetIOPort'   )
        IF !empty( cNetIOServer ) .and. !empty( cNetIOPort )
           lSuccess  := netio_connect( cNetIOServer, val( cNetIOPort ) )
           uiDebug( "netio_connect()", lSuccess, cNetIOServer, cNetIOPort )
           uiDebug( " " )
        ENDIF
     ENDIF
  #endif

IniValue() parses the vouch.ini and keeps in static variable and
supplies a value as requested.

The other functions which I adjusted to change the root
folder to "net:" looks like this:

Function VouExistTable( cAlias, cFile, cPath, cDriver, lTemp )
  Local lRet := .f.

  DEFAULT lTemp TO .f.

  cFile := UPPER( trim( cFile ) )
  if right( cFile,4 ) == '.DBF'
     cFile := substr( cFile, 1, len( cFile )-4 )
  endif

  do case

  case lTemp
     lRet := file( cPath +'\'+ cFile + '.DBF' )

  case cDriver == 'SQLRDD'
     lRet := VouIsFile( cFile )

  case cDriver == 'CACHERDD'
     #ifdef __CACHE__
     lRet := CacheExistTable( cFile )
     #endif

  otherwise
     IF Vou_IsNetIO()
        IF right( cPath, 1 ) == ":"
           cFile := cPath + cFile + '.DBF'
        ELSE
           cFile := cPath +'\'+ cFile + '.DBF'
        ENDIF
     ELSE
        cFile := cPath +'\'+ cFile + '.DBF'
     ENDIF
     lRet := DbExists( cFile )

  endcase

  Return lRet

//----------------------------------------------------------------------//

Function VouExistIndex( cAlias, cFile, cPath, cDriver, lTemp )
  Local lRet := .f.

  DEFAULT lTemp TO .f.

  cFile := UPPER( trim( cFile ) )
  if right( cFile,4 ) == '.Z01'
     cFile := substr( cFile, 1, len( cFile )-4 )
  endif

  do case

  case lTemp
     lRet := file( cPath +'\'+ cFile + '.Z01' )

  case cDriver == 'SQLRDD'
     lRet := VouIsFile( cFile,.t. )

  case cDriver == 'CACHERDD'
     #ifdef __CACHE__
     lRet := CacheExistIndex( cFile )
     #endif

  otherwise
     IF Vou_IsNetIO()
        IF right( cPath, 1 ) == ":"
           cFile := cPath + cFile + '.Z01'
        ELSE
           cFile := cPath +'\'+ cFile + '.Z01'
        ENDIF
     ELSE
        cFile := cPath +'\'+ cFile + '.Z01'
     ENDIF
     lRet := DbExists( cFile )

  endcase

  Return lRet

//----------------------------------------------------------------------//

FUNCTION Vou_IsNetIO()

  IF INIVLW( 'NetIOEnabled' )
     RETURN .t.
  ENDIF

  RETURN .f.

/*----------------------------------------------------------------------*/

FUNCTION Get_Path( cAlias )
  LOCAL cPath, p

  IF !empty( p := get_d_attr( cAlias,D_PATH ) )
     cPath := eval( COMPILE( p ) )
  ELSE
     cPath := setWPath()
  ENDIF

  IF get_d_attr( cAlias, D_FILE_TYPE ) <> 9  /* Vouch Specific and on the
Client */
     cPath := Vou_AdjustPathToNetIO( cPath )
  ENDIF

  RETURN cPath

/*----------------------------------------------------------------------*/

FUNCTION Vou_AdjustPathToNetIO( cPath )
  LOCAL n, cPathL

  IF Vou_IsNetIO()
     cPathL := lower( cPath )
     IF left( cPathL, 4 ) != "net:"
        n := at( 'creative.',  cPathL )
        IF n > 0  // And it must be
           cPath := "net:" + substr( cPath, n + 13 )
        ENDIF
     ENDIF
  ENDIF

  RETURN cPath

//----------------------------------------------------------------------//


NOTE: the above code is a case study only and should not
        be used as is. However you may adopt the similar approach if
        you want to.


OTHER CHANGES YOU MAY REQUIRE
==========================
  You may also need to swich to following changes which work in both modes.

  FILE()       =>   DBEXISTS()
  FERASE()   =>   DBDROP()

THE OBSERVATION
==============
  netiosrv.prg

//------------------------------//
proc main( cPort, cServer, cRoot )
  local pListenSocket

  if empty( cPort )
     cPort := '63000'
  endif

  pListenSocket := netio_mtserver( val( cPort ), cServer, cRoot )

  if empty( pListenSocket )
     ? "Cannot start server."
  else
     wait "Press any key to stop NETIO server."
     netio_serverstop( pListenSocket )
     pListenSocket := NIL
  endif

  return
//------------------------------//

  netiosrv.prg => hbmk2 netiosrv.hbp => netiosrv.exe

  * Consumes very little memory footprint : 2.5 MB
  * Consumes very little CPU time even if many instances are logged : 3-5%
  * With each instance increase in memory : 16 KB
  * Reduces 16 kb with every instance if quits or is killed
  * Record|File locks a released instantlt if an instance holding them is
killed.

THE EXPECTATIONS
===============
  Would been nice if root path be automatically stripped
  if "net:" is found a part of the table name, i.e.,
     net:c:\creative.ram\cac00001\mytable.dbf
        =>
     net:cac00001\mytable.dbf
         where
     c:\creative.ram == netiosrv's root path

THE RESULTS
==========
  Amazing.
  Przemek, accept my hats off to this contribution.

  BUT it will be really heartening if you decide to finish NETRDD.
  The community is looking at NETRDD desperately.

Regards
Pritpal Bedi
Saudações,
Itamar M. Lins Jr.

hbnetio

Enviado: 01 Dez 2014 14:03
por JoséQuintas
Esse exemplo causa confusão.

hbnetio

Enviado: 01 Dez 2014 16:25
por asimoes
José,

Tem exemplos de uso com MiniGui, procure na pasta Advanced\netio_1 e Advanced\netio_2

hbnetio

Enviado: 01 Dez 2014 16:57
por Itamar M. Lins Jr.
Esse exemplo causa confusão.
Causa confusão para quem ?
Esse é um bom exemplo, para alguém. Não serviu p/ você, mas tem informações úteis.

Saudações,
Itamar M. Lins Jr.

hbnetio

Enviado: 27 Set 2015 07:50
por JoséQuintas
Atualizando com um exemplo mais simples:

Código: Selecionar todos

PROCEDURE Main
   ...
  IF App_NetIo
      NetIo_Connect( cServer, nPort, , cPassword )
  ENDIF
  ...
  IF App_NetIo
      NetIo_Disconnect( cServer, nPort )
   ENDIF
   RETURN

FUNCTION OpenFile( cFileName )
   IF App_NetIo
      cFileName := "net:" + cFileName
   ENDIF
   USE ( cFileName )
   dbSetIndex( cFileName )
   RETURN .T.