comparison src/memory/persistent.py @ 432:31e8c48b5f5d

core: - memory refactoring (moved memory.py and sqlite.py from tools to memory) - private values are now stored in storage (currently sqlite database) and splitted in normal/binary storage. Normal storage is for string key/values, binary storage is for string key and any python data for value - PersistentDict and PersistentBinaryDict are sugar classes to manage the data in storage thought a python dictionary like class.
author Goffi <goffi@goffi.org>
date Sun, 20 Nov 2011 15:34:37 +0100
parents
children 866dbb0d7d87
comparison
equal deleted inserted replaced
431:482b9bcf0ca4 432:31e8c48b5f5d
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 """
5 SAT: a jabber client
6 Copyright (C) 2009, 2010, 2011 Jérôme Poisson (goffi@goffi.org)
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """
21
22 from logging import debug, info, warning, error
23
24 class MemoryNotInitializedError(Exception):
25 pass
26
27 class PersistentDict:
28 """A dictionary which save persistently each value assigned
29 /!\ be careful, each assignment means a database write
30 /!\ Memory must be initialised before loading/setting value with instances of this class"""
31 storage = None
32
33 def __init__(self, namespace, profile=None):
34 """@param namespace: unique namespace for this dictionary
35 @param profile: profile which *MUST* exists, or None for general values"""
36 if not self.storage:
37 error(_("PersistentDict can't be used before memory initialisation"));
38 raise MemoryNotInitializedError
39 self._cache = {}
40 self.namespace = namespace
41 self.profile = profile
42
43 def load(self):
44 """load persistent data from storage
45 """
46 if not self.profile:
47 return self.storage.loadGenPrivates(self._cache, self.namespace)
48 else:
49 return self.storage.loadIndPrivates(self._cache, self.namespace, self.profile)
50
51 def __repr__(self):
52 return self._cache.__repr__()
53
54 def __str__(self):
55 return self._cache.__str__()
56
57 def __lt__(self, other):
58 return self._cache.__lt__(other)
59
60 def __le__(self, other):
61 return self._cache.__le__(other)
62
63 def __eq__(self, other):
64 return self._cache.__eq__(other)
65
66 def __ne__(self, other):
67 return self._cache.__ne__(other)
68
69 def __gt__(self, other):
70 return self._cache.__gt__(other)
71
72 def __ge__(self, other):
73 return self._cache.__ge__(other)
74
75 def __cmp__(self, other):
76 return self._cache.__cmp__(other)
77
78 def __hash__(self):
79 return self._cache.__hash__()
80
81 def __nonzero__(self):
82 return self._cache.__nonzero__()
83
84 def __unicode__(self):
85 return self._cache.__unicode__()
86
87 def __contains__(self, key):
88 return self._cache.__contains__(key)
89
90 def __getitem__(self, key):
91 return self._cache.__getitem__(key)
92
93 def __setitem__(self, key, value):
94 if not self.profile:
95 self.storage.setGenPrivate(self.namespace, key, value)
96 else:
97 self.storage.setIndPrivate(self.namespace, key, value, self.profile)
98 return self._cache.__setitem__(key, value)
99
100 def __delitem__(self, key):
101 if not self.profile:
102 self.storage.delGenPrivate(self.namespace, key)
103 else:
104 self.storage.delIndPrivate(self.namespace, key, self.profile)
105 return self._cache.__delitem__(key)
106
107 def force(self, name):
108 """Force saving of an attribute to storage
109 @return: deferred fired when data is actually saved"""
110 if not self.profile:
111 return self.storage.setGenPrivate(self.namespace, name, self._cache[name])
112 return self.storage.setIndPrivate(self.namespace, name, self._cache[name], self.profile)
113
114
115 class PersistentBinaryDict(PersistentDict):
116 """Persistent dict where value can be any python data (instead of string only)"""
117
118 def load(self):
119 """load persistent data from storage
120 """
121 if not self.profile:
122 return self.storage.loadGenPrivatesBinary(self._cache, self.namespace)
123 else:
124 return self.storage.loadIndPrivatesBinary(self._cache, self.namespace, self.profile)
125
126 def __setitem__(self, key, value):
127 if not self.profile:
128 self.storage.setGenPrivateBinary(self.namespace, key, value)
129 else:
130 self.storage.setIndPrivateBinary(self.namespace, key, value, self.profile)
131 return self._cache.__setitem__(key, value)
132
133 def __delitem__(self, key):
134 if not self.profile:
135 self.storage.delGenPrivateBinary(self.namespace, key)
136 else:
137 self.storage.delIndPrivateBinary(self.namespace, key, self.profile)
138 return self._cache.__delitem__(key)
139
140 def force(self, name):
141 """Force saving of an attribute to storage
142 @return: deferred fired when data is actually saved"""
143 if not self.profile:
144 return self.storage.setGenPrivateBinary(self.namespace, name, self._cache[name])
145 return self.storage.setIndPrivateBinary(self.namespace, name, self._cache[name], self.profile)
146