Tablas de base de datos personalizadas Mantenimiento de la base de datos

Durante la vida útil de su tabla personalizada, probablemente encontrará que necesita realizar cambios en lo que almacena o en cómo la almacena. Esto puede ser en respuesta a la necesidad de almacenar más (o menos) datos. Es posible que el diseño inicial de su base de datos no haya tenido la intención de tratar (de manera eficiente) con lo que su base de usuarios ahora exige. De cualquier manera, necesitamos saber cómo adaptar nuestra mesa para satisfacer nuestras nuevas necesidades. Esto es lo que veremos en este tutorial, y nos centraremos principalmente en la función dbDelta () que nos conocimos en la primera parte.


dbDeta

Afortunadamente, la mayor parte del trabajo de campo en el manejo de cambios en la base de datos se realiza mediante la función WordPress. dbDelta (). Utilizamos esta función en la primera parte para crear nuestra tabla, pero en realidad hace mucho más que eso: antes de realizar la consulta que le dimos, verifica si la tabla ya existe. Si no, crea la tabla, pero si existe, compara la diferencia (de ahí el nombre) y hace algunos cambios Es por esto que en la primera parte no verificamos manualmente si la tabla ya existía.

Si la tabla ya existe, pero es diferente de la tabla dada por el SQL (por ejemplo, la tabla existente tiene una columna que falta, o una intercalación de columnas diferente), entonces dbDelta () Aplica automáticamente estas actualizaciones. De esta manera podemos lanzar una nueva versión de nuestro complemento que altera nuestra tabla simplemente aplicando 'dbDelta ()' con el SQL alterado. Casi.

Desafortunadamente, dbDelta () no aplica todos cambios Supongamos que en nuestra última versión de plug-in no necesitamos una columna, y queremos eliminarla. Así que lo eliminamos de la consulta SQL en la primera parte, y en la llamada a la rutina de actualización wptuts_create_tables (). Después de actualizar encontraremos que la columna todavía está allí. Peor que eso: los usuarios que actualicen desde la versión anterior a la nueva tendrán una tabla estructuralmente diferente a la de aquellos que comienzan con la nueva versión..

Nota: dbDelta () es no destructivo: es decir, agregará columnas faltantes o cambiará las columnas alteradas, pero no eliminará columnas o índices.

Entonces que hace dbDelta () en realidad hacer?

Recordemos la consulta SQL a la que pasamos dbDelta () al crear la tabla:

 $ 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 predeterminado '0', actividad varchar (20) NOT NULL default 'updated', object_id bigint (20) unsigned NOT NULL predeterminado '0', object_type varchar (20) NOT NULL predeterminado 'post', activity_date datetime NOT NULL predeterminado '0000-00-00 00:00:00', PRIMARY KEY (log_id), KEY user_id (user_id)) $ charset_collate "; dbDelta ($ sql_create_table);

Primero extrae todos los CREAR MESA consultas puede pasar múltiples consultas a dbDelta () a la vez, separándolos por un ';', pero para mejorar la legibilidad prefiero no). De ahí toma el nombre de la mesa., $ mesa, y corre

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

Esto devuelve una matriz de columnas existentes: cada columna es en realidad un objeto que contiene información perteneciente a esa columna (su nombre, tipo, valor predeterminado, etc.). Por ejemplo nuestro log_id columna se ve como

 stdClass Object ([Field] => log_id [Type] => bigint (20) unsigned [Null] => NO [Key] => PRI [Default] => [Extra] => auto_increment)

Si la tabla no existe, se devuelve una matriz vacía y se crea la tabla. De otra manera dbDelta () luego pasa por cada línea de la consulta pasada, extrae las columnas y las almacena en una matriz $ campos. Lo mismo ocurre con cada una de las claves (incluida la primaria)..

A continuación pasa por cada uno de los existente columnas Si están presentes en la matriz anterior., $ campos, son eliminados. Luego compara su tipo, si no coinciden, genera automáticamente un correspondiente ALTERAR MESA consulta a realizar más tarde. Después de hacer esto, las únicas columnas que quedan en $ campos Son los que no existen ya. A partir de esto se genera más. ALTERAR MESA consultas para crear estas columnas.

