core: - individual parameters managed through sqlite

- new asyncGetParamA method, which allow to get parameter for a not connected profile
	  	==> individual parameters are cached in memory when the profile is connected, but must be accessed
		    though sqlite else, and that must be done asynchronously
primitivus:
	  - profile manager updated to use asyncGetParamA

/!\ still broken, need more work before being able to run again
This commit is contained in:
Goffi 2011-11-01 20:39:22 +01:00
commit 554299aa91

View file

@ -39,6 +39,9 @@ SAVEFILE_HISTORY="/history"
SAVEFILE_PRIVATE="/private" #file used to store misc values (mainly for plugins)
SAVEFILE_DATABASE="/sat.db"
class ProfileNotInCacheError(Exception):
pass
class Param():
"""This class manage parameters with xml"""
### TODO: add desciption in params
@ -76,20 +79,18 @@ class Param():
"""Load parameters template from file"""
self.dom = minidom.parse(file)
def loadGenData(self, storage):
def loadGenData(self):
"""Load general parameters data from storage
@param storage: xxxStorage object instance
@return: deferred triggered once params are loaded"""
return storage.loadGenParams(self.params_gen)
return self.storage.loadGenParams(self.params_gen)
def loadIndData(self, storage, profile):
def loadIndData(self, profile):
"""Load individual parameters
set self.params cache
@param storage: xxxStorage object instance
@param profile: profile to load (*must exist*)
@return: deferred triggered once params are loaded"""
self.params[profile] = {}
return storage.loadIndParams(self.params, profile)
return self.storage.loadIndParams(self.params, profile)
def save_xml(self, file):
"""Save parameters template to xml file"""
@ -109,9 +110,10 @@ class Param():
with open(file+'_ind', 'w') as param_ind_pickle:
pickle.dump(self.params, param_ind_pickle)
def __init__(self, host):
def __init__(self, host, storage):
debug("Parameters init")
self.host = host
self.storage = storage
self.default_profile = None
self.params = {}
self.params_gen = {}
@ -227,7 +229,7 @@ class Param():
node = self.__getParamNode(name, category)
if not node:
error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name':name, 'category':category})
return None
return ""
if node[0] == 'general':
value = self.__getParam(None, category, name, 'general')
@ -239,12 +241,53 @@ class Param():
if not profile:
error(_('Requesting a param for an non-existant profile'))
return ""
if profile not in self.params:
error(_('Requesting synchronous param for not connected profile'))
return ""
if attr == "value":
return self.__getParam(profile, category, name) or node[1].getAttribute(attr)
else:
return node[1].getAttribute(attr)
def asyncGetParamA(self, name, category, attr="value", profile_key="@DEFAULT@", callback=None, errback=None):
"""Helper method to get a specific attribute
@param name: name of the parameter
@param category: category of the parameter
@param attr: name of the attribute (default: "value")
@param profile: owner of the param (@ALL@ for everyone)
@param callback: called when the profile is connected
@param errback: called is the connection fail"""
node = self.__getParamNode(name, category)
if not node:
error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name':name, 'category':category})
return None
if node[0] == 'general':
value = self.__getParam(None, category, name, 'general')
callback(value or node[1].getAttribute(attr))
return
assert(node[0] == 'individual')
profile = self.getProfileName(profile_key)
if not profile:
error(_('Requesting a param for a non-existant profile'))
errback()
return
if attr != "value":
callback(node[1].getAttribute(attr))
return
default = node[1].getAttribute(attr)
try:
callback(self.__getParam(profile, category, name) or default)
except ProfileNotInCacheError:
#We have to ask data to the storage manager
d = self.storage.getIndParam(category, name, profile)
d.addCallback(callback)
d.addErrback(lambda x:errback())
def __getParam(self, profile, category, name, type='individual'):
"""Return the param, or None if it doesn't exist
@ -257,7 +300,9 @@ class Param():
return self.params_gen[(category, name)]
return None #This general param has the default value
assert (type == 'individual')
if not self.params.has_key(profile) or not self.params[profile].has_key((category, name)):
if not self.params.has_key(profile):
raise ProfileNotInCacheError
if not self.params[profile].has_key((category, name)):
return None
return self.params[profile][(category, name)]
@ -418,7 +463,6 @@ class Memory:
self.presenceStatus={}
self.lastResource={} #tmp, will be refactored with bdd integration
self.subscriptions={}
self.params=Param(host)
self.history={} #used to store chat history (key: short jid)
self.private={} #used to store private value
self.server_features={} #used to store discovery's informations
@ -429,8 +473,9 @@ class Memory:
host.set_const('savefile_database', SAVEFILE_DATABASE)
database_file = os.path.expanduser(self.getConfig('','local_dir')+
self.host.get_const('savefile_database'))
self.loadFiles()
self.storage = SqliteStorage(database_file)
self.params=Param(host, self.storage)
self.loadFiles()
self.storage.initialized.addCallback(lambda ignore: self.load(init_defers))
defer.DeferredList(init_defers).chainDeferred(self.initialized)
@ -506,7 +551,7 @@ class Memory:
"""Load parameters and all memory things from db
@param init_defers: list of deferred to wait before parameters are loaded"""
#parameters data
init_defers.append(self.params.loadGenData(self.storage))
init_defers.append(self.params.loadGenData())
def loadIndividualParams(self, profile_key):
"""Load individual parameters for a profile
@ -764,6 +809,9 @@ class Memory:
def getParamA(self, name, category, attr="value", profile_key='@DEFAULT@'):
return self.params.getParamA(name, category, attr, profile_key)
def asyncGetParamA(self, name, category, attr="value", profile_key='@DEFAULT@', callback=None, errback=None):
return self.params.asyncGetParamA(name, category, attr, profile_key, callback, errback)
def getParamsUI(self, profile_key):
return self.params.getParamsUI(profile_key)