Vous êtes sur le site Web historique de la documentation de 4D. Les documentations sont progressivement déplacées vers developer.4d.com |
||||||||||
|
4D v20 R7
Services basés sur les procédures stockées (exemple)
|
Description | |
1 | la requête a été reçue mais pas encore traitée. |
0 | la requête a été traitée avec succès. |
< 0 | la 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.
La communication entre un process client et une procédure stockée peut être établié par l'intermédiaire des commandes GET PROCESS VARIABLE, SET PROCESS VARIABLE et VARIABLE TO 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 :
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
CREATE RECORD([SP Requests])
[SP Requests]reqID:=Sequence number([SP Requests])
[SP Requests]reqType:=$1
[SP Requests]reqStatus:=1
If(Count parameters>=2)
[SP Requests]reqParams:=$2
End if
SAVE RECORD([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 Sequence number. 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.
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_LONGINT($0;$1;$vlDelay)
$0:=1
$vlDelay:=0
If(Count parameters>=3)
$vlDelay:=$3
End if
READ ONLY([SP Requests])
Repeat
QUERY([SP Requests];[SP Requests]reqID=$1)
If(Records in selection([SP Requests])>0)
If([SP Requests]reqStatus # 1)
$2->:=[SP Requests]reqData
READ WRITE([SP Requests])
While(Locked([SP Requests]))
WAITING LOOP($vlDelay)
LOAD RECORD([SP Requests])
End while
DELETE RECORD([SP Requests])
$0:=[SP Requests]reqStatus
End if
Else
` 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
End if
` La requête n'a pas encore été traitée
If($0=1)
WAITING LOOP($vlDelay)
End if
Until($0 # 1)
READ ONLY([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_LONGINT($1)
$vlStartTicks:=Tickcount
Repeat
IDLE
Until((Tickcount-$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 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:=False
` La procédure stockée n'a pas besoin d'accès en écriture aux tables...
READ ONLY(*)
` ...sauf pour la table [SP Requests]
READ WRITE([SP Requests])
Repeat
` Recherche des requêtes non encore traitées
QUERY([SP Requests];[SP Requests]reqStatus=1)
` Traitement de ces requêtes les unes après les autres
For($vlRecord;1;Records in selection([SP Requests]))
` Si l'enregistrement de la requête est verrouillé, attendre son déverrouillage
While(Locked([SP Requests]))
` Attendre une seconde avant d'essayer encore
DELAY PROCESS(Current process;60)
` Essayer de charger l'enregistrement
LOAD RECORD([SP Requests])
End while
` Supposons que la requête sera traitée avec succès
[SP Requests]reqStatus:=0
Case of
:([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 !
` ...
Else
` Le type de requête est inconnu, retourner l'erreur -1 (valeur arbitraire)
[SP Requests]reqStatus:=-1
End case
` 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)
If([SP Requests]reqStatus=1)
[SP Requests]reqStatus:=-3
End if
` Mettre à jour l'enregistrement de la requête
SAVE RECORD([SP Requests])
` Passer à la requête non traitée suivante
NEXT RECORD([SP Requests])
End for
` Libérer le dernier enregistrement traité
UNLOAD RECORD([SP Requests])
` Attendre une seconde avant de continuer à répondre aux requêtes
DELAY PROCESS(Current process;60)
` Boucle jusqu'à ce qu'on ordonne à la procédure stockée de stopper son exécution
Until(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
TEXT TO BLOB(Application version(*);[SP Requests]reqData;UTF8 C string)
TEXT TO BLOB(Structure file;[SP Requests]reqData;UTF8 C string;*)
TEXT TO BLOB(Data file;[SP Requests]reqData;UTF8 C string;*)
PLATFORM PROPERTIES($vlPlatform;$vlSystem;$vlMachine)
VARIABLE TO BLOB($vlPlatform;[SP Requests]reqData;*)
VARIABLE TO BLOB($vlSystem;[SP Requests]reqData;*)
VARIABLE TO 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
VOLUME LIST($asVName)
$vlSize:=Size of array($asVName)
ARRAY REAL($arVSize;$vlSize)
ARRAY REAL($arVUsedSpace;$vlSize)
ARRAY REAL($arVFreeSpace;$vlSize)
For($vlElem;1;$vlSize)
VOLUME ATTRIBUTES($asVName{$vlElem};$arVSize{$vlElem};$arVUsedSpace{$vlElem};$arVFreeSpace{$vlELem})
End for
VARIABLE TO BLOB($asVName;[SP Requests]reqData)
VARIABLE TO BLOB($arVSize;[SP Requests]reqData;*)
VARIABLE TO BLOB($arVUsedSpace;[SP Requests]reqData;*)
VARIABLE TO BLOB($arVFreeSpace;[SP Requests]reqData;*)
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_LONGINT($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
If($vlErrCode=0)
` Extraction de l'information résultante du BLOB
$vlOffset:=0
vsServerVersion:=BLOB to text(vxData;UTF8 C string;$vlOffset)
vsStructureFile:=BLOB to text(vxData;UTF8 C string;$vlOffset)
vsDataFile:=BLOB to text(vxData;UTF8 C string;$vlOffset)
BLOB TO VARIABLE(vxData;$vlPlatform;$vlOffset)
BLOB TO VARIABLE(vxData;$vlSystem;$vlOffset)
BLOB TO 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
DIALOG([SP Requests];"SERVER INFORMATION")
Else
ALERT("Erreur de requête "+String($vlErrCode))
End if
` Le BLOB est désormais inutile
CLEAR VARIABLE(vxData)
Voici le formulaire [SP Requests];"SERVER INFORMATION" en exécution :
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
If($vlErrCode=0)
` Extraction de l'information résultante du BLOB
$vlOffset:=0
BLOB TO VARIABLE(vxData;asVName;$vlOffset)
BLOB TO VARIABLE(vxData;arVSize;$vlOffset)
BLOB TO VARIABLE(vxData;arVUsedSpace;$vlOffset)
BLOB TO VARIABLE(vxData;arVFreeSpace;$vlOffset)
For($vlElem;1;Size of array(arVSize))
` Conversion d'octets en méga-octets
arVSize{$vlElem}:=arVSize{$vlElem}/1048576
arVUsedSpace{$vlElem}:=arVUsedSpace{$vlElem}/1048576
arVFreeSpace{$vlElem}:=arVFreeSpace{$vlElem}/1048576
End for
` Affichage de l'information résultante
DIALOG([SP Requests];"VOLUME LIST")
Else
ALERT("Erreur de requête "+String($vlErrCode))
End if
` Le BLOB est désormais inutile
CLEAR VARIABLE(vxData)
Voici le formulaire [SP Requests];"VOLUME LIST" en exécution :
Import basé sur les procédures stockées (exemple)
Procédures stockées
Produit : 4D
Thème : 4D Server et le langage 4D
4D Server - Référence ( 4D v20 R7)