Debugować EntityFieldQuery?

27

Mam moduł, który źle działa. EFQ jest returing nieoczekiwane rezultaty, ale nie widzę , dlaczego po prostu patrząc na kod. Czy istnieje odpowiednik dpq () dla EFQ? Inne sposoby ich debugowania?

Letharion
źródło
Podobne pytanie: drupal.stackexchange.com/questions/33473/... . Czy możesz rzucić obiekt zapytania na ciąg, aby sprawdzić, czy SQL daje jakieś wskazówki?
Clive
1
Świetne sugestie: błąd krytyczny możliwy do odzyskania: Obiekt klasy EntityFieldQuery nie mógł zostać przekonwertowany na ciąg znaków :(
Letharion

Odpowiedzi:

36

To trochę hack, ale możesz dodać tag do każdego, EntityFieldQuerykto jest zainteresowany wydrukowaniem zapytania, a następnie zaimplementować hook_query_alter()przechwytywanie, gdy jest to standard SelectQuery, a następnie rzucić go na ciąg znaków w celu debugowania:

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

To trochę hack, ale załatwia sprawę. Wynik dla powyższego jest:

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

Przypuszczalnie zadziała to również tylko przy użyciu MySQL jako systemu pamięci masowej.

Clive
źródło
Brzmi świetnie w teorii, ale co z komentarzami do pytania? EFQ nie implementuje __toString ()?
Letharion,
4
Zanim dotrze do hook_query_alter()zapytania, już nie jest EntityFieldQuery, zostało przekonwertowane do standardu db_select(), więc __tostring()działa świetnie :) Odkąd to wypracowałem, używałem go całkiem sporo i działa całkiem dobrze
Clive
Potwierdzono, że rzutowanie na ciąg działa, gdy zapytanie dotrze do hook_query_alter().
jhedstrom
Aby zobaczyć zapytanie argumentos („: typ_instancji” w powyższym przykładzie), możesz użyć dpm ($ query-> arguments ());
sanzante
13

Zamiast tworzyć własną funkcję hook_query_alter (), możesz pozwolić modułowi Devel wykonać ciężkie podnoszenie, dodając debugtag:

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

Spowoduje to wydrukowanie zapytania na ekranie, tak jak dpq()by to zrobiło.

Dalin
źródło
4

Dodanie do odpowiedzi @Clive, która generalnie drukuje zapytanie z symbolem zastępczym nie razem z wartością. Aby wydrukować wartość z zapytaniem, użyj następującego kodu pod 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();

Nie jest dobrą praktyką instalowanie modułu dla kilku wierszy kodu. Dlatego zdecydowałem się na wyżej wspomniane rozwiązanie.

Sukhjinder Singh
źródło
2

Jeśli pobierzesz wersję deweloperską Nice DPQ (lub cokolwiek => 1.1), możesz po prostu zrobić:

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

i dostaniesz ładnie dpm'owane zapytanie :). Ważną częścią powyższego kodu jest addTag ('nicedpq') - który uruchamia dpm().

mojzi
źródło
fajne alternatywne obejście do rozwijania. Nie można znaleźć tego modułu bezpośrednio nad DO, ponieważ usunęli powiązany moduł modułu, który był tam wcześniej.
Kiranking
1

Możesz spróbować debugować go za pomocą XDebug . Po zainstalowaniu wykonaj xdebug_start_trace()przed kodem, a xdebug_stop_trace()następnie wyczyść dziennik śledzenia, co zostało wykonane i gdzie.

Możesz także włączyć rejestrator zapytań w konfiguracji MySQL.

Inną metodą jest użycie strace / truss / dtruss jak debuggerów.

Przykład użycia dtruss:

  • wszystkie zapytania

    sudo dtruss -t read -n mysqld
  • konkretne zapytania

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

Zauważ, że dtrussto tylko skrypt, który używa DTrace, więc możesz rozważyć bezpośrednią implementację statycznych sond PHP DTrace lub DTracing MySQL , pisząc własny skrypt.

Czytaj więcej: Zaawansowane debugowanie rdzenia Drupala za pomocą wiersza poleceń (strace i tcpdump)

kenorb
źródło
0

Dodaj tę funkcję do swojego modułu. Następnie dodaj znacznik debugdo dowolnego EFQ. Wymaga włączenia modułu Devel w celu wydrukowania zapytania.

/**
 * 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
źródło