Code

issue2550729: Fix password history display for anydbm backend, thanks to
[roundup.git] / roundup / backends / sessions_rdbms.py
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 list(self):
76         c = self.cursor
77         n = self.name
78         c.execute('select %s_key from %ss'%(n, n))
79         return [res[0] for res in c.fetchall()]
81     def destroy(self, infoid):
82         self.cursor.execute('delete from %ss where %s_key=%s'%(self.name,
83             self.name, self.db.arg), (infoid,))
85     def updateTimestamp(self, infoid):
86         """ don't update every hit - once a minute should be OK """
87         now = time.time()
88         self.cursor.execute('''update %ss set %s_time=%s where %s_key=%s
89             and %s_time < %s'''%(self.name, self.name, self.db.arg,
90             self.name, self.db.arg, self.name, self.db.arg),
91             (now, infoid, now-60))
93     def clean(self):
94         ''' Remove session records that haven't been used for a week. '''
95         now = time.time()
96         week = 60*60*24*7
97         old = now - week
98         self.cursor.execute('delete from %ss where %s_time < %s'%(self.name,
99             self.name, self.db.arg), (old, ))
101 class Sessions(BasicDatabase):
102     name = 'session'
104 class OneTimeKeys(BasicDatabase):
105     name = 'otk'
107 # vim: set et sts=4 sw=4 :