Парсинг плейсхолдеров strikes back

Фанат

oncle terrible
Команда форума
Я тут все думаю, как бы забацть новую версию.
С учетом всех тех доработок, которые были сделаны и предложены

Что хочется сделать:

1. поддержку именованных плейсхолдеров
2. плейсхолдер без типа, по дефолту - строка
3. Обозначение типа не только буквой но и словом.
4. поддержку родных препаредов, транслируя, по возможности, именованные в родные, как это делает ПДО.
5. Отдельный плейсхолдер все-таки, для белых спысков. Который на вход принимает массив - само значение и массив вариантов.
6. выкинуть все "массивные" плейсхолдеры, добавив простой синтаксис для повторения (не помню, у кого идею подсмотрел, но она все больше и больше нравится). Скорее всего - уже стандартные для пхп квадратные скобки:
PHP:
SELECT [?n] FROM ?n WHERE id IN ([?i])
UPDATE t SET [?n = ?s]
INSERT INTO t (field, [?n]) VALUES (?f, [?s])
7. разделение класса на части: отдельно парсер, отдельно основной класс, отдельно стейтмент. И только потом понаписать хелперов-однострочников. А не как сейчас, когда весь класс только из них и состоит.
Чтобы можно было множественное execute() для родных препаредов. B чтобы внутри функции не переписывать список параметров вручную, как сейчас.
Чтобы было этакое API, которое можно было бы вызывать как напрямую, так и послужило бы базой для хелперов. или даже вообще без них обойтись, сделав method-chaining:
PHP:
$sql  = "SELECT [?n] FROM table WHERE id IN ([?i])"
$data = DB::parse($sql)->execute($fieldlist, $ids)->fetchAll();
Хотя нет, наверное. Однострочники все равно нужны. Но именно как сахар, а не как основа.

В топик призываются все неравнодушные, а так же авторы собственных классов (которым я безмерно благодарен - не ожидал, если честно, что идея получит такую широкую поддержку и развитие) - обсудить идеи и предложить свои. Я, скорее всего, что-то пропустил из отличных идей. Ну, и критика приветствуется.
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Вот даже форумный парсер дразнится, что статики - жопа :)
Я, в общем, не настаиваю. Если прям все-провсе классами, то не нужно. А для классического говнокода волне годно и статик.
 

hell0w0rd

Продвинутый новичок
На мой взгляд не нужен спец синтаксис для массивов.
PHP:
$db->query('UPDATE users u SET u.active = false WHERE u.id IN (i:ids)', ['ids' => [1,2,3]]);
 

Фанат

oncle terrible
Команда форума
На мой взгляд не нужен спец синтаксис для массивов.
PHP:
$db->query('UPDATE users u SET u.active = false WHERE u.id IN (i:ids)', ['ids' => [1,2,3]]);
Ну, с одной стороны, это противоречит моим принципам (не допускать никакой магии).
С другой - это наоборот, следует другому моему принципу (максимально простой синтаксис)
С третьей - остается выражение типа
Код:
SET [?n = ?s]
Но оно все равно выбивается из общего ряда - это же получается вообще не плейсхолдер, а комплексное выражение. которое и именованным даже не сделаешь (без дальнейшего усложнения синтаксиса)

Так что наверное ты прав.
Стоит все-таки определять по массиву, а для SET оставить таки плейсхолдер
 
Последнее редактирование:

riff

Новичок
- поддержку именованных плейсхолдеров
Дежавю. Делал, делал, вдруг опять всплывает "надо сделать" ?

А что за новая "фишка" с квадратными скобками? (Я честно не понял. Что-то с массивами, а почему скобки?)

добавив простой синтаксис для повторения
Можно пример о чём идёт речь?

- разделение класса на части: отдельно парсер, отдельно основной класс...
(imho) В своём (переделанном из темы "Пятница. ... Парсинг плейхолдеров") разделять не буду. Мне очень удобно, когда класс получает все данные, и по окончании выплёвывает результат, без лишних ->ещё_это->и_вот_это. (Я, как писал в одном из последних сообщений в той теме, расширил (extends) базовый класс mysqli_result (лень лезть вспоминать, кажется он так называется), добавив пару удобных функций.)

Зачем тут нужны статики? Пользы нет, проблемы есть.
Пользуюсь статичным вариантом (DB::query(...)->get), просто замечательно. "Не представляю" как таскать по всюду переменную $db.
(нет-нет, а иногда скажу мысленно: "ну почему было не сделать define(), принимающую класс...")

$db->query('UPDATE users u SET u.active = false WHERE u.id IN (i:ids)', ['ids' => [1,2,3]]);
Я думаю убрать у себя плейсхолдеры означающие массивы. Достаточно того, что в значениях передаётся массив.

DB::parse($sql)->execute($fieldlist, $ids)->...
В качестве наброска идеи для множественных execute (или ещё для чего):
DB::parse($sql, 'UniqueQueryName'); //здесь подготавливаем запрс
И потом в любом месте можно будет делать так:
DB::query('UniqueQueryName')->execute($fieldlist, $ids)->... //а здесь обращаемся за подготовленным запросом по имени
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Дежавю. Делал, делал, вдруг опять всплывает "надо сделать" ?
Ну, ты сделал, а у меня-то нет :)
А что за новая "фишка" с квадратными скобками? (Я честно не понял.)
Автоматическое размножение. То, что в квадратных скобках, требует массива на вход, и имплодится через запятую. Но вот hell0w0rd предлагает вовсе от них отказаться и размножать просто если пришел массив. Так что в итоге я тоже склоняюсь к тому, чтобы
Я думаю убрать плейсхолдеры означающие массивы. Достаточно того, что в значениях передаётся массив.
В своём (переделанном из темы "Пятница. ... Парсинг плейхолдеров") разделять не буду.
Разделение нужно. Если перечитать мою аргументацию внимательно, должно быть ясно, о чем речь. Я там написал, что не собираюсь отказываться от хелперов-однострочников. Но бывают ситуации, когда они не годятся. Поэтому вместо двух слоев,
1 - "голый API mysql"
2 - хелперы
должен появиться третий:
1 - "голый API mysql"
2 - API всех фишек - с парсером, с возвращением результата, и пр. Чтобы придать гибкость и расширяемость.
3 - а потом уже на основе (2) сделать хелперы.
В качестве наброска идеи для множественных execute (или ещё для чего):
не. Мне кажется, стандартный подход лучше.
 

