Divné chování delete() nad podmínkami
- Sochi
- Člen | 17
Narazil jsem na (z mého pohledu) na podivné chování Nette\Database, kdy jsou ignorovány doplňující podmínky před mazáním nad výběrem z připojených tabulek. Příklad:
<?php
// Vytvořeni výběru přes továrničku
$sel = $this->context->createXyz()->get($id); // 14
// Nastavení připojené tabulky
$ext = $sel->related('table_name');
// EDIT: Oprava, ve snaze vytáhnout jenom problematickou část jsem špatně překopíroval názvy proměnných
// Výběr z tabulky s použitím další podmínky
$ugh = $ext->where('parameter_key', 'active')->fetchPairs('parameter_key');
?>
Vygeneruje následující dotaz:
<?php
SELECT ..., `parameter_id`
FROM `table_name`
WHERE (`table_name`.`xyz_id` IN (14)) AND (`parameter_key` = 'active')
?>
Když ale změním dotaz z fetchPairs na mazání:
<?php
// Identicky dotaz, pouze změna na mazání
// EDIT: Oprava, stejně jako výše
$ext->where('parameter_key', 'active')->delete();
?>
Vytvořený dotaz zcela ignoruje přidanou podmínku (na omezení názvu parametru).
<?php
DELETE
FROM `table_name`
WHERE (`xyz_id` = ?) -- s hodnotou 14
?>
Jedná se o standardní nebo zamýšlené chování (které jsem pouze nepochopil) nebo chybu? Stejná situace se vyskytuje i použití limitů, při výběru se aplikují, při mazání opět ignorují. Verze Nette 2.0.5, bez prefixů. Názvy tabulek jsem pro přehlednost trochu zkrátil..
Editoval Sochi (24. 9. 2012 8:20)
- Sochi
- Člen | 17
pawouk napsal(a):
Typuji že se autor jen přepsal:
Jasně, chtěl jsem to rozdělit pro přehlednost na více řádků a vloudila se chybka.
Přepsal jsem problematickou situaci do ukázkového quickstarteru, takže struktura tabulek:
<?php
CREATE TABLE `task` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`text` varchar(100) NOT NULL,
`created` datetime NOT NULL,
`done` tinyint(1) unsigned NOT NULL DEFAULT '0',
`user_id` int(10) unsigned NOT NULL,
`tasklist_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `order` (`tasklist_id`,`done`,`created`),
KEY `fk_user` (`user_id`),
CONSTRAINT `fk_tasklist` FOREIGN KEY (`tasklist_id`) REFERENCES `tasklist` (`id`),
CONSTRAINT `fk_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8;
CREATE TABLE `tasklist` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
?>
Továrnička zcela standardní, bez úprav:
<?php
class Tasklists extends TableSelection
{
public function __construct(Connection $connection)
{
parent::__construct('tasklist', $connection);
}
}
?>
Funkční kód:
<?php
$item = $this->context->createTasklists()->get(2);
$rels = $item->related('task');
$arr = $rels->where('id', 8)->fetchPairs('id', 'text');
// Vytvoří správný dotaz:
// SELECT `id`, `tasklist_id`, `text`
// FROM `task`
// WHERE (`task`.`tasklist_id` IN (2)) AND (`id` = 8)
?>
Kód s podivným chováním:
<?php
$item = $this->context->createTasklists()->get(2);
$rels = $item->related('task');
$rels->where('id', 8)->delete();
// Vytvoří dotaz bez podmínky na "task"
// DELETE
// FROM `task`
// WHERE (`tasklist_id` = ?) -- s parametrem 2
?>
Feature nebo bug? Rozhodně takové chování je podivné.
- Sochi
- Člen | 17
hrach napsal(a):
aktualni stav issue trackeru neodpovida tomu, jak by mel vypadat
Toho už jsem si bohužel taky všimnul. Spíš mi šlo o to, které místo sdružuje bugreporty? (Protože za poslední dobu tento není jediný, který bych na fóru zmínil a žádný nikam nedospěl; např. https://forum.nette.org/…abase-notorm).