tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

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

navrh k vylepseni postgre driveru, vraceni chyboveho kodu

před 11 lety

A.
Člen | 87

Do metody connect pridat kekonci pg_set_error_verbosity($this->connection, PGSQL_ERRORS_VERBOSE); a pak nasledne v query rozparsovat error hlasku a vytahnout navratovou chybu, kterou spravne ulozit do vyjimky.

Ja si to tam sice dodelal, ale Ty jiste vymyslis nejaky hezci parsovani s hezcim regexpem, to neni moje parketa.

Errory pak vypadaji zhruba takto, takze staci vzit to mezi prvnimi dvemi dvojteckami, popr. i odseknout to LOCATION: at to neni moc ukecany.

ERROR:  23505: duplicate key value violates unique constraint "unq_foo_bar" LOCATION:  _bt_check_unique, nbtinsert.c:298
ERROR: P0001: User custom exception. LOCATION: exec_stmt_raise, pl_exec.c:2298

edit: No jeste je nutne zminit, ze tam je trochu problem, kdyz neni navratovy kod ciselny. Nejspis by bylo vhodne pro tuto promennou udelat novy atribut v DibiDriverException. Jiste se to casem uzije i u ostatnich driveru.

Editoval A. (12. 11. 2008 12:22)

před 11 lety

David Grudl
Nette Core | 6806

Moc nerozumím, o co jde (neznám PostgreSQL). Proč nelze použít pg_last_error nebo pg_result_error, respektive co se má parsovat?

před 11 lety

A.
Člen | 87

Jde o to „nasimulovat“ neco jako mysql_errno pro postgres driver (btw. v mysqli mysqli_errno pouzivas, v mysql mysql_errno ne, takze by to tam asi take chtelo doplnit).

Abys dostal z postgre cislo navratove chyby, je prave nutne nastavit ono pg_set_error_verbosity a to cislo si pak vytahnout zezacatku te stringove hlasky.

Proc je to potreba? Pokud se chci oprit o ruzne integritni omezeni, napr. unikatni klic, musim pak uzivateli vypsat neco rozumneho a ne primo hlasku z db. Dale take lokalizace chybovych hlaseni. Takze je proste navratovy kod potreba.

Editoval A. (12. 11. 2008 17:29)

před 11 lety

David Grudl
Nette Core | 6806

Nebylo by vhodnější použít třeba pg_result_error_field ?

před 11 lety

A.
Člen | 87

Hm, to samozrejme bylo. Ta funkce tam jiste nebude vice nez tri roky, jinak bych ji zaregistroval.

před 11 lety

A.
Člen | 87

Tak jsem to zkusil a tezko rict, jestli je to nakonec lepsi. Musi se pouzit onoho asynchroniho odesilani dotazu, jak sami pisi, jinak se to musi parsovat po staru.

if (!pg_connection_busy($this->connection)) {
    if (!pg_send_query($this->connection, $sql)) {
        throw new DibiDriverException('Fatal error when querying database.', 0, $sql);
    }
}

$this->resultSet = pg_get_result($this->connection);

if (pg_result_error_field($this->resultSet, PGSQL_DIAG_SQLSTATE) !== NULL) {
    throw new DibiDriverException(
        pg_result_error_field($this->resultSet, PGSQL_DIAG_MESSAGE_PRIMARY),
        pg_result_error_field($this->resultSet, PGSQL_DIAG_SQLSTATE),
        $sql
    );
}

pg_result_error, ktera by byla vhodnejsi na zjisteni, zda-li doslo vubec k chybe bohuzel namisto slibovaneho FALSE radsi vzdy vraci string(0). Zda-li je tento bug uz nahlasen, ci jen v me verzi jsem uz nezjistoval.

No a je jeste nutna uprava DibiDriverException, jelikoz SQLSTATE nemusi byt integer.