Brevet FR2793917A1 — publié le 20001124

Procédé de gestion, dans un système informatique, de requêtes dans un arbre de contenance hiérarchique. La présente invention a pour objet, dans un système informatique, un procédé de gestion de requêtes dans un arbre de contenance. L'arbre de contenance est inclus dans un système de gestion. Le système informatique peut contenir plusieurs systèmes de gestion, Le terme gestion sera utilisé pour être conforme à la traduction Afnor (Association Française de NORmalisation) de Management . Egalement, le terme arbre de contenance sera utilisé comme traduction du terme MIB (Management Information Base) issu de la norme OSI (Open Systems Interconnection). Un système informatique comprend une machine ou plusieurs machines reliées au système de gestion par l'intermédiaire d'un réseau LAN (Local Area Network), WAN (Wide Area Network) ou INTERNET. Ce système peut être un système distribué ou non, hétérogène ou non. Un système distribué est un environnement de système informatique qui fonctionne au moyen d'au moins deux systèmes d'exploitation identiques ou différents. Une machine est associée à un système d'exploitation. Une machine comprend au moins une ressource physique (par exemple des réseaux, des concentrateurs, des segments, etc) ou logique (par exemple une base de données, etc.). Un système informatique hétérogène contient en général une variété de protocoles de gestion. Dans ce système, chaque machine est associée à au moins un protocole de gestion. Dans ce système informatique, au moins un agent est, en général situé sur une machine du système informatique. Un agent traite des requêtes qui lui sont adressées. Un agent logiciel gère et met à jour des données sur la machine sur laquelle il est situé. Chaque agent supporte un protocole tel que le protocole SNMP (Simple Network Managment Protocol), le protocole CMIP (Common Managment Information Protocol), le protocole DSAC (Distributed Systems Administration and Control) ou d'autres protocoles. Le système de gestion commande les agents, et l'agent répond et notifie des événements en utilisant un protocole de gestion identique SNMP, CMIS/CMIP ou DSAC/AEP (DSAC Administrative Exchange Protocol). Le système de gestion comprend plusieurs agents dits agents intégrateurs en ce sens qu'ils sont intégrés au système de gestion. Les agents et les agents intégrateurs du (des) système(s) de gestion coexistent et communiquent pour masquer l'hétérogénéité du réseau. Dans ce système informatique, un système de gestion de machines d'un système informatique de type OPENMASTER (marque déposée par la société BULL S.A.), connue de l'homme du métier, est particulièrement bien adapté. Ce système utilise des services CMIS (Common Managment Information Services) normalisés, connus de l'homme du métier. Ce système de gestion peut être assimilé à un ensemble de services qui interagissent entre eux pour donner une représentation virtuelle du monde réel qui est le système informatique. C'est une représentation virtuelle qu'un administrateur manipule (surveillance, action) pour gérer le monde réel. La représentation virtuelle porte sur des objets virtuels du monde réel et constitue un modèle objet. Cette représentation virtuelle est concrétisée par l'intermédiaire d'un arbre de contenance. Par définition, l'arbre de contenance est strictement hiérarchique. Le service CMIS (Common Managment Information Services) est bien adapté à la structure hiérarchique de l'arbre de contenance. Dans l'exemple de mise en oeuvre, cet arbre est un logiciel conforme au protocole CMIP (Common Managment Information Protocol). Cet arbre comprend en ses noeuds l'ensemble des objets gérés par le système de gestion. Par définition, un objet géré est une vue abstraite, définie pour les besoins de gestion, d'une ressource logique ou physique d'un système. Une classe d'objets gérés est un ensemble nommé d'objets gérés partageant les mêmes propriétés. Un attribut est une caractéristique d'un objet géré qui a un type nommé et une valeur. La valeur d'un attribut d'un objet peut être consultée ou modifiée par une requête adressée à l'objet. Nommer un objet d'une classe donnée, c'est choisir, conformément aux liens de nommage possibles, ce que l'homme du métier appelle le plus souvent son Full Distinguished Name FDN, c'est-à-dire choisir son supérieur dans l'arbre de nommage et choisir un nom que l'homme du métier appelle le plus souvent Distinguished Name DN vis-à-vis de ce supérieur. Le nommage des objets fait appel à un arbre de nommage. Chaque objet se situe dans l'arbre de nommage par rapport à un supérieur dont il est le subordonné. Cette relation entre subordonnée et supérieure est spécifié e- au niveau des classes par un lien de nommage (name binding en anglais). Lors de la création d'un objet, il faut choisir un seul lien de nommage parmi les liens de nommage possibles pour les objets de cette classe. Plusieurs liens de nommage peuvent être définis pour une même classe, mais un objet ne peut avoir qu'un seul supérieur immédiat. .En d'autres termes, chaque instance de l'arbre est identifié par un FDN et un DN. Le nom DN est un couple qui permet l'identification unique d'une instance de l'arbre de contenance par rapport à une instance père. Le nom FDN d'une instance est une suite de noms DN montrant le chemin de la racine jusque cette instance. De manière générale et connue de l'homme du métier, pour créer un objet dans cette base, il faut choisir sa classe, le nommer conformément aux liens de nommage relatifs à la classe, et donner une valeur à ses attributs. Un arbre de contenance est un arbre constitué d'instances de classes. Actuellement, il est possible de construire une requête de consultation ou de mise à jour de l'arbre de contenance et de l'exécuter. Le gros problème est qu'il n'est pas possible de lier des requêtes. Une conséquence est qu'il n'est pas possible de créer une requête qui permette de travailler sur deux sous-ensembles d'instances différents pour la même classe. Par exemple, considérons un arbre de contenance comprenant la liste des instances de classe Réseau dont une partie comprend un attribut de valeur A et l'autre partie un même attribut avec une valeur différente B. Comme dans tout système informatique, ces réseaux sont associés à un ensemble d'équipements tels que des concentrateurs, des routeurs, etc. Considérons également que cette liste d'instances de classe Réseau soient des instances subordonnées à une instance dite Quartz d'une classe dite Inventaire de l'arbre de classes. Une requête sur cet arbre peut consister à rechercher, dans l'inventaire Quartz, la liste des instances de classe Réseau incluant l'attribut de valeur B dont le nombre d'équipements est supérieur à la moyenne du nombre d'équipements des réseaux incluant l'attribut de valeur A. Le traitement de cette requête fait intervenir deux sous-ensembles différents d'instances d'une même classe Réseau. Le premier sous-ensemble est constitué par les instances de classe Réseau incluant l'attribut de valeur A et le second est constitué par les instances de classe Réseau incluant le même attribut de valeur B dont on ne retient que ceux dont le nombre d'équipements est supérieur à la moyenne calculée. Cette requête doit donc être décomposée en deux sous-requêtes indépendantes. Une première sous-requête comprend un filtre sur l'attribut de valeur A et le calcul de la moyenne des équipements pour les réseaux incluant l'attribut de valeur A. Une deuxième sous-requête qui comprend un filtre sur l'attribut de valeur B et sélectionne les instances de Réseaux incluant l'attribut de valeur B dont le nombre d'équipements est supérieur à la moyenne calculée dans la première sous-requête. La décomposition d'une requête en plusieurs sous-requête n'est pas possible.- Or, les utilisateurs sont de plus en plus amenés à concevoir des requêtes compliquées, beaucoup d'entre elles nécessitant une décomposition en plusieurs sous-requêtes. Un premier but de l'invention est donc de donner la possibilité à un concepteur de requêtes de créer une requête incluant des sous-requêtes pour la mise en #uvre de requêtes complexes. Un deuxième but visé est de procurer au système une puissance d'interrogation de l'arbre de contenance à l'image des clauses dites Select du langage SQL connues de l'homme du métier. A cet effet, la solution a pour objet un Procédé de manipulation d'objets inclus dans un arbre de contenance, les objets étant interrogeables par l'intermédiaire d'au moins une requête multiple incluant au moins deux sous- requêtes incluant chacune une classe d'entrée et une classe de sortie caractérisé en ce qu'il consiste, à définir au moins une variable partagée entre lesdites au moins deux sous-requêtes, a à fixer un ordre temporel d'exécution des différentes sous-requêtes et à lier l'ensemble des sous-requêtes de façon à ce que le résultat d'une sous- requête puisse être exploité par d'autres sous-requêtes de la requête multiple, a et en ce qu'il consiste, à l'exécution de la requête multiple, à sélectionner une instance de départ sur laquelle porte la requête et à lancer séquentiellement les sous-requêtes construites conformément à l'ordre temporel fixé, une sous requête étant activée seulement après que la sous- requête en cours d'exécution soit terminée. Description d'un exemple illustrant la solution. La solution apportée sera mieux comprise à la lecture de la description qui suit donnée à titre d'exemple et faite en référence aux dessins annexés. Dans les dessins la figure 1 est une vue synoptique de l'architecture d'un système informatique sur lequel peut s'appliquer trois solutions à trois problèmes distincts, la figure 2 est une vue schématique d'un arbre de classe et d'un arbre de contenance ; les figures 3 et 4 sont des vues schématiques d'une requête multiple illustrant la solution comprenant respectivement deux sous-requêtes et un nombre quelconque de sous-requêtes; les figures 5A et 5 B sont des vues schématiques respectives d'un arbre de classe et d'un arbre de contenance illustrant une troisième solution à un autre problème. Sur la figure 1, on a représenté un système informatique SYS distribué de type hétérogène. Dans l'exemple illustré, ce système SYS inclut au moins un système gestionnaire SG et au moins une machine distante associée à un protocole de gestion. Le système de gestion peut être compris dans une station de travail. Dans l'exemple, on a représenté une machine distante Ml. Une machine Ml comprend des objets manipulables. Une manipulation inclut des commandes connues de l'homme du métier. Le protocole de gestion de la machine Ml peut-être indifféremment un protocole de type SNMP, CMIS/CMIP ou DSAC/AEP. Dans notre exemple, le système SG supporte un protocole de type CMIS conforme au modèle OSI (Common Managment Information service), connu de l'homme du métier. Cette application peut être lancée par l'intermédiaire d'un utilisateur UT de ce système de gestion SG. Un utilisateur peut être un administrateur. Le système gestionnaire SG comprend également au moins un agent intégrateur associé à un protocole de gestion afin de masquer l'hétérogénéité du système informatique. Dans l'exemple illustré, un agent intégrateur AI est associé au protocole de gestion de la machine Ml. De façon générale, un agent intégrateur est de type logiciel. Il procure des services. Un service peut être une conversion du protocole de gestion. Dans l'exemple illustré, l'agent intégrateur AI convertit le protocole de gestion du système de gestion SG en un protocole de gestion associé à la machine Ml. Réciproquement, l'agent intégrateur AI convertit le protocole de gestion associé à la machine Ml en un protocole de gestion associé au système de gestion SG. Un agent intégrateur ne se limite pas à ce type de service et procure d'autres services. De manière générale, une conversion de protocole de gestion s'effectue naturellement entre un système de gestion SG et une machine qui supportent des protocoles de gestion différents. Naturellement, le serveur de gestion SG peut comprendre plusieurs agents intégrateurs. L'agent intégrateur AI est relié à la machine Ml et à la machine M2 par l'intermédiaire d'un réseau RES1 de type quelconque. Le réseau RESI peut être de type LAN (Local Area Network) ou WAN (Wide Area Network). Un ensemble de couches logicielles s'interpose entre le système de gestion SG et le réseau RES et entre le réseau et la machine Ml. Cet ensemble de couches logicielle repose sur le modèle OSI (Open System Interconnection) d'architecture en couche de VISO (International Organization for Standard ization), connu de l'homme du métier. Pour des raisons de simplification de la description, cet ensemble de couches logicielles n'est pas représenté sur la figure 1. Dans l'exemple illustré, une requête issue du système de gestion est transmise à l'agent. Une requête est, de manière générale, une manipulation d'objets sur une machine distante. La construction d'une requête est expliquée dans la suite de la description. Le système de gestion SG comprend aussi un arbre de contenance MIB associé à l'agent AG. Une vue de cet arbre de contenance MIB est représentée sur la figure 2. L'arbre de contenance peut être entièrement compris dans l'agent AG. Pour simplifier la description, on a choisi de séparer, sur la figure 1, l'arbre de contenance MIB et l'agent AG. Cet arbre MIB assure une représentation virtuelle du monde réel qui entoure le système de gestion SG. C'est une représentation virtuelle que l'utilisateur UT ou qu'un administrateur manipule (surveillance, action) pour gérer le monde réel. La représentation virtuelle porte sur des objets virtuels du monde réel et constitue un modèle objet. Dans l'exemple illustré, le monde réel est matérialisé par le machine Ml. Par définition, l'arbre de contenance MIB est orienté objet et est constitué de noeuds et de branches. Cet arbre comprend en ses noeuds l'ensemble des objets gérés par le système de gestion SG. De manière générale et connue de l'homme du métier, pour créer un objet dans cette base MIB, il faut choisir sa classe, le nommer conformément aux liens de nommage relatifs à la classe, et valoriser ses attributs. Un objet géré est une vue abstraite, définie pour les besoins de gestion, d'une ressource logique ou physique d'un système. Dans l'arbre de contenance, des noeuds appartiennent à une même classe. Un arbre de classes est créé. Dans l'exemple illustré, l'arbre de classes comprend 3 classes: # une classe Inventaire, # une classe Network qui représente les réseaux découverts et est défini par des attributs : # adresse IP du réseau, # état du réseau (bloqué ou libre), nombre d'équipements pour le réseau, classe IP du réseau (A, ou B, ou C, ... ), adresse IP de l'équipement ayant permis la découverte du réseau, etc. # une classe Equipement qui représente les réseaux découverts. Cette classe comprend des attributs : adresse IP de l'équipement, *type de l'équipement (passerelle, concentrateur, etc.), type d'équipement SNIVIP - oui/non classe [P du réseau ( IPA, ou IPB, ou IPC, etc.), nom de l'équipement, adresse IP de l'équipement ayant permis la découverte de l'équipement, etc. La valorisation de ces attributs conduit à l'arbre de contenance de la figure 2. Cet arbre de contenance comprend la racine. Trois noeuds 11, Quartz, et 12 constituant des instances de la classe Inventaire sont des noeuds subordonnés à la racine. Trois noeuds NET1, NET2 et NET3 constituant des instances de la classe Réseau sont des noeuds subordonnés au noeud Quartz. Enfin, dans cet arbre, chaque noeud NET1, NET2 et NET3 a des noeuds subordonnés respectifs (DEV1, DEV2, DEV3), (DEV4, DEV5, DEV6), (DEV7) instances de la classe Equipement. Considérons à nouveau la requête Rl énoncée dans l'introduction Dans l'inventaire Quartz, donner la liste des réseaux de classe IPB dont le nombre d'équipements est supérieur à la moyenne du nombre d'équipements des réseaux de classe IPA . Il est nécessaire d'apporter quelques définitions qui serviront à la compréhension de la description. Rappelons la définition d'un contexte de requête. Le contexte d'une requête se défini comme étant l'ensemble des paramètres décrivant tous les éléments d'une requête # filtres # classes # attributs # opérateurs # variables, etc. Considérons V une variable définie sur une classe X. Dans l'exemple illustré, la classe X peut être la classe Inventaire, la classe Réseau ou la classe Equipement. On qualifiera d'interne toute variable définie sur la classe X et d'externe toute variable définies sur d'autres classes que la classe X. Une variable V peut avoir la forme suivante : V attl... F(att2) ... W... G(Z) où attl, att2 sont des attributs de la classe X, W, Z sont des variables internes ou externes à la classe X F, G sont des fonctions qui s'appliquent sur des variables est un opérateur arithmétique quelconque, Rappelons qu'un filtre est un ensemble d'expressions basées sur les valeurs des attributs d'une classe donnée. Un filtre peut être décomposé en plusieurs expressions qui peuvent être combinées par l'intermédiaire des opérateurs booléen AND- OR - NOT connus de l'homme du métier. Rappelons également, dans l'exemple illustré, qu'au moins une variable est définie pour une classe donnée et que son évaluation repose sur des règles formelles citées ci-dessus. Par exemple, une expression ne peut renvoyer qu'à des attributs de la classe courante. De plus, une expression peut référencer des variables locales ou des variables externes définies sur une autre classe que la classe courante. La résolution de cette requête impose la décomposition en plusieurs sous-requêtes. Le gras problème, tel quénoncé dans l'introduction, est qu'il n'existe pas de moyens de décomposition d'une requête en sous-requêtes. Le traitement de cette requête travaille sur deux sous-ensemble d'instances différents pour la même classe Réseau. Le premier sous-ensemble est constitué par les instances de la classe Réseau de classe réseau IPA et le deuxième sous-ensemble est les instances de la classe Réseau de classe IPB. Pour des- raisons de simplifications de la description, les instances de la classe Réseau de classe réseau ]PA et IPB seront notées réseau A et réseau B respectivement. Cette requête pose un gros problème de conception avec les opérateurs actuels. Ainsi, la définition d'un filtre sur les réseaux A élimine les réseaux B, et vis versa. Dans l'exemple illustré, l'interprétation de la requête Rl conduit donc à créer deux sous-requêtes : # une première sous-requête SRO qui calcul, dans l'inventaire Quartz, la moyenne des équipements pour les réseaux A. # une deuxième sous-requête SIR1 qui sélectionne, toujours dans l'inventaire Quartz, les réseaux B dont le nombre d'équipements est supérieur à la moyenne calculée par l'intermédiaire de la première sous-requête SRO. Dans l'exemple illustré, la solution consiste en une suite d'étapes : Etape 1 : une première étape consiste à définir les opérateurs qui interviennent dans la requête Rl. Ces opérateurs sont pour la plupart inspirés de l'algèbre relationnel, complétés par le concept de variables permettant d'effectuer des calculs sur les données et de mettre en relation les classes entre elles. L'annexe 1 donne un exemple d'opérateurs et la fonction associée que l'on trouve sur une machine de type OPENMASTER. Par exemple, on trouve des opérateurs fondamentaux comme le filtrage, la jointure, les tests ensemblistes (ls-in, Exists, Contains, ... ), le tri, le groupement (GROUP BY), l'opérateur Unique, etc. Des fonctions d'agrégation sur variables ou attributs comme SUM, MIN, MAX, COUNT, AVG, .... sont également disponibles. Etape 2 : une seconde étape consiste à déterminer la classe finale appelée aussi classe de sortie, pour la première et la seconde sous-requête. Cette classe de sortie est la classe sur laquelle on sélectionne les attributs et variables résultats. On détermine cette classe de sortie en fonction de la requête globale à exécuter. Par opposition, lorsqu'une requête est exécutée, elle commence par une instance de la classe d'entrée. Par construction, dans l'exemple illustré, les deux sous-requêtes admettent la même classe d'entrée, et donc seront lancées sur la même instance d'entrée. Dans l'exemple illustré, la classe d'entrée correspond à la classe Inventaire de l'arbre des classes. La requête globale porte sur une instance Quartz de cette classe Inventaire. Dans un autre exemple, si les instances d'entrée sont différentes entre sous-requêtes, la requête globale doit donc avoir comme classe d'entrée la classe Racine. De manière générale, une requête globale porte sur une ou plusieurs instances de base dont la classe doit correspondre avec la classe de départ de la requête globale. La solution consiste à partager les données entre au moins deux sous- requêtes. Les deux sous-requêtes vont interagir en ce sens qu'elles vont toutes deux partager au moins une variable. Etape 3 : Dans l'exemple illustré, la solution comprend une troisième étape de construction de la requête. Cette étape de construction peut être réalisée de deux manières. - Un première manière consiste à créer la requête de manière unitaire. Plus précisément, on crée une sous-requête et on l'enregistre comme étant une sous requête d'une requête multiple. Successivement, on crée et on sauvegarde les autres sous-requêtes comme étant des sous-requêtes d'une même requête, Selon une variante préférée, le système à la charge de créer dynamiquement des pointeurs qui vont lier toutes les sous-requêtes créées. Le lien de toutes les sous-requêtes constitue la requête multiple. - Une seconde manière consiste à créer la requête de façon décomposée. On crée les sous-requêtes indépendamment l'une de l'autre. Afin de lier les sous- requêtes, l'utilisateur sélectionne la dernière requête créée et sélectionne ensuite une fonctionnalité du système propre à établir dans le contexte d'une requête un chaînage inverse. Ce chaînage inverse est procuré par l'intermédiaire de pointeurs. Dans la description, on choisit comme exemple d'illustration le mode unitaire. Dans un exemple, la première sous-requête SRO a la forme suivante: # Sur la classe Réseau # Filtre: classe IP du réseau # variable V-AVG=AVG (nombre d'équipements pour le réseau) (2) # Sur la classe Inventaire (classe d'entrée et classe finale) # variable moy-dev V-AVG (3) # attributs résultat (facultatif) - Identificateur de l'instance d'inventaire, moy_dev (4) Dans cette première sous-requête, l'expression (1) est un filtre sur l'attribut nommé classe IP du Réseau dont la valeur est A. Plus précisément, l'expression (1) est un filtre sur tous les réseaux A et élimine donc tous les réseaux B. Dans l'expression (2), la variable A - AVG est constitué d'une fonction d'agrégation AVG qui calcule pour tous les réseaux A la moyenne du nombre d'équipements. La requête comprenant une fonction d'agrégation, le traitement de cette requête ne porte alors que sur un sous- ensemble d'instances qui inclut l'attribut IPA. La définition du filtre réseau A élimine les réseaux B, et vis versa. La solution consiste donc a exporter, dans la première sous-requête SRO, le résultat obtenu sur la classe Réseau dans la classe finale Inventaire. La classe inventaire comprend une seule instance Quartz. On défini donc sur cette classe une variable moy_dev initialisé à la valeur obtenue V-AVG dans la classe Réseau. Dans l'exemple illustré, les attributs résultats apparaissent dans une matrice Ml: On choisi de faire apparaître dans cette matrice l'identificateur de l'instance sur laquelle est lancée la requête multiple et la valeur obtenu moy_dev, c'est-à-dire la moyenne obtenue. Dans notre exemple, la seconde sous-requête SR1 a la forme B Sur la classe Réseau (classe finale) : Filtre : classe IP du réseau B (5) nombre d'équipements > moy_dev (6) attributs résultats adresse IP du réseau, nombre d'équipements pour ce réseau, avgDev (7) B Sur la classe d'entrée Inventaire (classe d'entrée) variable : moy_dev (valeur arbitraire) (8) Le procédé de construction de cette deuxième sous-requête SR1 est le même que précédemment. On effectue un double filtre. Un premier filtre sur les réseaux B et un deuxième filtre incluant un opérateur de comparaison l'expression (5) est un filtre sur les réseaux B. Concrètement, a l'expression (6) est un filtre sur l'attribut nombre d'équipement qui doit être supérieur à une moyenne. Dans l'expression (7), on choisi les attributs que l'on souhaite afficher dans une matrice M2. Dans l'exemple illustré, les attributs adresse IP du réseau, nombre d'équipements pour ce réseau, avgDev apparaîtront dans cette matrice M2. Dans l'expression (8), on défini une variable arbitraire. Comme cette variable est partagée avec la sous-requête SRO, son exécution diffère dans le cas de l'exécution de sous-requêtes conformément à la première solution. Le choix de la valeur de cette moyenne dans la seconde sous-requête diffère selon que la moyenne est une variable partagée ou non. Conformément à la solution, si cette variable est partagée, la valeur de cette moyenne est la valeur calculée dans une sous-requête. Si cette variable n'est pas partagée entre deux sous-requêtes, la variable partagée est calculée normalement comme pour l'exécution d'une requête non multiple Pour cela, un autre aspect important de la solution est que si moy_dev est une variable partagée entre les deux sous-requêtes : Pour que SR1 ait une visibilité de cette variable partagée dans SRO, cette variable doit être définie sur la classe finale de SRO. Dans l'exemple illustré, la classe finale de SRO est la classe Inventaire. Etape 4 : Les deux sous requêtes sont archivées dans une base de données. Etape 5 : Une autre étape consiste, lors de la validation des sous-requêtes, à établir un ordre temporel d'exécution des sous-requêtes et à munir chaque sous-requête d'au moins un pointeur pour respecter l'ordre d'exécution. Un pointeur peut être un attribut. Dans l'exemple illustré, la première sous-requête et la dernière inclut un seul pointeur. Eventuellement, si la requête multiple comprend au moins trois sous-requêtes, les sous-requêtes intermédiaires comprennent deux pointeurs. La fonction d'un pointeur est évoquée dans une des étapes suivantes. Dans l'exemple illustré, l'exécution de la sous-requête SRO précède l'exécution de la sous-requête SR1. Etape 6 : Une quatrième étape consiste à exécuter la requête. Cet exécution consiste à sélectionner et lancer la dernière sous-requête en ayant sélectionné l'instance de départ sur laquelle porte la requête multiple. L'exécution d'une telle requête est possible à la condition que les sous-requêtes admettent la même classe de départ, et donc sont lancées sur la même instance de départ. Dans l'exemple illustré, l'instance de départ est l'instance Quartz. Si les classes d'entrée diffèrent, on choisi la classe Racine comme classe d'entrée. Etape 7 Lors de l'exécution de la dernière sous-requête SR1, le système détecte la présence d'une requête multiple. Un mécanisme de chaînage est exécuté par le système. Le mécanisme de chaînage est logiciel et c onsiste - lors d'une première phase à pointer successivement, à partir de la dernière sous-requête SR1 sélectionnée, vers la première sous-requête SRO, - et lors d'une seconde phase à lancer séquentiellement les sous-requêtes de la première sous-requête SRO jusque la dernière sous requête SR1, une sous- requête étant activée seulement si l'exécution de la précédente sous-requête est terminée. Durant cette seconde phase, lors de l'évaluation de la variable partagée moy_dev sur la classe Inventaire pour l'instance réseau B, si il existe une valeur de moy_dev dans la première sous-requête SRO pour cette même instance, moy_dev sera calculée dans SR1 avec cette valeur déjà calculée. Dans le cas contraire, si la variable moy_dev n'est pas partagée et est calculée indépendamment de tout autre sous-requête selon des règles d'évaluation normale. Lors des deux phases précitées, le passage d'une sous-requête à une autre est effectué par l'intermédiaire des pointeurs. Dans l'exemple de deux sous- requêtes (SRO, SR1), les deux sous-requêtes incluent un seul pointeur respectif (Rl,Pl). Lors de la première phase, le pointeur Pl pointe vers la première sous-requête SRO. Lors de la deuxième phase, le pointeur Rl pointe vers la deuxième sous-requête. Etape 8 Une sixième étape consiste à afficher les résultats de préférence dans une matrice M2. Les colonnes représentent les attributs résultats sélectionnés et les lignes les instances qui vérifient la ou les sous-requêtes. Par extension, une requête multiple RM peut être considérée comme la suite de n sous requêtes notées SRi, i variant de 1 à n : RM SRO + SR1 + SR1 + ...+ SRi + ... SRn Un exemple d'une requête multiple est montré à la figure 4. L'exécution de RM consiste à lancer l'exécution de la dernière sous- requête SRn, plus précisément celle pour laquelle on désire obtenir les résultats. L'utilisateur lance donc de manière classique l'exécution de SRn en ayant. sélectionné, au préalable, l'instance d'entrée sur laquelle porte la requête multiple RM. Dans l'exemple illustré, les sous-requêtes SRO et SRn comprennent un pointeur respectif RO et Pn. Les sous requêtes intermédiaires SRj comprennent deux pointeurs Pj et Rj. Le système détecte en SRn la présence d'une requête multiple RM. On comprend que si la requête comprend n sous-requêtes, lors de la première phase, la sous-requête SRj inclut un pointeur Pj pour pointer vers la vers la sous-requête SRj-1 de position U-1), et Le système lance ensuite l'exécution séquentielle des sous-requêtes SRi, en commencant par la première SRO, une sous-requête SRi étant activée si et seulement si l'exécution de la sous-requête SRi-1 de position (i-1) est terminée. Lors de cette seconde phase, la même sous-requête SRj inclut un autre pointeur Rj pour pointer vers la vers la sous-requête SRj+l de position U+I). De façon générale, soit VPi une variable partagée entre SRi et SRj. Par exemple, la variable partagée VPi peut être un paramètre d'une fonction d'agrégation F dans la sous-requête SRj. Pour que la sous-requête SRj ait une visibilité de la variable partagée VPi et puisse la prendre en compte lors de son exécution, cette variable partagée VPi doit donc être définie sur la classe finale de la sous-requête SIRi. Soit X cette classe finale. Lors de l'exécution de SRj, l'évaluation de la variable VPi pour la sous-requête SRj sur la classe X pour une instance Xk de la classe X peut avoir deux valeurs : # s'il existe une valeur de VlPi pour Xk dans la sous-requête SRi, la variable partagée VPi sera calculée avec cette valeur calculée, # dans le cas contraire, c'est-à-dire que l'instance Xk n'est pas une solution de la sous-requête SRi, la variable partagée VlPi est calculée normalement comme pour l'exécution d'une requête non multiple. La solution donne la possibilité aux utilisateurs de concevoir des requêtes compliquées, beaucoup d'entre elles nécessitant une décomposition en sous-requêtes. Cette solution évite de recourir à une programmation du type SML-CMIS de leur applicatif qui est lourde, non trivial, et très coûteux en temps. Cette solution procure au système une gestion de sous-requêtes simple d'utilisation qui fournit un éventail considérable de possibilité d'interrogations non envisageables pour le concepteur de requêtes. D'autre part, cette solution permet de définir de manière naturelle un enchaînement de sous-requêtes. Ce concept fort doublé de la notion de partage de variables entre sous-requêtes apportent une autre dimension au pouvoir d'expression du langage, permettant ainsi des réponses simples à des requêtes compliquées. Un deuxième gros problème est lié à la notion de comptabilité entre noms distinctifs de type FDN. Revenons à l'écriture d'une variable V attl ... F(att2) ... W ... G(Z) où - attl, att2 sont des attributs de la classe X, La clas se- X pouvant être indifféremment la classe Inventaire, la classe Réseau ou la classe Equipement, et attl, att2 pouvant être indifféremment des attributs de l'une des classes, W, Z sont des variables internes ou externes à la classe X, F. G sont des fonctions qui s'appliquent sur des variables, et est un opérateur arithmétique quelconque. L'évaluation des variables sur exécution d'une requête satisfait à des règles précises : En effet, la variable V est calculée pour chaque instance de la classe X (Règle 1). Soient Vi la valeur calculée de la variable V pour l'instance Xi de la classe X, et Pi l'instance père de l'instance Xi. Entre autres, pour chaque valeur Vi calculée de l'instance Xi : # l'attribut attl est évalué avec la valeur d'attribut attl de l'instance Xi (Règle 2), # la fonction F(att2) est calculée avec (règle 3) * la valeur de l'attribut att2 de l'instance Xi si F n'est pas une fonction d'agrégation * ou la liste des valeurs de l'attribut att2 des instances Xi subordonnées à Pi si F est une fonction d'agrégation. a VV sera évaluée avec (Règle 4) * la valeur Wi calculée si W est une variable interne, * ou la première valeur calculée de W pour une instance compatible à l'instance Xi si W est une variable externe conformément à la première solution. a -F(W) sera évaluée avec (Règle 5) * la liste des valeurs de VV calculées pour l'ensemble des instances compatibles à Xi si W est externe, * ou la valeur Wi calculée si W est interne. A titre d'exemple, considérons sur la classe Equipement une variable dev-Name nom de l'équipement . Considérons également, sur la classe Réseau, pour une instance de la classe Réseau, l'évaluation des variables suivantes : # fDev dev-Name : cette variable dev-Name est une variable externe qui ne comprend pas de fonction d'agrégation. Selon la règle 4, pour une instance de Réseau, fDev prend la valeur de dev - Name calculée pour la première instance de la classe Equipement compatible ou attachée à cette instance dans l'arbre. # nbDEV LENGTH (dev-Name): cette variable dev - Name est une variable externe comprenant une fonction d'agrégation. Selon la règle 5, cette variable est évaluée avec la liste des dev-Name calculées pour les instances attachées (compatibles) au réseau courant. Comme la fonction LENGTH rend la longueur d'une liste, la variable nbDev sera donc le nombre d'équipements attachés au réseau. # enfin, aliNetw List (nom du réseau). Selon la règle 3, l'attribut nom du réseau est évalué avec la liste des noms de réseau pour l'instance père du réseau courant (ici l'entrée Inventaire), à tous les réseaux. Lors des règles d'évaluations de variables, la règle 3 énonce que F(att2) est calculée avec la liste des valeurs de l'attribut att2 des instances Xi subordonnées à Pi si F est une fonction d'agrégation. Le gros problème est que si la requête comprend une fonction d'agrégation, le traitement de cette requête ne porte que sur un sous-ensemble d'instances compatibles d'une classe donnée. D'une manière générale, la règle de compatibilité intervient dès qu'une variable d'une requête fait référence à une variable externe. Il en est de même pour les opérateurs et filtres spécifiant des variables dans leurs expressions. De la même façon, pour une requête comprenant au moins un filtre avec au moins une variable ou au moins un opérateur (opérateur de jointure, opérateur de tests ensemblistes), la règle de compatibilité entre instances est utilisée automatiquement, ce qui pose problème. De tels opérateurs et filtres reposent sur une notion de compatibilité de noms distinctifs FDN limitant le traitement d'une requête à un sous-ensemble d'instances d'une classe donnée. Or, une requête peut porter sur des instances quelconques d'une classe de l'arbre de contenance. A cet effet, la seconde solution consiste à créer un opérateur supplémentaire NoComp permettant d'inhiber sur une classe donnée les règles de compatibilité sur instances afin de traiter une requête, non pas sur un sous- ensemble d'instances de la classe, mais sur l'ensemble des instances d'une classe. Afin d'illustrer ce second problème, une requête R3 concerné par le problème cité ci-dessus peut être du type : Pour chaque réseau, donner le pourcentage du nombre d'équipements enregistré dans l'arbre de contenance par rapport au nombre total d'équipements de type SNMP . La sémantique de la requête qui en résulte peut être du type - Sur la classe Equipement: variable: dev-Name Nom de l'équipement filtres: SNMP oui - et sur la classe Réseau (classe résultat) Variables nbDev LENGTH (dev-Name) prctDev Nombre d'équipements/nbDev. La fonction LENGTH est donnée en annexe 1. Cette fonction d'agrégation est choisie comme exemple d'illustration du fait que son exécution repose sur les règles de compatibilité. Ce choix est arbitraire en ce sens qu'une autre fonction d'agrégation se reposant sur les mêmes règles aurait pu être choisie à titre d'exemple. PrctDEV calcul le pourcentage du nombre d'équipements enregistrés dans un réseau donné par rapport au nombre total de réseau, L'écriture de cette requête pose deux problèmes : - les réseaux ne comprenant pas d'équipements SNMP sont éliminés, - et le nombre nbDev calcule, pour un réseau, le nombre d'équipements compatibles et non sur le nombre total d'équipements de type SNMP. Selon la seconde solution, l'utilisateur construit la requête en faisant abstraction des règles de compatibilité, dans le calcul de variables, ou dans l'exécution de certains opérateurs. A cet effet, un opérateur NoComp de type logiciel est créé. Considérons, par exemple, une classe X et VX une variable de cette classe X. Ce nouvel opérateur Nocomp a pour fonction, entre autres, - d'évaluer toute variable externe (c'est-à-dire une variable d'une autre classe que la classe X) référençant la variable VX de manière agrégée avec les valeurs de la variable VX calculées pour l'ensemble des instances lues sur la classe X, - d'évaluer une variable de la classe X référençant un attribut avec une fonction d'agrégation avec les valeurs de l'attribut de l'ensemble des instances lues de la classe X. - et si un filtre est défini sur la classe X, la règle de compatibilité des instances des autres classes n'est pas appliquée et les instances des autres classes non compatibles avec les instances concernées de la classe X ne sont pas éliminées. Dans notre exemple, la seconde solution peut consister en une série d'étapes étape 1 : Premièrement, l'utilisateur analyse la requête à traiter et détermine si la règle de compatibilité doit être inhibée en fonction de ce qui précède. Si l'utilisation de la règle de compatibilité est justifiée, l'exécution de la requête R3 s'effectue normalement. Si l'utilisation de la règle de compatibilité n'est pas justifiée, l'exécution de la requête R3 est différente. En effet, dans l'exemple illustré, le concepteur insère l'opérateur d'inhibition Nocomp dans la requête. Cet opérateur peut être appliqué sur n'importe quelle classe où sont définies des variables. Dans l'exemple illustré, la requête a la forme suivante Sur la classe Equipement variable: dev-Name Nom de l'équipement filtres : SNMPstate SNMP-supporté opérateur: NoComp Sur la classe Réseau (classe résultat) Variables nbDev LENGTH (dev-Name) prctDev Nombre d'équipements/nbDev. Ainsi, avec la seconde solution, les réseaux n'ayant pas de réseaux de type SNMP ne sont pas éliminés. Au contraire, la variable nbDev calcule bien pour un réseau le nombre total d'équipement de type SNMP. Etape 2 Une deuxième étape consiste à lire toutes les instances concernées par la requête. On extrait, à partir des instances lues, la valeur de l'attribut objet de l'interrogation qui est inclus dans l'instance respective. Etape 3 Une troisième étape consiste à mémoriser, dans une mémoire quelconque du système, les valeurs des attributs des instances lues. Etape 4 - Une quatrième étape consiste à exécuter la requête en tenant compte des valeurs obtenues à l'étape 3. L'opérateur créé propre à la seconde solution donne à un utilisateur la possibilité d'inhiber les règles de compatibilité sur instances. Un requête ne se limite plus à un sous-ensemble d'instances d'une classe. Au contraire, l'utilisateur peut désormais considérer dans une seule requête l'ensemble des instances d'une classe. L'opérateur peut désormais appliquer un opérateur de jointure ou un test ensembliste sur des instances non compatibles de l'arbre de contenance par l'intermédiaire d'une unique requête. L'utilisateur n'est pas contraint de dupliquer les variables, cette duplication étant lourde à mettre en #uvre et surchargeant l'écriture de la requête. Un troisième gros problème, évoqué dans l'introduction, est lié à la présence d'une même classe à des niveaux différents dans l'arbre de classes. En effet, le modèle GDMO permet à une même classe d'objet d'être subordonnée à plusieurs classes différentes dans l'arbre de classes Sur la figure 4-a, on a représenté un arbre de classes pour illustrer le problème. Cet arbre comprend trois types de classe. La classe racine est, par exemple, la classe Inventaire. Deux classes Note et Réseau de cet arbre sont subordonnées à la classe Inventaire. Enfin, la même classe Note est subordonnée à la classe Réseau. On s'aperçoit donc que cet arbre de classes comprend une même classe Note qui se situe à des niveaux différents de l'arbre. La figure 4-b représente un arbre de contenance comprenant des instances de l'arbre de classes de la figure 4-a. Sur cette figure 4-b, une instance Quartz est une instance de la classe Inventaire. Trois instances Notel, Note2 et Note3 de la classe Note sont subordonnées à l'instance Quartz. Une instance K de la classe Réseau est subordonnée à l'instance Quartz. Enfin, deux instances Notelet Note4 sont subordonnées à l'instance K. On constate également qu'une même instance d'une même classe peut se situer à deux niveaux différents de l'arbre de contenance. Le problème réside ici dans le traitement de la différence, ou de l'intersection ou de l'union dans une même requête sur des instances d'une même classe situées à différents niveaux de l'arbre. A titre d'exemples, considérons une première requête R4 à traiter donner la liste des instances de la classe NOTE attachées à l'instance Quartz de la classe Inventaire . On constate que le résultat réel correspond à l'ensemble des instances de la classe Note subordonnée à la classe Inventaire, mais également l'ensemble des instances de la classe Note directement ou indirectement attachées par l'intermédiaire d'une ou plusieurs instances d'autres classes distinctes de la classe Note dans l'arbre. En l'espèce, les instances subordonnées à l'instance K de la classe Réseau sont une solution. Un autre exemple de requête R5 peut être du type : - Donner, pour une instance Quartz de la classe d'inventaire, la liste des instances de la classe Note attachées, mais n'apparaissant dans aucune autre classe Note indirectement subordonnée. . Le résultat de cette requête comprend l'ensemble des instances de la classe Note attachées à l'instance Quartz, en retirant les instances qui apparaissent sous les classes indirectement attachées à la classe Réseau. Un dernier exemple de requête R6 peut être du type : Donner pour l'instance Quartz, la liste des instances de la classe Note directement attachées à cette instance Quartz et apparaissant dans chacune des autres classes Note indirectement subordonnées. Le résultat de cette requête est l'ensemble des instances de la classe Note attachées à l'instance Quartz de la classe Inventaire et qui apparaissent également sous les classes indirectement attachées à l'instance Quartz. A cet effet, la troisième solution consiste à fournir trois nouveaux opérateurs : # un opérateur d'union propre à unifier des instances d'une même classe situées à différents niveaux de l'arbre de classe, # un opérateur de différence propre à effectuer une soustraction entre instances d'une même classe situées à différents niveaux de l'arbre de classe, # un opérateur d'intersection propre à réaliser une intersection entre instances d'une même classe situées à différents niveaux de l'arbre de classe. La troisième solution consiste donc à disposer d'opérateurs permettant l'union, la différence, et l'intersection de classes situées à un niveau quelconque dans un environnement objets hiérarchique. Selon un exemple de réalisation, la troisième solution peut consister en une autre série d'étapes. Cet exemple de réalisation fait appel au mécanisme de variable et donc aux règles d'évaluation de variables et donc aux règles de compatibilité sur instances. Etape 1 : Une première étape consiste à introduire ces trois opérateurs dans la liste des opérateurs existants (voir annexe 1). Etape 2 : Une interface graphique visible sur un écran d'ordinateur visualise l'arbre des classes. Une classe de cet arbre apparalit par exemple sous la forme d'icône. Les icônes sont, par exemple, reliés par des branches. L'utilisateur peut donc manipuler les noeuds de l'arbre par l'intermédiaire d'une souris. Etape 3 :- La troisième étape consiste à sélectionner les classes situées à des niveaux différents de l'arbre de contenance et sujettes à l'union, la différence ou l'intersection. On appellera classe source la classe d'où part l'opération (classe finale). De même, on appellera classe cible la classe pointée par une opération. De préférence, dans l'arbre de classes, la sélection d'une classe est réalisée en cliquant sur un bouton de la souris, cette sélection entraînant la surbrillance de l'icône associé dans l'arbre. Etape 4 Une quatrième étape consiste à afficher sur la classe finale, un menu MEN présentant les différents opérateurs présents dans le système. Ce menu inclut les opérateurs objets de la troisième solution. Cette étape consiste à sélectionner un opérateur dans le menu qui peut être lUnion, la Différence ou VIntersection sur la classe finale. Sur sélection de l'un des opérateurs booléens objets de la troisième solution, les icônes sélectionnés et coïncidant avec la classe finale sont mémorisés pour l'opération (une fenêtre de type filtre apparaît à l'écran). Etape 6 Une sixième étape consiste à appliquer l'opérateur et à afficher les résultats. Un opérateur conforme à l'invention effectue une opération entre noeuds de même classe de l'arbre de classes, plus précisément entre la classe source et au moins une classe cible. Soit X la classe finale sur laquelle s'applique les requête R4, R5, et R6. Le résultat diffère selon le choix de l'opérateur: A) Le fonctionnement de l'opérateur Union est défini par les définitions suivantes : # a- L'opérateur Union ne peut s'appliquer que sur la classe finale X de la requête, # b- les classes cibles de l'union doivent appartenir à la même classe que la classe source, # c- le résultat de l'opération est l'union des instances qui sont résultats de la classe X et des instances des classes compatibles avec les instances de la classe source (classe finale X), # d- et il n'y a pas de contrôle de duplication d'instances pour le résultat. B) Le fonctionnement de l'opérateur Différence est défini par les définitions suivantes : # a- L'opérateur Différence ne peut s'appliquer que sur la classe finale X de la requête, # b- les classes cibles de cet opérateur doivent appartenir à la même classe que la classe source, # c- le résultat de l'opération est la différence de noms DN entre les instances qui sont résultats de la classe finale et entre les instances compatibles des classes cibles. C) Le fonctionnement de l'opérateur Intersection est défini par les définitions suivantes : # a- Cet opérateur ne peut s'appliquer que sur la classe finale X de la requête, # b- les classes cibles de cet opérateur doivent appartenir à la même classe que la classe source, # c- le résultat de l'opération est l'intersection de noms DN entre les instances qui sont résultats de la classe finale et entre les instances compatibles des classes cibles. NotelD est un attribut de nommage DN défini précédemment. Dans l'exemple illustré, Le terme ID est une valeur numérique. Concrètement, dans l'exemple illustré, la requête R4 peut être construite conformément à cette suite d'étapes. Premièrement, on Sélectionne avec la souris des classes cibles NOTE dans l'arbre de classes. Deuxièmement, on sélectionne l'opérateur Union qui correspond à la requête R4 sur la classe Note subordonnée à la classe Inventaire, Troisièmement, on obtient le résultat de la requête R4. Le résultat est les instances Notel, Note2 et Note3 subordonnées à Vintance Quartz et les instances Note 1 et Note4 subordonnées à l'instance K. Dans ce résultat, conformément aux fonctionnement de l'opérateur Union, deux instances du résultat ont le même nom DN (Notel) avec des noms FDN différents. En effet, le nom DN pour les instances résultats est Notel et les noms FDN respectifs pour les instances résultats sont FDN quartz / NotelD Notel FDN quartz / K/ NotelD Notel Compte tenu de ces définitions, dans l'exemple illustré, la requête R5 peut être construite. Premièrement, on Sélectionne avec la souris des classes cibles NOTE dans l'arbre de classes. Deuxièmement, on sélectionne l'opérateur Différence qui correspond à la requête R4 sur la classe Note subordonnée à la classe Inventaire. Troisièmement, on obtient le résultat de la requête R5. Le résultat est les instances Note2 et Note3 subordonnées à l'instance Quartz et l'instance Note4 subordonnées à l'instance K. Le résultat de cette requête R5 montre que l'instance Notel n'est pas incluse dans le résultat car le nom DN des deux instances Notel dans l'arbre est le même. Compte tenu des définitions, dans l'exemple illustré, la requête R6 peut être construite. Premièrement, on Sélectionne avec la souris des classes cibles NOTE dans l'arbre de classes. Deuxièmement, on sélectionne l'opérateur Intersection qui correspond à la requête R6 sur la classe Note subordonnée à la classe Inventaire. Troisièmement, on obtient le résultat de la requête R6. Le résultat est l'instance Notel. En effet, l'instance Notel subordonnée à l'instance Quartz est la seule instance de la classe Note (classe finale) pour laquelle son nom DN figure dans les instances des autres classes Note indirectement subordonnées à l'instance Quartz. De manière générale, la première solution a pour objet un procédé de manipulation d'objets inclus dans un arbre de contenance, les objets étant interrogeables par l'intermédiaire d'au moins une requête multiple (RM) incluant au moins deux sous-requêtes (SRi et SRj) incluant chacune une classe d'entrée et une classe de sortie caractérisé en ce qu'il consiste, a à définir au moins une variable partagée VP entre lesdites au moins deux sous-requêtes (SRi et SRj), a à fixer un ordre temporel d'exécution des différentes sous-requêtes et à lier l'ensemble des sous-requêtes de façon à ce que le résultat d'une sous- requête (SRi) puisse être exploité par d'autres sous-requêtes (SRj) de la requête multiple (RIVI), a et en ce qu'il consiste, à l'exécution de la requête multiple (RM), à sélectionner une instance de départ sur laquelle porte la requête (RM) et à lancer séquentiellement les sous-requêtes construites conformément à l'ordre temporel fixé, une sous requête étant activée seulement après que la sous- requête en cours d'exécution soit terminée. Dans un exemple, le procédé consiste, pour la fixation de l'ordre temporel, à ajouter à toutes les sous-requêtes au moins un pointeur propre à pointer vers une autre sous-requête conformément à l'ordre temporel fixé. On a vu que l'exploitation d'un résultat obtenu par une sous-requête dans une autre sous-requête consiste à déterminer le classe d'entrée et la classe finale de toutes les sous-requêtes, et en ce qu'il consiste à placer la variable partagée VP sur la classe finale de chaque sous-requête. Ensuite, consiste à lancer séquentiellement les sous-requêtes de la première sous-requête jusque la dernière sous-requête par l'intermédiaire dudit au moins un pointeur une sous-requête étant activée seulement si l'exécution de la précédente sous-requête est terminée. On a vu également dans notre exemple de réalisation que le procédé consiste, avant l'exécution d'une requête à détecter la présence d'une requête multiple, et en ce qu'il consiste, à l'exécution de la requête à enclencher un mécanisme de chaînage consistant . - lors d'une première phase, à pointer successivement à partir de la dernière sous-requête sélectionnée vers la première sous-requête, - et lors d'une seconde phase à lancer séquentiellement les sous- requêtes de la première sous-requête jusque la dernière sous requête, une sous-requête étant activée seulement si l'exécution de la précédente sous- requête est terminée. On a vu que le procédé consiste, Lors de l'exécution de SRj, l'évaluation de la variable VP pour la sous-requête SRj sur la classe X pour une instance Xk de la classe X peut avoir deux valeurs : M s'il existe une valeur de VP pour l'instance Xk dans SRi, la variable partagée VP sera calculée avec cette valeur calculée, dans le cas contraire, si l'instance Xk n'est pas une solution de la sous- requête SRi, la variable partagée VP est calculée normalement comme pour l'exécution d'une requête non multiple. ANNEXE1 EXEMPLES DE FONCTIONS ENSEMBLISTES Fonctions mathématiques - AVG Syntaxe AvG (list-1 , list-2 ... Description : Calcule la moyenne des valeurs des éléments des listes list-1, list-2... et renvoie la moyenne globale. - COUNT Syntaxe : COUNT (liSt-1 Description : Calcule le nombre d'éléments dans la liste list-Il. Utilisez cette fonction pour calculer le nombre d'instances d'une classe. - MAX Syntaxe mAx (list-Il , list-2 ... Description : Calcule le maximum des valeurs des éléments dans les listes list-1, list-2, etc. - MIN Syntaxe MIN (liSt-1 , list-2 ... Description : Calcule le minimum des valeurs des éléments dans les listes list-1, list-2... - MUL Syntaxe MUL(liSt-1 , list-2 ... Description , Calcule le produit des valeurs des éléments dans les listes list-1, list-2... - ROUND Syntaxe : ROUND (val) Description Renvoie la valeur arrondie à l'entier supérieur de val. - SUM Syntaxe sum (list-1 , list-2. . . Description : Calcule la somme des valeurs des éléments dans les listes list-Il, list-2... - ABS Syntaxe ABS (val) Description Renvoie la valeur positive de val. EXEMPLES D'OPÉRATEURS Définir un filtre pour des variables Cet opérateur est analogue à l'opérateur de filtre défini plus haut, à cette différence près qu'il vous autorise à définir un filtre qui ne porte pas sur les attributs de la classe, mais sur les variables définies antérieurement pour cette classe. Ainsi, en sélectionnant l'entrée du menu Filter-Variable, une fenêtre de gestion de filtre apparaît. Une liste des variables pour cette classe s'affiche dans la partie gauche de cette fenêtre. Tout comme pour un filtre classique, la partie "valeu#'de l'expression du filtre peut être spécifiée au moyen d'un élément: - valeur de variable, - référence à une autre variable (rappelez-vous de préfixer le nom de la variable avec un caractère Lorsque la requête est exécutée, les instances retenues pour la classe dans laquelle le filtre a été défini sont conçues de telle manière que les valeurs des variables associées puissent satisfaire l'expression du filtre. Opérateur Jointure CMIS Query Builder propose une opération de jointure équivalente à celle d'une base de données relationnelle. Une "jointure" consiste à combiner les résultats de deux branches différentes sur un arbre de requête. - Une jointure peut être définie dans n'importe quelle classe de la requête. - Plusieurs jointures peuvent être définies dans une requête. Mécanisme d'une iointure Définir une jointure entre la classe A et B d'une requête revient à - supprimer des classes A et B toutes les instances qui ne font pas l'objet d'une union, - créer un objet virtuel dans lequel chaque instance est issue de la concaténation des instances compatibles de A et B se joignant correctement. Exemple : La classe A, dotée des attributs att-al, att-a2 et att-a3, comprend quatre instances. La classe B, dotée des attributs att-bl et att-b2, contient trois instances. Les attributs att-al et att-bl sont sémantiquement identiques. Les tables suivantes présentent les valeurs des attributs pour toutes les instances des classes A et B. instance att-a 1 att-a2 att-a3 ------------------------------------------------------ Al al all a12 A2 a2 a2l a22 A3 a3 a3l a32 A4 a4 a4l a42 instance att-bl att-b2 -------------------------------------------- Bl al bl B2 a2 b2 B3 a5 b3 La table ci-dessous indique le résultat d'une jointure entre les classes A et B dans Une fois la jointure exécutée, les instances A3, A4 et B3 sont supprimées. R E V E N D 1 C A T 10 N S 1- Procédé de manipulation, dans un système informatique, d'objets inclus dans un arbre de contenance inclus dans au moins un système de gestion, ledit système de gestion étant connecté à au moins une machine par l'intermédiaire d'un réseau, les objets étant interrogeables par l'intermédiaire d'au moins une requête multiple (RIVI), une requête multiple consistant en une mise à jour ou une consultation des objets de l'arbre via le réseau, une requête multiple incluant au moins deux sous-requêtes (SRi et SRj) incluant chacune une classe d'entrée et une classe de sortie, caractérisé en ce qu'il consiste, préalablement à l'exécution de la requête multiple, - à définir au moins une variable partagée VP entre lesdites au moins deux sous-requêtes (SRi et SRj), - à fixer un ordre temporel d'exécution des différentes sous-requêtes et à lier l'ensemble des sous-requêtes de façon à ce que le résultat d'une sous-requête (SRi) puisse être exploité par d'autres sous-requêtes (SRj) de la requête multiple (RIVI), et en ce qu il consiste, à l'exécution de la requête multiple (RM), à sélectionner une instance de départ sur laquelle porte la requête (RM) et à lancer séquentiellement les sous-requêtes construites conformément à l'ordre temporel fixé, une sous requête étant activée seulement après que la sous- requête en cours d'exécution soit terminée. 2- Procédé selon la revendication 1, caractérisé en ce qu'il consiste, pour la fixation de l'ordre temporel, à ajouter à toutes les sous-requêtes au moins un pointeur propre à pointer vers une autre sous-requête conformément à l'ordre temporel fixé. 3- Procédé selon la revendication 1 ou 2, caractérisé en ce que l'exploitation d'un résultat obtenu par une sous-requête dans une autre sous- requête consiste à déterminer le classe d'entrée et la classe finale de toutes les sous-requêtes, et en ce qu'il consiste à placer la variable partagée VP sur la classe finale de chaque sous-requête. 4- Procédé selon l'une des revendications 1 ou 3, caractérisé en ce qu'il consiste à lancer séquentiellement les sous-requêtes de la première sous- requête jusque la dernière sous-requête par l'intermédiaire dudit au moins un pointeur une sous-requête étant activée seulement si l'exécution de la précédente sous-requête est terminée. 5- Procédé selon l'une des revendications 1 ou 3, caractérisé en ce qu'il consiste, avant l'exécution d'une requête à détecter la présence d'une requête multiple, et en ce qu'il consiste, à l'exécution de la requête à enclencher un mécanisme de chaînage consistant: - lors d'une première phase, à pointer successivement à partir de la dernière sous-requête sélectionnée vers la première sous-requête, - et lors d'une seconde phase à lancer séquentiellement les sous- requêtes de la première sous-requête jusque la dernière sous requête, une sous-requête étant activée seulement si l'exécution de la précédente sous- requête est terminée. 6- Procédé selon l'une des revendications 1 ou 5, caractérisé en ce qu'il consiste, Lors de l'exécution de SRj, l'évaluation de la variable VP pour la sous- requête SRj sur la classe X pour une instance Xk de la classe X peut avoir deux valeurs : # s'il existe une valeur de VP pour l'instance Xk dans SRi, la variable partagée VP sera calculée avec cette valeur calculée, # dans le cas contraire, si l'instance Xk n'est pas une solution de la sous- requête SRi, la variable partagée VP est calculée normalement comme pour l'exécution d'une requête non multiple.