Nejste přihlášen(a)
Stránky: 1
Téma zavřeno
Jelikož je někdy i v MySQL nutné používat rutiny (a to jak funkce tak procedůry), hodilo by se nějakým způsobem zautomatizovat jejich vytváření/úpravu/likvidaci.
Standartně se rutiny v MySQL dají vytvářet tímto způsobem (přes cli):
delimiter //
CREATE PROCEDURE simpleproc1 (OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t1;
END//
CREATE PROCEDURE simpleproc2 (OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t2;
END//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
V API php ovšem není možné používat příkaz DELIMITER a tak nelze výše uvedený kód přímo importovat do DB přes dibi::loadFile() ani přes phpMyAdmina. Nadruhou stranu, když se celý kód vytváření rutiny provede v jednom query příkazu, není delimiter potřeba a rutina se úspěšne vytvoří:
<?php
dibi::query("
CREATE PROCEDURE simpleproc (OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM t;
END
");
?>
Čímž se dostáváme k možnosti podpory importu rutin přes
dibi::loadFile. Aby import proběhl správně, je nutné sql skript správně
rozparsovat, a jednotlivé části provést. V současnosti se parsování
provádí pomocí napevno nastaveného oddělovače
;, takže se samotný příkaz pro vytvoření rutiny rozseká a
nešťastná MySQL to vůbec nepobere. Se středníky v těle rutiny se sice
nic dělat nedá, ale
s těmi mimo tělo ano – můžeme je nahradit jiným znakem/znaky a podle
něj v dibi::loadFile skript parsovat. Samozřejmě, ja pak nutné tento
nestandartní oddělovač z sql query vynechat. Po úpravách by samotná
funkce loadFile mohla vypadat nějak takto:
<?php
public function loadFile($file, $delimiter = ';')
{
$this->connect();
@set_time_limit(0); // intentionally @
$handle = @fopen($file, 'r'); // intentionally @
if (!$handle) {
throw new FileNotFoundException("Cannot open file '$file'.");
}
$count = 0;
$sql = '';
while (!feof($handle)) {
$s = fgets($handle);
$sql .= $s;
if (substr(rtrim($s), -strlen($delimiter)) === $delimiter) {
$sql = substr(rtrim($sql), 0, -strlen($delimiter)); // delimiter se vynecha
$this->driver->query($sql);
$sql = '';
$count++;
}
}
fclose($handle);
return $count;
}
?>
Myslím si, že by nebylo od věci tuhle funkčnost implmenetovat přímo do
dibi, opravdu hodně to import procedůr a funkcí usnadní :) Nicméně si
nejsem jistý tím, jak je to v případě databází jiných než MySQL a jak
se jim bude líbit vynechání delimiteru (;). Výše uvedený kód
jsem testoval s MySQL 5.0.51 a byl plně funkční.
Co vy na to?