Le service web RecordSql est une fonctionnalité native du runtime, disponible en mode REST uniquement.
Info |
---|
ParamétrageLe paramétrage du SW RecordSql doit être effectué en amont pour lister les RecordSql autorisés |
Sommaire | ||||
---|---|---|---|---|
|
La demande d'action RecordSql au service web REST se fait au format JSON dans le corps du message.
Il permet a un appelant, après avoir passé les informations d'authentification, d'interroger un RecordSql directement afin d'obtenir des données de la base de données, sans entrer dans la gestion de l'ERP et donc sans invoquer de programme Diva car cette API s'en charge directement.
Info |
---|
RappelLes RecordSql sont des objets compilé en Diva (extension .DHOQ) qui contiennent un ensemble de requêtes SQL. Ces requêtes SQL comportent la table, les champs, les jointures, les clauses WHERE, etc... |
L'appelant et le paramétrage du service web détermine dans quel contexte (environnement, utilisateur, implicite) les données vont être lues.
Format de la demande
...
Paramètre
...
Balise
...
Description
...
Nom dictionnaire RecordSql
...
"dhoq"
(obligatoire)
...
Nom du dictionnaire record sql : c’est le fichier .dhoq.
Par exemple GTRSART.dhoq contient plusieurs RecordSql liés aux articles
...
Nom RecordSql
...
"recordsql"
(obligatoire)
...
Nom du record sql unitaire : correspond a la balise <RecordSql du dictionnaire.
Par exemple Article est la requête SQL principal de la base articles
...
Token
...
"access_token"
(obligatoire)
...
Valeur du TOKEN obtenu durant la phase d'authentification
...
Paramètres
...
"parameters"
...
Liste des champs et leurs valeurs (en majuscules et en précisant le nom de table) au format table.champ=valeur séparés par le point-virgule.
Ce champs servent de référence en tant que clé pour exécuter la requête. Par défaut ce champ reste vide car le moteur REST cherche s’il peut remplir tout seul les paramètres variables pour traiter la requête, en se basant sur la table des utilisateurs et les tables communes de l’ERP.
En principe ce champ devrait être toujours vide, à part quelques exceptions, sinon il doit contenir une suite de champs .
Exemple : MZ.DOS=998 ; etc
...
Champs à récupérer
...
"fields"
...
Liste des champs à récupérer, en majuscules et sans préciser la table, séparés par un point virgule.
Par défaut * indique qu’on veut récupérer tous les champs de la table.
Exemple CPOSTAL;VIL
Note : pour les champs provenant d'une jointure soit on utilise l'alias (si existant dans le recordSql), soit on utilise le nom de la table jointée avec le nom du champ séparés par un '_'. Exemple : jointure sur ART, la récupération du champ ART.REF s'obtient avec l''écriture du champ ART_REF
Attention, ce sont les champs renvoyés par le service web, et pas ceux retournés par la requêre SQL. Pour optimiser la requête, il convient d'utiliser les options
...
Condition where
...
"where”
...
Nom de la condition where existante dans le RecordSql
Le programme XRecordSQLCheck.exe vous permet de connaitre le contenu des fichier .dhog avec la liste des recordSQL qu’ il contient et pour chacun la liste des clauses where, des tris et des clauses having ainsi que les paramètres à transmettre.
...
Paramètres where
...
"where_parameters"
...
Liste des paramètres de la condition where selon le RecordSql au format nomDuParametre1=valeur1;nomDuParametre2=valeur2 ou directement les valeurs au format valeur1;valeur2 dans ce cas les conditions sont appliquées dans l’ordre d’apparition
Pour les champs valeur de type ‘chaîne de caractères’, ne pas mettre de cote ou double cote pour les chaines
...
Pagination offset
...
"offset"
...
Mettre une valeur > 0 pour récupérer un nombre important d'enregistrements. Voir plus loin au sujet des lectures en mode pagination pour renvoyer les enregistrements en plusieurs fois, sachant que le serveur est configuré pour une valeur maximale du nombre d'enregistrements
La valeur 0 équivaut a la valeur 1, c'est à dire que seul le premier enregistrement sera retourné.
...
Pagination count
...
"count"
...
Tri
...
"orderby"
...
Nom du tri orderby du RecordSql : nom tel qu'il apparaît par exemple Par_Ref
...
Condition having
...
"having"
...
Nom de la condition having
...
Paramètres having
...
"having_parameters"
...
Paramètres de la condition having
...
Filtres SQL
...
"filter"
...
Filtres avancés concernant les clauses WHERE et la gestion des jointures (voir plus bas)
...
Informations
...
"infos"
...
Informations complémentaires, notamment sur la performances (voir plus bas)
Info |
---|
HeaderUn HEADER est uniquement utilisé pour indiqué le Content-Type : application/json , mais pas de header d'authentification puisqu'elle passe par le champ "access_token" du corps |
Astuce |
---|
EspacementsLes 'espaces' sont interdits dans les noms de balises. Exemple : un appel "dhoq " (donc un espace en trop) provoque une erreur |
L'URL a utilisé pour les demandes d'action RecordSql est sous la forme : base commune de l'URL + '/api/v1/RecordSql/Execute'
Exemple d'URL sur un poste local:
http://localhost:8080/DhsDivaltoServiceDivaApiRest/api/v1/RecordSql/Execute
Exemple d'URL en Divalto cloud:
URL : http://api.divaltocloud.com/123456/testing1/api/v1/RecordSql/Execute
Informations complémentaires : gestion des dossiers et utilisateur
L'authentification permet d'identifier, via les utilisateurs Harmony, un utilisateur Divalto. Cet utilisateur doit bénéficier dans le paramétrage Divalto d'un dossier par défaut
...
C'est ce dossier qui est appliqué par défaut lors d'une appel API RecordSql.
Pour modifier le dossier, il faut indiquer le nom du dossier dans la zone 'parameters' sous la forme suivant
"parameters" : "MZ.DOS=MONDOSSIER"
Informations complémentaires : gestion des jointures
Le champ 'filter' peut contenir les commandes suivantes:
...
<joinactivate>
...
Nom de la jointure
ou
$ALL
...
<joindeactivate>
...
<columnactivate>
...
Nom de la colonne
ou
$ALL
...
<columndeactivate>
Utilisation de ces options:
Le fonctionnement de ces options est strictement le même que pour l'écriture en langage Diva (voir l'aide en ligne pour plus de détails)
Permet donc d'activer ou desactiver des jointures ou des colonnes, afin d'optimiser la lecture, ou de lire des champs de jointures optionnelles
L'utilité de ces options dépend de la manière dont le RecordSql a été écrit. Un RecordSql qui n'a pas de jointure activée par défaut sera optimisé sans cette option
Les noms de jointure ou $all sont toujours convertis en majuscules avant leur utilisation.
On peut combiner les options. Elle seront exécutées dans l'ordre d'apparition
Exemples 'infos':
filter= "<joindeactivate>$all" ;permet de lire uniquement la table du FROM sans aucune jointure, donc de manière beaucoup rapide
filter= "<joindeactivate>$all<joinactivate>majointure" ;permet de désactiver toutes les jointures, puis de ne réactiver que la jointure 'majointure'
Informations complémentaires : filtres SQL
Le champ "filter" permet l'utilisation de filtres SQL avancés pour la gestion des clauses WHERE
...
Balise
...
Utilisation
...
"operator_where"
...
La valeur ‘OR’ permet d’appliquer un OU logique (Défaut : ET)
...
"where"
...
Définition des clauses WHERE
...
"whereaddcondition”
...
Définition des conditions entre les clauses WHERE.
name : nom de la condition, par exemple “maCondition1”
condition : valeur de la condition, par exemple “where1 et (where2 ou where3)”
...
"createwhere"
...
Création de nouvelles conditions WHERE
...
"whereremovecondition"
...
Suppression de conditions WHERE spécifiques
...
"joindeactivate"
...
Désactivation des jointures vers les tables en dépendance
Les mécanismes appliqués sont ceux des RecordSql Diva.
Remarque |
---|
L’utilisation de la balise “filter” pour décrire les conditions est incompatible avec les balises “where” et “whereparamaters” du niveau supérieur (réservé pour le cas simple d’une seule condition where) |
Conditions where simple
Pour positionner une condition where simple il n’est pas utile de passer par la balise “filter”
Bloc de code | ||
---|---|---|
| ||
"where":"Equal_Vil",
"where_parameters":"ENTZHEIM",
// Utilisation des basises WHERE et WHERE_PARAMETERS pour un cas de clause unique |
Conditions where multiple en combinaison simple ET
Pour positionner de multiples conditions where avec un ET logique, il s’agit d’indiquer les noms des clauses WHERE et leurs paramètres, mais le record SQL faisant par défaut un ET logique, il n’est pas utile de donner plus d’information
Bloc de code | ||
---|---|---|
| ||
"filter": {
"where": [
{"name":"LIKE_VIL", "parameters":"EN%" },
{"name":"LIKE_CPOSTAL", "parameters":"67%" }
]
}
// Première clause WHERE 'Equal_vil' et la valeur demandée 'ALBI'
// Seconde clause WHERE 'Like_CPostal' et la valeur demandée '67%' pour obtenir les 67****
// Par défaut, un ET logique est appliqué |
Conditions where multiple en combinaison simple OU
Pour positionner de multiples conditions where avec un OU logique, il s’agit d’indiquer les noms des clauses WHERE et leurs paramètres, et d’indiquer le type d’opérateur OU
Bloc de code | ||
---|---|---|
| ||
"filter": {
"where": [
{"name":"EQUAL_VIL", "parameters":"ALBI" },
{"name":"EQUAL_VIL", "parameters":"TOULOUSE" }
],
"operator_where":"OR"
}
// Première clause WHERE 'Equal_vil' et la valeur demandée 'ALBI'
// Seconde clause WHERE 'Equal_vil' et la valeur demandée 'TOULOUSE'
// Deux clauses WHERE avec un OU logique |
Conditions where multiple en combinaison complexe
Pour positionner de multiples conditions where en combinaisons complexe avec parenthésage, ET logique, OU logique, il s’agit d’indiquer les noms des clauses WHERE et leurs paramètres, et d’indiquer la condition complète
Bloc de code | ||
---|---|---|
| ||
"filter": {
"where": [
{"name":"EQUAL_VIL", "parameters":"ENTZHEIM" },
{"name":"LIKE_VIL", "parameters":"%OBER%" },
{"name":"LIKE_CPOSTAL", "parameters":"67%" }
],
"whereaddcondition":
{ "name":"cond1", "condition":"(Like_Cpostal and Equal_Vil) or Like_Vil" }
}
// Première clause WHERE 'Equal_vil' et la valeur demandée 'ENTZHEIM'
// Seconde clause WHERE 'Like_vil' et la valeur demandée '%OBER%' pour obtenir les *OBER*
// Troisième clause WHERE 'Like_CPostal' et la valeur demandée '67%' pour obtenir les 67****
// Définition de la condition complexe : (Like_Cpostal and Equal_Vil) or Like_Vil |
Conditions where spécifique en combinaison complexe
Pour positionner de multiples conditions where spécifiques (non prévue dans le recordSql) en combinaisons complexe avec parenthésage, ET logique, OU logique, il s’agit d’indiquer les noms des clauses WHERE et leurs paramètres, et d’indiquer la condition complète
Bloc de code | ||
---|---|---|
| ||
"filter": {
"whereremovecondition" : // Toujours demander a effacer les conditions que l'on veut créer
{ "name":"", "parameters": "CONDVILLE1;CONDVILLE2;CONDVILLE3" },
"createwhere": // Création temporaire de conditions spécifiques (inexistant dans le recordSql)
[
{ "name":"CONDVILLE1", "condition": "T057.VIL='STRASBOURG'" }, // Première clause WHERE avec le nom attribué, et sa valeur construite directement à partir du nom de champ
{ "name":"CONDVILLE2", "condition": "T057.VIL='TOULOUSE'" }, // Seconde clause WHERE avec le nom attribué, et sa valeur construite directement à partir du nom de champ
{ "name":"CONDVILLE3", "condition" : "T057.VIL='ALBI'"} // Troisième clause WHERE avec le nom attribué, et sa valeur construite directement à partir du nom de champ
],
"whereaddcondition": // Définition de la condition complexe en utilisant les conditions créés
{ "name" : "CONDTEST", "condition": "CONDVILLE2 OR CONDVILLE3" } // CONDVILLE1 n'est pas utilisé, d'où sa suppression préalable
} |
Informations complémentaires : performances
Le champ 'infos' peut contenir les commandes suivantes:
...
<perf>
...
1
La balise xperf à 1 indique que le demandeur souhaite obtenir des informations générales et de performances sur l'exécution de la demande.
Si la balise est donnée lors de l’authentification, toutes les demandes utilisant le token correspondant se feront avec réponse de performances.
Sinon le demandeur peut demander les performances demande par demande.
La réponse est obtenue dans la balise "infos" de la réponse. Voir plus bas pour le format de la réponse.
...
...
...
...
...
...
...
...
...
Exemple de programmation
Bloc de code |
---|
int woffset = 0
int mycount = 10
int fini = 0
while ( fini = 0 )
{
;requete rest rsql avec {offset=woffset count= mycount }
;traiter le resultat, dont en retour le nbrecord
if ( nbrecord < mycount )
fini = 1 ;plus de suite
else
woffset = woffset + mycount ;on lit la suite
} |
Astuce |
---|
Le mécanisme de pagination se repose strictement sur la pagination SQL Server. Chaque appel déclenche donc une requête différente, sans cache ni curseur, avec les éventuelles modification de données effectuées entre chaque appel. Consultez l'aide Microsoft SQL Server pour plus d'informations |
Format de la réponse
Le service web RecordSql REST répond a une demande de lecture de données sous une forme JSON avec les résultats suivants:
...
Balise
...
Description
...
"error"
...
Contient le CODE ERREUR
0 signifie qu'il n'y a pas d'erreur
tout autre valeur indique une erreur
...
"txterr"
...
Texte de l'erreur, si applicable
...
"tablename"
...
Nom de la table FROM lue
...
"nbrecord"
...
Nombre d'enregistrements retournés
...
"records"
...
Tableau avec les enregistrements retournés
...
"infos"
...
Informations générales ou performance
Le champs 'infos', dans le cas d'une demande d'information de performance, peut contenir plusieurs informations indiquant des temps d'exécution.
Exemples : "{\"xperf\" : {\"ExecuteRequestSQL\" : \"0\",\"LoadUser\" : \"1\",\"LoadDHXISAM\" : \"15\",\"LoadRecordForSQL\" : \"1\",\"LoadDataForSQL\" : \"1\",\"ImpersonationSQL\" : \"1\",\"ExecuteSQL\" : \"1\",\"ResultSQL\" : \"3\" }}"
Info |
---|
Information technique
|
Dans les exemples suivants, xxxxxx pour 'access_token' est a remplacer par la valeur du token obtenue lors de l'authentification.
Comment trouver le recordSql a utiliser
Infinity se repose sur les recordSql pour l'accès aux données de la base de données.
Quelques définitions d'un recordSql:
porte un nom (en clair, en français), par exemple Article
fait partie d'un ensemble (codifié) : le dictionnaire de recordSql, par exemple gtrsart.dhoq
xxRSyyyy.DHOQ : xx correspond au module (par exemple GT pour la gestion commerciale) et yyyy a une famille (par exemple art pour la famille articles)
assemble tous les composants d'une requête SQL
la table principale (celle du FROM)
les champs (du FROM, champs calculés et champs des jointures)
les conditions (WHERE, HAVING, COUNT)
les tris
Avertissement |
---|
Pour trouver le nom du dictionnaire, du recordsql, des clauses where, etc...il faut nécessairement trouver le fichier source correspondant xxRSyyyy.DHSP , et l'ouvrir avec Harmony SDK ou a défaut un bloc-notes |
La moyen le plus simple de trouver une table courante est d'utiliser le zoom correspondant.
Avec le menu Aide / A propos, la fenêtre indique des informations
Exemple : zoom article
On y trouve le nom du recordSql et on peut y trouver une indication sur le module.
Exemple : recordSql Article module GT
=>notre recordSql se trouve dans GTRSART.DHSP et s'appelle Article
...
et on y trouvera plus bas les jointures, clauses where et tris.
Une fois identifié, l'utilitaire Harmony XRecordSQLCheck.exe (a lancer depuis /divalto/sys) permet de manipuler le recordSql et de le tester avant de l'utiliser dans un service web
...
Le bas de l'écran contient la requête SQL générée, qui peut être copiée dans un éditeur de requêtes SQL, par exemple Sql Management Studio
Exemples
Lecture en échec
Exemple de demande de lecture de la table de codes postaux, alors que le paramétrage des RecordSql n'est pas fait :
{
"dhoq" : "xxrstab.dhoq",
"recordsql" : "",
"access_token" : "xxxxxx",
"parameters" : " ",
"fields" : "*",
"where" : " ",
"where_parameters" : " ",
"offset" : 0,
"count" : 0,
"orderby" : " ",
"havingc" : " ",
"having_parameters" : " ",
"infos" : " "
}
Réponse :
...
Lecture simple
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
Réponse :
...
...
Lecture avec pagination
Exemple de demande de lecture de la table des modes de règlement avec pagination par 10 : Première lecture
{
"dhoq" : "gtrstab.dhoq",
"recordsql" : "MODEREGLEMENT",
"access_token" : "xxxxxx",
"parameters" : " ",
"fields" : "*",
"where" : " ",
"where_parameters" : " ",
"offset" : 0,
"count" : 10,
"orderby" : " ",
"having" : " ",
"having_parameters" : " ",
"infos" : " "
}
Réponse :
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
La réponse indique un NBRECORD qui vaut le COUNT demandé, donc il faut une seconde lecture:
{
"dhoq" : "gtrstab.dhoq",
"recordsql" : "MODEREGLEMENT",
"access_token" : "xxxxxx",
"parameters" : "",
"fields" : "DOS;REGL;LIB",
"where" : " ",
"where_parameters" : " ",
"offset" : 10,
"count" : 10,
"orderby" : " ",
"havingc" : " ",
"having_parameters" : " ",
"infos" : " "
}
Réponse :
...
...
...
...
...
...
...
La réponse indique un NBRECORD différent de COUNT, donc c'est terminé
Lecture avec champs, clause where join et orderby
Exemple de demande de lecture de la table des articles pour une plage de code ean, trié par ean, en récupérant 3 champs, sans jointures et sans autres colonnes
{
"dhoq" : "gtrsart.dhoq",
"recordsql" : "ARTICLE",
"access_token" : "xxxxxx",
"parameters" : "",
"fields" : "DOS;REF;EAN",
"where" : "Between_Ean",
"where_parameters" : "eanD=3000000000000;eanF=4000000000000",
"offset" : 0,
"count" : 5,
"orderby" : "Par_CodeEAN",
"having" : " ",
"having_parameters" : " ",
"infos" : "<joindeactivate>$ALL<columndeactivate>$ALL"
}
Réponse :
...
...
...
...
...
...