Article
· Jan 4 9m de lecture

L'art de mapper les globales aux classes (5 sur 3)

Exemples de mappage

De toute évidence, si vous avez un quatrième article dans une trilogie, vous devez tenter votre chance et écrire le cinquième, alors le voici !

Remarque : Il y a de nombreuses années, Dan Shusman m'a dit que cartographier des globales était une forme d'art. Il n’y a pas de bonne ou de mauvaise manière de procéder. La façon dont vous interprétez les données vous amène au type de cartographie que vous effectuez. Comme toujours, il existe plusieurs façons d’arriver à une réponse finale. En parcourant mes exemples, vous verrez que certains exemples mappent le même type de données de différentes manières.

À la fin de cet article, vous trouverez un fichier zip contenant la collection d'exemples de cartographie que j'ai écrits pour les clients au fil des ans. Ci-dessous, j'en soulignerai quelques-uns qui mettront en évidence certaines choses que j'ai référencées dans mes 4 précédents articles de cartographie. Comme il s'agit d'une pure ponction d'argent, il n'y aura pas le même niveau de détail que les 4 derniers. Si quelque chose n'a pas de sens, veuillez le faire savoir et j'entrerai plus en détail avec vous.

Row ID Spec: 

Exemple de classe : Mapping.RowIdSpec.xml

Je l'ai promis à plusieurs reprises dans des articles précédents. Vous devez définir cela uniquement lorsque vos expressions d'indice ne sont pas de simples champs. Dans mon exemple, je prends la valeur stockée dans l'indice et je la multiplie par 100. Ainsi, lorsque je regarde la globale, j'ai besoin de 1,01 mais je veux que la valeur logique soit 101. L'indice 2 a donc une expression de { ClassNumber}/100 et RowIdSpec est {L2}*100. Je fais toujours ça à l'envers la première fois. L'expression d'indice prend la valeur logique et l'utilise dans le $ORDER() de la globale, donc divisez par 100. La spécification RowId prend la valeur du global et construit la valeur logique, donc multipliez par 100.

Vous pouvez également le faire en écrivant le code suivant et une condition invalide qui géreraient la multiplication et la division.

Subscript Expression Type Other / Next Code / Invalid Condition / Data Access: 

Exemple de classe : Mapping.TwoNamespacesOneGlobal.xml

Wow, quelle mine d'or ce cours est ! Ce cours utilise la moitié des choses dont je veux parler. Cette classe boucle sur le même global dans 2 espaces de noms différents. Nous ne pouvons pas utiliser le mappage au niveau de l'indice car les deux espaces de noms utilisent les mêmes valeurs d'indice. Au lieu de cela, nous allons utiliser la syntaxe de référence globale étendue, ^|namespace|GlobalName, en parcourant d'abord la globale dans l'espace de noms USER, puis en parcourant le même global dans l'espace de noms SAMPLES. L'IDKey de cette table sera composée de deux parties : Namespace et Sub1.

                Subscript Expression Other:  Au niveau d'indice 1, nous n'effectuons pas $ORDER() ou $PIECE(). Nous définissons plutôt {L1} sur l'une des deux valeurs codées en dur :  USER ou SAMPLES. Aucune globale n’est utilisée ici, le type est donc « Autre ».

                Next Code:  Si vous utilisez une expression d'indice de type « Autre », vous devrez fournir le code suivant (OK, vous pouvez donc écrire une expression complexe pour ce faire, mais dans tous les cas, vous fournissez le code). La première fois que le code suivant est appelé {L1}, il sera défini sur la « valeur de départ », la valeur par défaut est la chaîne vide. Votre prochain code doit définir {L1} égal à Chaîne vide lorsque vous avez terminé la boucle. Pour cet exemple, {L1} sera défini sur « USER », « SAMPLES » et « » les trois fois où il sera appelé. Le code suivant du niveau d'indice 2 sera réinitialisé à "" pour les 2 bonnes valeurs renvoyées par le niveau d'indice 1. Le code suivant ici est juste un simple $$ORDER() sur la globale avec la référence étendue.

                Invalid Condition:  Les niveaux d'indice 1 et 2 ont le code suivant, ce qui signifie qu'ils ont tous deux besoin d'une condition invalide.  Étant donné une valeur pour ce niveau d'indice, la condition doit renvoyer 1 s'il s'agit d'une mauvaise valeur. Pour {L1}, si la valeur n'est pas "USER" ou "SAMPLES", elle renverra 1.

