I. Préparation▲
Vous devez tout d'abord recopier le fichier libmySQL.dll dans le répertoire windows. Ensuite il vous faut les déclarations des fonctions de l'API MySQL. Vous pouvez télécharger ma traduction des fichiers entêtes ici. Une fois le fichier .zip téléchargé, il vous suffit d'ajouter à votre projet les 3 modules contenus dans l'archive.
II. Manipulation des pointeurs en Visual Basic▲
Les fonctions de l'API Windows sont assez faciles à utiliser avec Visual Basic, car elles ne renvoient pas de pointeurs.
Mais la grande majorité des fonctions de l'API MySQL renvoient un pointeur, sur une structure ou sur une chaîne de caractères. VB ne permet pas de déclarer un pointeur sur une variable. Donc si nous avons besoin des champs de la structure renvoyée, ou de la chaîne de caractères, nous devons recopier la zone mémoire qui est pointée, dans une variable. Afin d'y parvenir, nous pouvons utiliser ces deux fonctions de l'API windows :
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Any, _
ByVal lpString2 As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, _
Source As Any, ByVal Length As Long)lstrcpy (lpString1, lpString2) recopie la chaîne qui est à l'adresse lpString2 dans la chaîne lpString1.
CopyMemory() recopie une zone mémoire dans une autre. Les paramètres sont :
- l'adresse de la zone mémoire de destination ;
- l'adresse de la zone mémoire à recopier ;
- le nombre d'octets à recopier.
Voyons comment récupérer une chaîne de caractères qui se trouve à une adresse donnée, à l'aide de lstrcpy() :
Private Function CopieChaine(ByVal adresse As Long) As String
Dim ret As String
If adresse > 0 Then
ret = Space(256)
lstrcpy ret, adresse
ret = Trim(ret)
If ret <> "" Then CopieChaine = left(ret, Len(ret) - 1)
End If
End FunctionIII. Initialiser la connexion à MySQL▲
Avant tout chose il est nécessaire d'initialiser l'accès à la DLL.
Dim pMySQL As Long
pMySQL = mysql_init(0)Au retour, pMySQL contient l'adresse de la structure permettant l'interfaçage avec mySQL, ou 0 en cas d'erreur. Il est tout à fait possible d'avoir plusieurs connexions dans le même programme.
IV. Fermer la connexion▲
Dim pMySQL As Long
mysql_close (pMySQL)mysql_close() ferme la connexion à la base de données et libère les ressources allouées lors de la création de la connexion.
V. Se connecter à la base de données▲
Dim pMySQL As Long
If mysql_real_connect(pMySQL, "127.0.0.1", "", "", "test", 0, "", 0) = 0 Then
' ...
' la connexion a échoué
' ...
Else
' la connexion a réussimysql_real_connect() ouvre la connexion à la base de données. Les paramètres sont :
- le handle de connexion ;
- l'adresse du serveur où mySQL est installé ;
- le nom de user ;
- le mot de passe ;
- le nom de la base de données ;
- le n° de port (0 indique que l'on utilise le port par défaut) ;
- le nom du pipe ou le socket qui sera utilisé (habituellement 0) ;
- des statuts permettant de configurer la connexion (habituellement 0).
Une valeur de retour nulle indique qu'une erreur s'est produite. Une valeur autre indique que la connexion est ouverte.
VI. Lister les tables dans la base de données▲
Private Sub EnumTables(pMySQL As Long)
Dim pMyROW As Long, myROW As Long, pMyRES As Long, i As Long
pMyRES = mysql_list_tables(pMySQL, "")
If (pMyRES <> 0) Then
For i = 0 To mysql_num_rows(pMyRES) - 1
pMyROW = mysql_fetch_row(pMyRES)
CopyMemory myROW, ByVal pMyROW, 4
ListBox1.AddItem CopieChaine(myROW)
Next
mysql_free_result (pMyRES)
End If
End Submysql_list_tables() permet de lire le nom de toutes les tables de la base de données. Ses paramètres sont :
- le handle de connexion ;
- un masque permettant de filtrer les noms des tables à lire.
La valeur de retour est un handle vers le résultat de la requête, qui est un pointeur vers une structure MYSQL_RES. Si la requête échoue, la valeur de retour est nulle.
mysql_num_rows() renvoie le nombre d'enregistrements contenus dans le résultat.
mysql_fetch_row() permet d'accéder aux champs de l'enregistrement courant, et passe automatiquement à l'enregistrement suivant. En langage C, elle renvoie un tableau de chaînes de caractères, dont chaque élément contient la valeur d'un champ. Jetons un coup d'œil sur la déclaration de cette fonction en langage C :
typedef char **MYSQL_ROW;
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);En C, un tableau de chaînes de caractères est un pointeur vers un pointeur sur une chaîne de caractères. Le tableau est en fait une chaîne unique, contenant les différentes chaînes juxtaposées, chaque chaîne se terminant par un caractère nul.
En VB, nous récupérons avec CopyMemory() le pointeur sur la chaîne de caractères, et enfin la chaîne de caractères elle-même avec la fonction CopieChaine(), que nous avons écrite précédemment. Ici chaque enregistrement ne contient qu'un seul champ.
Une fois que l'on n'a plus besoin du résultat de la requête, il ne faut pas oublier de libérer les ressources en appelant la fonction mysql_free_result().
VII. Accéder aux données de la table▲
Private Sub LitEnregistrements(pMySQL As Long)
Dim pMyROW As Long, myROW As Long, pLengths As Long, pMyRES As Long
Dim i As Long, j As Long, nbFields As Long, lengths() As Long, texte As String
If (mysql_query(pMySQL, "select * from tTest") = 0) Then
pMyRES = mysql_store_result(pMySQL)
If (pMyRES <> 0) Then
nbFields = mysql_num_fields(pMyRES)
If nbFields > 0 Then
ReDim lengths(0 To nbFields - 1)
For i = 0 To mysql_num_rows(pMyRES) - 1
pMyROW = mysql_fetch_row(pMyRES)
CopyMemory myROW, ByVal pMyROW, 4
pLengths = mysql_fetch_lengths(pMyRES)
CopyMemory lengths(0), ByVal pLengths, 4 * nbFields
For j = 0 To nbFields - 1
texte = Space(lengths(j))
lstrcpy texte, myROW
myROW = myROW + lengths(j) + 1
ListBox1.AddItem texte
Next
Next
End If
End If
mysql_free_result (pMyRES)
End If
End SubLa fonction mysql_query() exécute une requête, et renvoie 0 si la requête a abouti.
Pour accéder au résultat de la requête, il est nécessaire d'appeler la fonction mysql_store_result(). Celle-ci renvoie un handle vers le résultat de la requête, qui est un pointeur vers une structure MYSQL_RES, ou 0 en cas d'erreur.
Nous pouvons ensuite lire les données. Vous voyez que la boucle qui est chargée de parcourir les enregistrements est ici plus complexe. Ceci vient du fait que nous avons plusieurs champs. mysql_fetch_row() nous renvoie la valeur des champs, juxtaposés dans une chaîne de caractères unique. Nous ne pouvons pas lire toute la chaîne de caractères en une seule fois. Car avec lstrcpy(), nous récupèrerons que le premier élément. Et avec CopyMemory(), nous devons connaître le nombre d'octets à lire.
La solution à notre problème est la fonction mysql_fetch_lengths(), qui renvoie un tableau contenant la longueur des différents champs.
Nous pouvons alors lire la valeur de chaque champ, un par un, en nous déplaçant dans la chaîne de caractères unique, et en copiant le nombre d'octets nécessaires à chaque fois. Le schéma ci-dessous montre un exemple de ce que l'on peut obtenir.
VIII. Lire la structure d'une table▲
Private Sub LitStructure(pMySQL As Long)
Dim pMyROW As Long, pMyRES As Long, pMyFields As Long, myFields() As MYSQL_FIELD
Dim aStr As String, CountFields As Integer, i As Integer
If (mysql_query(pMySQL, "select * from pet") = 0) Then
pMyRES = mysql_store_result(pMySQL)
If (pMyRES <> 0) Then
CountFields = mysql_num_fields(pMyRES)
If (CountFields > 0) Then
pMyFields = mysql_fetch_fields(pMyRES)
ReDim myFields(0 To CountFields - 1)
CopyMemory myFields(0), ByVal pMyFields, Len(myFields(0)) * CountFields
For i = 0 To CountFields - 1
aStr = "Le champ " & CopieChaine(myFields(i).name) & " est du type " & _
myFields(i).type
ListBox1.AddItem (aStr)
Next
End If
mysql_free_result (pMyRES)
End If
End If
End SubLa fonction mysql_fetch_fields() renvoie un tableau de structures MYSQL_FIELD, dont chaque élément représente un champ de la table.
Les attributs de la structure MYSQL_FIELD sont les informations relatives à un champ.
IX. Gestion des erreurs▲
IX-A. Obtenir le code d'erreur▲
Dim myErrorCode As Long
myErrorCode = mysql_errno(pMySQL)mysql_errno() renvoie le n° de l'erreur survenue lors du dernier appel à l'API, pour la connexion donnée. Une valeur nulle indique qu'il n'y a pas eu d'erreur.
IX-B. Obtenir un message décrivant l'erreur▲
Dim pMyErrorMsg As Long, myErrorMsg As String
pMyErrorMsg = mysql_error(pMySQL)
myErrorMsg = CopieChaine(pMyErrorMsg)mysql_error() renvoie un message décrivant l'erreur survenue lors du dernier appel à l'API, pour la connexion donnée. Un message vide indique qu'il n'y a pas eu d'erreur.



