Wednesday, August 15, 2007

Understanding Session object behavior

I was getting creative this evening with the VFP Session class. I was getting tired of changing the DataSession each time I created a private DataSession with the following code:
loSession = CREATEOBJECT("Session")
SET DATASESSION TO (loSession.DataSessionId)
So I created a class in a program and added this code to the Init() of the Session class:
SET DATASESSION TO (this.DataSessionID)
This does not work, the DataSession stays with the current DataSession. So I created a custom method in the Session class and called the method externally. Same result. Here is my test program:
LOCAL loSession as Session

?"--------------"
?"Should be default DS 1: ", SET("Datasession")

loSession = CREATEOBJECT("Session")
SET DATASESSION TO (loSession.DataSessionId)

?"Should be DS > 1: ", SET("Datasession")
loSession = .NULL.

?"Should be default DS 1: ", SET("Datasession")

* Now work with a customized session class
loSession2 = CREATEOBJECT("pssSession")
?"Would think this would be DS > 1 after set in " +;
"Init(): ",;
SET("Datasession")

loSession3 = CREATEOBJECT("pssSession")
loSession3.SetSession()
?"Would think this would be DS > 1 after set in " +;
"Init() and custom method: ",;
SET("Datasession")

loSession2 = .NULL.
loSession1 = .NULL.

?"Should be default DS 1: ", SET("Datasession")

RETURN

*************************************
DEFINE CLASS pssSession AS Session

DataSession = 2

PROCEDURE Init
* Does not set the datasession to the
* private DataSession, why?
SET DATASESSION TO (this.DataSessionID)
ENDPROC

PROCEDURE Destroy
ENDPROC

PROCEDURE Error(nError, cMethod, nLine)
ENDPROC

PROCEDURE SetSession
* Does not set the datasession to the
* private DataSession, why?
SET DATASESSION TO (this.DataSessionID)
ENDPROC

ENDDEFINE
*: EOF :*
In my mind it should work and for some reason I could not explicitly understand why it does not. Then it hits me, the object is created in the current DataSession, thus when code returns from the Session object back to the calling program, VFP is automatically returning to the current DataSession. This is a common trap I see developers falling into when debugging code that is changing data in an object that was created in the VFP Default DataSession (DS 1). Not exactly the same thing, but very similar. Tonight I fell into the trap.

I proved this was the case by adding code in the Init and SetSession methods to display the current DataSession after the switch, and the DataSession is getting set in code, then reset when returning to the calling code.

Now I understand why I always use the following code when creating and moving to a private DataSession:
loSession = CREATEOBJECT("Session")
SET DATASESSION TO (loSession.DataSessionId)
Maybe this will save you an hour of frustration down the line.
(edited to make sure code word-wrapped for visibility)

Labels:

2 Comments:

At 8/17/2007 04:48:00 PM, Anonymous Anonymous said...

You might want to look at doing common data stuff in a .prg file rather than a class. I am pretty sure VFP doesn't switch the session when calling functions in a .Prg.

I actually approached a FW design to rewrite one of our 2.6 apps that needed the 2.6 form's SPR to still run where I created/used many of my common data access type functions in a prg then in the base class forms calling those functions. I't worked fairly well.

Too bad we decided not to follow through on this ap.

BOb A

 
At 8/18/2007 12:41:00 PM, Blogger Rick Schummer said...

Good point BOb and right on, but it sort of goes against my nature not to code in a class. I am not saying this is a bad idea. I am saying it just would force me to think outside of the box (which is something I like to do). Thanks for this comment.

 

Post a Comment

<< Home