Par exemple: 

SELECT * FROM Mapping.RowIdSpec WHERE NS = “%SYS”

ne renverra aucune ligne en raison de la condition invalide pour {L1}

                Data Access:  Supposons que vous ayez un global avec une IdKey basée sur 2 propriétés dans un global comme ^glo({sub1},{Sub2}). Si vous fournissez une valeur pour {Sub1} avant de démarrer la boucle sur {Sub2}, nous vérifierons si il y a des données au niveau précédent en effectuant un $DATA(^glo({Sub1}).  Dans cet exemple, nous n'avons pas de global au niveau d'indice 1, nous devons donc savoir quoi tester.  Il s'agit de l'expression d'accès aux données :  ^|{L1}|Facility.  L'exemple suivant nécessite également une expression d'accès aux données et il pourrait être plus facile à suivre.  Si celui-ci prête à confusion, regardez l'exemple suivant.

 

Data Access / Full Row Reference: 

Exemple de classe : Mapping.TwoNamespacesOneGlobal2.xml

Cette classe mappe les mêmes données que la précédente. La différence réside dans le niveau d'indice 1. Au lieu de coder en dur les valeurs de l'espace de noms, cette classe possède un deuxième global contenant les espaces de noms sur lesquels nous voulons boucler :  ^NS("Claims",{NS}). Non seulement cela simplifie le mappage, mais cela rend les choses plus flexibles car vous pouvez ajouter un nouvel espace de noms simplement en définissant une globale au lieu de modifier le mappage de classe.

                Data Access:   La "Globale" dans le mappage est défini comme ^NS puisqu'il s'agit de la globale sur laquellle nous bouclons dans les niveaux d'indice 1 et 2. Pour le niveau d'indice 3, nous souhaitons passer à ^|{NS}|Facility({Sub1}).  Avant de pouvoir utiliser une Globale différente dans le code suivant, nous devons la définir dans « Accès aux données ». {L1} n'était qu'une contrainte dans le ^NS global et n'est pas utilisé dans le ^Facility global, nous le nivelons donc simplement. {L2} est désormais utilisé comme référence d'espace de noms dans la syntaxe globale étendue :  ^|{L2}|Facility. Dans cette classe, le « code suivant » n'est pas défini (il n'était donc pas nécessaire non plus dans le dernier exemple). Le compilateur de classe prend « l'accès aux données » et l'utilise pour générer le $ORDER() nécessaire à ce niveau.

               Full Row Reference:  Semblable à la "Condition invalide", elle est utilisée pour référencer la ligne si toutes les parties de l'IdKey sont utilisées :  ^|{L2}|Facility({L3}). Je pense que nous pourrions nous en sortir sans définir la « référence de ligne complète » pour cette classe, mais cela ne fait pas de mal. Si vous disposez d'un « code suivant » qui modifie la valeur logique d'un indice avant de parcourir le global, vous devrez définir la « référence de ligne complète ». Par exemple, comme je l'ai dit ci-dessus, la classe RowIdSpec aurait pu être créée en utilisant « Next Code ». Si vous aviez emprunté cette voie, la « référence de ligne complète » aurait été ^Mapping({L1},{L2}/100).

 

Subscript Access Type Global:

Exemple de classe : Mapping.TwoGlobals.xml

