TIP: Use Markdown or, <pre> for multi line code blocks / <code> for inline code.
These forums are read-only and for archival purposes only!
Please join our new forums at discourse.kohanaframework.org
Added support multiple operators and multiple conditions in query builder
  • Мной добавлена поддержка выражений для построителя запросов к Базе Данных вида:
    ->or_where('number', array('<','>'), array('10', '50'))

    Пул висит уже два дня, и судя по активности их обработки - может провисеть еще пару месяцев. Мне охота уже услышать мнения по этому поводу.

    P.S. Чтобы протестить у себя этот код, можно его добавить в APPPATH/classes/Database/Query/Builder.php
  • основной багтрекер тут http://dev.kohanaframework.org. серьезные правки в коде лучше снабжать тестами.


    // ->or_where('number', array('='), array('10', '20', '30'))
    // Note: arrays are of unequal length, and usage or_where()
    // Will output:
    // `number` = '10'
    // OR `number` = '20'
    // OR `number` = '30'

    // ->or_where('number', array('in'), array(10, 50))
    // Note: arrays are of unequal length, and usage operator IN
    // Will output:
    // `number` IN (10, 50)

    вот это одно и тоже и второй вариант явно лучше.


    // ->or_where('number', array('in', '>', '<'), array(array(10, 50), 60, 2))<br />// Note: usage operator IN
    // Will output:
    // `number` IN (10, 50)
    // OR `number` > 60
    // OR `number` < 2

    слишком мутная конструкция.

    зачем в sql запросах переносы строк?
  • А зачем это все? Приведенный вариант плохо читается, остальные тоже. Ради сокращения в пару символов Вы предлагаете усложнить код?

    Или кроме сокращения, есть какие-то условия, которые невозможно реализовать сейчас?
  • @like_you, а чем не устраивает "not in"?
  • @Ramallah а как как с помощью "not in" сделать `number` > 60 OR `number` < 100 ? о_0
  • @WinterSilence, по поводу примеров работы построителя - конечно же правильнее написать в IN набор цифр, чем перечислять их с помощью OR. Мне важнее было показать "что на входе и что на выходе", чем рационально ли именно такое выражение строить.
    По поводу ->or_where('number', array('in', '>', '<'), array(array(10, 50), 60, 2)) как "слишком мутной конструкции" - ну не знаю, мне достаточно все просто понять - для IN ожидается массив, для всех других операторов строка.

    @biakaveron, вы имеете ввиду, что вместо
    ->or_where('number', array('in', '>', '<'), array(array(10, 50), 60, 2))<br />


    написать более читабильную конструкцию:

    ->or_where('number', 'in', array(10, 50))
    ->or_where('number', '>', 60)
    ->or_where('number', '<', 2)<br />

    Так? А как на счет, если количество входящих параметров неизвестно? Сооружать цикл?

    Я написал это дополнение, когда как раз стала задача: юзер отмечает неопределенное количество чекбоксов, исходя с которых нужно динамически формировать запрос к БД.
    Можно, конечно, каждому параметру найти свое место, но мне показалось более логичнее передавать построителю масив параметров...
  • Сократил код, исправил баги.
    APPPATH/classes/Database/Query/Builder.php
  • >> @Ramallah а как как с помощью "not in" сделать `number` > 60 OR `number` < 100 ? о_0

    А для этого between есть.
  • @Ramallah between допускает только "между", но не "за рамками".
    По поводу вашего "а чем не устраивает "not in" - его нельзя применять, например, с оператором LIKE...

    В общем, выгода от построителя запросов состоит только в том, что можно не беспокоится "есть или нет" значение в переменных для него. Он автоматически исключает части запроса, для которых нет значений переменных. За это отвечают 9 классов в Kohana 3.3.

    В общем, выгода от моих нововведений, как я выше упоминал, состоит только в том, что теперь можно не беспокоится за "количество передаваемых параметров". Для этого код одного из классов увеличился на 61 строку (вместе с комментариями).

    Update:
    • "За рамками" between можно использовать not between, но все равно есть ограничение - строго две границы.
    • Kohana не "исключает автоматически части запроса, для которых нет значений переменных", но в коде программы легко спрятать кусок запроса в блок if() {..} (Кстати надо подумать можно ли легко добавить именно автоматическое исключение, о котором я сначала говорил)
  • @Ramallah o! пасиб, не знал.
  • @WinterSilence, на здоровье.

    @like_you, ИМХО пример использования очень специфический, так у меня есть такой кусок специфики:


    /**
    * Добавление дополнительного массива условий.
    * Используется, когда необходимо добавить дополнительные условия массивом.
    *
    * $terms = array(array('id','=',10),array('name','=','petro');
    * $result = ORM::factory('Example')->groupWhere($terms);
    *

    *
    * @param Array $terms
    * @return $this
    * @autor Ramallah
    */
    public function groupWhere(Array $terms) {
    foreach ($terms as $term)
    $this->where($term[0], $term[1], $term[2]);
    return $this;
    }


    Значительно полезнее описать CASE к примеру. Вот пример костыля, уже и не помню где использовался, но штука разовая была.


    /**
    * Реализация CASE для MySQL
    *
    * @param $data
    * @autor Ramallah
    */
    public function cases($column, $datas, $keys, $name) {
    if (is_array($datas)) {
    $query = array();
    foreach ($datas as $data) {
    $query[] = "WHEN {$data[$keys[0]]} THEN {$data[$keys[1]]}";
    }

    $query = 'CASE ' . $column . ' ' . implode(' ', $query) . ' END ' . $name;
    $this->select(DB::expr($query));
    }
    return $this;
    }
  • @Ramallah, если вы намекаете на простоте решения вопроса с массивами, то я с вами в этом согласен. Я не придумал новой формулы - всего лишь немного сократил работу програмерам Кохана. По поводу вашего метода groupWhere() - если это разширение Кохановского построителя, то вы описали только один из вариантов использования where(), но есть еще or_where(), having(), or_having, где также используется предложенный мной вариант. А если еще дописать фичу "розтягивания" оператора сравнения, которую я реализовал, то станет более полная картина.

    По поводу специфичности, то, честно говоря, меня удивляет почему этого ещё до меня никто не реализовал. Хотя может это потому, что по роду своей деятельности (построение разных отчетов в банковской сфере) я привык работать со сложными отчетами, которые будут тяжелыми для их веб-реализации...

    Да, и кстати, по поводу отсутствия CASE в построителе, я бы это тоже назвал странным...

    Я вот подумую сейчас как бы объединить динамический запрос со статическим. Пока что не увидел, что есть готовое решение.
  • >> По поводу специфичности, то, честно говоря, меня удивляет почему этого ещё до меня никто не реализовал. Хотя может это потому, что по роду своей деятельности (построение разных отчетов в банковской сфере) я привык работать со сложными отчетами, которые будут тяжелыми для их веб-реализации.

    Если сложные запросы, то не лучше ли создавать базовое представление в БД, а потом усекать до необходимого уже построителем?

    И ясное дело, что Kohana это базовый фреймворк, который имеет возможности расчудеснейшого расширения и примантулить что-то необходимое для крупного проекта не составляет труда.

    Поэтому сколько человеческих желаний, столько и решений )

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion