Académique Documents
Professionnel Documents
Culture Documents
Bonjour tous. Nous allons voir, dans ce tutoriel, quels sont les outils et les manipulations ncessaires pour obtenir une application wxWidgets qui puisse communiquer avec un serveur MySql sous Windows. Pour la compilation, nous utiliserons Code::Blocks et MinGW.
1) Prparation et tlchargements
Avant toute chose, vous devez possder une installation de Code::Blocks et wxWidgets fonctionnelle, c'est--dire que vous devez tre en mesure de pouvoir compiler une application wxWidgets sous Code::Blocks. Nous allons dans un premier temps procder deux petits tlchargements : Il vous faut dabord les libs permettant la communication directe avec le serveur MySql. Le moyen le plus simple de les obtenir est de trouver le DevPak adquat. Vous aurez ainsi les libs utilisables directement avec MinGW. Rendez-vous sur le site http://devpaks.org/ dans la rubrique database , vous trouverez deux DevPaks nomms libmysql (un destin la version 4 de MySql, lautre la version 5). Cliquez sur celui qui vous intresse, en fonction de la version du serveur MySql avec lequel vous voulez communiquer. Vous devez normalement arriver sur une page donnant les dtails du DevPak correspondant et contenant un lien pour le tlcharger. Enregistrez le fichier obtenu dans un coin de votre disque dur, nous nous en occuperons un peu plus loin. Pendant que nous sommes dans les tlchargements, nous allons rcuprer un petit Add-On des libs wxWidgets nomm DatabaseLayer, permettant de faire linterface entre votre programme et les libs MySql, le tout en utilisant les classes wxWidgets. Pour cela, rendez-vous sur le site http://wxcode.sourceforge.net qui est un site regroupant un grand nombre de mini-projets relatifs wxWidgets. Dans la partie de gauche, vous trouverez un lien Component search qui vous permettra de rechercher le composant databaselayer . Tlchargez le fichier zip contenant les sources de la dernire version, ainsi que celui contenant la documentation, et enregistrez-le au mme endroit que le fichier prcdent. Maintenant, nous allons crer larborescence destine recevoir les fichiers libs et le projet pour compiler le composant databaselayer . Pour ce tutoriel, je vais choisir de placer les libs dans le dossier C:\LibMySql\ . Je vous laisse bien entendu adapter votre configuration, sachant quil y a malgr tout une rgle respecter : il faut savoir que les chemins contenant des espaces ont tendance poser problme lors de la compilation et ldition des liens. Je vous recommande donc dutiliser un chemin nen contenant pas. Donc, dans le dossier C:\LibMySql\ , nous allons crer 6 rpertoires : - le rpertoire bin qui va recevoir les fichiers dll , et dont il faudra ajouter le chemin la variable systme PATH . - le rpertoire include qui va recevoir tous les headers dont lapplication finale aura besoin pour tre compile. - le rpertoire lib qui va contenir les fichiers libs pour MinGW (fichiers portant les extensions .a et .def ). - le rpertoire tmp dans lequel nous allons dcompresser les fichiers tlchargs. - Le rpertoire dblayer qui nous servira compiler le projet DatabaseLayer . - Le rpertoire doc qui contiendra la documentation du composant DatabaseLayer , ainsi que celle prsente dans le DevPak mysql. Lorsque ces rpertoires sont crs, placez les deux fichiers tlchargs prcdemment dans le rpertoire temporaire : C:\LibMySql\tmp\
Les fichiers DevPak sont en fait des archives tarball compresses avec la mthode bzip2 . Il vous suffit donc de renommer votre fichier libmysql-5.0.5-1sid.DevPak (ou libmysql4.1.13a-1sid.DevPak si vous avez opt pour la version MySql 4) en libmysql-5.0.51sid.tar.bz2 (ou libmysql-4.1.13a-1sid.tar.bz2). Vous pouvez dsormais ouvrir ce fichier avec WinRar ou 7Zip (avec 7Zip, lorsque vous louvrez, vous avez accs au fichier .tar sur lequel il faut double-cliquer pour accder son contenu).
Une fois ouvert avec votre gestionnaire darchives favori, double-cliquez sur le rpertoire bin prsent dans larchive, afin daccder son contenu. Il doit normalement contenir un fichier libmysql.dll . Faites glisser ce fichier dans le rpertoire C:\LibMySql\bin\ . Double-cliquez ensuite sur les deux points dans larchive, afin de revenir en arrire (comme sur la capture ci-dessus) et procdez de la mme manire pour faire glisser le contenu des dossiers docs , include et lib respectivement dans les dossiers C:\LibMySql\doc\ , C:\LibMySql\include\ et C:\LibMySql\lib\ . Vous pouvez maintenant fermer le gestionnaire darchives, nous avons termin linstallation du DevPak.
ajouter les fichiers sources notre projet. Ouvrez le fichier databaselayer_src_1.8.zip que nous avons plac dans C:\LibMySql\tmp\ . Entrez dans le dossier databaselayer au sein de cette archive (double-clic), slectionnez les dossiers src et include et faites-les glisser dans le dossier de notre projet. Vous pouvez maintenant fermer votre gestionnaire darchives. Nous allons faire le mnage dans les fichiers que nous venons dextraire. Rendez-vous dans le dossier C:\LibMySql\dblayer\src\ qui a t cr par les manipulations prcdentes et supprimez tous les fichiers relatifs aux types de bases de donnes qui ne nous intressent pas : - Firebird*.cpp : 8 fichiers - Odbc*.cpp : 6 fichiers - Oracle*.cpp : 5 fichiers - OTL*.cpp : 4 fichiers - Progres*.cpp : 8 fichiers - Sqlite*.cpp : 4 fichiers - Tds*.cpp : 5 fichiers Placez-vous ensuite dans le dossier C:\LibMySql\dblayer\include\ et rptez lopration avec les fichiers en-tte . Il faut supprimer : - Firebird*.h : 8 fichiers - Odbc*.h : 6 fichiers - Oracle*.h : 5 fichiers - Otl*.h : 5 fichiers - Progres*.h : 8 fichiers - Sqlite*.h : 4 fichiers - Tds*.h : 5 fichiers Au final, il ne doit rester plus que 15 fichiers cpp dans le dossier src et 19 fichiers .h dans le dossier include . Nous pouvons maintenant ajouter les fichiers cpp au projet Code::Blocks (menu project , Add files ). Avant de lancer la compilation, il faut encore faire quelques rglages afin que Code::Blocks puisse trouver les fichiers en-ttes et lib de mysql. Il faudra galement lui indiquer que lon veut compiler une bibliothque, et non un excutable. Dans la bote de proprits du projet (menu Project , Properties ), activez longlet Build Targets , et pour chaque configuration dans la liste de gauche (debug, release), modifiez, droite, la valeur de la zone droulante (changez GUI Application en Dynamic library ). Quand cest fait, fermez la boite de dialogue Project / Targets options . Ouvrez ensuite la boite de dialogue des options de compilation (menu Project , Build options ), slectionnez le projet dans la liste de gauche (de cette faon, les rglages que nous allons faire seront appliqus chaque configuration). Pour indiquer Code::Blocks o se trouvent les fichiers en-ttes supplmentaires dont il aura besoin, slectionnez longlet Search directories , et le sous-onglet Compiler . Ajoutez le dossier C:\LibMySql\include\ la liste actuelle (bouton Add ). Ensuite, faites la mme chose pour ajouter le dossier C:\LibMySql\lib\ au linker . Il reste indiquer le fait que notre bibliothque sera lie la lib mysql : dans longlet Linker settings , ajoutez libmysql.a la liste link libraries . Vous pouvez maintenant fermer la boite de dialogue doptions du projet. Voil, il ne reste plus qu slectionner la bonne configuration (debug ou release), et lancer la compilation qui devrait normalement se drouler sans problme. La compilation a d vous crer 3 fichiers dans le dossier C:\LibMySql\dblayer\ : - Un fichier .a et un .def quil faut copier dans le dossier C:\LibMySql\lib\ - Un fichier .dll quil faut copier dans le dossier C:\LibMySql\bin\ Voil, il ne reste plus qu copier le contenu entier du dossier C:\LibMySql\dblayer\include\ dans le dossier C:\LibMySql\include\ afin de regrouper les fichiers en-ttes de cette nouvelle lib avec ceux de mysql, et nous avons termin linstallation des libs. Pendant que nous y sommes, nous allons mettre en place la documentation de DatabaseLayer.
Nous
allons
maintenant
Ouvrez le fichier databaselayer_documentation_1.8.zip , slectionnez le dossier html prsent dans cette archive et faites-le glisser dans le dossier doc de notre arborescence (C:\LibMySql\doc\ ). Pour la consulter, il suffit douvrir le fichier index.html . Nous allons maintenant passer la partie utilisation de ces libs dans une petite application.
Et voil, cest aussi simple que cela. Bien sr, la simplicit du code est en rapport avec celle de laction effectue. Nous verrons plus loin comment effectuer des actions plus complexes sur une base de donnes mysql. Une petite prcision malgr tout : suivant votre installation, il se peut que le serveur mysql ne soit pas joignable sur le port habituel (3306). Dans ce cas, vous pouvez spcifier le numro de port la suite du nom de lhte sur lequel tourne ce serveur. Par exemple, si vous avez install UsbWebServer (http://www.usbwebserver.com), mysql utilise par dfaut le port 3307. Il aurait dans ce cas fallut mettre _T("localhost:3307") lors de la construction de lobjet MysqlDatabaseLayer. Autre petite prcision, qui a son importance : par dfaut, les erreurs lors de requtes, ou lors de connexion au serveur, sont gres avec des exceptions. Comme vous pouvez le constater, le code ci-dessus ne les gre pas, ce qui fait que dans le cas d'un serveur injoignable, vous risquez d'obtenir un joli message d'erreur. Nous allons donc modifier le code afin d'en tenir compte :
#include "MysqlDatabaseLayer.h" // Cration de l'objet MysqlDatabaseLayer MysqlDatabaseLayer *dbLayer=new MysqlDatabaseLayer(); try { // Ouverture de la connexion avec le serveur dbLayer->Open( _T("localhost"), // Hte sur lequel tourne le serveur mysql _T("test_db"), // Nom de la base de donnes _T("user"), // Nom d'utilisateur _T("pwd")); // Mot de passe } catch (DatabaseLayerException& e) { wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str()); wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); delete dbLayer; return; } // Cration de l'objet wxArrayString pour rcuprer les rsultats wxArrayString arrResult; // Rcupration de la liste des tables de la base de donnes try { arrResult=dbLayer->GetTables(); } catch (DatabaseLayerException& e) { wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str()); wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); dbLayer->Close(); delete dbLayer; return; } // Prparation du message afficher wxString sMsg=_T("Liste des tables :"); for (int i=0;i<(int)arrResult.Count();i++) { sMsg << _T("\n") << arrResult[i]; } // Affichage du rsultat avec une wxMessageBox wxMessageBox(sMsg); // Fermeture de la connexion avec le serveur mysql dbLayer->Close(); // Libration de la mmoire occupe par l'objet MysqlDatabaseLayer delete dbLayer;
Voil, nous avons maintenant ce quil nous faut pour travailler. La premire requte que nous allons excuter sur cette base de donnes va nous permettre dajouter un enregistrement. Nous nen attendons aucun rsultat, si ce nest la confirmation que tout sest bien pass. La classe MysqlDatabaseLayer possde deux mthodes permettant dexcuter une requte sur le serveur : - RunQuery(const wxString &strQuery, bool bParseQuery) pour une requte simple, avec pour seule valeur de retour un boolen indiquant si cette excution de requte sest bien passe (ne me demandez pas quoi sert le deuxime paramtre, ce nen sais rien pour linstant). - RunQueryWithResults(const wString &strQuery) pour une requte dont on attend une srie de rsultats en retour. Vous lavez sans doute devin : pour insrer un enregistrement dans la table, nous allons utiliser la premire mthode. Voici donc le code correspondant (je ne rentrerais pas plus dans les dtails, car cette opration ne le ncessite pas) :
Code wxWidgets :
#include "MysqlDatabaseLayer.h" // Cration de l'objet MysqlDatabaseLayer MysqlDatabaseLayer *dbLayer=new MysqlDatabaseLayer(); try { // Ouverture de la connexion avec le serveur dlLayer->Open(_T("localhost"), _T("wxdb-test"), // Hte + Nom base de donnes _T("user"), _T("pwd")); // Utilisateur + Mot de passe } catch (DatabaseLayerException& e) { wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str()); wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); delete dbLayer; return; } bool bRes; // Variable pour le stockage du rsultat // Ajout d'un enregistrement dans la base de donnes try
{ // Excution de la requte bRes=dbLayer->RunQuery(_T("INSERT INTO `utilisateurs` (`nom`,`prenom`) VALUES ('Dupont','Marie');"), false); } catch (DatabaseLayerException& e) { wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str()); wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); dbLayer->Close(); delete dbLayer; return; } // On informe ventuellement lutilisateur sil y a eut un problme if (bRes==false) wxMessageBox(_T("Erreur lors de lexcution de la requte")) ; // Fermeture de la connexion avec le serveur mysql dbLayer->Close(); // Libration de la mmoire occupe par l'objet MysqlDatabaseLayer delete dbLayer;
Vous pouvez compiler et excuter, il ny a pas de raison pour que a ne marche pas : avec PhpMyAdmin, vous devriez tre en mesure de voir que notre nouvel enregistrement a bel et bien t ajout la table.
Comme cette requte ne fourni quun seul rsultat (et non une liste de rsultats comme cest frquemment le cas lors de lutilisation dune base de donnes), nous allons utiliser la mthode GetSingleResultInt de la classe MysqlDatabaseLayer. Le premier paramtre fournir cette mthode est un wxString contenant la requte excuter. Le deuxime est le numro dindex du champ rcuprer. Dans notre cas, le rsultat ne contiendra quun seul champ. Il faudra donc lui donner la valeur 1 pour rcuprer le 1er champ. Ce qui donne comme code :
Code wxWidgets :
#include "MysqlDatabaseLayer.h" // Cration de l'objet MysqlDatabaseLayer MysqlDatabaseLayer *dbLayer=new MysqlDatabaseLayer(); try { // Ouverture de la connexion avec le serveur dlLayer->Open(_T("localhost"), _T("wxdb-test"), // Hte + Nom base de donnes _T("user"), _T("pwd")); // Utilisateur + Mot de passe } catch (DatabaseLayerException& e) { wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str()); wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); delete dbLayer; return; } int iRes=0; // Variable pour le stockage du rsultat // Lecture du nombre d'utilisateurs enregistrs dans la base de donnes try { // Excution de la requte iRes=dbLayer->GetSingleResultInt(_T("SELECT COUNT(1) FROM utilisateurs;"), 1); } catch (DatabaseLayerException& e)
{ wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str()); wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); dbLayer->Close(); delete dbLayer; return; } // Affichage du rsultat wxString sMsg; sMsg.Printf(_T("Il y a %0d entres dans la table utilisateurs."),iRes); wxMessageBox(sMsg) ; // Fermeture de la connexion avec le serveur mysql dbLayer->Close(); // Libration de la mmoire occupe par l'objet MysqlDatabaseLayer delete dbLayer;
Si vous jetez un coup dil la documentation de la classe MysqlDatabaseLayer (et surtout celle de la classe DatabaseLayer dont elle est drive), vous vous apercevrez quelle contient plusieurs mthodes de ce style, en fonction du type de valeur rcuprer : - GetSingleResultInt () dont nous venons de voir lutilisation. - GetSingleResultString () pour rcuprer une chane de caractres (un wxString). - GetSingleResultLong () pour un entier de type long . - GetSingleResultBool () pour une valeur boolenne. - GetSingleResultDate () pour une valeur de type wxDateTime. - GetSingleResultBlob () pour des donnes binaires. - GetSingleResultDouble () pour une valeur dcimale de type double .
Code MySql
Dans le cas contraire, il pointera vers un lment vide prcdant le premier enregistrement obtenu. Ainsi, il suffira d'appeler la mthode Next() de cette classe pour obtenir le premier lment et les suivants. Quand tous les lments ncessaires auront t rcuprs, il faudra penser appeler la mthode Close() pour fermer la liste des rsultats et librer la mmoire qu'elle occupe. Ce qui donne comme code :
Code wxWidgets :
#include "MysqlDatabaseLayer.h" // Cration de l'objet MysqlDatabaseLayer MysqlDatabaseLayer *dbLayer=new MysqlDatabaseLayer(); try { // Ouverture de la connexion avec le serveur dlLayer->Open(_T("localhost"), _T("wxdb-test"), // Hte + Nom base de donnes _T("user"), _T("pwd")); // Utilisateur + Mot de passe } catch (DatabaseLayerException& e) { wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str());
wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); delete dbLayer; return; } DatabaseResultSet* rSet=NULL;; // Pointeur pour les rsultats // Obtention des utilisateurs enregistrs dans la base de donnes try { // Excution de la requte rSet=dbLayer->RunQueryWithResults(_T("SELECT * FROM utilisateurs;"), 1); } catch (DatabaseLayerException& e) { wxString sErr; sErr.Printf(_T("Erreur %0d\n%s"), e.GetErrorCode(), e.GetErrorMessage().c_str()); wxMessageBox(sErr, _T("Exception wxDatabaseLayer"), wxICON_ERROR); dbLayer->Close(); delete dbLayer; return; } if(rSet==NULL) // Y a-t'il eut des rsultats ? { wxMessageBox(_T("Aucun rsultat trouv !"), _T("Rsultat"), wxICON_INFORMATION); } else { wxString Nom, Prenom, sRes=_T("Liste des enregistrements :"); int id; while(rSet->Next()) // On itre sur tous les rsultats { // Rcupration de l'id (champ n1) id=rSet->GetResultInt(1); // Rcupration du nom (champ n2) Nom=rSet->GetResultString(2); // Rcupration du prnom (champ n3) Prenom=rSet->GetResultString(3); // Ajout de l'enregistrement aux rsultats sRes << wxString::Format(_T("\n %02d : %s %s"), id, Nom.c_str(), Prenom.c_str()); } // On libre la mmoire occupe par les rsultats dbLayer->CloseResultSet(rSet); // Et on les affiche wxMessageBox(sRes); } // Fermeture de la connexion avec le serveur mysql dbLayer->Close(); // Libration de la mmoire occupe par l'objet MysqlDatabaseLayer delete dbLayer;
Voil, vous disposez maintenant du minimum vital pour dvelopper une application communicant avec un serveur MySql. Dans suite de ce tutoriel, nous verrons comment prparer une liste de requtes afin d'en excuter plusieurs en mme temps, ce qui permettra de limiter les accs au serveur, mais il faudra pour linstant vous contenter de ce que vous venez de lire. @+, et bonne prog. Xav