Data Base API

Опубликовано 2012.04.14

API для работы с БД в Drupal 7. На мой взгляд – это самое лучшее API. Поначалу оно может показаться сложным и непонятным. Для работы с БД вы должны понимать, что такое SQL запросы и уметь их писать.  Drupal 7 понимает как обыкновенные SQL запросы(как в Drupal 6), так и построенные с помощью API.

Вы также можете почитать на эту тему статью, описывающую работу с БД в Drupal 7.

Начнем с простого select.

Извлечём nid всех нод с типом page.

  1. //подключаемся к таблице.обязательно даём ей псевдоним
  2. $q=db_select('node','n');
  3. //задаем условие выборки
  4. $q->condition('n.type','page');
  5. //выбираем нужные нам поля
  6. $q->fields('n',array('nid'));
  7. //отрабатываем запрос
  8. $res=$q->execute();

Теперь применим к переменной res метод fetchAssoc, который выведет результат запроса в виде ассоциативного массива. Код будет выглядеть вот так.

  1. //подключаемся к таблице.обязательно даём ей псевдоним
  2. $q=db_select('node','n');
  3. //задаем условие выборки
  4. $q->condition('n.type','page');
  5. //выбираем нужные нам поля
  6. $q->fields('n',array('nid'));
  7. //отрабатываем запрос
  8. $res=$q->execute();
  9.  
  10. //выводим результат запроса
  11. while($rec=$res->fetchAssoc()){
  12. echo $rec['nic'].'<br />';
  13. }

Как видите – каждый оператор запроса является обращением к определённому свойству объекта запроса. Если в запросе нужно обратиться к нескольким таблицам, то у каждой таблицы будет свой псевдоним. И при обращении к методу fields будет указываться псевдоним таблицы, а вторым аргументом этого метода будет массив с именами полей таблицы.

Давайте напишем более сложный запрос. Приджоиним к запросу таблицу пользователей и выведем автора ноды. Используем метод leftJoin.

  1. //подключаемся к таблице.обязательно даём ей псевдоним
  2. $q=db_select('node','n');
  3. //задаем условие выборки
  4. $q->condition('n.type','page');
  5. //выбираем нужные нам поля
  6. $q->fields('n',array('nid'));
  7.  
  8. //приджоиним таблицу пользователей
  9. $q->leftJoin('users','u','u.uid=n.uid');
  10. $q->fields('u',array('name'));
  11.  
  12. //отрабатываем запрос
  13. $res=$q->execute();
  14.  
  15. //выводим результат запроса
  16. while($rec=$res->fetchAssoc()){
  17. echo $rec['nic'].' -> '.$rec['name'].'<br />';
  18. }

У метода leftJoin 3 аргумента – имя таблицы, её псевдоним и условие. Обратите внимание, в условии оператора нет слова on.

Также вы заметили, что порядок операторов в запросе не оказывает никакого влияния на работу запроса. То есть если в ваш запрос входят операторы order, group, where, having, несколько join и т.д. – то вам абсолютно не важно в каком порядке их писать. Построитель запросов сам их упорядочит и сформируем запрос с которым обратится к БД. Такая форма написания запроса будет кроссплатформенной. Если у Drupal есть драйвер к БД, например MS SQL – то Drupal сам напишет запрос. Который подойдет к этому типу БД, так как некоторые запросы будут выглядеть по-разному.

Также легко вывести запрос на экран. Для этого следует написать такой код.

  1. echo (string)$q;

Такая конструкция выведет следующее.

  1. SELECT n.nid AS nid, u.name AS name FROM {node} n LEFT OUTER JOIN {users} u ON u.uid=n.uid WHERE (n.type = :db_condition_placeholder_0)

Как видите, названия таблиц уже обернуты в кавычки, и такой запрос будет работать с таблицами с префиксами.

Опираясь на такое API можно написать фактически любой запрос. Давайте сделаем апдейт таблицы.

  1. $q=db_update('node');
  2. $q->condition('type','page');
  3. $q->fields(array('type' => 'type-1','uid'=>10));
  4. $q->execute();

Такой запрос проапдейдит таблицу node, установив значение поля type равным type-1 и установит автором пользователя с uid равным 10. Данный запрос сработает для строк с полем type равным page.

Для удаления строк можно использовать оператор db_delete. Для вставки строк db_insert.

А теперь составим сложный запрос. В нём почти 20 строк. Составить такой запрос несложно и очень удобно понять, как сработает данный запрос, просто посмотрев на код.

  1. // соединение с бд,подключение пагинации
  2. $q=db_select('custom_sessionss','s')->extend('PagerDefault');
  3.  
  4. //джоиним таблицы
  5. $q->leftjoin('custom_videos', 'v', 's.videoid = v.id');
  6. $q->leftjoin('custom_guid','ng','ng.guid=v.avsurl');
  7. $q->leftjoin('node', 'n', 'n.nid = ng.nid');
  8.  
  9. //условия
  10. $q->condition('s.playerid',$player_list,'=');
  11. $q->condition('s.datetimestart',$day_first_int,'>');
  12. $q->condition('s.datetimestart',$day_end_int,'<');
  13. $q->condition('n.title','','<>');
  14.  
  15. //извлекаемые поля
  16. $q->fields('s',array('videoid'));
  17. $q->fields('v',array('avsurl'));
  18. $q->fields('n',array('title'));
  19.  
  20. $q->addExpression('count(*)','views');
  21. $q->addExpression('count(distinct s.userid)','uniques');
  22.  
  23. //группировки
  24. $q->groupBy('s.videoid');
  25. $q->groupBy('v.avsurl');
  26. $q->groupBy('n.title');
  27.  
  28. //сортировки
  29. $q->orderBy('views','desc');
  30. $q->orderBy('uniques','desc');
  31.  
  32. //выполнение запроса
  33. $res=$q->limit(20)->execute();
  34. </');>

В этом запросе есть условия больше, меньше, равно и не равно. Если оператор условия не стоит-то по умолчанию он будет считаться как знак равенства. Также посчитано количество строк оператором count. Есть группировки и сортировки.

В этом запросе группировки и сортировки можно было бы уместить в двух(вместо текущих 5) вызовах методов groupBy и orderBy, но такой запрос сработал бы только в MySQL. Данная форма более кроссплатформенна и сработает и в других типах БД.