Cette classe affiche des données provenant de deux globales différentes :  ^Member et ^Provider. Dans le dernier exemple, nous avons commencé dans une globale, puis sommes passés à une autre globale pour arriver à une ligne. Dans ce cas, nous avons deux globales qui contiennent toutes deux des lignes. Nous allons parcourir toutes les lignes de la première globale, puis parcourir les lignes de l'autre globale.

               Subscript Expression Type Global:  Lorsque vous avez défini le premier niveau d'indice comme « Global », la propriété globale de la carte doit être définie sur « * ». Je parie que nous aurions pu utiliser ce style de mappage pour faire Mapping.TwoNamespacesOneGlobal. N'oubliez pas que vous êtes un artiste lorsque vous créez ces mappages !

Dans {L1} le type d'accès est ‘Global’ et le ‘Next Code’ renverra “Member”, “Provider” and “”.  En définissant le type d'accès comme « Global », le compilateur sait utiliser {L1} comme nom global, donc {L2} et {L3} ne sont que de simples indices. {L4} est également un indice mais il contient du code supplémentaire pour gérer le fait que les deux globales stockent les propriétés à des emplacements différents.

Cette classe montre une autre chose intéressante dans la section Données du mappage. Si nous avions uniquement mappé le ^Member global, j'aurais défini seulement trois niveaux d'indice et la section Données aurait eu des valeurs de nœud de 4, 5, 6, 7, 8 et 9. Pour gérer le code postal étant dans le nœud 9 ou dans nœud 16, nous ajoutons le nœud de base à l'IdKey 4 ou 10 et utilisons +6 dans le nœud pour obtenir le décalage par rapport au code postal.

 

Access Variables: 

Exemple de classe : Mapping.SpecialAccessVariable.xml

               Special Access Variables peut être défini à n’importe quel niveau d’indice. Il peut y en avoir plus d'un par niveau. Dans cet exemple, nous en avons un défini appelé {3D1}. Le 3 signifie qu'elle est définie au niveau d'indice 3 et le 1 signifie qu'il s'agit de la première variable définie à ce niveau. Le compilateur générera un nom de variable unique pour cela et gérera sa définition et sa suppression. La variable est définie après avoir exécuté le « next code». Dans cet exemple, je souhaite utiliser la variable dans le "next code" du niveau 4, je l'ai donc définie au niveau 3. Dans cet exemple, j'utilise {3D1} pour "se souvenir" de l'endroit où nous étions dans la boucle afin de pouvoir modifier une valeur de date invalide à « * » mais revient toujours au même endroit dans la boucle.

 

Bitmaps: 

Exemple de classe : Mapping.BitMapExample.xml

Bien que les index Bitmap soient assez nouveaux, cela ne signifie pas que vous ne voudriez pas les ajouter à votre application qui utilise Cache SQL Storage. Vous pouvez ajouter un index Bitmap à n'importe quelle classe ayant un simple %Integer IdKey positif​.

Vous définissez le « Type » comme « bitmap » et vous n’incluez pas l’IdKey en indice. La seule chose dont vous devez vous rappeler lorsque vous définissez un bitmap est que vous avez également besoin d'un extent Bitmap. Encore une fois, rien de spécial, l'extent est un index des valeurs IdKey, donc aucun indice n'est nécessaire et le « Type » est « bitmapextent ».

La classe dispose de méthodes que vous pouvez appeler pour conserver les index bitmap lorsque vous modifiez les données via Sets et Kills. Si vous pouvez utiliser SQL ou des objets pour apporter des modifications, les index seront automatiquement conservés.

 

Certains de ces exemples sont donc un peu complexes ! Jetez un œil aux cours et voyez si vous pouvez en tirer une conclusion. Si ce n'est pas le cas, faites-le-moi savoir :  Brendan@interSystems.com,  je serai toujours heureux d'aider un artiste en difficulté. smiley

 

Obtenez les exemples Ici.

 

Si vous souhaitez revenir en arrière et consulter les autres articles sur la cartographie, voici les liens :

 

The Art of Mapping Globals to Classes (1 of 3)

The Art of Mapping Globals to Classes (2 of 3)

The Art of Mapping Globals to Classes (3 of 3)

The Art of Mapping Globals to Classes (4 of 3)

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer