Existuje záznam v databázi?
- buffus
- Člen | 101
PHP 5.3.3, Nette Framework 2.0.8 pro PHP 5.3 nebo 5.4
Prosím o radu. Potřebuji opakovaně ukládat data z proměnného xml
souboru např.
<cats>
<cat>
<name>Jack</name>
<age>2</age>
<color>grey</color>
</cat>
<cat>
<name>Maxwell</name>
<age>12</age>
<color>orange</color>
</cat>
</cats>
do MySQL tabulky (sloupce name, age, color) s podmínkou, že sloupec name bude primární klíč a pokud se v novém xml souboru vyskytne jméno, které již sloupec name obsahuje, celý řádek (tag cat) se nezapíše, ale ostatní ano. Nemám zkušenost s návrhem modelu a vycházím z quickstartu. V modelu dědím z nezměněného repozitáře Repository do CatRepository:
<?php
namespace Todo;
use Nette;
class CatRepository extends Repository
{
public function findName($p)
{
return $this->findBy(array('name' => $p));
}
}
V config.neon mám zaregistrovanou službu catrepository.
services:
catrepository: Todo\CatRepository
V CatPresenteru bych rád akci zápisu xml do tabulky realizoval. Představa je nějak zapsat v Nette kód 550 „Existuje záznam?“ z knihy Jakuba Vrány 1001 tipů a triků pro PHP
$exists = mysql_num_rows(mysql_query("
SELECT 1
FROM user
WHERE email = 'test@example.com'
LIMIT 1
"));
jako vylučující podmínku pro zápis do tabulky, ale nevím jak. Předem díky za radu.
- nanuqcz
- Člen | 822
Ahoj,
nevím, jestli jsem přesně pochopil dotaz. Ale metoda v modelu, která
zapíše jen dosud ne-existující záznam, by mohla vypadat třeba takto (pokud
používáš Nette\Database):
namespace Todo;
use Nette;
class CatRepository extends Repository
{
public function create($values)
{
if ($this->db->table('cats')->where('name', $values['name'])->count() == 0) { // Pokud dosud neexistuje záznam s daným jménem
return $this->db->table('cats')->insert($values); // ulož ho
} else {
return NULL;
}
}
}
- thorewi
- Člen | 84
No, pokud už tam je záznam se stejným jménem a má tedy v DB nastavený PRIMARY nebo UNIQUE, tak při vkládání to vyhodí PDOException, takže řešení by mohlo být také uzavřít to do try.
namespace Todo;
use Nette;
class CatRepository extends Repository
{
public function create($values)
{
try {
return $this->db->table('cats')->insert($values); // ulož ho
} catch(\PDOException $e) {
if($e->getCode() == '23000') {
// duplicita
} else {
// jina chyba
echo $e->getMessage();
}
return NULL;
}
}
}
Editoval thorewi (24. 1. 2013 10:09)
- buffus
- Člen | 101
Použil jsem první řešení od nanuqcz. Díky! Funguje bez problémů. PDOException při existujících jménech nevyhazuje. Zkoušel jsem to na této tabulce:
SET NAMES utf8;
DROP TABLE IF EXISTS `cats`;
CREATE TABLE `cats` (
`name` varchar(12) DEFAULT NULL,
`age` varchar(12) DEFAULT NULL,
`color` varchar(12) DEFAULT NULL,
PRIMARY KEY (`name`),
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Díky všem.