Как я могу смешать OR и AND в запросах ORM - PullRequest
0 голосов
/ 30 июня 2010

Я занимаюсь разработкой сайта с использованием Kohana 2.3 и у меня возникли проблемы с конкретным запросом ORM.По сути, я делаю следующий запрос

SELECT *
   FROM 'records'
   WHERE ('ServRepSupervisor' = name AND 'Followup_read' = 0) OR ('ServRepSupervisor' = name AND `read` = 0)

, когда я пытаюсь выполнить запрос ORM следующим образом ...

$unread = ORM::factory('record')
   ->where(array('ServRepSupervisor' => Auth::instance()->get_user()->name, 'Followup_read' => 0))
   ->orwhere(array('ServRepSupervisor' => Auth::instance()->get_user()->name, 'read' => 0))
   ->find_all();

запрос, с которым я получаю в итоге:

SELECT `records`.*
   FROM (`records`)
   WHERE `ServRepSupervisor` = 'name' AND `Followup_read` = 0
   OR `ServRepSupervisor` = 'name'
   OR `read` = 0

Как я могу переработать этот запрос ORM для получения желаемого результата?

РЕДАКТИРОВАТЬ: мне удалось заставить его работать, но это не выглядит как очень элегантное решение.

$unread = ORM::factory('record')
   ->where('(\'ServRepSupervisor\' = \'' . Auth::instance()->get_user()->name . '\' AND \'Followup_read\' = 0) OR (\'ServRepSupervisor\' = \'' . Auth::instance()->get_user()->name . '\' AND \'read\' = 0)')
   ->find_all();

Это возвращает набор данных, который я хочу, но это просто уродливый код.Должен быть лучший способ сделать это.

Ответы [ 3 ]

1 голос
/ 02 июля 2010

Ну, после небольшого исследования я нашел патч для изменения ORM KO2, чтобы иметь open_paren () и close_paren (), но поведение по умолчанию orwhere в KO2 не разрешает желаемую операцию, поэтому парены не помогут мне.Я смирился с тем, что подробный метод where (), который я использую, является лучшим вариантом для меня, учитывая мои временные ограничения.Я немного изменил запрос, чтобы учесть некоторые особенности в моем экземпляре mysql.

Это работает и является окончательным запросом для этого проекта.

$unread = ORM::factory('record')
   ->where('(ServRepSupervisor = \'' . Auth::instance()->get_user()->name . '\' AND Followup_read = 0) OR (ServRepSupervisor = \'' . Auth::instance()->get_user()->name . '\' AND records.read = 0)')
   ->find_all();
0 голосов
/ 13 мая 2019

При использовании Kohana 2 вы можете сделать следующее:

в файле system/libraries/ORM.php:223 внутри __call() добавить 'or_open_paren' в массиве в

if (in_array($method, array('open_paren', 'close_paren', 'enable_cache', 'disable_cache'))) {

или, если этот файл еще не исправлен, измените case 0:, чтобы он выглядел следующим образом:

case 0:
    if (in_array($method, array('open_paren', 'or_open_paren', 'close_paren', 'enable_cache', 'disable_cache'))) {
        $this->db->$method();
    } else {
        return $this->db->$method();
    }
break;

добавить следующий код к system/libraries/Database.php

public function open_paren()
{
    $this->where[] = $this->get_where_count() ? 'AND (' : '(';
    return $this;
}
public function or_open_paren()
{
    $this->where[] = $this->get_where_count() ? 'OR (' : '(';
    return $this;
}
public function close_paren()
{
    $this->where[] = ')';
    return $this;
}
protected function get_where_count()
{
    $lastWhen = end($this->where);
    if ( $lastWhen === false )
        return 0;
    $lastWhen = trim( str_replace( array('AND ', 'OR '), '', $lastWhen ) );
    return $lastWhen === '(' ? 0 : count($this->where);
}

и замените все экземпляры count($this->where) на $this->get_where_count() в том же файле, за исключением нового метода get_where_count() (очевидно) и метода delete($table, $where) (всего 11 замен).

0 голосов
/ 01 июля 2010

ko3 имеет такие методы, как ->where_open() и ->where_close(), ko2 не

, поэтому это лучшее решение

ps: я бы кешировал пользователя, кстати

$current_user = Auth::instance()->get_user();
...