Какой формат именованного типизованного плейсхолдера выбрать?

Фанат

oncle terrible
Команда форума
От избалованных PDO пользователей я довольно часто получаю запросы на добавление поддержки именованных плейсхолдеров.

Самому мне идея типизованных плейсхолдеров кажется надуманной, поскольку выражение "last_name = ?s" уже поименовано, и писать мало масляное "last_name = :last_name" я не вижу смысла. Но количество желающих не уменьшается, и поэтому я решил-таки прогнуться.

Но как-то мне никакой формат из приходящих в голову не нравится.
Я так понимаю, что знак препинания, стоящий после пробела (? и : ) выбран не случайно. И поэтому я не уверен, что "a:name" не будет ни с чем конфликтовать. Или пофиг?

Какой формат подошел бы тебе, юзернейм?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
a:name
писать мало масляное "last_name = :last_name" я не вижу смысла.
у нас для вывода каталога Criteria формируется в 2 этапа: общий код с join-ами и where-условиями, которые используются во многих методах модели, и дополнительный код, который нужен в конкретном запросе.
(Criteria - объект деталей и параметров запроса в Yii, по которому формируется sql.)

Общая часть - это, например:
PHP:
            $criteria->addCondition('`t`.product_id = :product_id');
            $criteria->params += array(':product_id'=>$params['product_id']);

            $criteria->join .= ' LEFT JOIN {{category_x_product}} as cxp ON `t`.product_id = `cxp`.product_id';
            $criteria->addCondition('`cxp`.category_id = :category_id');
            $criteria->addCondition('`cxp`.is_deleted = 0');
            $criteria->params += array(':category_id' => $params['category_id']);
здесь нельзя заменить :category_id и : product_id на ?i ?i - мы не знаем какие еще появятся параметры и в каком порядке они будут заданы
 

ksnk

прохожий
А избалованные PDO пользователи, с большой вероятностью не захотят ли такой же вид биндженного значения? С теми же bindParam'ами? Тогда и менять формат не нужно. Тип параметра и так есть - он указывается юзером вручную.
 

Фанат

oncle terrible
Команда форума
биндженного значения? С теми же bindParam'ами?
Не-не-не, Девид Блейн.
Вся соль типизованного плейсголдера в том, что никаких простыней из bindParam у нас нету.
кто хочет - может продолжать пользоваться пдошечкой же. Ну, заекстендив её на пару типов только
 

ksnk

прохожий
Фанат
А как тогда будет выглядеть использование такого поименованного параметра для юзера? Ну, вот с нумерованными паметрами я могу себе вообразить, они перечисляютcя после запроса при вызове, а имена откуда возмутся?
 

ksnk

прохожий
grigori Юзер - это тот, кто использует. PDOшный юзер указывает значение именованого параметра с помощю bindParam. И после указания имеет право использовать :name в нужных местах запроса. А как представляет себе Фанат способ указания такого значения, без использования bindParam? Вот это мне непонятно.
Сейчас все параметры запроса передаются при вызове, sql-первый, параметры следом.
 

Фанат

oncle terrible
Команда форума
Фанат
А как тогда будет выглядеть использование такого поименованного параметра для юзера?
Это как раз проблема.
Видимо, дубли функций придется писать, чтобы принимали не список параметров, а массив. Что-то вроде
PHP:
rawGetArr($query,$params);
или, пошли они все нафиг - сделать одну функцию
PHP:
run($type,$query,$params);
я все равно собирался её сделать, и переписать хелперы на её исползование.
 

Фанат

oncle terrible
Команда форума
Кстати, можно как-то этот рег оптимизировать?
PHP:
(\?[nsiuap]|[nsiuap]:[a-z_])
 

ksnk

прохожий
В бинде есть таки приятная фенечка. Можно один раз забиндить переменную и использовать ее в нескольких запросах. Так что совсем от него отказываться, вообще говоря, неправильно.
Другое дело, что в Pdo навводили идиотских ограничений на неиспользование параметров в именах столбцов и таблиц. Как бы понятно, что это оттого, что имена столбцов могут быть комбинациями из любых символов (в том числе и с : и вопросиком и ), и они просто поленились на эту тему подумать. Вот Котеров, к примеру, не парсит отквоченные '' "" `` значения и все какбы в порядке.

Как вариант -
PHP:
(\??[nsiuap](?::[a-z_])?)
В виде ?s:name получается автоматический бинд. Не?
 

ksnk

прохожий
Регулярка с ошибкой :( без разных вариантов, видимо, не обойтись
 

ksnk

прохожий
Это требуется 1 раз на 1000 запросов
А забиндить имя таблицы никогда не хотелось? Это не ПДО, тут можно было бы ;) В любом случае - пользователи скажут нужно или нет.

или, пошли они все нафиг - сделать одну функцию
Пользователям тоже переписывать все свои запросы? Не! Путь истинного джедая - не навредить существующему у юзера коду ;)
 

Absinthe

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

Более того при сложных запросах (> 20 строк) сложно уследить за порядком неименованных.

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

P.S. Можно ссылку на библиотеку? Посмотреть хочу.
 
  • Like
Реакции: AmdY

Фанат

oncle terrible
Команда форума
P.S. Можно ссылку на библиотеку? Посмотреть хочу.
Да ладно. Не говори что не видел. Её же тут обсасывали до костей, и даже сплагиатили не раз :)
Вот, кстати, иссуй, который пару дней назад оживили, с теми же самыми формулировками: https://github.com/colshrapnel/safemysql/issues/8#issuecomment-19760435

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

Фанат

oncle terrible
Команда форума
Пользователям тоже переписывать все свои запросы?
при чем здесь запросы? Речь идет о вызове функции АПИ с функционалом, которого до сих пор еще не было.
поэтому переписывать ничего не придется.
а любители именованных вместо наборе хелпер-функций нехай юзают одну. или екстендят класс и добавляют свои собственные. Потому что у меня от размыышений, как назвать второй набор функций, голова пухнет.
 

hell0w0rd

Продвинутый новичок
Для подобного как мне кажется нужен querybuilder, но простота библиотеки тогда уменьшается)
 

Absinthe

жожо
Для подобного как мне кажется нужен querybuilder
Для подобного чего?
С QB все равно нельзя написать сложные запросы, для которых именованные параметры и нужны.

Библиотеку посмотрел - не увидел в ней следующего:
У меня есть проект. Он нормально работает на pdo или другой библиотеке на нем основанной, к прмеру DBAL.
Из-за того, что интерфейс твоей библиотеки не тот же, что и у pdo, я не могу прозрачно заменить ее.
Поэтому и не могу использовать.

Вопрос: почему не был унаследован pdo?
 

Фанат

oncle terrible
Команда форума
Вопрос: почему не был унаследован pdo?
Ну, в первую очередь потому, что ПДО - фигня на палочке и недоделка. Проще новых нарожать, чем этих отмыть.
Ты не пробовал, кстати, наследовать ПДО? Увлекательное занятие.

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

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

Но вообще идея интересная, я её думаю. Взялся даже ПДО екстендить - но обломался.
 

Фанат

oncle terrible
Команда форума
Для подобного как мне кажется нужен querybuilder, но простота библиотеки тогда уменьшается)
На самом деле, надо просто сделать ядро-парсер. А потом его всраивать уже хоть в отдельную либу, хоть в кверибилдер. Кверибилдеру, между прочим, поддержка типизованных плейсхолдеров тоже совсем не помешает. Мы сейчас планируем ее впендюрить в свой форк йи.
 
Сверху