Date: Mon, 7 Sep 2009 13:29:16 -0700 (PDT)
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\
c:\creative.ram\caccomon\
^^^^^^^^^^ 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\
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\
=>
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
No comments:
Post a Comment