Introduction à la base de données MySQL de Bugzilla

Ces informations sont tirées de mon expérience personnelle. J’ai dû apprendre comment Bugzilla organise la base de données à cause des pinaillages d’utilisateurs demandant de minuscules changements dans le choix des termes plutôt que d’attendre que les gens se rééduquent par eux-même ou comprennent comment utiliser nos procédures. Ça craint mais vous y passerez peut-être aussi, donc apprenez comment fonctionne le schéma pour pouvoir vous débrouiller quand ça arrivera.

Donc, vous en êtes là avec votre installation toute neuve de Bugzilla. Vous avez installé MySQL, Apache tourne bien, Perl DBI et DBD communiquent parfaitement avec la base. Peut-être avez-vous même rentré quelques bogues de test pour vérifier que le courrier électronique fonctionne bien ; les gens semblent être avertis des nouveaux bogues ou modifications et vous pouvez créer ou éditer des bogues comme bon vous semble. Vous avez peut-être rencontré des problèmes lors de la configuration d’une passerelle de connexion destinée à permettre aux gens de soumettre des bogues à votre base de données par courrier électronique, vous avez demandé à des personnes de tester votre installation et reçu des retours enthousiastes de la part de vos bêta-testeurs.

Quelle est la suite au programme ? Esquisser une stratégie de formation de votre équipe de développement et leur demander de se précipiter sur le nouvel outil auquel vous avez consacré des heures de travail.

Votre première session de formation débute très bien ! Votre auditoire captivé semble émerveillé par l’efficacité intrinsèque de cette chose qui s’appelle "Bugzilla". Vous êtes complètement absorbé par la description des caractéristiques pratiques : comment les gens peuvent sauvegarder leurs requêtes favorites dans la base de données, les mettre en tête ou en pied de leur page, personnaliser leur mise en page, générer des rapports, suivre le statut avec une efficacité plus grande que jamais, atteindre le sommet d’un gratte-ciel d’un seul bond, sauver Jane des griffes de la Mort personnifiée !

Mais la Mort personnifiée prend la parole : une petite voix, venue d’un coin sombre de la salle de conférence. La voix sort de l’ombre : "J’ai une remarque au sujet de l’utilisation du mot ’verified’."

La salle, jusque là remplie d’un joyeux babil, plonge dans un silence religieux tandis que la Mort personnifiée (plus connue sous le nom de Vice-Président du Département Génie Logiciel) poursuit. "Vous voyez, cela fait deux ans que nous utilisons le mot ’verified’ pour indiquer le fait qu’un développeur ou un ingénieur qualité a confirmé qu’un bogue était valide. Je ne veux pas perdre deux ans de formation à un nouveau logiciel. Vous devez remplacer le statut ’verified’ d’un bogue par ’approved’ dès que possible. Pour éviter toute confusion, bien sûr."

Oh non ! La peur vous frappe de plein fouet alors que vous balbultiez "oui, oui, je pense que ça ne sera pas un problème," vous examinez les changements avec la Mort personnifiée et continuez à baragouiner, "non, ça ne représente pas une grosse modification. Je veux dire, nous avons le code source, n’est-ce pas ? Vous savez bien, ’Utiliser le code source tu dois, Luke’ et tout ça... aucun problème," pendant tout ce temps vous frémissez intérieurement comme une méduse échouée qui fait des gargouillis, des glougloutis et qui rôtit sur le sable brûlant d’une dune jamaïquaine...

Ainsi commence votre aventure au coeur de Bugzilla. Vous êtes condamné à faire connaissance avec les champs enum() fixes, les colonnes de varchar et les définitions des tinyint. Prêt pour l'aventure !

Les fondamentaux de la base de données de Bugzilla

Si, comme je l'étais, vous êtes totalement ignorant des mécanismes internes de MySQL à ce stade, et si vous n’étiez pas sous les ordres du Vice-Président, vous vous moqueriez de la différence qui existe entre un champ « bigint » et un « tinyint » dans MySQL. Je vous recommande de consulter la documentation MySQL en ligne. Vous trouverez ci-dessous les rudiments nécessaires pour comprendre la base de données de Bugzilla. Consultez la documentation MySQL ci-dessus pour plus d'informations.

  1. Pour vous connecter à votre base de données :

    bash# mysql -u root

    Si cela fonctionnne sans demander de mot de passe, honte sur vous ! Vous auriez dû mettre en place un verrouillage de sécurité comme cela était expliqué dans les instructions d’installation. Vous pouvez trouver plus d'informations concernant le verrouillage de votre base de données dans la FAQ de Bugzilla de ce répertoire (dans la partie "Sécurité"), ou des généralités plus solides sur la sécurité dans la documentation consultable de MySQL.

  2. Vous devez maintenant voir une invite de commande qui ressemble à celle-ci :

    mysql>

    A l’invite, si « bugs » est le nom que vous avez choisi dans le fichier localconfig pour votre base de données Bugzilla, tapez :

    mysql use bugs;

