livestreet-framework
livestreet-framework copied to clipboard
Есть такое в ORM?
Возможно уже каким-то образом есть, но вот так на первый взгляд не вижу: хотелось бы группировок условий AND и OR в условии #where для ORM
Сейчас такая конструкция:
$aFilter['#where'] = array(
'creator_id=?' => array(10),
'status=?' => array(2),
);
результирует в условие creator_id=10 AND status=2, предлагаю добавить конструкцию
$aFilter['#where'] = array(
array(
'creator_id=?' => array(10),
'status=?' => array(2),
),
array(
'status=?' => array(1),
)
);
которая бы результировала в условие (creator_id=10 AND status=2) OR (status=1)
И дальше рекурсивно по иерархии:
array(
'creator_id=?' => array(10),
'status=?' => array(2),
array(
array(
'price>?' => array(100)
),
array(
'price=?' > array(0)
)
)
),
array(
'status=?' => array(1),
)
условие (creator_id=10 AND status=2 AND ((price>100) OR (price=0))) OR (status=1)
Это все позволит формировать комплексные динамические запросы используя все тот же движок ORM со всеми его остальными вкусностями.
Да, и еще добавить какой-нибудь #-ключ для задания дополнительные тегов кэша.
На самом деле его можно вот так использовать:
$aFilter['#where']=array('(creator_id=? AND status=? AND ((price>?) OR (price=?))) OR status=?' => array(10,2,100,0,1));
Нет-нет, идея в том, что бы можно было формировать фильтр последовательно и динамично по критериям, что-то подобное функционалу buildFilter в мэппере топиков, только для ORM и с гарантированным нормальным экранированием.
Можно не писать так:
$aFilter['#where'] = array(
'creator_id=?' => array(10),
'status=?' => array(2),
);
а так:
$aFilter['#where'] = array(
'creator_id' => 10,
'status' => 2,
);
в этом плане орм лс гибок.
Это все позволит формировать комплексные динамические запросы используя все тот же движок ORM со всеми его остальными вкусностями.
но не совсем интуитивно понятно что это будет "ИЛИ"
Да, и еще добавить какой-нибудь #-ключ для задания дополнительные тегов кэша.
не совсем понял, есть же #cache
и с гарантированным нормальным экранированием.
то, что показал Максим - гарантировано экранируется.
а так:
я специально максимально параметризированную одинаковую запись использовал
но не совсем интуитивно понятно что это будет "ИЛИ"
Я не знаю, как еще сделать это более интуитивно понятно, но на мой взгляд и так все хорошо - если ключ у элемента массива не числовой - значит условие И, если числовой - ИЛИ
не совсем понял, есть же #cache
Если использовать #cache то надо и стандартные теги на сохранение и удаление в нем задавать, а это дополнительный лишний код для их формирования. А вот именно дополнительные ключи было бы лучше
то, что показал Максим - гарантировано экранируется.
Это понятно. Идея же в стандартном механизме динамического формирования, чтобы каждый использовал его, а не изгалялся как хочет.
Я не знаю, как еще сделать это более интуитивно понятно
Единственное, что мне приходит в голову это сделать такую запись, что:
Если ключ элемента массива числовой - это "скобки" и тогда первым элементом массива можно указать, что условие OR, если первый элемент не OR, то считать, что перед скобками условие AND. Если не числовой то это тоже самое, что и сейчас, т.е. как-то так.
$aFilter = array(
'#where' => array(
array(
'creator_id=?' => array(10),
'status=?' => array(2),
array(
array(
'price>?' => array(100)
),
array(
'OR',
'price=?' > array(0)
)
),
),
array(
'OR',
'status=?' => array(1),
)
)
);
преобразуется в запись
AND (creator_id=10 AND status=2 AND ((price>100) OR (price=0))) OR (status=1)
В предыдущем варианте синтаксиса было плохо с объединением условий AND в группы, т.е. задать такое условие было проблематично:
((status=0 and sum>100) and (status=2 and sum<=100)) or (status=1)
Понятно, что внутренние скобки тут выглядят искусственное, но речь ведь идет о динамическом формировании запроса, и это вполне реальная ситуация.
Подумал, что вот такая реализация будет чище и интуитивно понятней:
$aFilter = array(
'#where' => array(
array(
'creator_id=?' => array(10),
'status=?' => array(2),
array(
'price>?' => array(100),
'#or price=?' > array(0),
)
),
),
array(
'#or status=?' => array(1),
)
)
);
Получается:
AND (creator_id=10 AND status=2 AND (price>100 OR price=0)) OR (status=1)
Т.е. array внутри это скобки, если ключ-условие начинается с #or - надо объединять с OR, и если это первый ключ в массиве-скобках, то и перед скобками ставится OR.