Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Proper way to store counters
Message
 
To
02/06/2005 00:58:08
Randy Wessels
Screentek Business Solutions, Llc.
Phoenix, Arizona, United States
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Environment versions
Visual FoxPro:
VFP 9
OS:
Windows XP SP2
Network:
Windows 2003 Server
Database:
Visual FoxPro
Miscellaneous
Thread ID:
01019240
Message ID:
01019241
Views:
17
I use a modified version of something I found in a book I read once, I believe it was Kilofox. Involves creating a table called systable with two fields, ctable and ilastkey. Then create an index on ctable. Next use the code below in a stored procedure in your database (in which case you can put newid("MyTable") in as the default value for your primary key fields in tables the database contains) or use it as a function in a prg that you just call when inserting or replacing the primary key in your table. You will notice an _screen variable being used, this is just a property that I always add to my _screen when my applications start up that holds the path to the database folder: _screen.addproperty("DataPath", "C:\Program Files\MyApp\Data\"), you can modify this to suit your needs and/or framework. The class object clsOpenTable handles the opening of the systable and closing it once the object is destroyed (in this case when loAlias1 goes out of scope).
Create table systable (cTable C(10), ILastKey I)
Index on cTable Tag cTable
************************************
Function newid( tcTable )
************************************
Local lcTable, lnNextVal, lnOldRepro
Local loAlias1

*** Check Param and convert to upper case
If Empty(tcTable) Or Type( "tcTable" ) # "C"
	Return 0
Endif

lcTable = Upper(Alltrim( tcTable ))

*** Save Settings and Open Systable if not already open
lnOldRepro = Set('REPROCESS')

loAlias1 = Createobject("clsOpenTable", 'systable', .T.)

*** Now find the required table
If Seek( lcTable, 'systable', 'cTable' )

	*** Found the required table
	*** Get a Lock on systable
	Set Reprocess To Automatic

	If Rlock( 'systable' )
	*** Get next value and update systable
		lnNextVal = systable.iLastKey + 1
		Replace iLastKey With lnNextVal In systable
		Unlock In systable
	Else
	*** This should NEVER happen!
		lnNextVal = 0
	Endif
Else

	*** Table Not Found!
	*** Needs a new entry in systable
	lnNextVal = 1
	Insert Into systable (cTable, iLastKey) Values ( lcTable, lnNextVal )
Endif

*** Return New ID
Set Reprocess To (lnOldRepro)
Return lnNextVal
Endfunc

************************************
Define Class clsOpenTable As Custom
************************************
	Name = "clsOpenTable"
	aliasname = ""
	NoBuffering = .F.
	PreviousBuffering = 0
	TableWasOpen = .T.

	Procedure Init(lname, lTurnOff)
		This.aliasname = lname
		This.NoBuffering = lTurnOff
		If !Used(lname)
			Use (_screen.datapath + lname) In 0 Shared
			This.TableWasOpen = .F.
		Endif
		This.PreviousBuffering = CursorGetProp("Buffering",lname)
		If lTurnOff And This.PreviousBuffering != 1
			=Tableupdate(1, .F., lname)
			=CursorSetProp('Buffering', 1, lname)
		Endif
	Endproc

	Procedure Destroy
		If !This.TableWasOpen
			Use In (This.aliasname)
		Else
			If This.NoBuffering And This.PreviousBuffering != 1
				=CursorSetProp('Buffering', This.PreviousBuffering, This.aliasname)
			Endif
		Endif
	Endproc

Enddefine
>I have an application that uses 1 table that only has one record in it to store various applicaiton configuration options such as company address information, office hours, and lastly counters for various parts of the system. These counters store information such as next order number, next customer number, etc. Right now I am having a problem with duplicate numbers being assigned - sometimes to the same user, sometimes to antoher user (it is a multi-user application). I believe the problem is that the record is not being locked correctly. I would like to standardize the way these counters are being used. I am envisioning a program that I can call that I pass it the name of the counter, it correctly locks a record, updates it, and spits back the next counter number for that counter name. I am also thinking that I should use a seperate table for the counters, maybe even a seperate record for each counter. If I can;t figure out how to correctly lock the record, I might even
>consider using a text file to store the counter and lock the text file. Does anyone have a good solution?
>
>Thank you!
>
>Randy Wessels
Previous
Reply
Map
View

Click here to load this message in the networking platform