Сталкивался с проблемами в pdoFetch
Это копия github.com/sergant210/pdoTools/issues/311. На гитхаб не читабельно из-за того, что апострофы на sql на markdown выделяются как код.
1) В этой строке в $fields приходил почему-то массив github.com/sergant210/pdoTools/blob/daf2e1c2062c2a3080bde221672a43c7dab2e11c/core/components/pdotools/model/pdotools/pdofetch.class.php#L368
Сейчас такое воспроизвести не удалось. Где-то видно сам косячил.
2)
3) Не работают вложенные функции SQL
Решение(может костыль) в строке github.com/sergant210/pdoTools/blob/daf2e1c2062c2a3080bde221672a43c7dab2e11c/core/components/pdotools/model/pdotools/pdofetch.class.php#L373
Добавить в регулярку AS, так как на функции стопроцентно алиас ставиться.
Преодолел костылем
github.com/sergant210/pdoTools/blob/daf2e1c2062c2a3080bde221672a43c7dab2e11c/core/components/pdotools/model/pdotools/pdofetch.class.php#L516
1) В этой строке в $fields приходил почему-то массив github.com/sergant210/pdoTools/blob/daf2e1c2062c2a3080bde221672a43c7dab2e11c/core/components/pdotools/model/pdotools/pdofetch.class.php#L368
Сейчас такое воспроизвести не удалось. Где-то видно сам косячил.
2)
'select'=>[
'modResource'=>'DISTINCT pagetitle',
],
Выдает 0.0001791: SQL prepared "SELECT `` FROM `modx_site_content`
в отличии от 'select'=>[
'modResource'=>'DISTINCT modResource.pagetitle',
],
Вообщем-то не страшно.3) Не работают вложенные функции SQL
$pdo = $modx->getService("pdoFetch");
$default = [
'select'=>[
'modResource'=>'modResource.id,IF(SUM(modResource.published)/COUNT(*) = 1,1,0) as all_published',
],
'groupby'=>'modResource.parent',
'setTotal'=>0,
'limit'=>10,
'return'=>'data',
];
$pdo->setConfig($default);
$pdo->run();
echo "<pre>".$pdo->getTime()."</pre>";
Выдает0.0001471: SQL prepared "SELECT modResource.id, IF(SUM(modResource.published)/COUNT(*) = 1, `1`, 0) as all_published FROM `modx_site_content`
ставит кавычку на `1`Решение(может костыль) в строке github.com/sergant210/pdoTools/blob/daf2e1c2062c2a3080bde221672a43c7dab2e11c/core/components/pdotools/model/pdotools/pdofetch.class.php#L373
Добавить в регулярку AS, так как на функции стопроцентно алиас ставиться.
$fields = preg_replace_callback('/\(.*?\bAS\b/i', function($matches) {
return str_replace(",", "|", $matches[0]);
}, $fields);
4) $miniShop2 = $modx->getService('miniShop2');
$pdo = $modx->getService("pdoFetch");
$default = [
'includeTVs'=>'in_stock',
'leftJoin'=>[
'Data'=>[
'class'=>'msProductData',
'on'=>'Data.id = modResource.id'
]
],
'select'=>[
'modResource'=>'modResource.id',
],
'sortby'=>'(IF(`Data`.`price` > 0, 1, 0)) DESC, `in_stock` desc',
'setTotal'=>0,
'limit'=>10,
'return'=>'data',
];
$pdo->setConfig($default);
$pdo->run();
echo "<pre>".$pdo->getTime()."</pre>";
выдает двойные апострофы в сорт0.0002031: Sorted by (IF(`Data`.`price` > 0, 1, 0)) DESC, ``TVin_stock`.`value`` desc,
Преодолел костылем
$sortby = str_replace("``","`",$sortby);
после строкиgithub.com/sergant210/pdoTools/blob/daf2e1c2062c2a3080bde221672a43c7dab2e11c/core/components/pdotools/model/pdotools/pdofetch.class.php#L516
Поблагодарить автора
Отправить деньги
Комментарии: 2
1. Видимо нужна foolproof защита.
2. Или используем твой вариант с таблицей в виде префикса или такой
Но так как запрос простой и без логики, я бы не стал вообще использовать xPDO, а сделал бы маленький и лёгкий запрос (без кучи объектов xPDO)
2. Или используем твой вариант с таблицей в виде префикса или такой
'select'=>[
'modResource'=>'DISTINCT pagetitle as pagetitle',
],
Напомню, что можно работать напрямую с запросами через базовый API.$query = $modx->newQuery('modResource');
$query->query['distinct'] = 'DISTINCT';
...
3. Это чудит xPDO. Он формирует запрос, а не pdoFetch. А вообще очень странная конструкция. Я бы так даже не додумался написать. Для сравнения на SQL сервере я бы написал так'select'=>[
'parent',
'SUM(published) = COUNT(*) as all_published'
],
Для сравнения на клиенте так'select'=>[
'parent',
'SUM(published) as all_published',
'COUNT(*) as count'
],
А потом в цикле проверил бы на равенство два последних поля.Но так как запрос простой и без логики, я бы не стал вообще использовать xPDO, а сделал бы маленький и лёгкий запрос (без кучи объектов xPDO)
$table = $modx->getTableName('modResource');
$sql = "SELECT parent, SUM(published) = COUNT(*) as all_published FROM $table GROUP BY parent";
$statement = $modx->prepare($sql);
if ($statement->execute()) {
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
}
4. Скорее всего тоже xPDO шалит. Проверю.
2. А я добавил исключение
Блок
preg_match('/DISTINCT/i',
$fields)
В блокеif ($fields == 'all' || $fields == '*' || empty($fields)) {
$fields = $this->modx->getSelectColumns($class, $alias);
} elseif(preg_match('/DISTINCT/i',
$fields)){
}else {
$fields = $this->modx->getSelectColumns($class, $alias, '',
array_map('trim', explode(',', $fields)));
}
3. Это чудит xPDO.В курсе. Если select строка, xPDO разбивает select по запятым и затем решает, что 1 это колонка и ставит апострофы.
Блок
if (is_string($fields) && strpos($fields, '(') !== false) {
// Commas in functions
$fields = preg_replace_callback('/\(.*?\)/', function($matches) {
return str_replace(",", "|", $matches[0]);
}, $fields);
$fields = explode(',', $fields);
foreach ($fields as &$field) {
$field = str_replace('|', ',', $field);
}
$this->query->select($fields);
$this->addTime('Added selection of <b>' . $class . '</b>: <small>' . str_replace('`' . $alias . '`.',
'', implode(',', $fields)) . '</small>', microtime(true) - $time);
}
вообще не был бы нужен, если бы XPDO не чудила.Но так как запрос простой и без логики, я бы не стал вообще использовать xPDO, а сделал бы маленький и лёгкий запрос (без кучи объектов xPDO)У меня pdoTools в компонентах используется, чтобы изменить запрос не трогая сам компонент. Например из excelconvertrule
{
"class": "MaterialZakupList",
"leftJoin": {
"MaterialZakup": {
"class": "MaterialZakup",
"on": "MaterialZakup.id = MaterialZakupList.order_id"
},
"gtsBAccount": {
"class": "gtsBAccount",
"on": "gtsBAccount.id = MaterialZakup.account_id"
},
"raschetsMaterial": {
"class": "raschetsMaterial",
"on": "raschetsMaterial.id = MaterialZakupList.mat_id"
},
"Orgs": {
"class": "Orgs",
"on": "Orgs.id = MaterialZakup.org_id"
}
},
"select": {
"MaterialZakupList": "*",
"Orgs": "Orgs.shortname",
"gtsBAccount": "gtsBAccount.label as account",
"raschetsMaterial": "IF(MaterialZakupList.prihod_date IS NULL,'в дороге','получено') as status1,IF(MaterialZakupList.type_id = 3,raschetsMaterial.name,MaterialZakupList.tovar) as tovar1,raschetsMaterial.type,raschetsMaterial.metall,raschetsMaterial.ed_izm",
"MaterialZakup": "MaterialZakup.date,MaterialZakup.document"
},
"sortby": {
"MaterialZakupList.id": "ASC"
}
}
При экспорте в excel без правок pdoTools на строке IF(MaterialZakupList.prihod_date IS NULL,'в дороге','получено')
'в дороге' обрамляется апострофами.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.