Accéder à une base de données MariaDB en langage C
Documentation : MariaDB Connector/C API Functions
Prenons pour sujet d'étude la base meubleFournisseur qui a été créée dans
l'article Requêtes SQL. Le serveur MariaDB a été installé et un utilisateur créé dans
l'article : Installer et utiliser un serveur MariaDB.
Installer le connecteur C - MariaDB
adminX@serveurWebX:~$ su - root Mot de passe : root@debian:~# apt install libmariadbd-dev
Effectuer des requêtes sur la base
Insertion
Programme source
/**
* @file insertEnCMysql.c
* @brief
* compilation: gcc -o insertEnCMysql insertEnCMysql.c `mariadb_config --cflags --libs`
* exécution : ./insertEnCMysql -u <user> -p <password>
* Ce programme insère des données dans la table fournisseur de la base de données meubleFournisseur.
* Il utilise les fonctions de la bibliothèque MySQL C API pour se connecter à la base de données,
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <mysql.h>
#define HOTE "localhost"
#define NOM_BASE "meubleFournisseur"
/* Fonction pour afficher l'usage du programme */
void usage(const char *prog_name) {
fprintf(stderr, "Usage: %s -u <user> -p <password> \n", prog_name);
exit(1);
}
int main(int argc, char *argv[]) {
MYSQL *pMysql;
MYSQL_STMT *stmt;
MYSQL_BIND param[2];
const char *sql = "INSERT INTO fournisseur (fou_nom, fou_ville) VALUES (?, ?)";
char *user = NULL, *password = NULL;
int opt;
// Analyser les arguments avec getopt
while ((opt = getopt(argc, argv, "u:p:")) != -1) {
switch (opt) {
case 'u':
user = optarg; // Utilisateur de la base de données
break;
case 'p':
password = optarg; // Mot de passe
break;
default:
usage(argv[0]); // Afficher l'usage si un argument invalide est passé
}
}
// Vérifier que tous les arguments nécessaires sont fournis
if (user == NULL || password == NULL ) {
usage(argv[0]);
}
/* Initialiser la structure MySQL */
if ((pMysql = mysql_init(NULL)) == NULL) {
fprintf(stderr, "mysql_init() échoué : %s\n", mysql_error(pMysql));
return -1;
}
/* Se connecter à la base de données */
if (mysql_real_connect(pMysql, HOTE, user, password, NOM_BASE, 0, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() échoué : %s\n", mysql_error(pMysql));
mysql_close(pMysql);
return -1;
}
/* Préparer la requête SQL */
stmt = mysql_stmt_init(pMysql);
if (mysql_stmt_prepare(stmt, sql, strlen(sql)) != 0) {
fprintf(stderr, "mysql_stmt_prepare() échoué : %s\n", mysql_error(pMysql));
mysql_close(pMysql);
return -1;
}
/* Lier les paramètres */
memset(param, 0, sizeof(param));
param[0].buffer_type = MYSQL_TYPE_STRING;
param[0].buffer = "B Meubles";
param[0].buffer_length = strlen(param[0].buffer);
param[1].buffer_type = MYSQL_TYPE_STRING;
param[1].buffer = "Brétigny";
param[1].buffer_length = strlen(param[1].buffer);
if (mysql_stmt_bind_param(stmt, param) != 0) {
fprintf(stderr, "mysql_stmt_bind_param() échoué : %s\n", mysql_error(pMysql));
mysql_stmt_close(stmt);
mysql_close(pMysql);
return -1;
}
/* Exécuter la requête */
if (mysql_stmt_execute(stmt) != 0) {
fprintf(stderr, "mysql_stmt_execute() échoué : %s\n", mysql_error(pMysql));
mysql_stmt_close(stmt);
mysql_close(pMysql);
return -1;
}
/* Fermer la requête préparée et la connexion à la base */
mysql_stmt_close(stmt);
mysql_close(pMysql);
printf("Insertion réussie dans la base de données.\n");
return 0;
}
Compilation
Pour pouvoir compiler, il est nécessaire d'utiliser les fichiers
d'en-tête .h et la librairie lib*.so de la bibliothèque MySQL.
La commande mariadb_config --cflags --libs fournit les informations nécessaires à la compilation.
Remarque : il peut être nécessaire de remplacer mariadb_config par mysql_config
adminX@serveurWebX:~$ gcc -o insertEnCMysql insertEnCMysql.c `mariadb_config --cflags --libs`
Exécution
adminX@serveurWebX:~$ ./insertEnCMysql Usage: ./insertEnCMysql -u-p adminX@serveurWebX:~$ ./insertEnCMysql -u adminBasemeuble1 Usage: ./insertEnCMysql -u -p adminX@serveurWebX:~$ ./insertEnCMysql -u adminBaseMeuble1 -p bonjour Insertion réussie dans la base de données.
Vérification
adminX@serveurWebX:~$ mysql -u adminBaseMeuble1 -p meubleFournisseur Enter password: mysql> SELECT * from fournisseur; +--------+-----------+-----------+ | fou_id | fou_nom | fou_ville | +--------+-----------+-----------+ | 1 | A Meubles | Arpajon | | 2 | E Meubles | Etampes | | 3 | D Meubles | Dourdan | | 7 | B Meubles | Brétigny | +--------+-----------+-----------+
Affichage sans contraintes : affichage de tous les fournisseurs
Dans ce cas, il n'est pas nécessaire d'utiliser les requêtes préparées
Programme source
/**
* @file selectEnCMysql.c
* Compilation: gcc -o selectEnCMysql selectEnCMysql.c `mariadb_config --cflags --libs`
* Exécution : ./selectEnCMysql -u <user> -p <password>
* Ce programme affiche les données de la table fournisseur de la base de données meubleFournisseur
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <mysql.h>
#define HOTE "localhost"
#define NOM_BASE "meubleFournisseur"
/* Fonction pour afficher l'usage du programme */
void usage(const char *prog_name) {
fprintf(stderr, "Usage: %s -u <user> -p <password>\n", prog_name);
exit(1);
}
int main(int argc, char *argv[]) {
MYSQL *pMysql;
MYSQL_STMT *stmt;
MYSQL_BIND param[2];
char *user = NULL, *password = NULL;
int opt;
// Analyser les arguments avec getopt
while ((opt = getopt(argc, argv, "u:p:")) != -1) {
switch (opt) {
case 'u':
user = optarg;
break;
case 'p':
password = optarg;
break;
default:
usage(argv[0]);
}
}
if (user == NULL || password == NULL ) {
usage(argv[0]);
}
/* Initialiser la structure MySQL */
if ((pMysql = mysql_init(NULL)) == NULL) {
fprintf(stderr, "mysql_init() échoué : %s\n", mysql_error(pMysql));
return -1;
}
/* Se connecter à la base de données */
if (mysql_real_connect(pMysql, HOTE, user, password, NOM_BASE, 0, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() échoué : %s\n", mysql_error(pMysql));
mysql_close(pMysql);
return -1;
}
printf("Contenu de la table fournisseur :\n");
/* Afficher le contenu de la table fournisseur */
if (mysql_query(pMysql, "SELECT fou_nom, fou_ville FROM fournisseur") != 0) {
fprintf(stderr, "Erreur SELECT : %s\n", mysql_error(pMysql));
mysql_close(pMysql);
return -1;
}
MYSQL_RES *result = mysql_store_result(pMysql);
if (result == NULL) {
fprintf(stderr, "Erreur mysql_store_result : %s\n", mysql_error(pMysql));
mysql_close(pMysql);
return -1;
}
int num_fields = mysql_num_fields(result);
MYSQL_ROW row;
MYSQL_FIELD *fields = mysql_fetch_fields(result);
// Afficher les noms de colonnes
for (int i = 0; i < num_fields; i++) {
printf("%s\t", fields[i].name);
}
printf("\n");
// Afficher les lignes
while ((row = mysql_fetch_row(result))) {
for (int i = 0; i < num_fields; i++) {
printf("%s\t", row[i] ? row[i] : "NULL");
}
printf("\n");
}
mysql_free_result(result);
mysql_close(pMysql);
return 0;
}
Compilation
adminX@serveurWebX:~$ gcc -o selectEnCMysql selectEnCMysql.c `mariadb_config --cflags --libs`
Remarque : il peut être nécessaire de remplacer mariadb_config par mysql_config
Exécution
adminX@serveurWebX:~$ ./selectEnCMysql -u adminBaseMeuble1 -p bonjour Contenu de la table fournisseur : fou_nom fou_ville A Meubles Arpajon E Meubles Etampes D Meubles Dourdan B Meubles Brétigny
Affichage avec contraintes : affichage des fournisseurs de la ville de Brétigny
Dans ce cas, il est ipmératif d'utiliser les requêtes préparées
Programme source
/**
* @file selectEnCMysql.c
* Compilation: gcc -o selectEnCMysql selectEnCMysql.c `mariadb_config --cflags --libs`
* Exécution : ./selectEnCMysql -u <user> -p <password>
* Ce programme affiche les fournisseurs de la ville de Brétigny
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <mysql.h>
#define HOTE "localhost"
#define NOM_BASE "meubleFournisseur"
void usage(const char *prog_name) {
fprintf(stderr, "Usage: %s -u <user> -p <password>\n", prog_name);
exit(1);
}
int main(int argc, char *argv[]) {
MYSQL *pMysql;
MYSQL_STMT *stmt;
char *user = NULL, *password = NULL;
int opt;
while ((opt = getopt(argc, argv, "u:p:")) != -1) {
switch (opt) {
case 'u':
user = optarg;
break;
case 'p':
password = optarg;
break;
default:
usage(argv[0]);
}
}
if (user == NULL || password == NULL ) {
usage(argv[0]);
}
if ((pMysql = mysql_init(NULL)) == NULL) {
fprintf(stderr, "mysql_init() échoué : %s\n", mysql_error(pMysql));
return -1;
}
if (mysql_real_connect(pMysql, HOTE, user, password, NOM_BASE, 0, NULL, 0) == NULL) {
fprintf(stderr, "mysql_real_connect() échoué : %s\n", mysql_error(pMysql));
mysql_close(pMysql);
return -1;
}
// Préparer la requête avec un paramètre
const char *sql = "SELECT fou_nom, fou_ville FROM fournisseur WHERE fou_ville = ?";
stmt = mysql_stmt_init(pMysql);
if (!stmt) {
fprintf(stderr, "mysql_stmt_init() échoué\n");
mysql_close(pMysql);
return -1;
}
if (mysql_stmt_prepare(stmt, sql, strlen(sql)) != 0) {
fprintf(stderr, "mysql_stmt_prepare() échoué : %s\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
mysql_close(pMysql);
return -1;
}
// Lier le paramètre (ville)
MYSQL_BIND bind_param[1];
memset(bind_param, 0, sizeof(bind_param));
char ville[] = "Brétigny";
bind_param[0].buffer_type = MYSQL_TYPE_STRING;
bind_param[0].buffer = ville;
bind_param[0].buffer_length = strlen(ville);
if (mysql_stmt_bind_param(stmt, bind_param) != 0) {
fprintf(stderr, "mysql_stmt_bind_param() échoué : %s\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
mysql_close(pMysql);
return -1;
}
// Préparer les buffers de sortie
MYSQL_BIND result_bind[2];
memset(result_bind, 0, sizeof(result_bind));
char fou_nom[100];
unsigned long fou_nom_length;
my_bool fou_nom_is_null;
char fou_ville[100];
unsigned long fou_ville_length;
my_bool fou_ville_is_null;
result_bind[0].buffer_type = MYSQL_TYPE_STRING;
result_bind[0].buffer = fou_nom;
result_bind[0].buffer_length = sizeof(fou_nom);
result_bind[0].length = &fou_nom_length;
result_bind[0].is_null = &fou_nom_is_null;
result_bind[1].buffer_type = MYSQL_TYPE_STRING;
result_bind[1].buffer = fou_ville;
result_bind[1].buffer_length = sizeof(fou_ville);
result_bind[1].length = &fou_ville_length;
result_bind[1].is_null = &fou_ville_is_null;
if (mysql_stmt_bind_result(stmt, result_bind) != 0) {
fprintf(stderr, "mysql_stmt_bind_result() échoué : %s\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
mysql_close(pMysql);
return -1;
}
// Exécuter la requête
if (mysql_stmt_execute(stmt) != 0) {
fprintf(stderr, "mysql_stmt_execute() échoué : %s\n", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
mysql_close(pMysql);
return -1;
}
// Afficher les résultats
printf("fou_nom\t\tfou_ville\n");
printf("-----------------------------\n");
while (mysql_stmt_fetch(stmt) == 0) {
printf("%s\t\t%s\n",
fou_nom_is_null ? "NULL" : fou_nom,
fou_ville_is_null ? "NULL" : fou_ville
);
}
mysql_stmt_close(stmt);
mysql_close(pMysql);
return 0;
}
Compilation
adminX@serveurWebX:~$ gcc -o selectEnCMysql selectEnCMysql.c `mariadb_config --cflags --libs`
Remarque : il peut être nécessaire de remplacer mariadb_config par mysql_config
Exécution
adminX@serveurWebX:~$ ./selectEnCMysql -u adminBaseMeuble1 -p bonjour fou_nom fou_ville ----------------------------- B Meubles Brétigny