Tables de base de données personnalisées Maintenance de la base de données

Au cours de la durée de vie de votre table personnalisée, vous constaterez probablement que vous devez modifier son contenu ou son mode de stockage. Cela peut être dû au besoin de stocker plus (ou moins) de données. Il se peut que la conception initiale de votre base de données n'ait pas été conçue pour traiter (efficacement) ce que votre base d'utilisateurs demande maintenant. Quoi qu'il en soit, nous devons savoir comment adapter notre table à nos nouveaux besoins. C’est ce que nous verrons dans ce tutoriel, et nous nous concentrerons principalement sur la fonction dbDelta () que nous avons rencontré pour la première fois dans la première partie.


dbDeta

Heureusement, la plupart des démarches dans la gestion des modifications de la base de données sont effectuées par la fonction WordPress dbDelta (). Nous avons utilisé cette fonction dans la première partie pour créer notre table, mais cela en fait beaucoup plus: avant d'exécuter la requête que nous lui avons donnée, il vérifie si la table existe déjà. Sinon, il crée la table, mais s’il existe, il compare la différence (d’où le nom) et crée certains changements. C'est pourquoi dans la première partie, nous n'avons pas vérifié manuellement si la table existait déjà..

Si la table existe déjà, mais est différente de la table indiquée par le code SQL (par exemple, la table existante a une colonne manquante ou un classement de colonne différent), puis dbDelta () applique automatiquement ces mises à jour. De cette façon, nous pouvons publier une nouvelle version de notre plug-in qui modifie notre table en appliquant simplement 'dbDelta ()' avec le code SQL modifié. Presque.

Malheureusement, dbDelta () ne s'applique pas tout changements. Supposons que dans notre dernière version de plug-in, nous n’avons pas besoin d’une colonne et nous voulons la supprimer. Nous le supprimons donc de la requête SQL de la première partie et de l'appel de routine de mise à niveau. wptuts_create_tables (). Après la mise à niveau, nous découvrirons que la colonne est toujours là. Pire que cela: les utilisateurs passant de l'ancienne version à la nouvelle version auront alors une table structurellement différente de celle qui commence par la nouvelle version.

Remarque: dbDelta () est non destructif: c’est-à-dire qu’il va ajouter des colonnes manquantes ou modifier les colonnes modifiées, mais ne supprimera pas les colonnes ni les index.

Alors qu'est-ce que dbDelta () effectivement faire?

Rappelons-nous la requête SQL à laquelle nous passons dbDelta () lors de la création de la table:

 $ sql_create_table = "CREATE TABLE". $ wpdb-> wptuts_activity_log. "(log_id bigint (20) unsigned NOT NULL auto_increment, user_id bigint (20) unsigned NOT NULL par défaut '0', activité varchar (20) NOT NULL par défaut 'mis à jour', object_id bigint (20) non signé NULL par défaut '0', type d'objet varchar (20) NOT NULL par défaut 'post', date_activité_actuelle NON NULL par défaut '0000-00-00 00:00:00', PRIMARY KEY (id_log), KEY id_utilisateur (id_utilisateur)) $ charset_collate ; "; dbDelta ($ sql_create_table);

Tout d'abord, il extrait tous les CREER LA TABLE requêtes (vous pouvez transmettre plusieurs requêtes à dbDelta () à la fois, en les séparant par un ';', mais pour améliorer la lisibilité, je préfère ne pas). A partir de là, prend le nom de la table, $ table, et court

 $ wpdb-> get_results ("DESCRIBE $ table;");

Cela retourne un tableau de colonnes existantes - chaque colonne est en fait un objet contenant des informations relatives à cette colonne (son nom, son type, sa valeur par défaut, etc.). Par exemple notre log_id la colonne ressemble à:

 Objet stdClass ([Field] => log_id [Type] => bigint (20) unsigned [Null] => NO [Key] => PRI [Par défaut] => [Extra] => auto_increment)

Si la table n'existe pas, un tableau vide est renvoyé et la table est créée. Autrement dbDelta () parcourt ensuite chaque ligne de la requête transmise, extrait les colonnes et les stocke dans un tableau $ cfields. Il en va de même avec chacune des clés (y compris primaire).

Ensuite, il passe par chacun des existant colonnes. S'ils sont présents dans le tableau ci-dessus, $ cfields, ils sont enlevés. Il compare ensuite leur type, s’ils ne correspondent pas, il génère automatiquement un ALTER TABLE requête à effectuer plus tard. Après cela, les seules colonnes restantes dans $ cfields sont ceux qui n'existent pas déjà. De cela, il génère plus ALTER TABLE requêtes pour créer ces colonnes.

