Due to the way that SQL Session now works with the transaction management system in Zope, you must either give SQL Session it's own database connection, or else patch lib/python/ZODB/Transaction.py using the patch in the distribution. If you don't do this, you may find that Sessions don't work.
This is a server-side session object that stores all state in an SQL database.
create an SQL Session object (it will be called Session), and make sure the SQL is correct. Copy the dtml in the file session_test.dtml into a DTML method in the same folder as the Session object to use if you want to test your SQL schema.
Session
session_test.dtml
in all documents that want to use Sessions, put, at the top:
<dtml-call Session>
(I'd suggest putting it in your standard_html_header)
_force_new_session
SESSION
__getitem__, __setitem__, set, keys, values, items, and most other dictionary methods (except copy)
From here on inside the document, you can do things like:
<dtml-call "SESSION.set('someitem', 'somevalue')"> <dtml-var "SESSION['someitem']">
and it will just be squirrelled away in the DB.
Session can also be called with an argument of session_id. If set, this is the name of the session to use.
It can also be called with a couple of flags: noCookie will stop the code setting a cookie, while validSession will raise an exception if the session being requested does not already exist.
SESSION supports the method getName() - this returns the name of the current session.
getName()
The data is now loaded from the database in one hit when the transaction (webpage) begins, and only changes are written down when the webpage is succesfully completed. This should reduce the load on a database server quite considerably.
The default SQL schema is pretty dumb, but it should work on everything (I test on gadfly):
create table ZSessions ( zsession varchar ) create unique index sessions_idx on ZSessions(zsession) create table ZSession_data ( zsession varchar, zname varchar, zvalue varchar )
A smarter one (like the one I use :) would use a sequence or similar to create a session_id, and use that in a key in zope_session_data. Or use a stored procedure to replace the delete-and-insert method of sqlSetValue.
Anyway, you don't have to use this schema - go edit the sql methods in the session (pull up it's management interface).
Right now the SessionObj stores base64 encoded pickles. It caches of results, but only for the lifetime of the REQUEST.
(sessionObjs are created for each request, so they don't have to worry about getting out of sync with the db.)
The nice thing about storing things this way is, of course, that you can stuff almost anything into it. The bad thing is, of course, that you can stuff almost anything into it. Make sure your definition of the session_data table makes the value column sufficiently large for your needs!
Note that some versions of gadfly gripe about storing strings with newlines in them. There's a patch available for this - see the bottom of this file.
The Session code loads up all values for a session at the start of the session, and saves all changed values off again at the end of the session. To do this, it hooks into Zope's transaction management code.
See seperate file TODO.txt
Anthony Baxter , Tue Jun 6 16:23:27 EST 2000
Gadfly patch: ------------ Aaron Watters wrote: > Anthony Baxter has mentioned a number of times that > gadfly barfs on strings with embedded newlines. There is a > one line patch to this. In sqlgen.py replace > > charstre = "'[^\n']'" > > with > > charstre = "'[^']'" >