Depurar EntityFieldQuery?

27

Eu tenho um módulo que está se comportando mal. Um EFQ está obtendo resultados inesperados, mas não vejo por que apenas olhando o código. Existe um equivalente dpq () para EFQs? Outras maneiras de depurá-los?

Letharion
fonte
Pergunta semelhante: drupal.stackexchange.com/questions/33473/… . Você pode converter o objeto de consulta em uma cadeia de caracteres para inspecioná-lo e verificar se o SQL fornece alguma pista?
Clive
11
Ótimas sugestões, no entanto: Erro fatal recuperável: O objeto da classe EntityFieldQuery não pôde ser convertido em string :(
Letharion

Respostas:

36

É um pouco complicado, mas você pode adicionar uma tag a qualquer uma EntityFieldQueryque esteja interessada em imprimir a consulta, implementar hook_query_alter()para interceptá-la quando for um padrão SelectQuerye convertê-la em string para depuração:

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();

É um pouco complicado, mas faz o truque. A saída para o acima é:

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

Presumivelmente, isso também funcionará ao usar o MySQL como o sistema de armazenamento em campo.

Clive
fonte
Parece ótimo em teoria, mas e os comentários sobre a questão? O EFQ não implementa __toString ()?
Letharion
4
No momento em que chega à hook_query_alter()consulta, não é EntityFieldQuerymais, ela foi convertida em um padrão db_select(), então __tostring()funciona muito bem :) Desde que resolvi isso, eu a uso bastante e funciona muito bem
Clive
Confirmado que a conversão para string funciona assim que a consulta chega hook_query_alter().
precisa saber é o seguinte
Para ver a consulta argumentos (": entity_type" no exemplo acima), você pode usar o dpm ($ query-> argumentos ());
sanzante
13

Em vez de usar o seu hook_query_alter (), você pode deixar o módulo Devel fazer o trabalho pesado adicionando a debugtag:

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

Isso imprimirá a consulta na tela, exatamente como dpq()faria.

Dalin
fonte
4

Adicionando à resposta @Clive, que geralmente imprime a consulta com o espaço reservado, não junto com o valor. Para imprimir o valor com a consulta, use o seguinte código no 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();

Não é uma boa prática instalar um módulo para as poucas linhas de código. Por isso, optei pela solução mencionada acima.

Sukhjinder Singh
fonte
2

Se você baixar a versão de desenvolvimento do Nice DPQ (ou qualquer coisa => 1.1), basta:

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

e você receberá a consulta dpm'ed muito bem :). A parte importante no código acima é addTag ('nicedpq') - que aciona o dpm().

mojzis
fonte
solução alternativa agradável a ser desenvolvida. Não foi possível encontrar esse módulo diretamente no DO porque eles removeram o bloco de módulo relacionado que estava lá anteriormente.
kiranking
1

Você pode tentar depurá -lo via XDebug . Depois de instalado, faça xdebug_start_trace()antes do código e, xdebug_stop_trace()depois disso, você terá um log de rastreamento claro, o que foi executado e onde.

Além disso, você pode habilitar o logger de consultas na configuração do MySQL.

O outro método é usar strace / truss / dtruss como depuradores.

Exemplo usando dtruss:

  • todas as consultas

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

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

Observe que este dtrussé apenas um script que usa o DTrace; portanto, você pode considerar uma implementação direta dos testes estáticos do PHP DTrace ou do DTracing MySQL , escrevendo seu próprio script.

Leia mais: Depuração avançada do núcleo do Drupal usando a linha de comando (strace & tcpdump)

kenorb
fonte
0

Adicione esta função ao seu módulo. Em seguida, adicione a tag debuga qualquer EFQ. Requer que o módulo Devel esteja ativado para imprimir a 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
fonte