2013-08-27 15:14:44 +04:00
|
|
|
# -*- coding: utf-8 -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
|
|
|
import ulib.base.i_need_py23
|
|
|
|
|
|
|
|
__all__ = ('MultipleStore',)
|
|
|
|
|
|
|
|
from ulib.base.base import isseq
|
|
|
|
from ulib.base.uio import _s, _u
|
|
|
|
from consts import *
|
|
|
|
from store import AbstractStore
|
|
|
|
|
|
|
|
class MultipleStore(AbstractStore):
|
|
|
|
_stores = None
|
|
|
|
_cstores = None
|
|
|
|
_last_lsid = 0
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
def __init__(self, stores=None):
|
|
|
|
AbstractStore.__init__(self)
|
|
|
|
if stores is None: stores = ()
|
|
|
|
elif not isseq(stores): stores = (stores,)
|
|
|
|
self._stores = []
|
|
|
|
for store in stores:
|
|
|
|
self.add_store(store)
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
def add_store(self, store):
|
|
|
|
if store.get_sid() is None:
|
|
|
|
store.set_lsid(self._last_lsid)
|
|
|
|
self._last_lsid = self._last_lsid + 1
|
|
|
|
self._stores.append(store)
|
|
|
|
self._cstores = None # pour qu'il soit reconstruit
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
def get_name(self):
|
|
|
|
u"""Retourner le nom de ce store.
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
Il s'agit des noms de tous les stores gérés par ce store, séparés par
|
|
|
|
des caractères '+'.
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
@rtype: unicode
|
|
|
|
"""
|
|
|
|
return u"+".join([store.name for store in self.get_stores()])
|
|
|
|
name = property(get_name)
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
_wstore = None
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
def get_wstore(self):
|
|
|
|
u"""Retourner le store destination, c'est à dire celui dans lequel on
|
|
|
|
ajoute les tâches par défaut. Par défaut, il s'agit du premier store
|
|
|
|
de la liste.
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
@raise IndexError: s'il n'y a aucun stores
|
|
|
|
"""
|
|
|
|
if self._wstore is not None:
|
|
|
|
return self._wstore
|
|
|
|
else:
|
|
|
|
if self._stores: return self._stores[0]
|
|
|
|
raise IndexError("Unable to find destination store")
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
def set_wstore(self, name=None):
|
|
|
|
u"""Choisir le store destination.
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
@param name: Nom du store à sélectionner, ou None pour prendre le
|
|
|
|
premier de la liste.
|
|
|
|
@return: self
|
|
|
|
"""
|
|
|
|
if name is None:
|
|
|
|
self._wstore = None
|
|
|
|
else:
|
|
|
|
for store in self.get_stores():
|
|
|
|
if store.get_name() == name:
|
|
|
|
self._wstore = store
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
raise ValueError("Invalid store: %s" % name)
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
def get_stores(self, force=False):
|
|
|
|
u"""Retourner la liste des stores gérés par ce store. Si c'est un store
|
|
|
|
simple, la liste de contient qu'un élément.
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
@param force: forcer la reconstruction de la liste. par défaut,
|
|
|
|
utiliser une valeur mise en cache.
|
|
|
|
@rtype: tuple
|
|
|
|
"""
|
|
|
|
if force or self._cstores is None:
|
|
|
|
stores = []
|
|
|
|
for store in self._stores:
|
|
|
|
stores.extend(store.get_stores())
|
|
|
|
self._cstores = tuple(stores)
|
|
|
|
return self._cstores
|
|
|
|
|
|
|
|
def get_store_by_sid(self, sid=None):
|
|
|
|
u"""Obtenir le store dont on donne le sid, ou None si le sid n'existe
|
|
|
|
pas. Si sid==None, retourner le store par défaut.
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
@rtype: AbstractStore
|
|
|
|
"""
|
|
|
|
if sid is None: return self.get_store()
|
|
|
|
sid = _u(sid)
|
|
|
|
for store in self.get_stores():
|
|
|
|
if _u(store.sid) == sid: return store
|
|
|
|
return None
|
2015-08-20 07:58:17 +04:00
|
|
|
|
2013-08-27 15:14:44 +04:00
|
|
|
def get_tasks(self):
|
|
|
|
tasks = []
|
|
|
|
for store in self.get_stores():
|
|
|
|
tasks.extend(store.tasks)
|
|
|
|
return tasks
|
|
|
|
tasks = property(get_tasks)
|
|
|
|
|
|
|
|
def remove(self, task):
|
|
|
|
for store in self.get_stores():
|
|
|
|
if store.remove(task): return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def load(self, infdn=None, force=False, force_reload=False, **ignored):
|
|
|
|
if infdn is not None:
|
|
|
|
raise ValueError("infdn is not supported for this store")
|
|
|
|
for store in self.get_stores():
|
|
|
|
if force_reload or store.should_reload():
|
|
|
|
store.load(force=force)
|
|
|
|
|
|
|
|
def should_reload(self):
|
|
|
|
for store in self.get_stores():
|
|
|
|
if store.should_reload(): return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def revert(self):
|
|
|
|
for store in self.get_stores(): store.revert()
|
|
|
|
|
|
|
|
def save(self, outfdn=None, force=False):
|
|
|
|
if outfdn is not None:
|
|
|
|
raise ValueError("outfdn is not supported for this store")
|
|
|
|
saved = False
|
|
|
|
for store in self.get_stores():
|
|
|
|
if store.save(force=force):
|
|
|
|
saved = True
|
|
|
|
return saved
|