Les tables de la base de données de Bugzilla

Imaginez votre base de données MySQL comme une série de feuilles de calcul d’un tableur, et vous ne serez pas loin de la vérité. Si vous tapez cette commande :

mysql> show tables from bugs;

vous pourrez voir le nom de toutes les « feuilles de calcul » (tables) dans votre base de données.

A partir de la commande tapée ci-dessus, vous devriez obtenir une réponse qui ressemble à celle-ci :

+-------------------+
| Tables in bugs    |
+-------------------+
| attachments       |
| bugs              |
| bugs_activity     |
| cc                |
| components        |
| dependencies      |
| fielddefs         |
| groups            |
| keyworddefs       |
| keywords          |
| logincookies      |
| longdescs         |
| milestones        |
| namedqueries      |
| products          |
| profiles          |
| profiles_activity |
| tokens            |
| versions          |
| votes             |
| watch             |
+-------------------+


  Voici un aperçu de ce que fait chaque table. La plupart des colonnes de chaque table possèdent
un nom descriptif qui permet de comprendre relativement rapidement leur rôle.

attachments : cette table contient tous les fichiers joints aux bogues. Cette table tend à être
la plus grande mais généralement aussi celle qui comporte le moins d’entrées car les fichiers
joints sont (relativement) gros.

bugs : c’est le coeur de votre système. La table bugs contient la plupart des
informations concernant les bogues à l’exception des informations stockées dans les
autres tables.

bugs_activity :  conserve les informations concernant les changements apportés aux bogues 
un fichier d’historique.

cc : Cette petite table conserve simplement toutes les informations de copie carbone (CC) des bogues
dont le champ CC est renseigné. Notez que, comme la plupart des autres tables dans Bugzilla,
il n’est pas fait référence aux utilisateurs par le biais de leur nom d’utilisateur, mais par leur seul
identifiant utilisateur, stocké dans la table profiles comme clé primaire.

components : stocke les programmes et les composants (ou les produits et les
composants dans le nouveau langage de Bugzilla) de Bugzilla. Curieusement, le champ "program"
(product) est le nom complet du produit et non un autre identifiant
unique, comme bug_id et user_id le sont ailleurs dans la base de données.

dependencies : contient les données sur ces supers arbres de dépendance.

fielddefs : table pratique qui définit les autres tables. Par exemple lorsque vous
validez un formulaire qui change la valeur de "AssignedTo", cette table permet le transfert
de l’information vers le champ actuel dont le nom est "assigned_to" pour une entrée de MySQL.

groups : définit les masques binaires pour les groupes. Un masque binaire est un nombre qui peut
identifier de manière unique les appartenances à un groupe. Par exemple, disons que le groupe qui a le droit
d’apporter quelques petites modifications aux paramètres est affecté d’une valeur "1", le groupe qui a la droit
d’éditer les utilisateurs est affecté d’une valeur "2" et le groupe qui peut créer de nouveaux groupes
est affecté d’un masque binaire de "4". Simplement en combinant les masques binaires des groupes (tout
comme la commande chmod d’UNIX,) vous pouvez identifier un utilisateur qui a le droit de modifier
légèrement les paramètres et de créer des groupes mais pas d’éditer les utilisateurs, en lui affectant un
masque binaire de "5", ou bien un utilisateur ayant le droit d’éditer des utilisateurs et de créer des
groupes, mais pas de modifier les paramètres, en lui donnant un masque binaire de "6". Simple, hein ?
  Si vous n’avez pas compris, essayer en tapant ceci à l’invite de commande de mysql :
mysql> select * from groups;
  Vous verrez la liste, c’est plus compréhensible de cette manière.

keyworddefs : définition des mots-clés utilisés.

keywords : a l’inverse de ce que vous pensez, cette table dit quels mots-clés sont
associés avec quels identifiants de bogues.

logincookies : cette table stocke tous les cookies de connexion qui vous sont assignés pour
chaque machine à partir de laquelle vous vous êtes connecté à Bugzilla. Curieusement, elle ne gère pas
le nettoyage ; je retrouve des cookies que je n’ai pas utilisés depuis des mois. Cependant,
comme Bugzilla ne donne pas de date d’expiration aux cookies, cela se comprend.

longdescs : la substance de Bugzilla : voici où sont stockés tous les commentaires des utilisateurs !
Vous disposez uniquement de 2^24 octets par commentaire (il s’agit d’un champ de type mediumtext), donc soyez
concis ; cela représente seulement l'espace que l'Ancien Testament
prendrait (16 mégaoctets, non compressé). Tout commentaire reçoit comme clé le
bug_id du bogue auquel il est lié de telle manière que l’ordre soit nécessairement chronologique car
les commentaires sont retournés dans l’ordre où ils ont été reçus.

