Depurar EntityFieldQuery?

27

Tengo un módulo que se está portando mal. Un EFQ está recuperando resultados inesperados, pero no puedo ver por qué solo mirando el código. ¿Hay un equivalente dpq () para EFQ? ¿Otras formas de depurarlos?

Letharion
fuente
Pregunta similar: drupal.stackexchange.com/questions/33473/… . ¿Puedes convertir el objeto de consulta en una cadena para inspeccionarlo y ver si el SQL da alguna pista?
Clive
1
Grandes sugerencias, sin embargo: Error fatal recuperable: el objeto de la clase EntityFieldQuery no se pudo convertir en cadena :(
Letharion

Respuestas:

36

Es un truco, pero puede agregar una etiqueta a cualquiera EntityFieldQueryque le interese imprimir la consulta, luego implementarla hook_query_alter()para interceptarla cuando sea un estándar SelectQueryy luego convertirla en cadena para la depuración:

function MYMODULE_query_alter($query) {
  if ($query->hasTag('efq_debug')) {
    dpm((string)$query);
  }
}

$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node')
  ->addTag('efq_debug')
  ->execute();

Es un poco hack pero funciona. La salida para lo anterior es:

SELECT node.nid AS entity_id, node.vid AS revision_id, node.type AS bundle, :entity_type     
AS entity_type
FROM {node} node

Presumiblemente, esto solo funcionará cuando se use MySQL como sistema de almacenamiento de campo.

Clive
fuente
Suena genial en teoría, pero ¿qué pasa con los comentarios sobre la pregunta? EFQ no implementa __toString ()?
Letharion
44
Para cuando llega hook_query_alter()la consulta ya no EntityFieldQueryexiste, se ha convertido a un estándar db_select(), por lo que __tostring()funciona muy bien :) Desde que lo resolví, lo he estado usando bastante y funciona bastante bien
Clive
Confirmó que la conversión a cadena funciona una vez que llega la consulta hook_query_alter().
jhedstrom
Para ver los argumentos de la consulta (": entity_type" en el ejemplo anterior) puede usar dpm ($ query-> argumentos ());
sanzante
13

En lugar de lanzar su propio hook_query_alter (), puede dejar que el módulo Devel haga el trabajo pesado por usted agregando la debugetiqueta:

$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
  ->addTag('debug')
  ->execute();

Esto imprimirá la consulta a la pantalla, tal como lo dpq()haría.

Dalin
fuente
4

Agregando a la respuesta @Clive, que generalmente imprime la consulta con el marcador de posición no junto con el valor. Para imprimir el valor con la consulta, use el siguiente código debajo de hook_query_alter.

function hook_query_alter($query) {
  if ($query->hasTag('debug')) {
    $sql = (string)$query;
    $connection = Database::getConnection();
    foreach ((array) $query->arguments() as $key => $val) {
      $quoted[$key] = $connection->quote($val);
    }
    $sql = strtr($sql, $quoted);
    dpm($sql);
  }
}


$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
  ->addTag('debug');
  ->execute();

No es una buena práctica instalar un módulo para las pocas líneas de código. Es por eso que opté por la solución antes mencionada.

Sukhjinder Singh
fuente
2

Si descarga la versión de desarrollo de Nice DPQ (o cualquier cosa => 1.1), simplemente puede hacer:

$user_query = new EntityFieldQuery();
$user_query->entityCondition('entity_type','user');
$user_query->addTag('nicedpq');
$user_result = $user_query->execute();

y obtendrá la consulta dpm'ed muy bien :). La parte importante en el código anterior es addTag ('nicedpq') , que activa el dpm().

mojzis
fuente
buena solución alternativa para desarrollar. No se pudo encontrar ese módulo directamente sobre DO porque eliminaron el bloque de módulo relacionado que estaba allí antes.
kiranking
1

Puede intentar depurarlo a través de XDebug . Una vez instalado, haga xdebug_start_trace()antes del código, y xdebug_stop_trace()después de eso, tendrá un registro de seguimiento claro qué se ejecutó y dónde.

También puede habilitar el registrador de consultas en la configuración de MySQL.

El otro método es usar strace / truss / dtruss como depuradores.

Ejemplo usando dtruss:

  • todas las consultas

    sudo dtruss -t read -n mysqld
  • consultas específicas

    sudo dtruss -t read -n mysqld 2>&1 | grep SPECIFIC_TEXT

Tenga en cuenta que dtrusses solo un script que utiliza DTrace, por lo que puede considerar una implementación directa de las sondas estáticas PHP DTrace o DTracing MySQL escribiendo su propio script.

Leer más: Depuración avanzada del núcleo de Drupal usando la línea de comando (strace & tcpdump)

kenorb
fuente
0

Agregue esta función a su módulo. Luego, agregue la etiqueta debuga cualquier EFQ. Requiere que el módulo Devel esté habilitado para imprimir la consulta.

/**
 * Implements hook_query_TAG_alter().
 *
 * Add the tag 'debug' to any EFQ and this will print the query to the messages.
 *
 * @param \QueryAlterableInterface $query
 */
function MYMODULE_query_debug_alter(QueryAlterableInterface $query) {
  if (function_exists('dpq') && !$query->hasTag('debug-semaphore')) {
    $query->addTag('debug-semaphore');
    dpq($query);
  }
}
KeyboardCowboy
fuente