Services basés sur les procédures stockées (exemple)

4D - Documentation   Français   English   German   Manuel de référence de 4D Server, Sommaire   Manuel de référence de 4D Server, Index   Retour   Précédent   Suivant

version 6.8 (Modifiée)


Dans l'exemple présenté dans la section Import basé sur les procédures stockées (exemple), une procédure stockée est lancée puis stoppée à chaque fois qu'une opération d'import de données est requise. Dans le présent exemple, une procédure stockée est lancée automatiquement lorsque la base serveur est ouverte et peut être stoppée et redémarrée à volonté par tout 4D connecté à la base. Dès qu'elle est exécutée, la procédure stockée peut répondre de manière asynchrone à de multiples requêtes envoyées par les clients connectés à la base.

Alors que la section Import basé sur les procédures stockées (exemple) vous montre comment optimiser un service 4D Server existant, cet exemple vous montre comment créer des services nouveaux et personnalisés disponibles pour tous les 4D connectés. En outre, cet exemple peut être utilisé comme modèle pour la création de vos propres services.

Démarrage automatique de la procédure stockée


La procédure stockée est lancée automatiquement par la Méthode base Sur démarrage serveur :

        ` Méthode base Sur démarrage serveur
   START SP SERVICES 

Comme la Méthode base Sur démarrage serveur lance la méthode projet SP SERVICES en tant que procédure stockée, cette dernière s'exécute dès que la base est ouverte avec 4D Server, que des client soient connectés à la base ou non. Ci-dessous, la fenêtre d'administration de 4D Server affiche la procédure stockée en cours d'exécution alors qu'aucun client n'est encore connecté.

Démarrer et stopper à volonté la procédure stockée


Voici la méthode projet START SP SERVICES :

      ` Méthode projet START SP SERVICES
   <>vlSPServices:=Executer sur serveur("SP SERVICES";32*1024;"SP SERVICES";*)

Comme la commande Executer sur serveur se comporte comme Nouveau process lorsqu'elle est appelée sur le serveur, la même méthode (START SP SERVICES) peut être utilisée sur le poste serveur ou sur tout poste client pour démarrer à volonté la méthode SP SERVICES en tant que procédure stockée sur le serveur.

