import cherrypy import cPickle as pickle from datetime import datetime class Session_storage( object ): """ 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 ) 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 """ def __init__( self ): 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: return None 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() now = datetime.now() 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,)) self.conn.commit() def acquire_lock( self ): raise NotImplemented() def release_lock( self ): raise NotImplemented()