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
Function
III. 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éussi
mysql_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
Sub
mysql_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
Sub
La 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
Sub
La 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.