La méthode projet STOP SP SERVICES "ordonne" à la méthode projet SP SERVICES de s'arrêter.

      ` Méthode projet STOP SP SERVICES
   ECRIRE VARIABLE PROCESS(<>vlSPServices;vbStopSPServices;Vrai)

La méthode projet SP SERVICES, lorsqu'elle démarre, met la variable process vbStopSPServices à Faux puis s'exécute en boucle jusqu'à ce que cette variable booléenne devienne Vraie. Grâce à la commande ECRIRE VARIABLE PROCESS, tout process utilisateur exécuté sur le serveur ou sur un poste client peut modifier la valeur de la variable vbStopSPServices, et donc stopper la procédure quand il le souhaite.

Communiquer avec la procédure stockée


La procédure stockée doit pouvoir, de manière asynchrone, recevoir des requêtes des clients et y répondre à tout moment et dans n'importe quel ordre. La moyen le plus simple et direct d'assurer cette communication est d'utiliser une table.

La table [SP Requests] contient les champs suivants :

[SP Requests]reqID est rempli à l'aide de la commande Numerotation automatique. Ce champ identifie chaque requête de manière unique.

[SP Requests]reqType décrit le type de la requête.

[SP Requests]reqStatus peut prendre une des valeurs suivantes :

ValeurDescription
1la requête a été reçue mais pas encore traitée.
0la requête a été traitée avec succès.
< 0la requête a été traitée mais une erreur s'est produite.

Note : Ces valeurs ont été choisies arbitrairement pour cet exemple, elles ne sont pas issues de 4D.

[SP Requests]reqData est un BLOB contenant les données de la requête. Il peut contenir les données envoyées par le demandeur ou les données retournées par la procédure stockée au demandeur.

[SP Requests]reqParams contient éventuellement les valeurs de paramètres envoyés par le demandeur à la procédure stockée.

Pourquoi utiliser une table ?

La communication entre un process client et une procédure stockée peut être établié par l'intermédiaire des commandes LIRE VARIABLE PROCESS, ECRIRE VARIABLE PROCESS et VARIABLE VERS VARIABLE. C'est, par exemple, la solution retenue dans la section Import basé sur les procédures stockées (exemple) ainsi que pour la méthode projet STOP SP SERVICES listée plus haut.

Ici, le système doit permettre à la procédure stockée de recevoir et de renvoyer des quantités variables de données. On pourrait utiliser des tableaux (y compris des tableaux Texte et Image), mais il existe deux raisons principales pour préférer l'emploi d'une table :

L'algorithme de gestion des requêtes via des enregistrements est plus simple à créer. Envoyer d'une requête depuis un poste client consiste simplement à ajouter une requête dans la table. Répondre à la requête depuis la procédure stockée consiste simplement à modifier cette requête.

Comme les requêtes sont stockées dans une table, elles le sont sur le disque. Par conséquent, si la taille d'une requête est importante, cela ne constituera pas un problème dans la mesure où elle peut être supprimée de la mémoire (contrairement aux données stockées dans des tableaux).

Envoyer une requête depuis le poste client


La méthode projet Client post request est une méthode générique pour envoyer une requête :

      ` Méthode projet Client post request
      ` Client post request ( Chaîne { ; Texte } ) -> Entier long
      ` Client post request ( Type de requête { ; Parametres } ) -> Numéro de requête
   CREER ENREGISTREMENT([SP Requests])
   [SP Requests]reqID:=Numerotation automatique([SP Requests])
   [SP Requests]reqType:=$1
   [SP Requests]reqStatus:=1
   Si (Nombre de parametres>=2)
      [SP Requests]reqParams:=$2
   Fin de si 
   STOCKER ENREGISTREMENT([SP Requests])
   $0:=[SP Requests]reqID

La méthode retourne le numéro de la requête, dont l'unicité est garantie par l'utilisation de la commande Numerotation automatique. Une fois que cet enregistrement a été ajouté dans la table [SP Requests], le client n'a plus qu'à interroger régulièrement le champ [SP Requets]redStatus jusqu'à ce que la procédure stockée ait terminé le traitement de la requête.

Tester le statut de la requête et récupérer le résultat sur le poste client


La méthode projet Client get result est une méthode générique pour tester le statut de la requête. Comme expliqué précédemment, dès que la valeur du champ [SP Requets]redStatus devient différente de 1, le client sait que la procédure stockée a traité (avec succès ou non) la requête.

      ` Méthode projet Client get result
      ` Client get result ( Entier long ; ->BLOB {;Entier long } ) -> Entier long
      ` Client get result ( Numéro de requête; ->Données {; Durée } ) -> Code d'erreur
   C_ENTIER LONG($0;$1;$vlDelay)
   $0:=1
   $vlDelay:=0
   Si (Nombre de parametres>=3)
      $vlDelay:=$3
   Fin de si 
   LECTURE SEULEMENT([SP Requests])
   Repeter 
      CHERCHER([SP Requests];[SP Requests]reqID=$1)
      Si (Enregistrements trouves([SP Requests])>0)
         Si ([SP Requests]reqStatus # 1)
            $2->:=[SP Requests]reqData
            LECTURE ECRITURE([SP Requests])
            Tant que (Enregistrement verrouille([SP Requests]))
               WAITING LOOP ($vlDelay)
               CHARGER ENREGISTREMENT([SP Requests])
            Fin tant que 
            SUPPRIMER ENREGISTREMENT([SP Requests])
            $0:=[SP Requests]reqStatus
         Fin de si 
      Sinon 
            ` L'enregistrement de la requête a été perdu !
            ` Cela ne devrait pas se produire. Mais fixons tout de même 
            ` le code d'erreur -2  (valeur arbitraire)
         $0:=-2
      Fin de si 
         ` La requête n'a pas encore été traitée  
      Si ($0=1)
         WAITING LOOP ($vlDelay)
      Fin de si 
   Jusque ($0 # 1)
   LECTURE SEULEMENT([SP Requests])

Si la requête a été traitée avec succès par la procédure stockée, la méthode copie le résultat (s'il y en a un) de l'enregistrement vers le BLOB sur lequel un pointeur a été passé en paramètre. La méthode appelante analyse puis exploite les données du BLOB en fonction du type de la requête. Notez que c'est au client de supprimer l'enregistrement de [SP Requests] une fois que la requête est terminée.

La petite méthode projet WAITING LOOP effectue une boucle pendant un certain nombre de ticks :

      ` Méthode projet WAITING LOOP
      ` WAITING LOOP ( Entier long )
      ` WAITING LOOP ( Durée en ticks )
   C_ENTIER LONG($1)
   $vlStartTicks:=Nombre de ticks 
   Repeter 
      APPELER 4D 
   Jusque ((Nombre de ticks-$vlStartTicks)>=$1)

