File: sessions_rdbms.py

package info (click to toggle)
roundup 1.4.15-3%2Bdeb6u1
  • links: PTS
  • area: main
  • in suites: squeeze-lts
  • size: 6,392 kB
  • ctags: 4,104
  • sloc: python: 31,373; sh: 392; perl: 23; makefile: 23
file content (108 lines) | stat: -rw-r--r-- 3,601 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#$Id: sessions_rdbms.py,v 1.8 2008-08-18 05:04:01 richard Exp $
"""This module defines a very basic store that's used by the CGI interface
to store session and one-time-key information.

Yes, it's called "sessions" - because originally it only defined a session
class. It's now also used for One Time Key handling too.
"""
__docformat__ = 'restructuredtext'

import os, time
from cgi import escape

class BasicDatabase:
    ''' Provide a nice encapsulation of an RDBMS table.

        Keys are id strings, values are automatically marshalled data.
    '''
    def __init__(self, db):
        self.db = db
        self.cursor = self.db.cursor

    def clear(self):
        self.cursor.execute('delete from %ss'%self.name)

    def exists(self, infoid):
        n = self.name
        self.cursor.execute('select count(*) from %ss where %s_key=%s'%(n,
            n, self.db.arg), (infoid,))
        return int(self.cursor.fetchone()[0])

    _marker = []
    def get(self, infoid, value, default=_marker):
        n = self.name
        self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n,
            n, n, self.db.arg), (infoid,))
        res = self.cursor.fetchone()
        if not res:
            if default != self._marker:
                return default
            raise KeyError('No such %s "%s"'%(self.name, escape(infoid)))
        values = eval(res[0])
        return values.get(value, None)

    def getall(self, infoid):
        n = self.name
        self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n,
            n, n, self.db.arg), (infoid,))
        res = self.cursor.fetchone()
        if not res:
            raise KeyError('No such %s "%s"'%(self.name, escape (infoid)))
        return eval(res[0])

    def set(self, infoid, **newvalues):
        c = self.cursor
        n = self.name
        a = self.db.arg
        c.execute('select %s_value from %ss where %s_key=%s'%(n, n, n, a),
            (infoid,))
        res = c.fetchone()
        if res:
            values = eval(res[0])
        else:
            values = {}
        values.update(newvalues)

        if res:
            sql = 'update %ss set %s_value=%s where %s_key=%s'%(n, n,
                a, n, a)
            args = (repr(values), infoid)
        else:
            sql = 'insert into %ss (%s_key, %s_time, %s_value) '\
                'values (%s, %s, %s)'%(n, n, n, n, a, a, a)
            args = (infoid, time.time(), repr(values))
        c.execute(sql, args)

    def list(self):
        c = self.cursor
        n = self.name
        c.execute('select %s_key from %ss'%(n, n))
        return [res[0] for res in c.fetchall()]

    def destroy(self, infoid):
        self.cursor.execute('delete from %ss where %s_key=%s'%(self.name,
            self.name, self.db.arg), (infoid,))

    def updateTimestamp(self, infoid):
        """ don't update every hit - once a minute should be OK """
        now = time.time()
        self.cursor.execute('''update %ss set %s_time=%s where %s_key=%s
            and %s_time < %s'''%(self.name, self.name, self.db.arg,
            self.name, self.db.arg, self.name, self.db.arg),
            (now, infoid, now-60))

    def clean(self):
        ''' Remove session records that haven't been used for a week. '''
        now = time.time()
        week = 60*60*24*7
        old = now - week
        self.cursor.execute('delete from %ss where %s_time < %s'%(self.name,
            self.name, self.db.arg), (old, ))

class Sessions(BasicDatabase):
    name = 'session'

class OneTimeKeys(BasicDatabase):
    name = 'otk'

# vim: set et sts=4 sw=4 :