convert program to a network version

convert program to a network version

Postby hag » Mon Jul 20, 2009 3:30 am

Can anyone recommend some material available on how to convert my present app (not networkable) to a network version.
Using clipper 5.2e Harbour and FWH

Thanks
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: convert program to a network version

Postby StefanHaupt » Mon Jul 20, 2009 8:07 am

Harvey,

just some hints:

databases must be opened in shared mode (SET EXLUSIVE OFF, USE...SHARED)
before any write access you must lock either the dbf or the record and unlock it when the write access is finished.
if you need to rebuild the index files you have to close the dbf and open it in exlusive mode

In clipper there is the file lock.prg where you can find usefull functions for opening and locking dbf´s in a network environment
kind regards
Stefan
StefanHaupt
 
Posts: 824
Joined: Thu Oct 13, 2005 7:39 am
Location: Germany

Re: convert program to a network version

Postby Rick Lipkin » Mon Jul 20, 2009 10:49 pm

Harvey

You are looking at a major update if you are going to move from an 'exclusive' .dbf environment to a network share .. I use the associated function(s) whether I use it on a network or on a local machine that is a single user.

Here is a set of functions you can use :

NetUse()
Addrec()
RecLock()

// netuse

select 1
if netuse( "test.dbf", .f.,5 ) // database, .t. for excluse lock, .f. for shared, 5 for time-out
else
return(.f.)
endif

// addrec()

select database
if addrec(5) // time-out
else
return(.f.)
endif

database->field := cValue
unlock



// reclock()

select database
if reclock( 5 ) // time-out
else
return(.f.)
endif

database->field1 := cValue
unlock


Hope this helps..

Rick Lipkin

Code: Select all  Expand view  RUN

/* LOGICAL NETUSE( CDATABASE, LOPENMODE, NSECONDS )

  CHARACTER CDATABASE      - NAME OF DATABASE
  LOGICAL LOPENMODE        - OPEN MODE .T. exclusive  .F. shared
  NUMERIC NSECONDS         - NUMBER OF SECONDS TO WAIT  0 forever

  RETURN  .T. if successful,  .F. if not

  SAMPLE CALL  IF NETUSE( "CALLS", .F., 5 )
*/


Func NETUSE( CDATABASE, LOPENMODE, NSECONDS )

LOCAL FOREVER, RESTART, WAIT_TIME, YESNO

RESTART := .T.
FOREVER := ( NSECONDS = 0 )
YESNO    := {"Yes" , "No"}

DO WHILE RESTART

   WAIT_TIME := NSECONDS

   DO WHILE ( FOREVER .OR. WAIT_TIME > 0 )

      IF LOPENMODE
         USE ( CDATABASE ) via "DBFCDX" EXCLUSIVE
      ELSE
         USE ( CDATABASE ) via "DBFCDX" SHARED
      ENDIF

      IF .NOT. NETERR()
         RETURN(.T.)
      ENDIF
      INKEY(1)
      WAIT_TIME--

   ENDDO

   * lock failed, ask to continue

   IF MsgYesNo( "Cannot lock " + CDATABASE + ", retry ?" )
   ELSE
      EXIT
   ENDIF

ENDDO

RETURN(.F.)

//--------------------------
/*
  LOGICAL ADDREC( NWAITSECONDS )

  NUMERIC NWAITSECONDS

  APPEND BLANK function with user interaction if failed

  RETURN  .T. if successful,  .F. if not

  SAMPLE CALL   IF ADDREC( 5 )

  SAMPLE TO UNSELECTED DATABASE     IF ADDRESS->(ADDREC(5))
*/


Func ADDREC( NWAITSECONDS )

LOCAL LFOREVER, WAIT_TIME, RESTART, YESNO

APPEND BLANK
IF .NOT. NETERR()
   RETURN(.T.)
ENDIF

RESTART  := .T.
LFOREVER := ( NWAITSECONDS = 0 )
YESNO     := {"Yes", "No"}

DO WHILE RESTART

   WAIT_TIME := NWAITSECONDS
   DO WHILE ( LFOREVER .OR. WAIT_TIME > 0 )
      APPEND BLANK
      IF .NOT. NETERR()
         RETURN .T.
      ENDIF
      INKEY(.5)                      // wait 1/2 second to try again
      WAIT_TIME := WAIT_TIME - .5
   ENDDO

   *  if failed ask user to continue

   IF MsgYesNo( "Cannot add Record, retry ?" )
   ELSE
      EXIT
   ENDIF

