mercredi 20 février 2019

Chapitre 55 : Accès à une base de donnée mariadb (ou mysql) en assembleur.


Pour cela, il faut d’abord avoir mis en place une base de données de ce type sur le Raspberry. Pour cela je vous renvoie à la nombreuse documentation disponible sur internet. Sur mon système, j’ai mis en place la base de donnée mariaDb à l’aide du package mariadb-server. Ensuite j’ai crée une base testvinc et une table département avec 2 champs, le N° du département et le nom du département. Pour ces premiers tests, je n’ai crée que 2 enregistrements dans la table. J’ai crée aussi un nouvel utilisateur pgmasm avec des droits réduits sur l’accès à la base testvinc. Pour être sûr que tout est ok, il faut mieux déjà vérifier par la commande mysql, que ce nouvel utilisateur peut bien afficher le contenu de la table (et éventuellement la modifier). Cela peut vous éviter des recherches inutiles lors de l’exécution du programme assembleur. Par exemple dans mon cas, le programme n’affichait pas la table et je n’avais pas fait cette vérification. Ce n’est qu’après en vérifiant par mysql, que j’avais créé la table dans la base mysql et pas dans ma base testvinc (Voui, il faut penser à changer de base par use testvinc avant de créer une table !!!).

Pour créer l’exécutable et faire fonctionner ce programme, il faut faire appel à des librairies de mariadb que l’on obtient en installant les packages supplémentaires :  libmariadbd-dev et libmariadbclient-dev. Pour vérifier et connaitre les options à ajouter au linker il suffit de taper la commande mysql_config --cflags –libs .
Sur mon système, celle-ci a retourné les 2 lignes :
-I/usr/include/mysql
-L/usr/lib/arm-linux-gnueabihf  -lmariadbclient -lpthread -lz -lm –ldl
La directive include ne nous concerne pas (concerne le C) et nous ajoutons les autres directives à gcc qui ici nous sert de linker après la compilation du programme assembleur.
La documentation des fonctions mysql peut être trouvée ici (mais en anglais) :
https://dev.mysql.com/doc/refman/8.0/en/c-api.html

Dans le programme assembleur (voir le source ici) nous commençons à initialiser les structures de mariadb par l’appel de la fonction mysql_init et nous testons le code retour.
Puis nous établissons une connexion à la base crée précédemment avec l’identifiant utilisateur crée et son mot de passe par l’appel de la fonction bl mysql_real_connect. Vous remarquerez que cette fonction a besoin de 8 paramètres dont les 4 premiers sont passés par les registres r0 à r3 et les autres par la pile dans l’ordre inverse de celui attendu par la procédure. Rappelez vous pour cela les premiers chapitres de ce blog ou les appels des fonctions X11 !! Et au retour de la procédure il faut penser à réaligner la pile avec l’instruction add sp,#16  (4 paramètres de 4 octets chacun !!). Puis il faut tester le code retour pour vérifier la bonne connexion. En cas d’erreur il faut revérifier votre saisie du nom de la base, du nom utilisateur et du mot de passe et l’ordre des paramètres.

Puis nous lançons une requête qui est contenue en totalité dans une chaîne de caractères et dont nous passons l’adresse à la fonction mysql_query par le registre r1. Le registre r0 contient le pointeur vers les structures mariadb. Comme ce pointeur va être très utilisé nous le conservons dans le registre r10. Remarque : la requête ne doit se terminer par le point virgule comme dans les commandes directes sous Mysql.
Nous récupérons le set des résultats par l’appel de la fonction mysql_store_result mais nous pouvons aussi utiliser mysql_use_result mais qui offre moins de possibilité. Après le test du code retour, nous conversons le pointeur du set de résultat dans r9, et nous utilisons la fonction mysql_fetch_field qui va nous donner l’adresse des données du premier champ. Nous affichons les noms des premières données à savoir le nom du champ (ou son alias) le nom du champ d’origine, le nom de la table (ou son alias) le nom de la table d’origine et le nom de la base utilisée. Nous refaisons un nouvel appel à cette fonction pour avoir les données du 2 ième champ.

Maintenant, nous allons afficher tous les champs de toutes les rangées de la base. D’abord nous récupérons le nombre de champ de chaque rangée par la fonction mysql_num_fields. Puis nous balayons chaque rangée par appel successif de la fonction mysql_fetch_row qui retourne l’adresse de chaque rangée ou zéro quand il n’y a plus de rangée. Avec l’adresse de chaque rangée, nous balayons les pointeurs de chaque champ pour afficher leurs valeurs.
Rien de bien compliqué !! En fin nous libérons les ressources du résultat et nous fermons la base de données utilisée.

Ce premier programme nous permet de voir l’utilisation de ces fonctions de base. Dans le deuxième programme, nous allons effectuer des mises à jour de notre base. Mais tout d’abord, j’ai récupéré la description de la structure des données des champs et je l’ai adapté au langage assembleur. Nous voyons que en plus des noms, nous pouvons récupérer le type de chaque champ et sa longueur. Cela permet d’envisager de nombreuses possibilité d’utilisation.
Ce deuxième programme contient une boucle de saisie du code département, du nom et de leur insertion dans la base. Après la saisie du code, nous vérifions que celui-ci n’est pas déjà connu dans la base. Remarque : comme nous l’avons déjà vu, l’appel au call system de lecture de Linux retourne une chaine de caractère avec un 0x0A final qu’il nous faut transformer en 0X00 final.

Nous concaténons le code saisi au début de la requête sous forme de chaine de caractère. Si le code est Ok, nous demandons la saisie du nom puis nous créons la requête de mise à jour, en concaténant tous les éléments. Nous vérifions la bonne exécution de la mise à jour puis nous bouclons sur une autre saisie jusqu’à la saisie du code 999 qui terminera la saisie.
Nous terminons par l’affichage complet de la base comme vu dans le programme précédant.

Il ne reste plus qu’à regarder toutes les autres fonctions et à les expérimenter !!

Aucun commentaire:

Enregistrer un commentaire