colshrapnel / safemysql

A real safe and convenient way to handle MySQL queries.
Apache License 2.0
396 stars 197 forks source link

_ #29

Closed justscribe closed 1 year ago

colshrapnel commented 9 years ago

Я так и не увидел конкретную практическую задачу, которую решает этот код. С задачей было бы гораздо проще.

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

alexprey commented 9 years ago

@colshrapnel я так понимаю, автор хочет сделать batch вставку данных в таблицу сделать

colshrapnel commented 9 years ago

В целом да - это моя недоработка. Уже был тикет на эту тему. Но для INSERT и UPDATE все решается через ?u Дело в том что для вставки всегда можно обойтись строковым типом, для любых полей. Поэтому те поля, которые мы хотим передать в запрос, мы пишем в массив

$insert = array(
    'id'   => $id,
    'name' => $name,
    'date' => $date,
);

и передаем этот массив в запрос через ?u:

$db->query("INSERT INTO ?n SET ?u", $table, $insert);

в дальнейшем мы можем как угодно менять массив на вставку - он отработает без проблем. К примеру, добавив одно поле

$insert = array(
    'id'   => $id,
    'name' => $name,
    'date' => $date,
    'pass' => $pass,
);

Однако для селекта, увы, решения нет. Можно только сделать костыль с помощью call_userfunc_array

colshrapnel commented 9 years ago

@alexprey для батч вставки есть костыль через parse() предполагая, что данные для вставки лежат в 2-d массиве $data, где каждая строка - это ассоциативный массив с данными каждой строки:

$ins = array();
foreach ($data as $row) {
    $ins[] = $db->parse("(NULL,?s,?s, NOW())",$row['name'],$row['lastname']);
}
$instr = implode(",",$ins);
$db->query("INSERT INTO table VALUES ?p",$instr);

Но в новой версии я хочу сделать модификатор для размножения значений - ?an, ?ai и т.п. И как-то batch вставку под это тоже подвести.

colshrapnel commented 9 years ago

@GZep двоеточие точно не подойдет - я хочу сделать именованные плейсхолдеры по типу ПДО-шных. Про синтаксис я долго думал, и пока решил остановиться на модификаторе 'a' - то есть, плейсхолдер может быть двухбуквенным, типа ?ia (при этом ? должен быть синонимом ?s и тогда текущий ?a нормально ляжет в общую схему).

Но вообще идея со сменой символа мне нравится. Осталось придумать, какой не задействованный в запросе символ использовать...

pafnuty commented 9 years ago

@colshrapnel а вариант с двумя вопросительными знаками не рассматривали?

?s - строка
??s - строки (текущий ?a)
?i - число
??i - числа
?n - имя поля
??n - имена полей
и т.д.
colshrapnel commented 9 years ago

@pafnuty с удвоением вопросительного знака - отличная идея! Мне нравится! Впрочем, @GZep предложил не хуже - удваивать саму букву. Теперь только выбрать, какой вариант лучше :)

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

Вообще, идея такая. Ввести именованные плейсхолдеры и - самое главное - дефолтные плейсхолдеры без указания типа (обрабатываются как строки). Ведь 99% данных - это строки! Поэтому можно писать просто ? или :name не запариваться с типами. А тип писать только там, где строка не подходит:

LIMIT ?i, ?i
LIMIT :start?i, :per_page?i
pafnuty commented 9 years ago

Ведь 99% данных - это строки! Поэтому можно писать просто ? или :name не запариваться с типами. А тип писать только там, где строка не подходит:

полностью поддерживаю!

Думаю с двумя буквами будет даже лучше, чем с двумя вопросами, более очевидно. По типу как с обозначениями пунктов или номеров (пп и №№ соответственно) в обычной жизни.

colshrapnel commented 9 years ago

@GZep смотри. Либа существует не сама по себе, а среди многих других. Поэтому я стараюсь ориентироваться на существующие стандарты. Если человек всегда писал просто ? для строк, то ему сложнее переучиваться на что-то другое. И, кстати, в этом смысле, ?p делать просто ? - это будет натуральная катастрофа :)

Тем более что я не собираюсь отказываться от ?s - ? будет просто алиасом, строку можно будет задать двумя способами.

По поводу же id - как раз здесь строка очень даже подходит. Передавать id как строку в запрос не представляет н единой проблемы. И пользователи PDO как раз постоянно это делают, обрабатывая 99% своих плейсхолдеров как строки. Это реально удобно и я дико жалею, что не сообразил ввести ? как синоним ?s рань раньше.