1 #$Id: sessions_rdbms.py,v 1.8 2008-08-18 05:04:01 richard Exp $
2 """This module defines a very basic store that's used by the CGI interface
3 to store session and one-time-key information.
5 Yes, it's called "sessions" - because originally it only defined a session
6 class. It's now also used for One Time Key handling too.
7 """
8 __docformat__ = 'restructuredtext'
10 import os, time
12 class BasicDatabase:
13 ''' Provide a nice encapsulation of an RDBMS table.
15 Keys are id strings, values are automatically marshalled data.
16 '''
17 def __init__(self, db):
18 self.db = db
19 self.cursor = self.db.cursor
21 def clear(self):
22 self.cursor.execute('delete from %ss'%self.name)
24 def exists(self, infoid):
25 n = self.name
26 self.cursor.execute('select count(*) from %ss where %s_key=%s'%(n,
27 n, self.db.arg), (infoid,))
28 return int(self.cursor.fetchone()[0])
30 _marker = []
31 def get(self, infoid, value, default=_marker):
32 n = self.name
33 self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n,
34 n, n, self.db.arg), (infoid,))
35 res = self.cursor.fetchone()
36 if not res:
37 if default != self._marker:
38 return default
39 raise KeyError('No such %s "%s"'%(self.name, infoid))
40 values = eval(res[0])
41 return values.get(value, None)
43 def getall(self, infoid):
44 n = self.name
45 self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n,
46 n, n, self.db.arg), (infoid,))
47 res = self.cursor.fetchone()
48 if not res:
49 raise KeyError('No such %s "%s"'%(self.name, infoid))
50 return eval(res[0])
52 def set(self, infoid, **newvalues):
53 c = self.cursor
54 n = self.name
55 a = self.db.arg
56 c.execute('select %s_value from %ss where %s_key=%s'%(n, n, n, a),
57 (infoid,))
58 res = c.fetchone()
59 if res:
60 values = eval(res[0])
61 else:
62 values = {}
63 values.update(newvalues)
65 if res:
66 sql = 'update %ss set %s_value=%s where %s_key=%s'%(n, n,
67 a, n, a)
68 args = (repr(values), infoid)
69 else:
70 sql = 'insert into %ss (%s_key, %s_time, %s_value) '\
71 'values (%s, %s, %s)'%(n, n, n, n, a, a, a)
72 args = (infoid, time.time(), repr(values))
73 c.execute(sql, args)
75 def destroy(self, infoid):
76 self.cursor.execute('delete from %ss where %s_key=%s'%(self.name,
77 self.name, self.db.arg), (infoid,))
79 def updateTimestamp(self, infoid):
80 """ don't update every hit - once a minute should be OK """
81 now = time.time()
82 self.cursor.execute('''update %ss set %s_time=%s where %s_key=%s
83 and %s_time < %s'''%(self.name, self.name, self.db.arg,
84 self.name, self.db.arg, self.name, self.db.arg),
85 (now, infoid, now-60))
87 def clean(self):
88 ''' Remove session records that haven't been used for a week. '''
89 now = time.time()
90 week = 60*60*24*7
91 old = now - week
92 self.cursor.execute('delete from %ss where %s_time < %s'%(self.name,
93 self.name, self.db.arg), (old, ))
95 class Sessions(BasicDatabase):
96 name = 'session'
98 class OneTimeKeys(BasicDatabase):
99 name = 'otk'
101 # vim: set et sts=4 sw=4 :