Rappel : ENDORMIR PROCESS n'a pas d'effet sur le process principal. Si vous utilisez la méthode projet WAITING LOOP, le process attendra pendant le temps défini même si la requête émane du process principal d'un poste client.



La procédure stockée et ses sous-routines


La méthode projet SP SERVICES est la méthode exécutée en tant que procédure stockée sur le poste serveur. La structure générale de cette méthode, présentée ci-dessous, est très simple :

   Initialisation d'une variable "stop"
   Repeter
      Recherche des requêtes dont le champ [SP Requests]reqStatus est égal à 1
      Pour chaque requête
         En fonction du type de la requête, appeler une sous-routine
            qui stocke le résultat dans le champ [SP Requests]reqData
         Changer le statut de la requête pour que le client sache ce qui s'est passé
      Fin de boucle
      "Dormir" un peu avant de recommencer
   Jusqu'à ce que la variable "stop" devienne vraie

Voici le code source réel :

      ` Méthode projet SP SERVICES
      ` La procédure stockée démarre
   vbStopSPServices:=Faux
      ` La procédure stockée n'a pas besoin d'accès en écriture aux tables...
   LECTURE SEULEMENT(*)
      ` ...sauf pour la table [SP Requests]
   LECTURE ECRITURE([SP Requests])
   Repeter  
         ` Recherche des requêtes non encore traitées
      CHERCHER([SP Requests];[SP Requests]reqStatus=1)
         ` Traitement de ces requêtes les unes après les autres
      Boucle ($vlRecord;1;Enregistrements trouves([SP Requests]))
            ` Si l'enregistrement de la requête est verrouillé, attendre son déverrouillage    
         Tant que (Enregistrement verrouille([SP Requests]))
               ` Attendre une seconde avant d'essayer encore      
            ENDORMIR PROCESS(Numero du process courant;60)
               ` Essayer de charger l'enregistrement
            CHARGER ENREGISTREMENT([SP Requests])
         Fin tant que 
            ` Supposons que la requête sera traitée avec succès    
         [SP Requests]reqStatus:=0
         Au cas ou 
            : ([SP Requests]reqType="Server Information")
               SP DO SERVER INFORMATION 
            : ([SP Requests]reqType="Volume List")
               SP DO VOLUME LIST 
            : ([SP Requests]reqType="Browse Directory")
               SP DO BROWSE DIRECTORY ([SP Requests]reqParams)
               ` ...
               ` D'AUTRES TYPES DE REQUETES PEUVENT ETRE AJOUTES ICI !
               ` ...
            Sinon 
                  ` Le type de requête est inconnu, retourner l'erreur -1 (valeur arbitraire)        
               [SP Requests]reqStatus:=-1
         Fin de cas 
            ` Forcer le statut de la requête à être différent de 1
            ` (pour le cas où une sous-routine lui a donné la valeur 1)
         Si ([SP Requests]reqStatus=1)
            [SP Requests]reqStatus:=-3
         Fin de si 
            ` Mettre à jour l'enregistrement de la requête    
         STOCKER ENREGISTREMENT([SP Requests])
            ` Passer à la requête non traitée suivante
         ENREGISTREMENT SUIVANT([SP Requests])
      Fin de boucle 
         ` Libérer le dernier enregistrement traité  
      LIBERER ENREGISTREMENT([SP Requests])
         ` Attendre une seconde avant de continuer à répondre aux requêtes
      ENDORMIR PROCESS(Numero du process courant;60)
         ` Boucle jusqu'à ce qu'on ordonne à la procédure stockée de stopper son exécution
   Jusque (vbStopSPServices)

La méthode projet SP SERVICES peut être utilisée comme modèle pour implémenter de nouveaux services dans une base. Dans ce document, nous détaillons les sous-routines SP DO SERVER INFORMATION et SP DO VOLUME LIST. La sous-routine SP DO BROWSE DIRECTORY (qui par ailleurs accepte comme paramètre le paramètre envoyé par le client dans le champ [SP Requests]reqParams) ne sera pas traitée ici.

En fonction du type de la requête, la méthode projet SP SERVICES appelle une sous-routine dont le rôle est de stocker les données résultantes dans le champ [SP Requests]reqData field. La sauvegarde de l'enregistrement et la modification du statut de la requête sont effectuées par la méthode projet SP SERVICES.

Voici la sous-routine SP DO SERVER INFORMATION. Elle stocke des informations relatives au serveur dans le BLOB. Une autre méthode projet extraira les données du BLOB en fonction du poste client.

      ` Méthode projet SP DO SERVER INFORMATION
   TEXTE VERS BLOB(Version application(*);[SP Requests]reqData;UTF8 Chaîne en C)
   TEXTE VERS BLOB(Fichier structure;[SP Requests]reqData;UTF8 Chaîne en C;*)
   TEXTE VERS BLOB(Fichier donnees;[SP Requests]reqData;UTF8 Chaîne en C;*)
   PROPRIETES PLATE FORME($vlPlatform;$vlSystem;$vlMachine)
   VARIABLE VERS BLOB($vlPlatform;[SP Requests]reqData;*)
   VARIABLE VERS BLOB($vlSystem;[SP Requests]reqData;*)
   VARIABLE VERS BLOB($vlMachine;[SP Requests]reqData;*)