Il effectue ensuite une procédure presque identique pour les clés.


Faites attention

La capacité de dbDelta () faire toute cette analyse a un coût: sa falsification de ce qu’elle acceptera (ou interprétera correctement). Par exemple:

  • Chaque partie de la requête (par exemple, chaque colonne et déclaration de clé) doit avoir sa propre ligne. Par exemple
     user_id bigint (20) unsigned NOT NULL par défaut '0', activity varchar (20) NOT NULL par défaut 'updated',

    agira comme si le activité la colonne n'est pas présente. Le format correct est:

     user_id bigint (20) unsigned NOT NULL par défaut '0', activity varchar (20) NOT NULL par défaut 'updated',
  • Vous devez utiliser KEY plutôt que son synonyme INDEX.
  • Toutes les clés doivent avoir un nom. Par exemple, n'écrivez pas
    KEY (user_id)]

    il devrait plutôt être

    KEY user_id (user_id)

    (bien que le nom ne doive pas nécessairement être identique à la colonne).

  • Il ne faut pas donner de nom à la PRIMARY KEY, mais plutôt deux les espaces entre CLÉ PRIMAIRE et la déclaration de colonne: (log_id). Par exemple,
     PRIMARY KEY (log_id),

    provoquera une erreur. Le format correct est:

     PRIMARY KEY (log_id),

Ce n'est pas une liste complète, comme règle générale vous devez éviter les espaces supplémentaires autour et entre les mots-clés, tels que CRÉER et TABLE et il ne devrait y avoir aucun espace supplémentaire autour des colonnes. Les internes de dbDelta () compter sur l'utilisation preg_match () extraire des informations de l'instruction SQL transmise - et en tant que tel, les choses peuvent mal se passer assez facilement si cette instruction n'est pas correctement formatée.

Certaines de ces erreurs se produiront en silence (par exemple, si vous ne donnez pas une CLÉ un nom, dbDelta () continuera à le dupliquer). Pour cette raison, il est important que vous inspectiez votre table manuellement (avec phpMyAdmin ou similaire) pour vérifier que votre code fonctionne correctement..


Ajouter ou changer des colonnes

Avec dbDelta (), c'est très simple - supposons que nous voulions faire object_id un index, ajouter une colonne supplémentaire user_ip pour stocker l'adresse IP de l'utilisateur et modifier le type de la colonne d'activité en varchar (30), nous remplaçons simplement la requête SQL d'origine par:

 $ sql_create_table = "CREATE TABLE". $ wpdb-> wptuts_activity_log. "(log_id bigint (20) unsigned NOT NULL auto_increment, user_id bigint (20) unsigned NOT NULL par défaut '0', user_ip varchar (15), activité par varchar (30) NON NULL par défaut 'updated', object_id bigint (20) unsigned NOT NULL par défaut '0', type d'objet varchar (20) NOT NULL par défaut 'post', date_activité datetime NON NULL par défaut '0000-00-00 00:00:00', PRIMARY KEY (id_log), KEY identifiant_utilisateur (id_utilisateur), KEY id_objet (id_objet),) $ charset_collate; ";

Ensuite, nous nous assurons que nous appelons wptuts_create_tables () dans la routine de mise à niveau, et les modifications prendront effet.


Supprimer des colonnes

Puisque dbDelta () ne supprimera pas les colonnes, le simple fait de supprimer la ligne appropriée de la requête ne suffira pas (il faut quand même). Au lieu de cela, nous devons faire les choses manuellement.

Commencez par extraire un tableau de colonnes existantes:

 $ existing_columns = $ wpdb-> get_col ("DESC $ wpdb-> wptuts_activity_log", 0);

Ensuite, si les colonnes que nous souhaitons supprimer sont présentes, nous pouvons les supprimer avec un ALTER TABLE question:

 $ remove_columns = array ('object_id'); // Tableau de colonnes à supprimer $ remove_columns = array_intersect ($ remove_columns, $ existing_columns); if (! empty ($ remove_columns)) $ wpdb-> query ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP COLUMN" .implode (', DROP COLUMN', $ remove_columns). ';');

Enlever des clés

Comme nous l’avons fait avec les colonnes, obtenons d’abord un tableau d’index:

 $ existing_keys = $ wpdb-> get_col ("SHOW INDEX FROM $ wpdb-> wptuts_activity_log WHERE nom_clé! = 'PRIMARY';", 2);

