Nette\Database – chybný průchod / počty

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

Zdravím,

narazil jsem jednu nesrovnalost, nevím zda je to chyba fw nebo má:

3 normální tabulky: song, interpret a spojovací interpret_song

  • tab interpret_song má PRIMARY „interpret_id, song_id“
  • v nich 1 song, navázaný na 2 interprety

vyhledávám řetězec v obou obsahových tabulkách tímto způsobem:

<?php
$this->interpretSongs->where('interpret.name LIKE ? OR song.title LIKE ? ', $keyword, $keyword);
?>

už při dotazu na počet vrácených výsledků se mi vrací různé počty:

<?php
$interpretSongs->count('interpret_song.created_at') // 2 - spravny pocet , shodny s poctem vracenych radku z db
$interpretSongs->count() // 1 - spatny pocet , ??
?>

a když provedu (klasický) průchod:

<tr n:foreach="$interpretSongs as $interpretSong">
    <td>{$interpretSong->interpret->name}</td>
    <td>{$interpretSong->song->title}</td>
</tr>

vypíše se mi jen jeden řádek, ačkoli by měly být dva.

důvod?
je to chyba, není to chyba? je to moje chyba?

hrach
Člen | 1834
+
0
-
  1. verze nette
  2. generuje to spravne dotazy?
    • generuje: pošli strukturu db
    • negeruje: jake by to mělo generovat?
knedle
Člen | 34
+
0
-
  1. verze nette – poslední stable:

Nette Framework (version 2.0.1 released on 2012–02–29)


  1. první sql generuje správné:
SELECT `interpret_song`.`song_id`, `interpret_song`.`interpret_id`, `interpret_song`.`year`,
`interpret_song`.`created_at`, `interpret_song`.`modified_at`
FROM `interpret_song`
INNER JOIN `interpret` ON `interpret_song`.`interpret_id` = `interpret`.`id`
INNER JOIN `song` ON `interpret_song`.`song_id` = `song`.`id`
WHERE (`interpret`.`name` LIKE "%rachel%" OR `song`.`title` LIKE "%rachel%" )
ORDER BY `created_at` DESC
LIMIT 25
OFFSET 0

tohle sql vrátí – správně – 2 řádky

problém vznikne při průchodu v latte – viz výše – kdy místo vyspání 2 řádků:

interpret A Ráchel
interpret B Ráchel

vypíše jen první z nich

(tech interpretů tam může být klidně 100, vypíše jen toho prvního)


db

DROP TABLE IF EXISTS `interpret`;
CREATE TABLE `interpret` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(250) COLLATE utf8_czech_ci NOT NULL,
  `created_at` datetime NOT NULL,
  `modified_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

DROP TABLE IF EXISTS `song`;
CREATE TABLE `song` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(250) COLLATE utf8_czech_ci NOT NULL,
  `created_at` datetime NOT NULL,
  `modified_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

DROP TABLE IF EXISTS `interpret_song`;
CREATE TABLE `interpret_song` (
  `interpret_id` int(11) NOT NULL,
  `song_id` int(11) NOT NULL,
  `created_at` datetime NOT NULL,
  `modified_at` datetime NOT NULL,
  `counter` int(11) NOT NULL DEFAULT '1',
  `year` smallint(6) NOT NULL,
  PRIMARY KEY (`interpret_id`,`song_id`),
  KEY `song_id` (`song_id`),
  CONSTRAINT `interpret_song_ibfk_1` FOREIGN KEY (`interpret_id`) REFERENCES `interpret` (`id`),
  CONSTRAINT `interpret_song_ibfk_2` FOREIGN KEY (`song_id`) REFERENCES `song` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

-- 2012-03-19 22:15:46

a ještě testovací data:

TRUNCATE `interpret`;
INSERT INTO `interpret` (`id`, `name`, `created_at`, `modified_at`) VALUES
(1,	'Interpret A',	'0000-00-00 00:00:00',	'0000-00-00 00:00:00'),
(2,	'Interpret B',	'0000-00-00 00:00:00',	'0000-00-00 00:00:00');

TRUNCATE `song`;
INSERT INTO `song` (`id`, `title`, `created_at`, `modified_at`) VALUES
(1,	'Ráchel',	'0000-00-00 00:00:00',	'0000-00-00 00:00:00'),
(2,	'Song ABC',	'0000-00-00 00:00:00',	'0000-00-00 00:00:00');

TRUNCATE `interpret_song`;
INSERT INTO `interpret_song` (`interpret_id`, `song_id`, `created_at`, `modified_at`, `counter`, `year`) VALUES
(1,	1,	'0000-00-00 00:00:00',	'0000-00-00 00:00:00',	1,	0),
(2,	1,	'0000-00-00 00:00:00',	'0000-00-00 00:00:00',	1,	0),
(2,	2,	'0000-00-00 00:00:00',	'0000-00-00 00:00:00',	1,	0);

Editoval knedle (20. 3. 2012 7:39)

hrach
Člen | 1834
+
0
-

Neprojevuje se ti to náhodou jen když máš zapnutou cache?
Řekl bych, že už je to opravený bug, který čeka na merge.
https://github.com/…tte/pull/574

hrach
Člen | 1834
+
0
-

už je to mergnute v nightly, vyzkoušej.

knedle
Člen | 34
+
0
-

díky za info, mrknu, poreferuju

knedle
Člen | 34
+
0
-

tak dev verze problém neřeší

version 2.1-dev released on 2012–03–20

Editoval knedle (20. 3. 2012 23:32)

knedle
Člen | 34
+
0
-

Neprojevuje se ti to náhodou jen když máš zapnutou cache?

no / ja nejak tu cache nedokazu vypnout:
https://forum.nette.org/…rror-warning#…

takze nemuzu porovat vypnuti/zapnuti

Editoval knedle (20. 3. 2012 23:35)

hrach
Člen | 1834
+
0
-

tak zkus vymazat cache rucne a udelat prvni refresh, jestli to bude ok.

knedle
Člen | 34
+
0
-

pravdu máš – potvrzuji úspěch – díky

díky – btw – jak vypíná ta cache (viz to druhé vlákno)

hrach
Člen | 1834
+
0
-

Prosim te, jeste si over, ze v tom dnesnim nightly buildu byly ty commity ode me, viz github.
Jak se vypina chache opravdu z hlavy nevim, je to tam silena magie.

knedle
Člen | 34
+
0
-

tak ten nightly build posral zas něco jiného – neni schopen najít nějakou referenci

  • sice nevyhledám všechny, ale zas mi funguje update jednoho urcitého záznamu :/

zatím jsem se vrátil k stable

jestě to projedu

Editoval knedle (21. 3. 2012 0:46)

knedle
Člen | 34
+
0
-

takze night build hlásí:

No reference found for $interpret_song->

a error ukáže zde (na druhem řádku):

$row = $this->interpretSongs->where('interpret_id', $interpretId)->where('song_id', $songId)->fetch();
$row->update(array('counter' => new \Nette\Database\SqlLiteral('`counter` + 1'), 'modified_at' => new \Nette\Database\SqlLiteral('NOW()')));

Editoval knedle (21. 3. 2012 0:51)