Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Multiple Data Sessions
Message
Information générale
Forum:
Visual FoxPro
Catégorie:
Base de données, Tables, Vues, Index et syntaxe SQL
Divers
Thread ID:
00316297
Message ID:
00316405
Vues:
13
>Hi gang,
>
>I have an unusual situation where an app requires the use of multiple data sessions, the number of which varies each time the application runs. Strangely, this application has NO USER INTERFACE (don't ask, and I won't tell < g > ), so anything to do with forms or the SET dialog won't work. I'm not allowed to rewrite this app, but I've been asked to make some "alterations" < s >.
>
>What I'm looking for is a way to tell how *many* data sessions are currently open and/or populated with an open DBC/table(s)/whatever. Anybody got any brilliant ideas/pieces of code that might accomplish this (ie, get it *off my plate* < BG >)?
>

I'll assume you're using Session objects; one easy way to handle this is to have an object that tracks them. Create an object with a member array in it. Add code so that each time a Session is created, it adds an entry to the member array of the application object containing its datasession. The Destroy event of the Session should go to the member array and remove its entry. A sample might look like:
DEFINE CLASS SessionTracker AS CUSTOM
   DIMENSION aSessions[1,2]
   aSessions = NULL
   PROTECTED nNumSessions
   nNumSessions = 0

PROCEDURE AddSession
   *  Record a new Session Object with the tracker
   LPARAMETERS toObjectRef
   IF toObjectRef.DataSession # 1
      *  Only register private datasessions
      WITH this
         *  Record the session object - add to tail of list
         .nNumSessions = .nNumSessions + 1
         DIMENSION .aSessions[.nNumSessions,2]
         .aSessions[.nNumSessions,1] = toObjectRef.DataSessionID
         .aSessions[.nNumSessions,2] = toObjectRef
      ENDWITH
   ENDIF
   RETURN (toObjectRef.DataSession # 1)
ENDPROC

PROCEDURE CheckRegisteredPrivateSessions
   RETURN this.nNumSessions
ENDPROC

PROCEDURE DropSession
   LPARAMETERS tnDataSessionID
   LOCAL lFound, nPtr
   WITH this
      lFound = .F.
      FOR nPtr = 1 TO .nNumSessions
         *  Search the member array for this DataSessionID
         IF .aSessions[nPtr,1] = tnDataSessionID
            lFound = .T.
            EXIT
         ENDIF
      ENDFOR
      IF lFound
         IF .nNumSessions > 1
            *  Only delete the row if there is >1 row
            =ADEL(.aSessions, nPtr)
            DIMENSION .aSessions[.nNumSessions - 1,2]
         ELSE
            * With only 1 row, just null it out
            .aSessions = NULL
         ENDIF
         .nNumSessions = .nNumSessions - 1
      ENDIF
   ENDWITH
   RETURN lFound
ENDPROC

PROCEDURE Destroy
   WITH this
      IF .nNumSessions # 0
         LOCAL nPtr, oSessionObj
         FOR nPtr = 1 TO .nNumSessions
            oSessionObj = .aSessions[nPtr,2]
            IF VARTYPE(oSessionObj) = 'O' AND ! ISNULL(oSessionObj)
               oSessionObj.RemoveSession(.t.)
            ENDIF
            oSessionObj = NULL
         ENDFOR
      ENDIF
      .aSessions = NULL
   ENDWITH
   DODEFAULT()
ENDPROC
ENDDEFINE

DEFINE CLASS RegSession AS Session
   PROTECTED oSessionTracker, lInvokeTracker
   oSessionTracker = NULL
   lInvokeTracker = .F.

PROCEDURE Init
   LPARAMETER toSessionTracker
   *  See if we were passed a tracker
   IF VARTYPE(toSessionTracker) = 'O'
      this.oSessionTracker = toSessionTracker
   ENDIF
   *  Register session with private datasessions if there is a tracker
   IF this.DataSession = 2  AND ! ISNULL(this.oSessionTracker) 
      this.lInvokeTracker = this.oSessionTracker.AddSession(this.DataSessionID,this)
   ENDIF
   *  and whatever else is needed
ENDPROC

PROCEDURE RemoveSession
   LPARAMETER tlBypassTracker
   IF tlBypassTracker
      this.lInvokeTracker = .F.
   ENDIF
   RELEASE this
ENDPROC

PROCEDURE Destroy
   IF this.lInvokeTracker AND ! ISNULL(this.oSessionTracker)
      this.oSessionTracker.DropSession(this.DataSessionID)
   ENDIF
   this.oSessionTracker = NULL
   DODEFAULT()
ENDPROC
ENDDEFINE

*  In your mainline code
oSessionTracker = CREATEOBJ('SessionTracker')

*  Each time you create a new session
oMySessionObj = CREATEOBJ('RegSession',oSessionTracker)

*  To check how many private data sessions are registered
? oSessionTracker.CheckRegisteredPrivateSessions()

*  To see what data sessions are in use
FOR nCtr = 1 TO oSessionTracker.CheckRegisteredPrivateSessions()
   ? oSessionTracker.aSessions[nCtr,1]
ENDFOR

*  To get an object ref to the Session object owning a specific DataSessionID
oSessionObject = NULL
FOR nCtr = 1 TO oSessionTracker.CheckRegisteredPrivateSessions()
   IF oSessionTracker.aSessions[nCtr,1] = nDataSessionToFind
      oSessionObject = oSessionTracker.aSessions[nCtr,2]
      EXIT
   ENDIF
ENDFOR
You'd build your Session subclasses starting from the RegSession class. It's critical that the SessionTracker object have scope at least for the duration of the Session objects that it tracks, if for no other reason than it'll try to kill them off when it dies!

You can have other classes that contain datasession use the same SessionTrack mechanism; make certain to call the SessionTracker's AddSession method, passing the Form/FormSet/Toolbar object ref, since they're the ones that have the DataSession and DataSessionID properties. I don't know how to hook the data environment details of a Report where the report uses its own Private datasession.

This obviously handles figuring out what Data Session numbers are in use as well as how many private datasessions there are. it does not address what objects are reliant on any given datasession (ie I have a Form with a Private datasession; it launches a modal form that has it's datasession set to 1, so that it inherits the data session of the parent form.)

This is not the mechanism I tend to use for managing Session objects; I prefer to use an Object Factory, where I create an object that is then responsible for creating other object instances that it manages. I use the object factory approach because it allows me to emulate static variables without resorting to publics, and I can provide other services like MUTEX and serialization of access to common resources using the factory as manager and administrator.
EMail: EdR@edrauh.com
"See, the sun is going down..."
"No, the horizon is moving up!"
- Firesign Theater


NT and Win2K FAQ .. cWashington WSH/ADSI/WMI site
MS WSH site ........... WSH FAQ Site
Wrox Press .............. Win32 Scripting Journal
eSolutions Services, LLC

The Surgeon General has determined that prolonged exposure to the Windows Script Host may be addictive to laboratory mice and codemonkeys
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform