Divné chování delete() nad podmínkami

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Sochi
Člen | 17
+
0
-

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)

vvoody
Člen | 910
+
0
-

dopln:

  • kod tovarnicky
  • dump oboch tabuliek
  • realny kod ktory si aj spustil, ten co si uviedol je nezmysel, lebo volas metodu where nad objektom ActiveRow
pawouk
Člen | 172
+
0
-

Typuji že se autor jen přepsal:

// Výběr z tabulky s použitím další podmínky
$ugh = $ext->where('parameter_key', 'active')->fetchPairs('parameter_key');
<?php
// Identicky dotaz, pouze změna na mazání
$ext->where('parameter_key', 'active')->delete();
?>
Sochi
Člen | 17
+
0
-

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é.

ViPEr*CZ*
Člen | 813
+
0
-

Toto vypadá na bug…

hrach
Člen | 1834
+
0
-

Díky, jasnej bug, bohuzel oprava nebude tak jednoducha, dokud kompletne nepredelam SqlBuilder. A to bych rad nechal az po mergnuti db-dev a to asi tento tyden nebude. Achjeee… to je prace :)

Sochi
Člen | 17
+
0
-

Mám to tedy rovnou přepsat do issue trackeru na GitHubu? :)

hrach
Člen | 1834
+
0
-

no, klidne muzes, bohuzel aktualni stav issue trackeru neodpovida tomu, jak by mel vypadat, takze je to prakticky jedno :)

Sochi
Člen | 17
+
0
-

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).

hrach
Člen | 1834
+
0
-

pull request dodelan (dopsan test), snad tedy brzy merge.