Voici la sous-routine SP DO VOLUME LIST. Elle stocke des informations relatives aux volumes dans le BLOB. Une autre méthode projet extraira les données du BLOB en fonction du poste client.

      ` Méthode projet SP DO VOLUME LIST
   LISTE DES VOLUMES($asVName)
   $vlSize:=Taille tableau($asVName)
   TABLEAU REEL($arVSize;$vlSize)
   TABLEAU REEL($arVUsedSpace;$vlSize)
   TABLEAU REEL($arVFreeSpace;$vlSize)
   Boucle ($vlElem;1;$vlSize)
      PROPRIETES DU VOLUME($asVName{$vlElem};$arVSize{$vlElem};$arVUsedSpace{$vlElem};$arVFreeSpace{$vlELem})
   Fin de boucle 
   VARIABLE VERS BLOB($asVName;[SP Requests]reqData)
   VARIABLE VERS BLOB($arVSize;[SP Requests]reqData;*)
   VARIABLE VERS BLOB($arVUsedSpace;[SP Requests]reqData;*)
   VARIABLE VERS BLOB($arVFreeSpace;[SP Requests]reqData;*)

Afficher les informations du serveur sur un poste client


Avec les méthodes projet génériques Client post request et Client get result, la méthode projet M_SERVER_INFORMATION affiche, sur le poste client, les informations sur le serveur retournées par la procédure stockée. Cette méthode pourrait être associée à une commande de menu ou appelée, par exemple, depuis la méthode objet d'un bouton :

      ` M_SERVER_INFORMATION
   C_BLOB(vxData)
   C_ENTIER LONG($vlReqID;$vlErrCode;$vlOffset)
      ` Envoi de la requête
   $vlReqID:=Client post request ("Server Information")
      ` Test du statut de la requête et réception du résultat
   $vlErrCode:=Client get result ($vlReqID;->vxData;60)
      ` Si la requête est terminée avec succès, affichage du résultat
   Si ($vlErrCode=0)
         ` Extraction de l'information résultante du BLOB  
      $vlOffset:=0
      vsServerVersion:=BLOB vers texte(vxData;UTF8 Chaîne en C;$vlOffset)
      vsStructureFile:=BLOB vers texte(vxData;UTF8 Chaîne en C;$vlOffset)
      vsDataFile:=BLOB vers texte(vxData;UTF8 Chaîne en C;$vlOffset)
      BLOB VERS VARIABLE(vxData;$vlPlatform;$vlOffset)
      BLOB VERS VARIABLE(vxData;$vlSystem;$vlOffset)
      BLOB VERS VARIABLE(vxData;$vlMachine;$vlOffset)
         ` Analyse des propriétés de la plate-forme
      vs4DPlatform:="Version de 4D Server inconnue"
      vsSystem:="Version du système inconnue"
      vsMachine:="Ordinateur inconnu"
         `...
         ` Ici est placé le code (non listé) qui analyse $vlSystem et $vlMachine
         ` ( reportez-vous à l'exemple de la commande PROPRIETES PLATE FORME)
         ` ...
         ` Affichage de l'information résultante
      DIALOGUE([SP Requests];"SERVER INFORMATION")
   Sinon 
      ALERTE("Erreur de requête "+Chaine($vlErrCode))
   Fin de si  
      ` Le BLOB est désormais inutile
   EFFACER VARIABLE(vxData)

Voici le formulaire [SP Requests];"SERVER INFORMATION" en exécution :

Afficher la liste des volumes du serveur sur un poste client


Avec les méthodes projet génériques Client post request et Client get result, la méthode projet M_SERVER_VOLUMES affiche, sur le poste client, les informations sur la liste des volumes du serveur retournée par la procédure stockée. Cette méthode pourrait être associée à une commande de menu ou appelée, par exemple, depuis la méthode objet d'un bouton :

      ` M_SERVER_VOLUMES
   C_BLOB(vxData)
      ` Envoi de la requête
   $vlReqID:=Client post request ("Volume List")
      ` Test du statut de la requête et réception du résultat
   $vlErrCode:=Client get result ($vlReqID;->vxData;120)
      ` Si la requête est terminée avec succès, affichage du résultat
   Si ($vlErrCode=0)
         ` Extraction de l'information résultante du BLOB  
      $vlOffset:=0
      BLOB VERS VARIABLE(vxData;asVName;$vlOffset)
      BLOB VERS VARIABLE(vxData;arVSize;$vlOffset)
      BLOB VERS VARIABLE(vxData;arVUsedSpace;$vlOffset)
      BLOB VERS VARIABLE(vxData;arVFreeSpace;$vlOffset)
      Boucle ($vlElem;1;Taille tableau(arVSize))
            ` Conversion d'octets en méga-octets    
         arVSize{$vlElem}:=arVSize{$vlElem}/1048576
         arVUsedSpace{$vlElem}:=arVUsedSpace{$vlElem}/1048576
         arVFreeSpace{$vlElem}:=arVFreeSpace{$vlElem}/1048576
      Fin de boucle 
            ` Affichage de l'information résultante  
      DIALOGUE([SP Requests];"VOLUME LIST")
   Sinon 
      ALERTE("Erreur de requête "+Chaine($vlErrCode))
   Fin de si 
      ` Le BLOB est désormais inutile
   EFFACER VARIABLE(vxData)

Voici le formulaire [SP Requests];"VOLUME LIST" en exécution :

Référence

Commandes du thème BLOB, Executer sur serveur, Import basé sur les procédures stockées (exemple), Procédures stockées.


4D - Documentation   Français   English   German   Manuel de référence de 4D Server, Sommaire   Manuel de référence de 4D Server, Index   Retour   Précédent   Suivant