go-db
go-db copied to clipboard
Указание модификаторов, для элементов данных плейсхолдеров values, list и set
Сори. я случайно создал пул-реквест. Не обратил внимание, что предлагает мержить в твою ветку . Но может и здесь будет полезно. Суть в следующем: Для плейсхолдера ?values нужна возможность указать модификаторы для каждого элемета массива. Решил немного доработать синтаксис плейсхолдеров, и теперь в квадратных скобках можно указывать модификаторы для элементов массива. на примере теста
// tests/Helpers/Templater/ValuesTest.php
$values = [
[0, 1, 2],
['one', null, 'three'],
];
// ожидаемый результат
'subset' => [
'INSERT INTO table VALUES ?values[?string, ?int-null, ?i]',
[$values],
'INSERT INTO table VALUES ("0", 1, 2), ("one", NULL, 0)',
]
Работает для типов values, list и set при этом для set обязательно именование прейсхоледеров, для ассоциации с полями
'subset' => [
'INSERT INTO `table` SET ?s[?string:foo, ?int:bar, ?null:baz]',
[$set],
'INSERT INTO `table` SET `foo`="str\"ing", `bar`=3, `baz`=NULL',
],
Coverage increased (+0.2%) to 93.122% when pulling 55afd851b7f49046e798dbfebe69163f5384514b on SteadyUA:master into c65eecde33df27be9252999e74021886710e0ddb on vasa-c:master.
Зачем усложнять? Можно привести данные к нужному типу и результат будет такой же. Например:
$values = [
[(string)0, 1, (int)2],
[(string)'one', null, (int)'three'],
];
$q = $db->makeQuery('INSERT INTO table VALUES ?values', [$values]);
var_dump($q);
// string(54) "INSERT INTO table VALUES ('0', 1, 2), ('one', NULL, 0)"
это продолжение темы модификатора ?hex когда строка интерпретируется как шестнадцатеричное значение такое нельзя обыграть преобразованием типов. хотя такое вполне может пригодится для булевых значений. для которых модификатор приводит к виду 1 или 0. так же не хочется дополнительно предварительно преобразовывать данные и отдать это на откуп модификаторам плейсхолдеров.
ну и ещё, использование именованых модификаторов для values помогает обойти требование к последовательности данных например есть массив данных $rows = [['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar']]; а запрос вида INSERT INTO table (name, id) VALUES ?v[?string:name, ?int:id] здесь сначала name потом Id - другой порядок следования то есть, нет жестких требовани в последовательности данных. и не нужно дополнительно обрабатывать, менять порядок или приводить к нужному типу перед вставкой
Как-то я пропустил эту тему, посмотрю попозже.