Page 1 of 2
questions manage dbf
Posted: Sat Sep 29, 2018 3:44 pm
by Silvio.Falconi
I 'm trying to create a app for network but I not remember how I must create it
because in the last 10 years I have preferred to deal with simple little programs where there was no need for the archives on the net. now I present the problem of an application that must necessarily use a shared management of the archives because it connects in the background with Telgram on the Internet and sends text messages taking information from the archives that could be used by the application
trying to manage the archive on the net I now find a test to cancel a record having opened an archives in NEW SHARED
in the old system I deleted a record and run the archive pack this way
Code: Select all
ES->(DbSkip())
nNext := ES->(Recno())
ES->(DbGoto(nRecord))
ES->(DbDelete())
ES->(DbPack())
ES->(DbGoto(nNext))
if ES->(EOF()) .or. nNext == nRecord
ES->(DbGoBottom())
endif
now if I try to make pack let me fwh sad me the dbf must be open on exclusive mode
how I can resolve it ?
this is the source when I try to erase a record
Code: Select all
local nRecord := ES->(Recno())
local nNext
ES->(DbSkip())
nNext := ES->(Recno())
ES->(DbGoto(nRecord))
IF!Ocupado("ES")
ES->(DbDelete())
ES->(DbCommit())
ES->(DbPack())
ES->(DbUnlock())
Endif
ES->(DbGoto(nNext))
if ES->(EOF()) .or. nNext == nRecord
ES->(DbGoBottom())
endif
why I cannot make dbpack ?
If I not make dbpack on xbrowse I see the record
the function Ocupado is a function with a cicle to try to rlock the dbf
Re: questions manage dbf
Posted: Sat Sep 29, 2018 4:16 pm
by Enrico Maria Giordano
You can't pack a DBF not opened in exclusive mode. Put
at the start of your main function and you will not see the deleted records anymore.
EMG
Re: questions manage dbf
Posted: Mon Oct 01, 2018 10:00 am
by Silvio.Falconi
I still do not understand why when I have to delete a record I am forced to use rlock / dbunclock when instead I insert a record he turns the old way without rlocking
I'm using an archive with the "New shared" method
I thought a control archive in the root of the program to open in "new shared" and then the others in the "data" folder can open with
DbUseArea( [<lNewArea>] , ;
[<cRddName>] , ;
<cDatabase> , ;
[<cAlias>] , ;
[<lShared>] , ;
[<lReadonly>] , ;
[<cCodePage>] , ;
[<nConnection>] ) --> NIL
cAlias:=New_Alias(cDbf,nD)
DbUseArea(.T.,cDriver,cDbf,cAlias,.T.,.F.)
in your opinion, it could be configured to be able to use an archive and at the same time reopen it from another part
I'm afraid that I get the message "alias do not exist" this is and it was my nightmare 15 years ago for this reason I had abandoned and embraced the exclusive way
Re: questions manage dbf
Posted: Mon Oct 01, 2018 10:18 am
by dagiayunus
Silvio.Falconi wrote:I 'm trying to create a app for network but I not remember how I must create it
because in the last 10 years I have preferred to deal with simple little programs where there was no need for the archives on the net. now I present the problem of an application that must necessarily use a shared management of the archives because it connects in the background with Telgram on the Internet and sends text messages taking information from the archives that could be used by the application
trying to manage the archive on the net I now find a test to cancel a record having opened an archives in NEW SHARED
in the old system I deleted a record and run the archive pack this way
Code: Select all
ES->(DbSkip())
nNext := ES->(Recno())
ES->(DbGoto(nRecord))
ES->(DbDelete())
ES->(DbPack())
ES->(DbGoto(nNext))
if ES->(EOF()) .or. nNext == nRecord
ES->(DbGoBottom())
endif
now if I try to make pack let me fwh sad me the dbf must be open on exclusive mode
how I can resolve it ?
this is the source when I try to erase a record
Code: Select all
local nRecord := ES->(Recno())
local nNext
ES->(DbSkip())
nNext := ES->(Recno())
ES->(DbGoto(nRecord))
IF!Ocupado("ES")
ES->(DbDelete())
ES->(DbCommit())
ES->(DbPack())
ES->(DbUnlock())
Endif
ES->(DbGoto(nNext))
if ES->(EOF()) .or. nNext == nRecord
ES->(DbGoBottom())
endif
why I cannot make dbpack ?
If I not make dbpack on xbrowse I see the record
the function Ocupado is a function with a cicle to try to rlock the dbf
The following commands require the exclusive use of a table with either SET EXCLUSIVE ON or USE...EXCLUSIVE:
CONVERT
DELETE TAG
INDEX...TAG
MODIFY STRUCTURE
PACK
REINDEX
ZAP
Re: questions manage dbf
Posted: Mon Oct 01, 2018 1:29 pm
by Enrico Maria Giordano
Silvio.Falconi wrote:I still do not understand why when I have to delete a record I am forced to use rlock / dbunclock when instead I insert a record he turns the old way without rlocking
Because APPEND BLANK automatically locks the newly created record. You still need to unlock it at the end of the assignment operation.
EMG
Re: questions manage dbf
Posted: Mon Oct 01, 2018 1:33 pm
by Enrico Maria Giordano
Silvio.Falconi wrote:in your opinion, it could be configured to be able to use an archive and at the same time reopen it from another part
Yes, but you have to use a different alias to reopen the same DBF. Try using TDatabase class that automatically handles all those alias complexities.
EMG
Re: questions manage dbf
Posted: Mon Oct 01, 2018 7:54 pm
by Silvio.Falconi
thanks Enrico,
I'm rehearsing to see if I can manage at least one customer on the net
This happens to me this evening
I have opened the customer file with
Code: Select all
DbUseArea(.T.,cDriver,cDir+cDbf,cAlias,.T.,.F.)
I made the indexes only two one for the field "FIRST" the other for "LAST"
insert a First such as "FALCONI"
the valid function attached to the get does not find the name and then makes me save the new record
now I want to delete the record "falconi"
and I execute the command with
Code: Select all
IF!Occupato(oDCli)
(oDCli)->(DbDelete())
(oDCli)->(DbCommit())
(oDCli)->(DbUnlock())
ENDIF
the "Occupato" function is a cycle to call the rlock function where is is not rlock wait 5 sec
OK THE RECORD IS DELETE
Now I want to do another test and insert the name "Falconi" again, Obviously without leaving the customer screen
when I insert the name "Falconi" the valid finds me the name and tells me existing record
It is possible that at the time of cancellation the index does not refresh and therefore the procedure always keeps the name in memory and finds it?
Re: questions manage dbf
Posted: Mon Oct 01, 2018 7:57 pm
by Silvio.Falconi
Sorry,
there was another record with "Falconi" .... mhm sorry , It seemed strange to me
Re: questions manage dbf
Posted: Mon Oct 01, 2018 8:27 pm
by Silvio.Falconi
So,
to insert a record the procedure inserts it
but when I have to modify or delete a record , I have to use rlock / dbunclock
I cannot use dbpack when I open on share mode
I must use
SET DELETE ON if I want not show the delete record into xbrowse
and I must index with the clausole FOR .not. Deleted()
I delete the command dbpack from mine sources but I need it or not ?
I not understood where i can make dbpack because when open the customer.dbf with emagdbu I see also the delete records
where I can use dpack ?
I must create a a new function where I can index all files and I can make dbpack and I must sure no user is on line
Re: questions manage dbf
Posted: Mon Oct 01, 2018 8:51 pm
by Enrico Maria Giordano
Silvio.Falconi wrote:where I can use dpack ?
I must create a a new function where I can index all files and I can make dbpack and I must sure no user is on line
Yes.
EMG
Re: questions manage dbf
Posted: Tue Oct 02, 2018 2:50 pm
by Rick Lipkin
Silvo
Re-Writing for a shared network multi-user environment takes a bit of skill .. I have exclusively moved to ADO and do not need these functions .. here are my DBFCDX network functions that may help you ...
Rick Lipkin
Code: Select all
/* 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.)
//--------------------------
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.
//-----------------------------
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.)
Re: questions manage dbf
Posted: Tue Oct 02, 2018 2:59 pm
by Enrico Maria Giordano
Rick Lipkin wrote:Silvo
Re-Writing for a shared network multi-user environment takes a bit of skill ..
Yes, it's not easy at all. Bad locking strategy could cause slowness, duplicated keys and other unpleasant things.
EMG
Re: questions manage dbf
Posted: Tue Oct 02, 2018 3:16 pm
by Rick Lipkin
Enrico
Yes, it's not easy at all. Bad locking strategy could cause slowness, duplicated keys and other unpleasant things.
EMG
I ( pretty much ) gave up on dbf\cdx because of the opportunistic locking issues and dbCommit() and workstation update visabilities on certain networks .. As you tutored me many years ago .. .mdb ( ms access ) is a good ADO solution for portable multi-user network apps .. Ms Sql Server is my choice for Enterprise corporate tables.
I only use dbf\cdx for writing reports and I where I need to create a ( local ) temporary table and I always create those tables on demand and open the .dbf exclusively .. I think the worst problem using dbf\cdx is the opportunistic locking issues that just destroy application speed and performance .. and this issue is random in nature and YOU ( the developer ) are always blamed for this issue which is beyond your control ..
Rick Lipkin
Re: questions manage dbf
Posted: Wed Oct 03, 2018 10:24 am
by Silvio.Falconi
everyone has their own situations, then the functions when we try them all turn then when one puts them in the big applications are created the problems, I never trusted to manage the archives in a local network for the countless problems that there are...
It's not so easy .
I created a "Netuse" type function but a little different management in order to open a dbf in specific folders
I have a difficult situation. it's not easy
I have a dbf named Dbase.dbf where I inserted all the dbf / cdx and more
when I do oDCli: = Open_Dbf ("Customer",. t..f.aIdx, .t.) means that the archive is in the folder. \ 2013 \ data if instead I make Open_dbf ("dbase") the file is in root obviously oDli is the area in which I open the file
in this way I also open the indexes that are stored in dbase.dbf
I do so since I work with clipper
I have a data folder divided for years eg 2013 and inside this folder other folders like: date, Doc, Pdf, Xls, Xml, Zip
Generally the archives are in the folder. \ Data \
The general archives I have to call them from the root of the application
So with Apri_Dbf / chiudi_Dbf (cdbf, calias) I manage the openings and the closures
With Busy () I see if the archive is busy or not with rlock and I wait for a cycle of 5 seconds
Now the problem is that I have to do a function inmodo to index all files and do the dbpack but I have the problem of checking if users are online
Re: questions manage dbf
Posted: Thu Oct 04, 2018 3:55 pm
by James Bott
Silvio,
As I mentioned in my post in another thread of yours, you really need to start using database objects. All of these problems will go away.
No more dealing with workareas, locking/unlocking, committing, opening and closing files, etc.
James