Developpez.com - 4D
X

Choisissez d'abord la catégorieensuite la rubrique :


Les triggers pour échanger des données

Date de publication : Mai 2003

Par David ADAMS
 

En client-serveur, les triggers s’exécutent sur la machine du serveur et non sur la machine du client. Et le code qui a initié l’action et celui du trigger étant sur des machines différentes, ils ne partagent donc pas les mêmes variables. Cette Note Technique explique comment, à l’aide d’une table utilitaire, partager en toute sécurité des données entre un trigger et le code qui l'a invoqué.

I. Résumé
II. Partager des données entre 4D Client et 4D Serveur
III. Un enregistrement pour échanger des données
IV. Suggestions d’implémentation
V. Utilisations courantes
VI. Méthodes utilisées
TriggerMessage_Load
TriggerMessage_Update
TriggerMessage_GetMessage
TriggerMessage_Unload
VII. Base exemple


I. Résumé

En client-serveur, les triggers s'exécutent sur la machine du serveur et non sur la machine du client. Toute action invoquant un trigger – comme par exemple sauvegarder un enregistrement – exécute le code du trigger sur le serveur. Et puisque le code qui a initié l'action et celui du trigger sont sur des machines différentes, alors ces codes ne partagent pas les mêmes variables. Ce code testé à présent en 4D monoposte se comporte de manière différente car le code du trigger s'exécute dans le même process que celui qui a invoqué le trigger. Cette Note Technique explique comment, à l'aide d'une table utilitaire, partager en toute sécurité des données entre un trigger et le code qui l'a invoqué. La technique est efficace en interprété et en compilé, en mono et en client/serveur. Une base exemple est fournie pour vos tests.


Rappel : les chaînes d'appel et les triggers

Cette Note technique étudie le comportement des triggers à travers à une base de données d'une bibliothèque. Le système de prêt de cette bibliothèque est fondé sur un module "utilisateurs et groupes" optimisé pour palier à la fonction Utilisateur courant qui ne peut être utilisée. Lors de la procédure de connexion de notre module optimisé, l'ID de l'actuel lecteur est stocké dans une variable interprocess. Le diagramme ci-dessous schématise le code du prêt :

Pictures 0418x0127


Voici le code de chaque méthode afin de montrer la séquence d'exécution :

Pictures 0408x0145


