comparison src/memory/sqlite.py @ 592:e5a875a3311b

Fix pep8 support in src/memory.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 18 Jan 2013 17:55:35 +0100
parents beaf6bec2fcd
children 70bae685d05c
comparison
equal deleted inserted replaced
591:65821b3fa7ab 592:e5a875a3311b
17 17
18 You should have received a copy of the GNU Affero General Public License 18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 """ 20 """
21 21
22
23 from logging import debug, info, warning, error 22 from logging import debug, info, warning, error
24 from twisted.enterprise import adbapi 23 from twisted.enterprise import adbapi
25 from twisted.internet import defer 24 from twisted.internet import defer
25 from time import time
26 import os.path 26 import os.path
27 import time
28 import cPickle as pickle 27 import cPickle as pickle
28
29 29
30 class SqliteStorage(object): 30 class SqliteStorage(object):
31 """This class manage storage with Sqlite database""" 31 """This class manage storage with Sqlite database"""
32
33 32
34 def __init__(self, db_filename): 33 def __init__(self, db_filename):
35 """Connect to the given database 34 """Connect to the given database
36 @param db_filename: full path to the Sqlite database""" 35 @param db_filename: full path to the Sqlite database"""
37 self.initialized = defer.Deferred() #triggered when memory is fully initialised and ready 36 self.initialized = defer.Deferred() # triggered when memory is fully initialised and ready
38 init_defers = [] #list of deferred we have to wait to before initialisation is complete 37 init_defers = [] # list of deferred we have to wait to before initialisation is complete
39 self.profiles={} #we keep cache for the profiles (key: profile name, value: profile id) 38 self.profiles = {} # we keep cache for the profiles (key: profile name, value: profile id)
40 39
41 info(_("Connecting database")) 40 info(_("Connecting database"))
42 new_base = not os.path.exists(db_filename) #do we have to create the database ? 41 new_base = not os.path.exists(db_filename) # do we have to create the database ?
43 self.dbpool = adbapi.ConnectionPool("sqlite3", db_filename, check_same_thread=False) 42 self.dbpool = adbapi.ConnectionPool("sqlite3", db_filename, check_same_thread=False)
44 init_defers.append(self.dbpool.runOperation("PRAGMA foreign_keys = ON").addErrback(lambda x: error(_("Can't activate foreign keys")))) 43 init_defers.append(self.dbpool.runOperation("PRAGMA foreign_keys = ON").addErrback(lambda x: error(_("Can't activate foreign keys"))))
45 if new_base: 44 if new_base:
46 info(_("The database is new, creating the tables")) 45 info(_("The database is new, creating the tables"))
47 database_creation = [ 46 database_creation = [
48 "CREATE TABLE profiles (id INTEGER PRIMARY KEY ASC, name TEXT, UNIQUE (name))", 47 "CREATE TABLE profiles (id INTEGER PRIMARY KEY ASC, name TEXT, UNIQUE (name))",
49 "CREATE TABLE message_types (type TEXT PRIMARY KEY)", 48 "CREATE TABLE message_types (type TEXT PRIMARY KEY)",
50 "INSERT INTO message_types VALUES ('chat')", 49 "INSERT INTO message_types VALUES ('chat')",
51 "INSERT INTO message_types VALUES ('error')", 50 "INSERT INTO message_types VALUES ('error')",
52 "INSERT INTO message_types VALUES ('groupchat')", 51 "INSERT INTO message_types VALUES ('groupchat')",
53 "INSERT INTO message_types VALUES ('headline')", 52 "INSERT INTO message_types VALUES ('headline')",
54 "INSERT INTO message_types VALUES ('normal')", 53 "INSERT INTO message_types VALUES ('normal')",
55 "CREATE TABLE history (id INTEGER PRIMARY KEY ASC, profile_id INTEGER, source TEXT, dest TEXT, source_res TEXT, dest_res TEXT, timestamp DATETIME, message TEXT, type TEXT, FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE, FOREIGN KEY(type) REFERENCES message_types(type))", 54 "CREATE TABLE history (id INTEGER PRIMARY KEY ASC, profile_id INTEGER, source TEXT, dest TEXT, source_res TEXT, dest_res TEXT, timestamp DATETIME, message TEXT, type TEXT, FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE, FOREIGN KEY(type) REFERENCES message_types(type))",
56 "CREATE TABLE param_gen (category TEXT, name TEXT, value TEXT, PRIMARY KEY (category,name))", 55 "CREATE TABLE param_gen (category TEXT, name TEXT, value TEXT, PRIMARY KEY (category,name))",
57 "CREATE TABLE param_ind (category TEXT, name TEXT, profile_id INTEGER, value TEXT, PRIMARY KEY (category,name,profile_id), FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE)", 56 "CREATE TABLE param_ind (category TEXT, name TEXT, profile_id INTEGER, value TEXT, PRIMARY KEY (category,name,profile_id), FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE)",
58 "CREATE TABLE private_gen (namespace TEXT, key TEXT, value TEXT, PRIMARY KEY (namespace, key))", 57 "CREATE TABLE private_gen (namespace TEXT, key TEXT, value TEXT, PRIMARY KEY (namespace, key))",
59 "CREATE TABLE private_ind (namespace TEXT, key TEXT, profile_id INTEGER, value TEXT, PRIMARY KEY (namespace, key, profile_id), FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE)", 58 "CREATE TABLE private_ind (namespace TEXT, key TEXT, profile_id INTEGER, value TEXT, PRIMARY KEY (namespace, key, profile_id), FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE)",
60 "CREATE TABLE private_gen_bin (namespace TEXT, key TEXT, value BLOB, PRIMARY KEY (namespace, key))", 59 "CREATE TABLE private_gen_bin (namespace TEXT, key TEXT, value BLOB, PRIMARY KEY (namespace, key))",
61 "CREATE TABLE private_ind_bin (namespace TEXT, key TEXT, profile_id INTEGER, value BLOB, PRIMARY KEY (namespace, key, profile_id), FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE)", 60 "CREATE TABLE private_ind_bin (namespace TEXT, key TEXT, profile_id INTEGER, value BLOB, PRIMARY KEY (namespace, key, profile_id), FOREIGN KEY(profile_id) REFERENCES profiles(id) ON DELETE CASCADE)",
62 ] 61 ]
63 for op in database_creation: 62 for op in database_creation:
64 d = self.dbpool.runOperation(op) 63 d = self.dbpool.runOperation(op)
65 d.addErrback(lambda x: error(_("Error while creating tables in database [QUERY: %s]") % op )) 64 d.addErrback(lambda x: error(_("Error while creating tables in database [QUERY: %s]") % op))
66 init_defers.append(d) 65 init_defers.append(d)
67 66
68 def fillProfileCache(ignore): 67 def fillProfileCache(ignore):
69 d = self.dbpool.runQuery("SELECT name,id FROM profiles").addCallback(self._profilesCache) 68 d = self.dbpool.runQuery("SELECT name,id FROM profiles").addCallback(self._profilesCache)
70 d.chainDeferred(self.initialized) 69 d.chainDeferred(self.initialized)
74 #Profiles 73 #Profiles
75 def _profilesCache(self, profiles_result): 74 def _profilesCache(self, profiles_result):
76 """Fill the profiles cache 75 """Fill the profiles cache
77 @param profiles_result: result of the sql profiles query""" 76 @param profiles_result: result of the sql profiles query"""
78 for profile in profiles_result: 77 for profile in profiles_result:
79 name, id = profile 78 name, id_ = profile
80 self.profiles[name] = id 79 self.profiles[name] = id_
81 80
82 def getProfilesList(self): 81 def getProfilesList(self):
83 """"Return list of all registered profiles""" 82 """"Return list of all registered profiles"""
84 return self.profiles.keys() 83 return self.profiles.keys()
85 84
86 def hasProfile(self, profile_name): 85 def hasProfile(self, profile_name):
87 """return True if profile_name exists 86 """return True if profile_name exists
88 @param profile_name: name of the profile to check""" 87 @param profile_name: name of the profile to check"""
89 return self.profiles.has_key(profile_name) 88 return profile_name in self.profiles
90 89
91 def createProfile(self, name): 90 def createProfile(self, name):
92 """Create a new profile 91 """Create a new profile
93 @param name: name of the profile 92 @param name: name of the profile
94 @return: deferred triggered once profile is actually created""" 93 @return: deferred triggered once profile is actually created"""
94
95 def getProfileId(ignore): 95 def getProfileId(ignore):
96 return self.dbpool.runQuery("SELECT (id) FROM profiles WHERE name = ?", (name,)) 96 return self.dbpool.runQuery("SELECT (id) FROM profiles WHERE name = ?", (name, ))
97 97
98 def profile_created(profile_id): 98 def profile_created(profile_id):
99 _id = profile_id[0][0] 99 _id = profile_id[0][0]
100 self.profiles[name] = _id #we synchronise the cache 100 self.profiles[name] = _id # we synchronise the cache
101 101
102 d = self.dbpool.runQuery("INSERT INTO profiles(name) VALUES (?)", (name,)) 102 d = self.dbpool.runQuery("INSERT INTO profiles(name) VALUES (?)", (name, ))
103 d.addCallback(getProfileId) 103 d.addCallback(getProfileId)
104 d.addCallback(profile_created) 104 d.addCallback(profile_created)
105 return d 105 return d
106 106
107 def deleteProfile(self, name): 107 def deleteProfile(self, name):
109 @param name: name of the profile 109 @param name: name of the profile
110 @return: deferred triggered once profile is actually deleted""" 110 @return: deferred triggered once profile is actually deleted"""
111 def deletionError(failure): 111 def deletionError(failure):
112 error(_("Can't delete profile [%s]") % name) 112 error(_("Can't delete profile [%s]") % name)
113 return failure 113 return failure
114
114 del self.profiles[name] 115 del self.profiles[name]
115 d = self.dbpool.runQuery("DELETE FROM profiles WHERE name = ?", (name,)) 116 d = self.dbpool.runQuery("DELETE FROM profiles WHERE name = ?", (name, ))
116 d.addCallback(lambda ignore: info(_("Profile [%s] deleted") % name)) 117 d.addCallback(lambda ignore: info(_("Profile [%s] deleted") % name))
117 return d 118 return d
118
119 119
120 #Params 120 #Params
121 def loadGenParams(self, params_gen): 121 def loadGenParams(self, params_gen):
122 """Load general parameters 122 """Load general parameters
123 @param params_gen: dictionary to fill 123 @param params_gen: dictionary to fill
124 @return: deferred""" 124 @return: deferred"""
125
125 def fillParams(result): 126 def fillParams(result):
126 for param in result: 127 for param in result:
127 category,name,value = param 128 category, name, value = param
128 params_gen[(category, name)] = value 129 params_gen[(category, name)] = value
129 debug(_("loading general parameters from database")) 130 debug(_("loading general parameters from database"))
130 return self.dbpool.runQuery("SELECT category,name,value FROM param_gen").addCallback(fillParams) 131 return self.dbpool.runQuery("SELECT category,name,value FROM param_gen").addCallback(fillParams)
131 132
132 def loadIndParams(self, params_ind, profile): 133 def loadIndParams(self, params_ind, profile):
133 """Load individual parameters 134 """Load individual parameters
134 @param params_ind: dictionary to fill 135 @param params_ind: dictionary to fill
135 @param profile: a profile which *must* exist 136 @param profile: a profile which *must* exist
136 @return: deferred""" 137 @return: deferred"""
138
137 def fillParams(result): 139 def fillParams(result):
138 for param in result: 140 for param in result:
139 category,name,value = param 141 category, name, value = param
140 params_ind[(category, name)] = value 142 params_ind[(category, name)] = value
141 debug(_("loading individual parameters from database")) 143 debug(_("loading individual parameters from database"))
142 d = self.dbpool.runQuery("SELECT category,name,value FROM param_ind WHERE profile_id=?", (self.profiles[profile],)) 144 d = self.dbpool.runQuery("SELECT category,name,value FROM param_ind WHERE profile_id=?", (self.profiles[profile], ))
143 d.addCallback(fillParams) 145 d.addCallback(fillParams)
144 return d 146 return d
145 147
146 def getIndParam(self, category, name, profile): 148 def getIndParam(self, category, name, profile):
147 """Ask database for the value of one specific individual parameter 149 """Ask database for the value of one specific individual parameter
148 @param category: category of the parameter 150 @param category: category of the parameter
149 @param name: name of the parameter 151 @param name: name of the parameter
150 @param profile: %(doc_profile)s 152 @param profile: %(doc_profile)s
151 @return: deferred""" 153 @return: deferred"""
152 d = self.dbpool.runQuery("SELECT value FROM param_ind WHERE category=? AND name=? AND profile_id=?", (category,name,self.profiles[profile])) 154 d = self.dbpool.runQuery("SELECT value FROM param_ind WHERE category=? AND name=? AND profile_id=?", (category, name, self.profiles[profile]))
153 d.addCallback(self.__getFirstResult) 155 d.addCallback(self.__getFirstResult)
154 return d 156 return d
155 157
156 def setGenParam(self, category, name, value): 158 def setGenParam(self, category, name, value):
157 """Save the general parameters in database 159 """Save the general parameters in database
158 @param category: category of the parameter 160 @param category: category of the parameter
159 @param name: name of the parameter 161 @param name: name of the parameter
160 @param value: value to set 162 @param value: value to set
161 @return: deferred""" 163 @return: deferred"""
162 d = self.dbpool.runQuery("REPLACE INTO param_gen(category,name,value) VALUES (?,?,?)", (category, name, value)) 164 d = self.dbpool.runQuery("REPLACE INTO param_gen(category,name,value) VALUES (?,?,?)", (category, name, value))
163 d.addErrback(lambda ignore: error(_("Can't set general parameter (%(category)s/%(name)s) in database" % {"category":category, "name":name}))) 165 d.addErrback(lambda ignore: error(_("Can't set general parameter (%(category)s/%(name)s) in database" % {"category": category, "name": name})))
164 return d 166 return d
165 167
166 def setIndParam(self, category, name, value, profile): 168 def setIndParam(self, category, name, value, profile):
167 """Save the individual parameters in database 169 """Save the individual parameters in database
168 @param category: category of the parameter 170 @param category: category of the parameter
169 @param name: name of the parameter 171 @param name: name of the parameter
170 @param value: value to set 172 @param value: value to set
171 @param profile: a profile which *must* exist 173 @param profile: a profile which *must* exist
172 @return: deferred""" 174 @return: deferred"""
173 d = self.dbpool.runQuery("REPLACE INTO param_ind(category,name,profile_id,value) VALUES (?,?,?,?)", (category, name, self.profiles[profile], value)) 175 d = self.dbpool.runQuery("REPLACE INTO param_ind(category,name,profile_id,value) VALUES (?,?,?,?)", (category, name, self.profiles[profile], value))
174 d.addErrback(lambda ignore: error(_("Can't set individual parameter (%(category)s/%(name)s) for [%(profile)s] in database" % {"category":category, "name":name, "profile":profile}))) 176 d.addErrback(lambda ignore: error(_("Can't set individual parameter (%(category)s/%(name)s) for [%(profile)s] in database" % {"category": category, "name": name, "profile": profile})))
175 return d 177 return d
176 178
177 #History 179 #History
178 def addToHistory(self, from_jid, to_jid, message, _type='chat', timestamp=None, profile=None): 180 def addToHistory(self, from_jid, to_jid, message, _type='chat', timestamp=None, profile=None):
179 """Store a new message in history 181 """Store a new message in history
183 @param _type: message type (see RFC 6121 §5.2.2) 185 @param _type: message type (see RFC 6121 §5.2.2)
184 @param timestamp: timestamp in seconds since epoch, or None to use current time 186 @param timestamp: timestamp in seconds since epoch, or None to use current time
185 """ 187 """
186 assert(profile) 188 assert(profile)
187 d = self.dbpool.runQuery("INSERT INTO history(source, source_res, dest, dest_res, timestamp, message, type, profile_id) VALUES (?,?,?,?,?,?,?,?)", 189 d = self.dbpool.runQuery("INSERT INTO history(source, source_res, dest, dest_res, timestamp, message, type, profile_id) VALUES (?,?,?,?,?,?,?,?)",
188 (from_jid.userhost(), from_jid.resource, to_jid.userhost(), to_jid.resource, timestamp or time.time(), 190 (from_jid.userhost(), from_jid.resource, to_jid.userhost(), to_jid.resource, timestamp or time(),
189 message, _type, self.profiles[profile])) 191 message, _type, self.profiles[profile]))
190 d.addErrback(lambda ignore: error(_("Can't save following message in history: from [%(from_jid)s] to [%(to_jid)s] ==> [%(message)s]" % 192 d.addErrback(lambda ignore: error(_("Can't save following message in history: from [%(from_jid)s] to [%(to_jid)s] ==> [%(message)s]" %
191 {"from_jid":from_jid.full(), "to_jid":to_jid.full(), "message":message}))) 193 {"from_jid": from_jid.full(), "to_jid": to_jid.full(), "message": message})))
192 return d 194 return d
193 195
194 def getHistory(self, from_jid, to_jid, limit=0, between=True, profile=None): 196 def getHistory(self, from_jid, to_jid, limit=0, between=True, profile=None):
195 """Store a new message in history 197 """Store a new message in history
196 @param from_jid: source JID (full, or bare for catchall 198 @param from_jid: source JID (full, or bare for catchall
197 @param to_jid: dest JID (full, or bare for catchall 199 @param to_jid: dest JID (full, or bare for catchall
198 @param size: maximum number of messages to get, or 0 for unlimited 200 @param size: maximum number of messages to get, or 0 for unlimited
199 """ 201 """
200 assert(profile) 202 assert(profile)
203
201 def sqliteToDict(query_result): 204 def sqliteToDict(query_result):
202 query_result.reverse() 205 query_result.reverse()
203 result = [] 206 result = []
204 for row in query_result: 207 for row in query_result:
205 timestamp, source, source_res, dest, dest_res, message, _type= row 208 timestamp, source, source_res, dest, dest_res, message, _type = row
206 result.append((timestamp, "%s/%s" % (source, source_res) if source_res else source, 209 result.append((timestamp, "%s/%s" % (source, source_res) if source_res else source,
207 "%s/%s" % (dest, dest_res) if dest_res else dest, 210 "%s/%s" % (dest, dest_res) if dest_res else dest,
208 message, _type)) 211 message, _type))
209 return result 212 return result
210 213
211
212 query_parts = ["SELECT timestamp, source, source_res, dest, dest_res, message, type FROM history WHERE profile_id=? AND"] 214 query_parts = ["SELECT timestamp, source, source_res, dest, dest_res, message, type FROM history WHERE profile_id=? AND"]
213 values = [self.profiles[profile]] 215 values = [self.profiles[profile]]
214 216
215 def test_jid(_type,_jid): 217 def test_jid(_type, _jid):
216 values.append(_jid.userhost()) 218 values.append(_jid.userhost())
217 if _jid.resource: 219 if _jid.resource:
218 values.append(_jid.resource) 220 values.append(_jid.resource)
219 return '(%s=? AND %s_res=?)' % (_type, _type) 221 return '(%s=? AND %s_res=?)' % (_type, _type)
220 return '%s=?' % (_type,) 222 return '%s=?' % (_type, )
221 223
222 if between: 224 if between:
223 query_parts.append("(%s OR %s) AND (%s or %s)" % (test_jid('source', from_jid), 225 query_parts.append("(%s OR %s) AND (%s or %s)" % (test_jid('source', from_jid),
224 test_jid('source', to_jid), 226 test_jid('source', to_jid),
225 test_jid('dest', to_jid), 227 test_jid('dest', to_jid),
226 test_jid('dest', from_jid))) 228 test_jid('dest', from_jid)))
227 else: 229 else:
228 query_parts.append("%s AND %s") % (test_jid('source', from_jid), 230 query_parts.append("%s AND %s" % (test_jid('source', from_jid),
229 test_jid('dest', to_jid)) 231 test_jid('dest', to_jid)))
230 232
231 query_parts.append("ORDER BY timestamp DESC") 233 query_parts.append("ORDER BY timestamp DESC")
232 234
233 if limit: 235 if limit:
234 query_parts.append("LIMIT ?") 236 query_parts.append("LIMIT ?")
241 def loadGenPrivates(self, private_gen, namespace): 243 def loadGenPrivates(self, private_gen, namespace):
242 """Load general private values 244 """Load general private values
243 @param private_gen: dictionary to fill 245 @param private_gen: dictionary to fill
244 @param namespace: namespace of the values 246 @param namespace: namespace of the values
245 @return: deferred""" 247 @return: deferred"""
248
246 def fillPrivates(result): 249 def fillPrivates(result):
247 for private in result: 250 for private in result:
248 key,value = private 251 key, value = private
249 private_gen[key] = value 252 private_gen[key] = value
250 debug(_("loading general private values [namespace: %s] from database") % (namespace,)) 253 debug(_("loading general private values [namespace: %s] from database") % (namespace, ))
251 d = self.dbpool.runQuery("SELECT key,value FROM private_gen WHERE namespace=?", (namespace,)).addCallback(fillPrivates) 254 d = self.dbpool.runQuery("SELECT key,value FROM private_gen WHERE namespace=?", (namespace, )).addCallback(fillPrivates)
252 return d.addErrback(lambda x: debug(_("No data present in database for namespace %s") % namespace)) 255 return d.addErrback(lambda x: debug(_("No data present in database for namespace %s") % namespace))
253 256
254 def loadIndPrivates(self, private_ind, namespace, profile): 257 def loadIndPrivates(self, private_ind, namespace, profile):
255 """Load individual private values 258 """Load individual private values
256 @param privates_ind: dictionary to fill 259 @param privates_ind: dictionary to fill
257 @param namespace: namespace of the values 260 @param namespace: namespace of the values
258 @param profile: a profile which *must* exist 261 @param profile: a profile which *must* exist
259 @return: deferred""" 262 @return: deferred"""
263
260 def fillPrivates(result): 264 def fillPrivates(result):
261 for private in result: 265 for private in result:
262 key,value = private 266 key, value = private
263 private_ind[key] = value 267 private_ind[key] = value
264 debug(_("loading individual private values [namespace: %s] from database") % (namespace,)) 268 debug(_("loading individual private values [namespace: %s] from database") % (namespace, ))
265 d = self.dbpool.runQuery("SELECT key,value FROM private_ind WHERE namespace=? AND profile_id=?", (namespace, self.profiles[profile])) 269 d = self.dbpool.runQuery("SELECT key,value FROM private_ind WHERE namespace=? AND profile_id=?", (namespace, self.profiles[profile]))
266 d.addCallback(fillPrivates) 270 d.addCallback(fillPrivates)
267 return d.addErrback(lambda x: debug(_("No data present in database for namespace %s") % namespace)) 271 return d.addErrback(lambda x: debug(_("No data present in database for namespace %s") % namespace))
268 272
269 def setGenPrivate(self, namespace, key, value): 273 def setGenPrivate(self, namespace, key, value):
270 """Save the general private value in database 274 """Save the general private value in database
271 @param category: category of the privateeter 275 @param category: category of the privateeter
272 @param key: key of the private value 276 @param key: key of the private value
273 @param value: value to set 277 @param value: value to set
274 @return: deferred""" 278 @return: deferred"""
275 d = self.dbpool.runQuery("REPLACE INTO private_gen(namespace,key,value) VALUES (?,?,?)", (namespace,key,value)) 279 d = self.dbpool.runQuery("REPLACE INTO private_gen(namespace,key,value) VALUES (?,?,?)", (namespace, key, value))
276 d.addErrback(lambda ignore: error(_("Can't set general private value (%(key)s) [namespace:%(namespace)s] in database" % 280 d.addErrback(lambda ignore: error(_("Can't set general private value (%(key)s) [namespace:%(namespace)s] in database" %
277 {"namespace":namespace, "key":key}))) 281 {"namespace": namespace, "key": key})))
278 return d 282 return d
279 283
280 def setIndPrivate(self, namespace, key, value, profile): 284 def setIndPrivate(self, namespace, key, value, profile):
281 """Save the individual private value in database 285 """Save the individual private value in database
282 @param namespace: namespace of the value 286 @param namespace: namespace of the value
284 @param value: value to set 288 @param value: value to set
285 @param profile: a profile which *must* exist 289 @param profile: a profile which *must* exist
286 @return: deferred""" 290 @return: deferred"""
287 d = self.dbpool.runQuery("REPLACE INTO private_ind(namespace,key,profile_id,value) VALUES (?,?,?,?)", (namespace, key, self.profiles[profile], value)) 291 d = self.dbpool.runQuery("REPLACE INTO private_ind(namespace,key,profile_id,value) VALUES (?,?,?,?)", (namespace, key, self.profiles[profile], value))
288 d.addErrback(lambda ignore: error(_("Can't set individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" % 292 d.addErrback(lambda ignore: error(_("Can't set individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
289 {"namespace":namespace, "key":key, "profile":profile}))) 293 {"namespace": namespace, "key": key, "profile": profile})))
290 return d 294 return d
291 295
292 def delGenPrivate(self, namespace, key): 296 def delGenPrivate(self, namespace, key):
293 """Delete the general private value from database 297 """Delete the general private value from database
294 @param category: category of the privateeter 298 @param category: category of the privateeter
295 @param key: key of the private value 299 @param key: key of the private value
296 @return: deferred""" 300 @return: deferred"""
297 d = self.dbpool.runQuery("DELETE FROM private_gen WHERE namespace=? AND key=?", (namespace,key)) 301 d = self.dbpool.runQuery("DELETE FROM private_gen WHERE namespace=? AND key=?", (namespace, key))
298 d.addErrback(lambda ignore: error(_("Can't delete general private value (%(key)s) [namespace:%(namespace)s] in database" % 302 d.addErrback(lambda ignore: error(_("Can't delete general private value (%(key)s) [namespace:%(namespace)s] in database" %
299 {"namespace":namespace, "key":key}))) 303 {"namespace": namespace, "key": key})))
300 return d 304 return d
301 305
302 def delIndPrivate(self, namespace, key, profile): 306 def delIndPrivate(self, namespace, key, profile):
303 """Delete the individual private value from database 307 """Delete the individual private value from database
304 @param namespace: namespace of the value 308 @param namespace: namespace of the value
305 @param key: key of the private value 309 @param key: key of the private value
306 @param profile: a profile which *must* exist 310 @param profile: a profile which *must* exist
307 @return: deferred""" 311 @return: deferred"""
308 d = self.dbpool.runQuery("DELETE FROM private_ind WHERE namespace=? AND key=? AND profile=?)", (namespace, key, self.profiles[profile])) 312 d = self.dbpool.runQuery("DELETE FROM private_ind WHERE namespace=? AND key=? AND profile=?)", (namespace, key, self.profiles[profile]))
309 d.addErrback(lambda ignore: error(_("Can't delete individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" % 313 d.addErrback(lambda ignore: error(_("Can't delete individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
310 {"namespace":namespace, "key":key, "profile":profile}))) 314 {"namespace": namespace, "key": key, "profile": profile})))
311 return d 315 return d
312
313 316
314 def loadGenPrivatesBinary(self, private_gen, namespace): 317 def loadGenPrivatesBinary(self, private_gen, namespace):
315 """Load general private binary values 318 """Load general private binary values
316 @param private_gen: dictionary to fill 319 @param private_gen: dictionary to fill
317 @param namespace: namespace of the values 320 @param namespace: namespace of the values
318 @return: deferred""" 321 @return: deferred"""
322
319 def fillPrivates(result): 323 def fillPrivates(result):
320 for private in result: 324 for private in result:
321 key,value = private 325 key, value = private
322 private_gen[key] = pickle.loads(str(value)) 326 private_gen[key] = pickle.loads(str(value))
323 debug(_("loading general private binary values [namespace: %s] from database") % (namespace,)) 327 debug(_("loading general private binary values [namespace: %s] from database") % (namespace, ))
324 d = self.dbpool.runQuery("SELECT key,value FROM private_gen_bin WHERE namespace=?", (namespace,)).addCallback(fillPrivates) 328 d = self.dbpool.runQuery("SELECT key,value FROM private_gen_bin WHERE namespace=?", (namespace, )).addCallback(fillPrivates)
325 return d.addErrback(lambda x: debug(_("No binary data present in database for namespace %s") % namespace)) 329 return d.addErrback(lambda x: debug(_("No binary data present in database for namespace %s") % namespace))
326 330
327 def loadIndPrivatesBinary(self, private_ind, namespace, profile): 331 def loadIndPrivatesBinary(self, private_ind, namespace, profile):
328 """Load individual private binary values 332 """Load individual private binary values
329 @param privates_ind: dictionary to fill 333 @param privates_ind: dictionary to fill
330 @param namespace: namespace of the values 334 @param namespace: namespace of the values
331 @param profile: a profile which *must* exist 335 @param profile: a profile which *must* exist
332 @return: deferred""" 336 @return: deferred"""
337
333 def fillPrivates(result): 338 def fillPrivates(result):
334 for private in result: 339 for private in result:
335 key,value = private 340 key, value = private
336 private_ind[key] = pickle.loads(str(value)) 341 private_ind[key] = pickle.loads(str(value))
337 debug(_("loading individual private binary values [namespace: %s] from database") % (namespace,)) 342 debug(_("loading individual private binary values [namespace: %s] from database") % (namespace, ))
338 d = self.dbpool.runQuery("SELECT key,value FROM private_ind_bin WHERE namespace=? AND profile_id=?", (namespace, self.profiles[profile])) 343 d = self.dbpool.runQuery("SELECT key,value FROM private_ind_bin WHERE namespace=? AND profile_id=?", (namespace, self.profiles[profile]))
339 d.addCallback(fillPrivates) 344 d.addCallback(fillPrivates)
340 return d.addErrback(lambda x: debug(_("No binary data present in database for namespace %s") % namespace)) 345 return d.addErrback(lambda x: debug(_("No binary data present in database for namespace %s") % namespace))
341 346
342 def setGenPrivateBinary(self, namespace, key, value): 347 def setGenPrivateBinary(self, namespace, key, value):
343 """Save the general private binary value in database 348 """Save the general private binary value in database
344 @param category: category of the privateeter 349 @param category: category of the privateeter
345 @param key: key of the private value 350 @param key: key of the private value
346 @param value: value to set 351 @param value: value to set
347 @return: deferred""" 352 @return: deferred"""
348 d = self.dbpool.runQuery("REPLACE INTO private_gen_bin(namespace,key,value) VALUES (?,?,?)", (namespace,key,pickle.dumps(value,0))) 353 d = self.dbpool.runQuery("REPLACE INTO private_gen_bin(namespace,key,value) VALUES (?,?,?)", (namespace, key, pickle.dumps(value, 0)))
349 d.addErrback(lambda ignore: error(_("Can't set general private binary value (%(key)s) [namespace:%(namespace)s] in database" % 354 d.addErrback(lambda ignore: error(_("Can't set general private binary value (%(key)s) [namespace:%(namespace)s] in database" %
350 {"namespace":namespace, "key":key}))) 355 {"namespace": namespace, "key": key})))
351 return d 356 return d
352 357
353 def setIndPrivateBinary(self, namespace, key, value, profile): 358 def setIndPrivateBinary(self, namespace, key, value, profile):
354 """Save the individual private binary value in database 359 """Save the individual private binary value in database
355 @param namespace: namespace of the value 360 @param namespace: namespace of the value
356 @param key: key of the private value 361 @param key: key of the private value
357 @param value: value to set 362 @param value: value to set
358 @param profile: a profile which *must* exist 363 @param profile: a profile which *must* exist
359 @return: deferred""" 364 @return: deferred"""
360 d = self.dbpool.runQuery("REPLACE INTO private_ind_bin(namespace,key,profile_id,value) VALUES (?,?,?,?)", (namespace, key, self.profiles[profile], pickle.dumps(value,0))) 365 d = self.dbpool.runQuery("REPLACE INTO private_ind_bin(namespace,key,profile_id,value) VALUES (?,?,?,?)", (namespace, key, self.profiles[profile], pickle.dumps(value, 0)))
361 d.addErrback(lambda ignore: error(_("Can't set individual binary private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" % 366 d.addErrback(lambda ignore: error(_("Can't set individual binary private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
362 {"namespace":namespace, "key":key, "profile":profile}))) 367 {"namespace": namespace, "key": key, "profile": profile})))
363 return d 368 return d
364 369
365 def delGenPrivateBinary(self, namespace, key): 370 def delGenPrivateBinary(self, namespace, key):
366 """Delete the general private binary value from database 371 """Delete the general private binary value from database
367 @param category: category of the privateeter 372 @param category: category of the privateeter
368 @param key: key of the private value 373 @param key: key of the private value
369 @return: deferred""" 374 @return: deferred"""
370 d = self.dbpool.runQuery("DELETE FROM private_gen_bin WHERE namespace=? AND key=?", (namespace,key)) 375 d = self.dbpool.runQuery("DELETE FROM private_gen_bin WHERE namespace=? AND key=?", (namespace, key))
371 d.addErrback(lambda ignore: error(_("Can't delete general private binary value (%(key)s) [namespace:%(namespace)s] in database" % 376 d.addErrback(lambda ignore: error(_("Can't delete general private binary value (%(key)s) [namespace:%(namespace)s] in database" %
372 {"namespace":namespace, "key":key}))) 377 {"namespace": namespace, "key": key})))
373 return d 378 return d
374 379
375 def delIndPrivateBinary(self, namespace, key, profile): 380 def delIndPrivateBinary(self, namespace, key, profile):
376 """Delete the individual private binary value from database 381 """Delete the individual private binary value from database
377 @param namespace: namespace of the value 382 @param namespace: namespace of the value
378 @param key: key of the private value 383 @param key: key of the private value
379 @param profile: a profile which *must* exist 384 @param profile: a profile which *must* exist
380 @return: deferred""" 385 @return: deferred"""
381 d = self.dbpool.runQuery("DELETE FROM private_ind_bin WHERE namespace=? AND key=? AND profile=?)", (namespace, key, self.profiles[profile])) 386 d = self.dbpool.runQuery("DELETE FROM private_ind_bin WHERE namespace=? AND key=? AND profile=?)", (namespace, key, self.profiles[profile]))
382 d.addErrback(lambda ignore: error(_("Can't delete individual private binary value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" % 387 d.addErrback(lambda ignore: error(_("Can't delete individual private binary value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
383 {"namespace":namespace, "key":key, "profile":profile}))) 388 {"namespace": namespace, "key": key, "profile": profile})))
384 return d 389 return d
385 ##Helper methods## 390 ##Helper methods##
386 391
387 def __getFirstResult(self, result): 392 def __getFirstResult(self, result):
388 """Return the first result of a database query 393 """Return the first result of a database query