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?
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?
Respostas:
É um pouco complicado, mas você pode adicionar uma tag a qualquer uma EntityFieldQuery
que esteja interessada em imprimir a consulta, implementar hook_query_alter()
para interceptá-la quando for um padrão SelectQuery
e 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.
hook_query_alter()
consulta, não é EntityFieldQuery
mais, 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
hook_query_alter()
.
Em vez de usar o seu hook_query_alter (), você pode deixar o módulo Devel fazer o trabalho pesado adicionando a debug
tag:
$q = new EntityFieldQuery;
$q->entityCondition('entity_type', 'node');
->addTag('debug')
->execute();
Isso imprimirá a consulta na tela, exatamente como dpq()
faria.
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.
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()
.
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)
Adicione esta função ao seu módulo. Em seguida, adicione a tag debug
a 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);
}
}