1"""Base class for SharedKeyDB and VerifierDB."""
2
3import anydbm
4import thread
5
6class BaseDB:
7    def __init__(self, filename, type):
8        self.type = type
9        self.filename = filename
10        if self.filename:
11            self.db = None
12        else:
13            self.db = {}
14        self.lock = thread.allocate_lock()
15
16    def create(self):
17        """Create a new on-disk database.
18
19        @raise anydbm.error: If there's a problem creating the database.
20        """
21        if self.filename:
22            self.db = anydbm.open(self.filename, "n") #raises anydbm.error
23            self.db["--Reserved--type"] = self.type
24            self.db.sync()
25        else:
26            self.db = {}
27
28    def open(self):
29        """Open a pre-existing on-disk database.
30
31        @raise anydbm.error: If there's a problem opening the database.
32        @raise ValueError: If the database is not of the right type.
33        """
34        if not self.filename:
35            raise ValueError("Can only open on-disk databases")
36        self.db = anydbm.open(self.filename, "w") #raises anydbm.error
37        try:
38            if self.db["--Reserved--type"] != self.type:
39                raise ValueError("Not a %s database" % self.type)
40        except KeyError:
41            raise ValueError("Not a recognized database")
42
43    def __getitem__(self, username):
44        if self.db == None:
45            raise AssertionError("DB not open")
46
47        self.lock.acquire()
48        try:
49            valueStr = self.db[username]
50        finally:
51            self.lock.release()
52
53        return self._getItem(username, valueStr)
54
55    def __setitem__(self, username, value):
56        if self.db == None:
57            raise AssertionError("DB not open")
58
59        valueStr = self._setItem(username, value)
60
61        self.lock.acquire()
62        try:
63            self.db[username] = valueStr
64            if self.filename:
65                self.db.sync()
66        finally:
67            self.lock.release()
68
69    def __delitem__(self, username):
70        if self.db == None:
71            raise AssertionError("DB not open")
72
73        self.lock.acquire()
74        try:
75            del(self.db[username])
76            if self.filename:
77                self.db.sync()
78        finally:
79            self.lock.release()
80
81    def __contains__(self, username):
82        """Check if the database contains the specified username.
83
84        @type username: str
85        @param username: The username to check for.
86
87        @rtype: bool
88        @return: True if the database contains the username, False
89        otherwise.
90
91        """
92        if self.db == None:
93            raise AssertionError("DB not open")
94
95        self.lock.acquire()
96        try:
97            return self.db.has_key(username)
98        finally:
99            self.lock.release()
100
101    def check(self, username, param):
102        value = self.__getitem__(username)
103        return self._checkItem(value, username, param)
104
105    def keys(self):
106        """Return a list of usernames in the database.
107
108        @rtype: list
109        @return: The usernames in the database.
110        """
111        if self.db == None:
112            raise AssertionError("DB not open")
113
114        self.lock.acquire()
115        try:
116            usernames = self.db.keys()
117        finally:
118            self.lock.release()
119        usernames = [u for u in usernames if not u.startswith("--Reserved--")]
120        return usernames