ENDDO

RETURN(.F.)

//-----------------
/*
  LOGICAL RECLOCK( WAIT )

  NUMERIC WAIT

  RETURN .T. if successful, .F. if not

  RECORD LOCK ROUTINE WITH USER INTERACTION IF LOCK FAILES

  SAMPLE CALL  IF RECLOCK( 5 )
*/


Func RECLOCK( NSECONDS )

LOCAL LFOREVER, RESTART, WAIT_TIME, YESNO

IF RLOCK()
   RETURN (.T.)        // LOCKED
ENDIF

RESTART  := .T.
LFOREVER := ( NSECONDS = 0 )
YESNO     := {"Yes" , "No"}

DO WHILE RESTART
   WAIT_TIME := NSECONDS
   DO WHILE ( LFOREVER .OR. WAIT_TIME > 0 )

      IF RLOCK()
         RETURN(.T.)
      ENDIF

      INKEY(.5)
      WAIT_TIME := WAIT_TIME - .5

   ENDDO

    * lock failed

   IF MsgYesNo( "Cannot lock Record, retry ?" )
   ELSE
      EXIT
   ENDIF

ENDDO

RETURN( .F.)

 
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: convert program to a network version

Postby hag » Mon Jul 20, 2009 11:38 pm

Rick:
You wrote "Hope this helps.."
I'm such a novice anything will help.

Where do I put the functions you described.
I open 20 + data files at beginning of the program and others elsewhere.

Are the functions a one time call for each file or a many time call where are initialized?
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: convert program to a network version

Postby anserkk » Tue Jul 21, 2009 5:11 am

Dear Mr.Harvey,

Where do I put the functions you described.
I open 20 + data files at beginning of the program and others elsewhere.


You should open all your dbf files in shared mode. You can use the functions provided by Mr.Rick to open the DBF files in shared mode

For Eg:
Assuming that you have 2 DBF files namely Customer.Dbf and Invoice.Dbf

Instead of executing the regular xBase command to open the Dbf
For eg:
Select 1
Use Customer
Select 2
Use Invoice

You should open the Dbf in shared mode using the Function NetUse() (the second parameter should be .F.)
Code: Select all  Expand view  RUN
select 1
if netuse( "Customer.dbf", .f.,5 ) // database, .t. for exclusive lock, .f. for shared, 5 for time-out
else
   return(.f.)
endif

Select 2
if netuse( "Invoice.dbf", .f.,5 ) // database, .t. for exclusive lock, .f. for shared, 5 for time-out
else
    return(.f.)
endif
 


Are the functions a one time call for each file or a many time call where are initialized?

Once you have opened a DBF in shared mode, it remains shared till you close the DBF.

Once you have opened a DBF in shared mode, you should also make use of the Functions Addrec() and RecLock()
ie Whenever you try to add a new record to the DBF opened in shared mode, instead of Append Blank you should use Addrec()
Whenever you try to edit a record, before you start editing, you should lock the record using the Function RecLock()

Regards
Anser
User avatar
anserkk
 
Posts: 1333
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: convert program to a network version

Postby hag » Tue Jul 21, 2009 6:22 am

Thanks for the useful info.

How do I use an alias with netuse() ?

I open file
Use name.dbf alias name new
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: convert program to a network version

Postby Otto » Tue Jul 21, 2009 6:39 am

To all,

>I open 20 + data files at beginning of the program and others elsewhere.



This is what I do, too. But nowadays I feel it would be better to open the files as short as possible.


What is your experience?
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6336
Joined: Fri Oct 07, 2005 7:07 pm

Re: convert program to a network version

Postby Otto » Tue Jul 21, 2009 6:48 am

Hello Anser, hello Rick,

ad Select 1)
What is the advantage of selecting a workarea before opening?


Ad exclusive)
I personally change always in a prgInit procedure the exclusive mode to off.
So all databases are automatically opened shared.


Code: Select all  Expand view  RUN
INIT PROCEDURE PrgInit
   SET CENTURY ON
   SET EPOCH TO YEAR(DATE())-98
   SET DELETED ON
   SET EXCLUSIVE OFF
   REQUEST HB_Lang_DE
   REQUEST HB_CODEPAGE_DEWIN
   HB_LangSelect("DE")
   HB_SetCodePage("DEWIN")
   SET DATE TO GERMAN
   SetHandleCount(205)
   rddsetdefault( "DBFCDX" )