Ensuite, si les clés que nous souhaitons supprimer existent, nous pouvons les supprimer comme ci-dessus, mais en utilisant DROP INDEX

 $ remove_keys = array ('user_id'); // Tableau de clés à supprimer $ remove_keys = array_intersect ($ remove_keys, $ existing_keys); if (! empty ($ remove_keys)) $ wpdb-> requête ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP INDEX" .implode (', DROP INDEX', $ remove_keys). ';');

Routine de mise à niveau

Maintenant que nous savons comment mettre à niveau notre base de données, voyons comment nous devrions gérer cela dans notre plug-in. Nous allons stocker toute notre gestion de mise à niveau à l'intérieur de la fonction: wptuts_activity_log_upgradecheck (). Notez que le crochet d’activation du plug-in ne pas déclenché lors de la mise à jour d'un plug-in: afin de nous assurer que notre routine de mise à niveau fonctionne, nous allons nous accrocher à admin_init.

Pour vérifier les routines de mise à niveau à effectuer, nous stockons la version du plug-in dans la base de données. Nous allons comparer cette version (la version installée) à la version actuelle (activée) du plug-in:

  • S'il n'y a pas de version dans la base de données, l'installation est récente et nous allons simplement ajouter la version actuelle
  • S'il y a est une version de la base de données, et c'est la version actuelle, on ne fait rien
  • Sinon, c'est une version plus ancienne, nous allons donc passer en revue toutes les routines de mise à niveau nécessaires.
 add_action ('admin_init', 'wptuts_activity_log_upgradecheck'); function wptuts_activity_log_upgradecheck () // Version du plugin actuellement activé $ current_version = '1.3'; // Version de la base de données - cela peut nécessiter une mise à niveau. $ installed_version = get_option ('wptuts_activity_log_version'); if (! $ installed_version) // Pas de version installée - nous supposerons qu'elle vient d'être installée add_option ('wptuts_activity_log_version', $ current_version);  elseif ($ installed_version! = $ current_version) / * * S'il s'agit d'une ancienne version, effectuez des mises à jour. * / // La version installée est antérieure à 1.1 - mise à niveau vers 1.1 si (version_compare ('1.1', $ installed_version)) // Code pour la mise à niveau vers la version 1.1 // La version installée est antérieure à 1.3 - mise à niveau vers 1.3 si (version_compare ( '1.3', $ installed_version)) // Code de mise à niveau vers la version 1.3 // La base de données est maintenant à jour: mettez à jour la version installée vers la dernière version update_option ('wptuts_activity_log_version', $ current_version); 

Remarque: Il est important que cette routine de mise à niveau soit présente dans le initiale release car cela ajoutera la version initiale (1.0) à la base de données. Ne pas le faire peut causer des problèmes pour ceux qui passent de 1.0 à 1.1.

Chacune des routines de mise à niveau doit s'assurer que la base de données est à jour en utilisant le code décrit dans les sections précédentes. Fait important, si nous apportons des modifications à CREATE TABLE SQL, vous devez vous rappeler d’exécuter cette requête via dbDelta () (dans notre exemple, en appelant wptuts_create_tables () dans le cadre de la routine de mise à niveau) pour que les modifications prennent effet.

Soyez prudent avec la façon dont vous gérez les mises à jour lorsque vous utilisez dbDelta. N'oubliez pas que certains utilisateurs peuvent effectuer une mise à niveau sur deux mises à jour ou plus. Donc, si de telles modifications ne peuvent pas être effectuées en parallèle - vous devrez alors effectuer la mise à niveau par étapes, en appelant plusieurs fois 'dbDelta ()', en effectuant les modifications appropriées pour cette étape..


Désinstallation de routine

Pendant que nous y sommes, examinons le nettoyage après la désinstallation du plug-in. Ce sont généralement des routines très simples: il suffit de supprimer la table de la base de données, les options enregistrées et les tâches cron que votre plug-in a activées. Nous accrochons notre routine au crochet de désinstallation à l'aide de register uninstall hook ()

 enregistrer la désinstallation en attente (__ FILE __, 'wptuts_uninstall_plugin'); function wptuts_uninstall_plugin () global $ wpdb; // Supprime notre table (si elle existe) $ wpdb-> query ("DROP TABLE IF EXISTS $ wpdb-> wptuts_activity_log"); // Supprime la version de la base de données delete_option ('wptuts_activity_log_version'); / * Supprimez toutes les autres options installées par votre plug-in et supprimez toutes les tâches cron de plug-in * /