A continuación, realiza un procedimiento casi idéntico para las teclas.


Ten cuidado

La capacidad de dbDelta () hacer todo este análisis tiene un costo: su inquietud por lo que aceptará (o interpretará correctamente). Por ejemplo:

  • Cada parte de la consulta (por ejemplo, cada columna y declaración de clave) debe tener su propia línea. Por ejemplo
     user_id bigint (20) sin signo NOT NULL por defecto '0', actividad varchar (20) NOT NULL por defecto 'actualizado',

    actuará como si el actividad La columna no está presente. El formato correcto es:

     user_id bigint (20) sin signo NOT NULL por defecto '0', actividad varchar (20) NOT NULL por defecto 'actualizado',
  • Debes usar KEY en lugar de su sinónimo INDEX.
  • Cualquier clave debe tener un nombre. Por ejemplo, no escribas
    KEY (user_id)]

    en su lugar debería ser

    KEY user_id (user_id)

    (aunque el nombre no tiene que ser el mismo que la columna).

  • La CLAVE PRIMARIA no debe recibir un nombre, sino que debe haber dos espacios entre CLAVE PRIMARIA y la declaración de la columna: (log_id). Por ejemplo,
     CLAVE PRIMARIA (log_id),

    causará un error. El formato correcto es:

     CLAVE PRIMARIA (log_id),

Esta no es una lista completa, como regla general, debe evitar los espacios adicionales alrededor y entre palabras clave, como CREAR y MESA y no debe haber espacios adicionales alrededor de las columnas. Los internos de dbDelta () confiar en usar preg_match () para extraer información de la declaración SQL pasada, y como tal, las cosas pueden salir mal con bastante facilidad si esa declaración no tiene el formato adecuado.

Algunos de estos errores ocurrirán en silencio (por ejemplo, si no da una LLAVE un nombre, dbDelta () Seguiré duplicándolo). Por esta razón, es importante que inspeccione su tabla manualmente (usando phpMyAdmin o similar) para verificar que su código esté funcionando correctamente.


Agregar o cambiar columnas

Con dbDelta (), esto es realmente simple - supongamos que queremos hacer object_id un índice, agregue una columna adicional usuario_ip para almacenar la dirección IP del usuario y cambiar el tipo de la columna de actividad a varchar (30), simplemente reemplazamos la consulta SQL original con:

 $ 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 predeterminado '0', user_ip varchar (15), actividad varchar (30) NOT NULL predeterminado 'updated', object_id bigint (20) unsigned NOT NULL predeterminado '0', object_type varchar (20) NOT NULL predeterminado 'post', activity_date datetime NOT NULL predeterminado '0000-00-00 00:00:00', KEY PRINCIPAL (log_id), KEY user_id (user_id), KEY object_id (object_id),) $ charset_collate; ";

Entonces solo nos aseguramos de que llamemos wptuts_create_tables () En la rutina de actualización, y los cambios tendrán efecto..


Eliminar columnas

Ya que dbDelta () no eliminará columnas, simplemente eliminando la línea apropiada de la consulta no será suficiente (aunque todavía es necesario). En su lugar tenemos que hacer las cosas manualmente..

Primero, extraiga una serie de columnas existentes:

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

Luego, si las columnas que deseamos eliminar están presentes, podemos eliminarlas con un ALTERAR MESA consulta:

 $ remove_columns = array ('object_id'); // Conjunto de columnas para eliminar $ 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). ';');

Quitando llaves

Al igual que hicimos con las columnas, primero obtenga una matriz de índices:

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

Luego, si existen las claves que deseamos eliminar, podemos eliminarlas tal como se indicó anteriormente, pero ahora usando ÍNDICE DE CAÍDA

 $ remove_keys = array ('user_id'); // Matriz de claves para eliminar $ remove_keys = array_intersect ($ remove_keys, $ existing_keys); if (! empty ($ remove_keys)) $ wpdb-> query ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP INDEX" .implode (', DROP INDEX', $ remove_keys). ';');