RETURN
 


Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6336
Joined: Fri Oct 07, 2005 7:07 pm

Re: convert program to a network version

Postby anserkk » Tue Jul 21, 2009 6:58 am

Dear Mr.Otto,

Normally I don't use Select while opening a DBF, instead I use the clause NEW in the Function NetUse() which is very much similar to what Mr.Rick has already posted above in this post. Using NEW clause will avoid errors of Selecting a workarea which is already used by another DBF

Code: Select all  Expand view  RUN
use &dbfname ALIAS &mAlias SHARED NEW


Ad exclusive)
I personally change always in a prgInit procedure the exclusive mode to off.
So all databases are automatically opened shared.


I have this flexibility in my NetUse(). A parameter to decide whether the DBF to be opened in Exclusive or shared mode.

Regards
Anser
Last edited by anserkk on Tue Jul 21, 2009 7:06 am, edited 1 time in total.
User avatar
anserkk
 
Posts: 1333
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: convert program to a network version

Postby anserkk » Tue Jul 21, 2009 7:02 am

Dear MR.Harvey,

How do I use an alias with netuse() ?


You will have to modify the Function NetUse() to accept one more parameter cAlias. After that you may modify the following code in the NetUse()

Code: Select all  Expand view  RUN
     IF LOPENMODE
         if empty(cAlias)
              USE ( CDATABASE ) via "DBFCDX" EXCLUSIVE
         else
              USE ( CDATABASE ) ALIAS &cAlias via "DBFCDX" EXCLUSIVE
         Endif
      ELSE
         if empty(cAlias)
              USE ( CDATABASE ) via "DBFCDX" SHARED
         else
              USE ( CDATABASE ) ALIAS &cAlias via "DBFCDX" SHARED
      ENDIF


Regards
Anser
User avatar
anserkk
 
Posts: 1333
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: convert program to a network version

Postby Enrico Maria Giordano » Tue Jul 21, 2009 9:20 am

hag wrote:Can anyone recommend some material available on how to convert my present app (not networkable) to a network version.
Using clipper 5.2e Harbour and FWH

Thanks


In 1985 I found Clipper 5 original manual very useful. But keep in mind that you can't simply take a single user app, replace some functions and magically get a multi users app. Multi user apps require a programming strategy because each section of the program can now be executed by more than one user simultaneously. Think about unique code generation or what can happen during the editing of record fields or report/export, etc. And some multi user effects are very hidden and nasty. In conclusion, you'd better not underestimate the difficult of porting your app to multiuser environment.

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8718
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: convert program to a network version

Postby hag » Tue Jul 21, 2009 3:22 pm

Thank you all for the help. Converting my app will not be easy and i'll spend sometime before I make my final decision to complete the task.

My preference would be to move the app to internet based. Any suggestions? :)
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: convert program to a network version

Postby James Bott » Wed Jul 22, 2009 4:44 pm

Harvey,

I should point out that using database objects make programming easier, including mult-user. The class automatically handles aliasing so instead of having to do (cAlias)->(dbskip()), you just do oCustomer:skip(). You can also open multiple copies of the same database using exactly the same syntax.

oCustomer1:= TCust():new()
oCustomer2:= TCust():new()

The database class can also handle all the multi-user issues.

For more information see my website http://www.goIntellitech.com/program.htm. There are a number of articles there.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: convert program to a network version

Postby hag » Wed Jul 22, 2009 6:22 pm

Thnks james all new stuff to me.
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: convert program to a network version

Postby James Bott » Wed Jul 22, 2009 6:35 pm

Harvey,

I know it is all scary since it is so different, but once you get over the intial learning curve, programming is so much easier, less error prone, and requires much less code. While converting some older programs I have reduced the code by as much as 50-90 percent.

When you are doing a conversion there are tricks. For instance, you can move entire functions into methods of a new class, then convert those functions into OOP as time permits. Think of it as wrapping legacy code into a class.

You can also use classes in some part of your application, and legacy code in others so you can convert a little at a time.

Read and re-read my articles, and then try some of the test programs. I think you will be amazed at how simple it is.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 67 guests