2008-10-29 21:26:22 +00:00
|
|
|
import cherrypy
|
2008-10-30 21:43:25 +00:00
|
|
|
import cPickle as pickle
|
2008-11-04 21:44:17 +00:00
|
|
|
from datetime import datetime
|
2008-10-29 21:26:22 +00:00
|
|
|
|
|
|
|
|
2008-10-30 21:43:25 +00:00
|
|
|
class Session_storage( object ):
|
2008-10-29 21:26:22 +00:00
|
|
|
"""
|
2008-10-30 21:43:25 +00:00
|
|
|
A CherryPy session storage class, originally based on CherryPy's PostgreSQLStorage. It assumes
|
|
|
|
a table like this:
|
|
|
|
|
|
|
|
create table session (
|
|
|
|
id text,
|
|
|
|
data text,
|
|
|
|
expiration_time timestamp
|
|
|
|
)
|
2008-10-29 21:26:22 +00:00
|
|
|
|
2008-10-30 21:43:25 +00:00
|
|
|
It differs from PostgreSQLStorage in the following ways:
|
|
|
|
|
|
|
|
* changes to the database are actually committed after they are made
|
|
|
|
* a new cursor is created for each database access to prevent problems with multiple threads
|
|
|
|
* a connection is requested from cherrypy.root.database instead of a session_filter.get_db method
|
|
|
|
* __del__ is not implemented because it should not be relied upon
|
|
|
|
* no locking is implemented
|
|
|
|
"""
|
2008-10-29 21:26:22 +00:00
|
|
|
def __init__( self ):
|
2008-10-30 21:43:25 +00:00
|
|
|
self.conn = cherrypy.root.database.get_connection()
|
|
|
|
|
|
|
|
def load( self, id ):
|
|
|
|
cursor = self.conn.cursor()
|
|
|
|
|
|
|
|
# Select session data from table
|
|
|
|
cursor.execute(
|
|
|
|
'select data, expiration_time from session where id=%s',
|
|
|
|
(id,))
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
if not rows:
|
2008-10-29 22:09:45 +00:00
|
|
|
return None
|
2008-10-30 21:43:25 +00:00
|
|
|
pickled_data, expiration_time = rows[0]
|
|
|
|
# Unpickle data
|
|
|
|
data = pickle.loads(pickled_data)
|
|
|
|
return (data, expiration_time)
|
|
|
|
|
|
|
|
def save( self, id, data, expiration_time ):
|
|
|
|
cursor = self.conn.cursor()
|
|
|
|
|
|
|
|
# Try to delete session if it was already there
|
|
|
|
cursor.execute(
|
|
|
|
'delete from session where id=%s',
|
|
|
|
(id,))
|
|
|
|
# Pickle data
|
|
|
|
pickled_data = pickle.dumps(data)
|
|
|
|
# Insert new session data
|
|
|
|
cursor.execute(
|
|
|
|
'insert into session (id, data, expiration_time) values (%s, %s, %s)',
|
|
|
|
(id, pickled_data, expiration_time))
|
|
|
|
|
|
|
|
self.conn.commit()
|
|
|
|
|
|
|
|
def clean_up( self, sess ):
|
|
|
|
cursor = self.conn.cursor()
|
|
|
|
|
2008-11-04 21:44:17 +00:00
|
|
|
now = datetime.now()
|
2008-10-30 21:43:25 +00:00
|
|
|
cursor.execute(
|
|
|
|
'select data from session where expiration_time < %s',
|
|
|
|
(now,))
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
for row in rows:
|
|
|
|
sess.on_delete_session(row[0])
|
|
|
|
cursor.execute(
|
|
|
|
'delete from session where expiration_time < %s',
|
|
|
|
(now,))
|
2008-10-29 22:09:45 +00:00
|
|
|
|
2008-10-30 21:43:25 +00:00
|
|
|
self.conn.commit()
|
2008-10-29 21:26:22 +00:00
|
|
|
|
2008-10-30 21:43:25 +00:00
|
|
|
def acquire_lock( self ):
|
|
|
|
raise NotImplemented()
|
|
|
|
|
|
|
|
def release_lock( self ):
|
|
|
|
raise NotImplemented()
|