tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

Pripojeni k DB2 – neimplementovane funkce v driveru

před 6 lety

Ekin
Člen | 4

Dibi 2.0 (revision 7c47f57 released on 2012–02–03)
PHP 5.3.8

Ahoj

mám pomerne rozsiahlu aplikáciu, kde používam dibi ako databázovú vrstvu. Jednou z charakteristík aplikácie je to, že sa nasadzuje na rôznych prostrediach a nad rôznymi databázami. V podstate sa mi bez extra problémov podarilo zabezpečiť pripojenie na MySql, Oracle a MSSQL(PDO). (požiadavka je, aby stačilo zmeniť nastavenie pripojenia a fungovalo to).

Momentálne riešim pripojenie na IBM DB2 (k dispozícii mám na testovanie verziu 9.2).

Moje pripojenie:

<?php
dibi::connect(array(
'driver' => 'pdo',
'pdo' => new PDO('odbc:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=SOMEDATABASE; HOSTNAME=SOMEHOSTNAME;PORT=50000;PROTOCOL=TCPIP;', 'username', 'password'),
'charset'  => 'utf-8'
));
?>

Connect je bez problémov. Problém nastane pri použití dibi::query alebo dibi::test. Jedná sa o to, že všetky stringy v úvodzovkách, alebo premenné resolvujúce sa na stringy mi z query zmiznú.
Príklad:

<?php
$value='somevalue';
dibi::test("select SOMECOLUMN from SOMETABLE where COLUMN = '".$value."'");
dibi::test("select SOMECOLUMN from SOMETABLE where COLUMN = %s",$value);
dibi::test("select SOMECOLUMN from SOMETABLE where COLUMN = 'somevalue'");
?>

vráti vo vsetkých prípadoch:

SELECT SOMECOLUMN FROM SOMETABLE WHERE COLUMN =

Zistil som, že v tomto prípade nastane problém v tom, že odbc/pdo driver pre DB2 nemá naimplementovanú funkciu quote (PDO::quote).
Konkrétne volanie je v „dibi/drivers/pdo.php“ vo funkcii escape :

<?php
public function escape($value, $type)
    {
        switch ($type) {
        case dibi::TEXT:
            return $this->connection->quote($value, PDO::PARAM_STR);

?>

quote skutočne vráti prázdny string, alebo null.

pre moje potreby som si to upravil na:

<?php
public function escape($value, $type)
    {
        switch ($type) {
        case dibi::TEXT:
            if ($this->driverName == "odbc") {return myQuoteMethod($value);} else {
            return $this->connection->quote($value, PDO::PARAM_STR);
            }

?>

kde „myQuoteMethod“ je nejaká moja funkcia, ktorá so postará o escaping/quoting

Ďalší problém nastáva pri použití ohraničenia [ na identifikátory. Tj napríklad query:

<?php
dibi::query("select [COLUMN] from Table");
?>

vrati:

select [COLUMN] from Table

V tomto prípade (zas v pdo.php vo funkcii escape) ide o :

<?php
case dibi::IDENTIFIER:
            switch ($this->driverName) {
            case 'mysql':
                return '`' . str_replace('`', '``', $value) . '`';

            case 'pgsql':
                return '"' . str_replace('"', '""', $value) . '"';

            case 'sqlite':
            case 'sqlite2':
                return '[' . strtr($value, '[]', '  ') . ']';

            case 'odbc':
            case 'oci': // TODO: not tested
            case 'mssql':
                return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';

            default:
                return $value;
            }
?>

zmenil som to na:

<?php
case 'odbc': return $value;
?>

Čo samozrejme nieje veľmi ok, ale pre účely testovania to zatiaľ funguje (v databázi sú len rozumné názvy).

Moje otázky:

  1. Je možné spraviť si do dibi vlastný driver (niečo ako pdo_DB2.php) a pri pripojení používať ten? Nerád by som tam nechával editované súbory z ofic distribúcie dibi pre prípad, že budem v budúcnosti prechádzať na ďalšiu verziu. Taktiež sa mi môže stať že budem používa´t odbc aj pre iné databázy.
  2. nemá dibi nejakú vstavanú quote funkciu, ktorú by som mohol použiť miesto <?php $this->connection->quote() ?> ?

Dík za odpovede

PS: po nikom nechcem, aby implementoval driver na DB2, ale niekomu inému, kto sa snaží pripojiť sa tento post môže hodiť.

před 6 lety

Milo
Nette Core | 1124

Můžeš vše nahlásit jako issue na Github. Těžko se to ale bude opravovat, protože to nejsou časté databáze.

Vlastní driver si můžeš napsat. Stačí třídu pojmenovat DibiSuperDriver, loadnout před Dibi a můžeš používat. Viz API

před 6 lety

Ekin
Člen | 4

Dik,

urobil som to tak, že som si z toho vyrobil vlasný driver.
v podstate zmeny sú v ňom také ako som opísal hore, takže keď to bude niekto potrebovať, tak nech to kľudne použije.

Je to zľahka otestované na DB2 verzie 9