Cette chaîne d'appel est identique en mono et en client/serveur. Cependant quand la méthode LendItem (Prêt d'article) est exécutée depuis 4D client, la fonction GetCurrentUser (Récuperation de l'utilisateur courant) génère une erreur pour cause de variable indéfinie ou retourne 0 pour toutes les ID des lecteurs de la bibliothèque. Ce comportement est simple à comprendre : la variable <>Lecteur_ID est initialisée et renseignée sur le client alors que le trigger et la fonction GetCurrentUser sont exécutés sur le serveur. 4D ne partage pas automatiquement les données entre les machines. Voici à nouveau le diagramme avec indication de l'environnement d'exécution de chaque méthode.

Pictures 0434x0169


II. Partager des données entre 4D Client et 4D Serveur

Le langage de 4D met à disposition trois commandes pour l'échange entre process et entre machines : LIRE VARIABLE PROCESS, ECRIRE VARIABLE PROCESS et enfin VARIABLE PROCESS.

Dès que le développeur rencontre une question comme évoqué ci-avant, il la traitera à l'aide d'une de ces commandes.

Dans la pratique, les utiliser pour apporter une réponse à un problème de trigger est inutilement compliqué :

- Des sémaphores doivent être utilisés pour contrôler les accès aux variables des différentes machines. Une simple erreur peut ruiner votre implémentation.

- Sur un serveur les variables process ont une portée différente en compilé ou en interprété. Dans une base interprétée chaque trigger est exécuté avec son jeu de variables process. En compilé, tous les triggers partagent le même jeu de variables. Les échanges entre variables devront prendre en compte cette particularité.

- Les triggers sont prévus pour réaliser des opérations de base sur les données quel que soit le type du client. Les triggers s'exécutent sans savoir qui les a invoqués : un process 4D Client, un process web, une procédure stockée ou une connexion de 4D Open. Beaucoup de ces clients n'ont aucune connaissance de vos variables 4D.


III. Un enregistrement pour échanger des données

Si un process d'une machine client et les triggers d'une machine serveur ne partagent pas les variables process, en revanche ils peuvent se partager des enregistrements. Par exemple, le code du trigger de la table « Item » n'est pas limité aux enregistrements de la table « Item » mais accède à toutes les tables de la base de données. Le process client et le code du trigger sur le serveur partagent la même sélection courante pour chaque table et devraient pointer vers le même enregistrement courant. Le trigger et le process client ne devraient pas avoir la même « copie » d'un enregistrement en particulier mais ce comportement est facilement gérable.

Pour aller plus loin sur les triggers de 4D, les triggers en cascade, les enregistrements et les sélections, vous pouvez lire « Joy of trigger » à l'adresse :
en http://www.4dcompanion.com/downloads/papers/.

La base TriggerMessage utilise une table à deux champs pour échanger les données : les données sont passées via [TriggerMessage]Message_field. Quand un client a besoin de fournir des informations à un trigger, le client charge un enregistrement de la table [TriggerMessage], met à jour le champ Message_field puis sauvegarde l'enregistrement. Cette valeur est dès à présent disponible aux triggers de n'importe quelle table. Dans l'exemple de notre bibliothèque, la variable <>Lecteur_ID devrait renseigner le champ Message_ field sous forme de chaine. La fonction GetCurrentUser peut être réécrite pour fonctionner convenablement.

   $0 : = Num ([TriggerMessage] Message_field)

Plutôt que de lire directement du champ [TriggerMessage] Message_field je recommanderai d'utiliser une sous-méthode :

   $0 : = Num (TriggerMessage_GetMessage)

Utiliser une sous-méthode comme TriggerMessage_GetMessage minimise la ré-écriture de code si vous changez la structure de la table [TriggerMessage] et simplifie l'ajout de nouvelles fonctionnalités comme par exemple la conversion automatique du type d'une donnée.


IV. Suggestions d’implémentation

La table utilisée dans l'exemple TriggerMessage et décrite ci-dessus est suffisante pour la plupart des applications mais n'est pas idéale pour des systèmes plus complexes. Voici des modifications et améliorations à apporter :

- Plusieurs champs pour des messages différents ;

- Plusieurs types de champs afin d'éviter trop de conversions inutiles ;

- Blobber les valeurs dans un champ ad hoc pour pouvoir envoyer des messages quels que soient leurs complexités et leurs types ;

- Placer les valeurs dans un objet ObjectTools puis stocker dans un blob et ainsi faciliter le travail avec des données de types particuliers.


V. Utilisations courantes

Plusieurs utilisations pourront être faites de la technique décrite :

- Envoi de pseudo-paramètres depuis le client ;

- Envoi de valeurs d'état à partir du client ;

- Envoi de données structurées depuis le client ;

- Retourner des informations supplémentaires d'un trigger comme une description détaillée d'erreur.

Même si cette Note technique se focalise sur l'usage d'un 4D Client comme logiciel client, d'autres types de client sont aussi possibles. Tout code ou client, par exemple le client 4D open, capable de lire et d'écrire des enregistrements 4D peut utiliser cette technique.


VI. Méthodes utilisées

Voici les différentes méthodes que vous trouverez dans la base exemple :


TriggerMessage_Load

      ` TriggerMessage_Load : ()
      ` Cette méthode charge ou crée un enregistrement dans [TriggerMessage]
      ` Utilisé par le code client et le trigger pour échanger des données


   C_ENTIER LONG($records_count)
   C_BOOLEEN($locked_b)

      ` Trouver un enregistrement existant
   CHERCHER([TriggerMessage];[TriggerMessage]RecordInUse=Faux)
   $records_count:=Enregistrements trouves([TriggerMessage])
   $locked_b:=Enregistrement verrouille([TriggerMessage])

   Si ($records_count=0) | ($locked_b)
         ` Créer un nouvel enregistrement plutôt que de rééutiliser un ancien
      CREER ENREGISTREMENT([TriggerMessage])
      [TriggerMessage]RecordInUse:=Vrai
      STOCKER ENREGISTREMENT([TriggerMessage])
   Fin de si  ` ($records_count=0) | ($locked_b)

      ` Fin de la routine


TriggerMessage_Update

      ` TriggerMessage_Update : ()

      ` La méthode met à jour l'enregistrement courant


   C_ALPHA(255;$1)
   CHARGER ENREGISTREMENT([TriggerMessage])
   [TriggerMessage]Message_:=$1+Caractere(Retour chariot )+[TriggerMessage]Message_
   STOCKER ENREGISTREMENT([TriggerMessage])

      ` Fin de la routine.


TriggerMessage_GetMessage

      ` TriggerMessage_GetMessage

      ` Retourne des valeurs de l'enregistrement courant


   C_TEXTE($0)
   $0:=[TriggerMessage]Message_

      ` Fin de la routine


TriggerMessage_Unload

      ` TriggerMessage_Unload : ()

      `La méthode marque un enregistrement comme disponible et le libère


   [TriggerMessage]Message_:=""
   [TriggerMessage]RecordInUse:=Faux
   STOCKER ENREGISTREMENT([TriggerMessage])
   LIBERER ENREGISTREMENT([TriggerMessage])

      ` Fin de la routine.


VII. Base exemple

Téléchargez la base exemple :

Base pour Windows

Base pour Mac OS

__________________________________________________
Copyright © 1985-2009 4D SA - Tous droits réservés
Tous les efforts ont été faits pour que le contenu de cette note technique présente le maximum de fiabilité possible.
Néanmoins, les différents éléments composant cette note technique, et le cas échéant, le code, sont fournis sans garantie d'aucune sorte. L'auteur et 4D S.A. déclinent donc toute responsabilité quant à l'utilisation qui pourrait être faite de ces éléments, tant à l'égard de leurs utilisateurs que des tiers.
Les informations contenues dans ce document peuvent faire l'objet de modifications sans préavis et ne sauraient en aucune manière engager 4D SA. La fourniture du logiciel décrit dans ce document est régie par un octroi de licence dont les termes sont précisés par ailleurs dans la licence électronique figurant sur le support du Logiciel et de la Documentation afférente. Le logiciel et sa documentation ne peuvent être utilisés, copiés ou reproduits sur quelque support que ce soit et de quelque manière que ce soit, que conformément aux termes de cette licence.
Aucune partie de ce document ne peut être reproduite ou recopiée de quelque manière que ce soit, électronique ou mécanique, y compris par photocopie, enregistrement, archivage ou tout autre procédé de stockage, de traitement et de récupération d'informations, pour d'autres buts que l'usage personnel de l'acheteur, et ce exclusivement aux conditions contractuelles, sans la permission explicite de 4D SA.
4D, 4D Calc, 4D Draw, 4D Write, 4D Insider, 4ème Dimension ®, 4D Server, 4D Compiler ainsi que les logos 4e Dimension, sont des marques enregistrées de 4D SA.
Windows,Windows NT,Win 32s et Microsoft sont des marques enregistrées de Microsoft Corporation.
Apple, Macintosh, Power Macintosh, LaserWriter, ImageWriter, QuickTime sont des marques enregistrées ou des noms commerciaux de Apple Computer,Inc.
Mac2Win Software Copyright © 1990-2002 est un produit de Altura Software,Inc.
4D Write contient des éléments de "MacLink Plus file translation", un produit de DataViz, Inc,55 Corporate drive,Trumbull,CT,USA.
XTND Copyright 1992-2002 © 4D SA. Tous droits réservés.
XTND Technology Copyright 1989-2002 © Claris Corporation.. Tous droits réservés ACROBAT © Copyright 1987-2002, Secret Commercial Adobe Systems Inc.Tous droits réservés. ACROBAT est une marque enregistrée d'Adobe Systems Inc.
Tous les autres noms de produits ou appellations sont des marques déposées ou des noms commerciaux appartenant à leurs propriétaires respectifs.
__________________________________________________
 



Valid XHTML 1.1!Valid CSS!

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique 4D