Debug EntityFieldQuery?

27

Saya memiliki modul yang nakal. EFQ mempertahankan hasil yang tidak terduga, tetapi saya tidak bisa melihat mengapa hanya dengan melihat kode. Apakah ada dpq () yang setara untuk EFQ? Cara lain untuk men-debug mereka?

Letharion
sumber
Pertanyaan serupa: drupal.stackexchange.com/questions/33473/… . Bisakah Anda melemparkan objek permintaan ke string untuk memeriksanya untuk melihat apakah SQL memberikan petunjuk?
Clive
1
Saran yang bagus, namun: Kesalahan fatal yang dapat dipulihkan: Objek kelas EntityFieldQuery tidak dapat dikonversi ke string :(
Letharion

Jawaban:

36

Ini sedikit hack, tetapi Anda bisa menambahkan tag ke apa pun yang EntityFieldQueryAnda tertarik untuk mencetak kueri, kemudian menerapkannya hook_query_alter()untuk mencegatnya ketika itu adalah standar SelectQuery, lalu melemparkannya ke string untuk debugging:

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

Ini sedikit hack tetapi melakukan trik. Output untuk di atas adalah:

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

Agaknya ini juga hanya akan berfungsi ketika menggunakan MySQL sebagai sistem penyimpanan lapangan.

Clive
sumber
Kedengarannya hebat dalam teori, tetapi bagaimana dengan komentar pada pertanyaan? EFQ tidak menerapkan __toString ()?
Letharion
4
Pada saat ia sampai ke hook_query_alter()query bukan EntityFieldQuerylagi, sudah dikonversi ke standar db_select(), jadi __tostring()berfungsi dengan sangat baik :) Sejak mengerjakan ini saya sudah menggunakannya cukup banyak dan bekerja cukup baik
Clive
Dikonfirmasi bahwa casting to string berfungsi setelah kueri diterima hook_query_alter().
jhedstrom
Untuk melihat query argumentos (": entity_type" pada contoh di atas) Anda dapat menggunakan dpm ($ query-> argumen ());
sanzante
13

Daripada memutar hook_query_alter Anda sendiri (), Anda dapat membiarkan modul Devel melakukan pekerjaan berat untuk Anda dengan menambahkan debugtag:

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

Ini akan mencetak kueri ke layar, sama seperti dpq()akan.

Dalin
sumber
4

Menambah jawaban @Clive, yang umumnya mencetak kueri dengan placeholder yang tidak sesuai dengan nilainya. Untuk mencetak nilai dengan kueri gunakan kode berikut di bawah 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();

Ini bukan praktik yang baik untuk menginstal modul untuk beberapa baris kode. Itu sebabnya saya memilih solusi yang disebutkan di atas.

Sukhjinder Singh
sumber
2

Jika Anda mengunduh versi bagus dari DPQ Bagus (atau apa pun => 1.1), Anda dapat melakukannya:

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

dan Anda akan mendapatkan kueri dpm'ed dengan baik :). Bagian penting dalam kode di atas adalah addTag ('nicedpq') - yang memicu dpm().

mojzis
sumber
solusi alternatif yang bagus untuk mengembangkan. Tidak dapat menemukan modul itu langsung dari DO karena mereka menghapus blok modul terkait yang ada di sana.
kiranking
1

Anda dapat mencoba men-debug-nya melalui XDebug . Setelah terinstal, lakukan xdebug_start_trace()sebelum kode, dan xdebug_stop_trace()setelah itu, maka Anda akan memiliki log jejak yang jelas apa yang dieksekusi dan di mana.

Anda juga dapat mengaktifkan logger kueri dalam konfigurasi MySQL.

Metode lainnya adalah dengan menggunakan strace / truss / dtruss seperti debuggers.

Contoh menggunakan dtruss:

  • semua pertanyaan

    sudo dtruss -t read -n mysqld
  • pertanyaan spesifik

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

Perhatikan bahwa dtrussini hanyalah skrip yang menggunakan DTrace, sehingga Anda dapat mempertimbangkan implementasi langsung probe statis PHP DTrace atau DTracing MySQL dengan menulis skrip Anda sendiri.

Baca selengkapnya: Melakukan debug lanjutan pada inti Drupal menggunakan baris perintah (strace & tcpdump)

kenorb
sumber
0

Tambahkan fungsi ini ke modul Anda. Kemudian, tambahkan tag debugke EFQ apa ​​pun. Membutuhkan modul Devel diaktifkan untuk mencetak kueri.

/**
 * 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
sumber