fixxxer

К.О.
Партнер клуба
Квадратные скобочки ставят крест на возможности использования парсера (который вроде выносим отдельно от коннектора) с mssql. ;)
 

Фанат

oncle terrible
Команда форума
Квадратные скобочки ставят крест на возможности использования парсера (который вроде выносим отдельно от коннектора) с mssql. ;)
Ну тогда тем более - поставим крест на них :)
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Позволю себе напомнить одну идею.
Вот кстати да.
Мне опять нравится.
Просто я надолго отвлекся от темы, и как раз и создал этот топик чтобы, в частности, как раз собрать все хорошие идеи, которые уже звучали.

Но в любом случае хочется широкого обсуждения. Вот fixxxer упомянул про ограничения квадратных скобок. Не будет ли предложенный синтаксис чему-то мешать? В частности, ?i может легко отлепиться от :time, которое тоже полноценный плейсхолдер, но уже строкового, по умолчанию, типа. Хотя если запрещать смешивание позиционных и именованных - то ничего.. Хотя это вот последнее - тоже вопрос для обсуждения...
 

riff

Новичок
Хотя если запрещать смешивание позиционных и именованных - то ничего.. Хотя это вот последнее - тоже вопрос для обсуждения..
Лично для меня, это не вопрос для обсуждения :)
Если бы не было разделения "или позиц. или инен.", я бы уже столько ошибок наделал. (то забудешь, то пропустишь).
Оставляю позиц. в коротеньких запросах, имен. в тяжёлых.

В частности, ?i может легко отлепиться от :time, которое тоже полноценный плейсхолдер
Я сделал всё только через "?", никаких :time без "?".
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Я сделал всё только через "?", никаких :time без "?".
Ну, дело в том, что УЖАСНО хочется оставить :time, со строковым типом по дефолту.
Ты не представляешь, как сильно этого хотят пользователи ПДО, чтобы им запросы не перепиписывать.

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

hell0w0rd

Продвинутый новичок
Не понимаю, если честно, чем неименованные плейсхолдеры полезны. Я у себя вообще их выкинуть хочу.
Всетаки когда смотришь, что биндишь - все предельно ясно, в случае с безымянными приходится заглядывать в SQL, чтобы понять о чем речь.

Фанат, ты уже хочешь написать FanatQueryLanguage, а мне кажется это плохо для простой либы.
Можно прикрутить обрывки query-builder'a.
Я посматриваю на https://github.com/jstayton/Miner - все довольно просто и удобно, за исключением сложных условий
->openWhere(Miner::LOGICAL_OR)
Вот эти конструкции мне всегда не нравились - если их переписать на колбеки и добавить именованные плейсхолдеры - цены такой библиотеке не будет:)
 

Фанат

oncle terrible
Команда форума
Не понимаю, если честно, чем неименованные плейсхолдеры полезны. Я у себя вообще их выкинуть хочу.
Еще со времён, когда я работал в армии машинисткой, меня просто убивает необходимость писать одно и то же.
Ср.:
Код:
$sql ="SELECT * FROM table WHERE foo=:foo AND bar=:baz";
$data = DB::getAll($sql, array('foo'=>$foo,'bar'=>$bar));
и
Код:
$sql ="SELECT * FROM table WHERE foo=? AND bar=?";
$data = DB::getAll($sql, array($foo, $baz));
или вот ещё пример
Код:
public function register($name, $email, $password) {
}
С позиционными это будет одно обращение к апи.
А брать каждую переменную и старательно засовываь её сначала в массив - выглядит как-то глупо.
И даже compact() не особо скрашивает вид.

Учитывая же, что имя переменной обычно совпадает с именем поля, скажи пожалуйста, так ли тебе действительно тяжело, какая переменная биндится к какому полю:
Код:
$sql ="SELECT * FROM table WHERE foo=? AND bar=?";
В любом случае, это вообще не тема для обсуждения. Зачем что-то ограничивать на пустом месте? Сделать и те и другие - не проблема. Пусть будут оба варианта - это никому не мешает. Не тот вопрос, мне кажется, об который стоит копья ломать. Там много других, посложнее :)
 

Фанат

oncle terrible
Команда форума
Фанат, ты уже хочешь написать FanatQueryLanguage, а мне кажется это плохо для простой либы.
погоди.
Квери ленгвидж я наоборот, хочу не написать, а зачеркнуть. Не расширить, а сократить.
Собственно, уже пришли, вроде, к консенсусу, что никакого ленгвиджа - одни плейсхолдеры так и остаются. причем даже уменьшенный набор, поскольку каждый принимает как скаляр, так и массив.
 
Последнее редактирование:

AmdY

Пью пиво
Команда форума
PHP:
$sql ="SELECT * FROM table WHERE foo=:foo AND bar=:baz";
$data = DB::getAll($sql, compact('foo','baz'));
 
Сверху