milestones : c’est une bonne chose que les jalons soient associés à un produit particulier
dans cette table mais Bugzilla ne supporte pas encore les jalons qui diffèrent en fonction des
produits via l’interface de configuration standard.

namedqueries : c’est ici que chacun stocke ses "requêtes personnelles". Caractéristique
très sympa ; avec cela, plus besoin de se casser la tête à mettre un signet sur chaque requète
sympa que vous élaborez.

products : indique les produits dont vous disposez, si les nouveaux ajouts de bogues sont permis pour ce
produit, sur quel jalon vous travaillez avec ce produit, les votes, etc. Ce
sera bien lorsque la table components contiendra les mêmes attributs, de telle façon que l’on
puisse bloquer l’ajout de nouveaux bogues pour un composant particulier sans bloquer un
produit entier...

profiles : Ahh, alors vous vous demandiez où vos précieuses informations d’utilisateur étaient
gardées ? C’est ici ! Avec les mots de passe en clair pour tout le monde ! (mais
chuut... n’en parlez pas à vos utilisateurs !)

profiles_activity : Vous avez besoin de savoir qui a fait quoi à quel profil utilisateur ? C’est
ici que vous le saurez, il s’agit d’un historique assez complet.

versions : informations sur la version de chaque produit.

votes : qui a voté pour quoi et quand.

watch : qui (relativement au userid) consulte les bogues de qui (relativement à leur
userid).


===
LES DÉTAILS
===

  Ahh, alors vous vous demandez que faire des informations ci-dessus ? A l’invite
de commande vous pouvez visualiser les informations sur n’importe quelle colonne d’une table grâce
à cette commande (où "table" est le nom de la table que vous souhaitez voir) :

mysql> show columns from table;

  Vous pouvez aussi voir toutes les données contenues dans une table avec cette commande :

mysql> select * from table;

  -- note : il est fortement déconseillé de le faire sur, par exemple, la table "bugs" si
vous avez 50 000 bogues. Vous pourriez rester planté là un bon moment avant de faire un ctrl-c ou
à attendre que les 50 000 bogues s'affichent à l’écran.

  Vous pouvez limiter un peu l’affichage ci-dessus avec cette commande où
"colonne" est le nom de la colonne à laquelle vous voulez restreindre l’affichage d’information :

mysql> select * from table where (column = "some info");

  -- ou l’inverse de cela

mysql> select * from table where (column != "some info");

  Reprenons l’exemple de l’introduction et supposons que vous ayez besoin de changer
le mot "verified" par "approved" dans le champ de résolution. Nous savons depuis la
partie précédente que la résolution doit se trouver dans la table
"bugs". Notez que nous devrons changer un peu le code perl en plus de la modification de
la base de données mais je ne vais pas aborder cela dans ce document. Vérifions que
l’information est bien stockée dans la table "bugs" :

mysql> show columns from bugs

  (résultat bien trop long, on l'a raccourci)
| bug_status| enum('UNCONFIRMED','NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED')||MUL | UNCONFIRMED||

  Désolé de cette longue ligne. Nous voyons à partir du résultat que la colonne "bug status" est
de type "enum field", ce qui est une particularité de MySQL où un champ de type chaîne de caractères ne peut
prendre que certaines valeur en entrée. Bien que je trouve cela vraiment sympa, il ne s’agit pas de
SQL standard. Néanmoins, nous avons besoin d’ajouter
’APPROVED’ dans les valeurs possibles du champ "enum" en modifiant la table "bugs".

mysql> ALTER table bugs CHANGE bug_status bug_status
    -> enum("UNCONFIRMED", "NEW", "ASSIGNED", "REOPENED", "RESOLVED",
    -> "VERIFIED", "APPROVED", "CLOSED") not null;

    (notez que vous pouvez entrer trois lignes ou plus ; tout ce que vous placerez avant le
point virgule sera compris comme une seule expression)

Maintenant si vous faites cela :

mysql> show columns from bugs;

  vous verrez que le champ bug_status dispose d’un ’APPROVED’ supplémentaire
dans "enum" ! Une autre chose sympa serait que ce changement soit aussi propagé jusqu’à votre page
de requête ; vous pouvez effectuer une requête au moyen du nouveau statut. Mais comment cela se propage-t-il
dans la réalité des choses ?
  Il semble que vous deviez retourner chercher les instances du mot "verified"
dans le code perl de Bugzilla ; partout où vous trouvez "verified", remplacez le par
"approved" et voilà, ça roule (assurez-vous que la recherche n’est pas sensible à la casse).
Bien que vous puissiez effectuer des requêtes grâce au champ "enum", vous ne pouvez donner le statut
"APPROVED" à quoi que ce soit avant d’avoir réalisé les changements dans le code perl. Notez que ce changement que
j’ai mentionné peut aussi être réalisé en éditant checksetup.pl, qui automatise un bon nombre de
choses. Mais vous avez besoin de connaître ce truc aussi, pas vrai ?