Rutina de actualización

Ahora que sabemos cómo actualizar nuestra base de datos, veamos cómo debemos manejar esto en nuestro complemento. Almacenaremos todo nuestro manejo de actualizaciones dentro de la función: wptuts_activity_log_upgradecheck (). Tenga en cuenta que el gancho de activación de plug-in será no se activará cuando se actualice un complemento: para garantizar que nuestra rutina de actualización haga su trabajo, lo conectamos admin_init.

Para verificar qué rutinas de actualización debemos realizar, almacenaremos la versión del complemento en la base de datos. Compararemos esta versión (la versión instalada) con la versión actual (activada) del complemento:

  • Si no hay una versión en la base de datos, es una instalación nueva y solo agregaremos la versión actual
  • Sí hay es una versión en la base de datos, y es la versión actual, no hacemos nada
  • De lo contrario, es una versión anterior, por lo que revisaremos todas las rutinas de actualización necesarias..
 add_action ('admin_init', 'wptuts_activity_log_upgradecheck'); function wptuts_activity_log_upgradecheck () // Versión del complemento actualmente activado $ current_version = '1.3'; // Versión de la base de datos - esto puede necesitar una actualización. $ installed_version = get_option ('wptuts_activity_log_version'); if (! $ Install_version) // No hay una versión instalada: asumiremos que se acaba de instalar add_option ('wptuts_activity_log_version', $ current_version);  elseif ($ installed_version! = $ current_version) / * * Si esta es una versión antigua, realice algunas actualizaciones. * / // La versión instalada es anterior a 1.1: actualice a 1.1 si (version_compare ('1.1', $ installed_version)) // El código para actualizar a la versión 1.1 // La versión instalada es anterior a 1.3 - actualice a 1.3 si (version_compare ( '1.3', $ Install_version)) // Código para actualizar a la versión 1.3 // La base de datos ya está actualizada: actualice la versión instalada a la última versión update_option ('wptuts_activity_log_version', $ current_version); 

Nota: Es importante que esta rutina de actualización esté presente en el inicial libere ya que agregará la versión inicial (1.0) a la base de datos. No hacerlo puede causar problemas para quienes actualicen de la versión 1.0 a la 1.1..

Cada una de las rutinas de actualización debe garantizar que la base de datos esté "actualizada" mediante el uso del código descrito en las secciones anteriores. Es importante destacar que, si realizamos cambios en CREATE TABLE SQL, debe recordar ejecutar esa consulta a través de dbDelta () (en nuestro ejemplo, llamando wptuts_create_tables () como parte de la rutina de actualización) para que los cambios surtan efecto.

Tenga cuidado con cómo maneja las actualizaciones cuando usa dbDelta. Recuerde que algunos usuarios pueden estar actualizando a través de dos o más actualizaciones. Por lo tanto, si dichos cambios no se pueden realizar en paralelo, entonces tendrá que actualizar en etapas, llamando 'dbDelta ()' varias veces, haciendo los cambios apropiados para esa etapa.


Desinstalar la rutina

Mientras estamos en ello, echemos un vistazo a la limpieza después de nosotros mismos cuando se desinstala el complemento. Estas son generalmente rutinas muy simples: simplemente elimine la tabla de la base de datos, las opciones guardadas y cualquier tarea cron que su complemento pueda haber activado. Enganchamos nuestra rutina en el gancho de desinstalación usando el registro desinstalar gancho ()

 registrar el gancho de desinstalación (__ ARCHIVO __, 'wptuts_uninstall_plugin'); función wptuts_uninstall_plugin () global $ wpdb; // Eliminar nuestra tabla (si existe) $ wpdb-> query ("DROP TABLE SI EXISTS $ wpdb-> wptuts_activity_log"); // Eliminar la versión de la base de datos delete_option ('wptuts_activity_log_version'); / * Elimine cualquier otra opción que haya instalado su complemento y borre cualquier tarea cron de complemento * /