diff --git a/lib/ulib/support/deploydb.py b/lib/ulib/support/deploydb.py index b1d7e2c..4dab3c3 100755 --- a/lib/ulib/support/deploydb.py +++ b/lib/ulib/support/deploydb.py @@ -17,6 +17,16 @@ def isseq(t): """Tester si t est une séquence """ return isinstance(t, list) or isinstance(t, tuple) or isinstance(t, set) +__SEQOF_UNDEF = object() +def seqof(o, noneValue=__SEQOF_UNDEF): + """Retourner un tuple à parti de o + * si o est une séquence, retourner tuple(o) + * si noneValue est défini, et que o is noneValue, retourner noneValue + * sinon, retourner le tuple (o,) + """ + if isseq(o): return tuple(o) + elif o is noneValue and noneValue is not __SEQOF_UNDEF: return noneValue + else: return (o,) def flatten(src, unique=True, clean=True, sep=','): """découper chaque élément du tableau src selon sep et les aplatir dans une @@ -28,9 +38,8 @@ def flatten(src, unique=True, clean=True, sep=','): e.g flatten(['a , b', 'c,']) --> ['a', 'b', 'c'] """ if src is None: return None - if not isseq(src): src = [src] dest = [] - for items in src: + for items in seqof(src): items = items.split(sep) if clean: items = filter(None, map(lambda item: item.strip(), items)) if unique: @@ -153,7 +162,7 @@ class GenericObject(object): """Tester si cet objet a l'une des valeurs spécifiées (avec match=='any' qui est la valeur par défaut) """ - if not isseq(values): values = [values] + values = seqof(values) if reverse: Yes, No = False, True else: Yes, No = True, False if match == 'any': @@ -233,7 +242,7 @@ class HostObject(GenericObject): return ib def match_values(self, values, match='any', reverse=False): - if not isseq(values): values = [values] + values = seqof(values) if reverse: Yes, No = False, True else: Yes, No = True, False if match == 'any': @@ -409,8 +418,8 @@ class GenericLink(object): spécifiés. """ if profiles is None: return True - if not isseq(profiles): profiles = [profiles] - if profiles == []: return self._profile is None + profiles = seqof(profiles) + if profiles == (): return self._profile is None for profile in profiles: if profile == self._profile: return True return False @@ -418,7 +427,7 @@ class GenericLink(object): """Tester si ce lien a l'un des objets spécifiés dans ses objets de départ (avec match=='any' qui est la valeur par défaut) """ - if not isseq(fos): fos = [fos] + fos = seqof(fos) if reverse: Yes, No = False, True else: Yes, No = True, False if match == 'any': @@ -435,7 +444,7 @@ class GenericLink(object): """Tester si ce lien a l'un des objets spécifiés dans ses objets d'arrivée (avec match=='any' qui est la valeur par défaut) """ - if not isseq(tos): tos = [tos] + tos = seqof(tos) if reverse: Yes, No = False, True else: Yes, No = True, False if match == 'any': @@ -642,24 +651,13 @@ class Database(object): """ return self._objects_ids_otype.keys() known_otypes = property(get_known_otypes) - def get_objects(self, otype, value=UNDEF, attrs=UNDEF): + def get_objects(self, otype): """Obtenir tous les objets définis du type spécifié ou None si le type d'objets est invalide. Si value ou attrs sont définis, filtrer sur ces valeurs. """ - if otype is None: - #XXX faire un traitement récursif avec get_known_otypes - objects = [] - for objects_ids in self._objects_ids_otype.values(): - objects.extend(objects_ids.values()) - else: - objects = self._objects_ids_otype.get(otype, None) - if objects is None: return None - objects = [objects[id] for id in objects if id is not None] - return [ - object for object in objects if - (value is UNDEF or object.match_values(value)) and - (attrs is UNDEF or object.match_attrs(attrs)) - ] + objects = self._objects_ids_otype.get(otype, None) + if objects is None: return None + return [objects[id] for id in objects if id is not None] def has_object(self, otype, id): """Vérifier si l'objet avec l'identifiant spécifié est défini """ @@ -682,6 +680,18 @@ class Database(object): self._objects_ids_otype[otype][id] = object return object + def find_objects(self, otype=UNDEF, value=UNDEF, attrs=UNDEF): + """Chercher tous les objets correspondant aux critères. + """ + objects = [] + otypes = seqof(otype, UNDEF) + for otype in self.get_known_otypes(): + if otypes is not UNDEF and otype not in otypes: continue + objects.extend(self.get_objects(otype)) + return [object for object in objects if + (value is UNDEF or object.match_values(value)) and + (attrs is UNDEF or object.match_attrs(attrs))] + def register_link(self, ltype, lclass): """Enregister un type de lien et la classe utilisée pour l'instancier. @@ -720,14 +730,10 @@ class Database(object): link = self._links_classes[ltype]() link.profile = profile if fo is not UNDEF: - if isseq(fo): fos = fo - else: fos = [fo] - for fo in fos: + for fo in seqof(fo): link.add_fo(fo) if to is not UNDEF: - if isseq(to): tos = to - else: tos = [to] - for to in tos: + for to in seqof(to): link.add_to(to) if attrs is not UNDEF: for name, value in attrs.items(): @@ -1529,7 +1535,7 @@ def print_var(name, values, format, avars, is_values=False): found = True break if not found: return - if not isseq(values): values = [values] + values = seqof(values) if format == 'shell': params = (name, " ".join(qshell(values))) if len(values) <= 1: print "%s=%s" % params @@ -1608,12 +1614,15 @@ def run_qdd(o): if query_type is None and object_type is None and link_type is None: query_type = 'dest' object_type = 'host' + if object_type is None: object_type = UNDEF + if link_type is None: link_type = UNDEF if o.profile is not None: profile = o.profile or None else: profile = UNDEF args = o.args or UNDEF format, ovars, lvars, ofunc, lfunc, avars = __resolve_format(o, query_type) if query_type == 'object': - objects = db.get_objects(object_type, args) + values, attrs = args, UNDEF #XXX part_filter_args(args) + objects = db.find_objects(object_type, values, attrs) print_objects(objects, format, ovars, ofunc, avars) elif query_type == 'source': tos, attrs = part_filter_args(args)