autocomplete в модуле users или друпал кретинизмы

Главные вкладки

Аватар пользователя Dеmimurych Dеmimurych 10 марта 2010 в 17:02
 $matches = array();
  function user_autocomplete($string = '') {
  $matches = array();
  if ($string) {
    $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10);
    while ($user = db_fetch_object($result)) {
      $matches[$user->name] = check_plain($user->name);
    }
  }

  drupal_json($matches);
}

Обращаем внимание на запрос
и видим что для поиска нужного имени используется оператор LIKE
при этом, автор этого куска кода, заворачивает данные в lower

на первый взгляд все верно - берется данные в нижнем регистре и берется имя в том же регистре и сравнивается like

на взгляд же человека с мозгами вместо задницы, понимающего что он делает полный кретинизм по двум параметрам

LIKE использует регулярные выражения для поиска нужного результата а значит в нашем случае не зависит от регистра и с равным успехом найдет например Demimurych задав LIKE 'DeMiMU%' так и 'demimu%'

второй, при использовании LOWER, mysql не может использовать индекс по полю name как результат имей вы в базе хотябы 300 00 пользователей, вы получите выполнение запроса от 0.1 секунды до 2 и выше.

Решение это го кретинизма в переопределении пути
user/autocomplete

на свой колбэк с функцией

 $matches = array();
  function user_autocomplete($string = '') {
  $matches = array();
  if ($string) {
    $result = db_query_range("SELECT name FROM {users} WHERE name LIKE '%s%%'", $string, 0, 10);
    while ($user = db_fetch_object($result)) {
      $matches[$user->name] = check_plain($user->name);
    }
  }

  drupal_json($matches);
}

Комментарии

Аватар пользователя Sinkora Sinkora 26 апреля 2010 в 3:34

Аналогично и в модуле profiles:

<?php

function profile_autocomplete($field$string) {
  
$matches = array();
  if (
db_result(db_query("SELECT COUNT(*) FROM {profile_fields} WHERE fid = %d AND autocomplete = 1"$field))) {
    
$result db_query_range("SELECT value FROM {profile_values} WHERE fid = %d AND LOWER(value) LIKE LOWER('%s%%') GROUP BY value ORDER BY value ASC"$field$string010);
    while (
$data db_fetch_object($result)) {
      
$matches[$data->value] = check_plain($data->value);
    }
  }

  

drupal_json($matches);
}

?>
Аватар пользователя Sinkora Sinkora 26 апреля 2010 в 4:23

Кстати, да. У меня как раз и была мысль, что это сделано для совместимости с другими СУБД.
Но если делаешь для себя, и знаешь, что будет работать только в Мускуле, то вполне актуально...

Хотя ТС как раз и указал, что имеет в виду MySql...