php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39822 new PDO() doesn't work with firebird
Submitted: 2006-12-13 22:08 UTC Modified: 2007-10-30 22:49 UTC
Votes:5
Avg. Score:4.0 ± 0.9
Reproduced:5 of 5 (100.0%)
Same Version:0 (0.0%)
Same OS:3 (60.0%)
From: bx at clansphere dot de Assigned: wez
Status: Closed Package: PDO related
PHP Version: 5CVS-2006-12-13 (snap) OS: Windows XP SP2
Private report: No CVE-ID:
 [2006-12-13 22:08 UTC] bx at clansphere dot de
Description:
------------
using try/catch doesn't work for firebird like it works with other rdbms extensions. i think the problem is that firebird returns something (NULL) so that try expects all went well, but it is not checking for the PDO object itself.

i am using is_object() currently to look for errors, but that way i can't get errorcodes like 'database does not exist' for example and even when track_errors is enabled $php_errormsg is empty.

Reproduce code:
---------------
try {
    $connection = new PDO('firebird:dbname=test.fdb', $user, $password);
}
catch(PDOException $error) {
    echo $error->getMessage();
}

Expected result:
----------------
catch can be called to get the exact error

Actual result:
--------------
try statement thinks everything is ok

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-12-18 15:26 UTC] wez@php.net
Looking for a maintainer
 [2007-10-12 20:14 UTC] Lars dot Westermann at privat dot dk
Maybe not the correct way of doing this, but it works:

In ext/pdo_firebird/firebird_driver.c:

/* the driver-specific PDO handle constructor */
static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
{
    struct pdo_data_src_parser vars[] = {
        { "dbname", NULL, 0 },
        { "charset",  NULL, 0 },
        { "role", NULL, 0 }
    };
    int i, ret = 0;
    short buf_len = 256, dpb_len;

    pdo_firebird_db_handle *H = dbh->driver_data = pecalloc(1,sizeof(*H),dbh->is_persistent);

    php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 3);

    do {
        static char const dpb_flags[] = {
            isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name };
        char const *dpb_values[] = { dbh->username, dbh->password, vars[1].optval, vars[2].optval };
        char dpb_buffer[256] = { isc_dpb_version1 }, *dpb;

        dpb = dpb_buffer + 1;

        /* loop through all the provided arguments and set dpb fields accordingly */
        for (i = 0; i < sizeof(dpb_flags); ++i) {
            if (dpb_values[i] && buf_len > 0) {
                dpb_len = slprintf(dpb, buf_len, "%c%c%s", dpb_flags[i], (unsigned char)strlen(dpb_values[i]),
                    dpb_values[i]);
                dpb += dpb_len;
                buf_len -= dpb_len;
            }
        }

        /* fire it up baby! */
        if (isc_attach_database(H->isc_status, 0, vars[0].optval, &H->db,(short)(dpb-dpb_buffer), dpb_buffer)) {
            break;
        }

        dbh->methods = &firebird_methods;
        dbh->native_case = PDO_CASE_UPPER;
        dbh->alloc_own_columns = 1;

        ret = 1;

    } while (0);

    for (i = 0; i < sizeof(vars)/sizeof(vars[0]); ++i) {
        if (vars[i].freeme) {
            efree(vars[i].optval);
        }
    }

    if (!dbh->methods) {
        char errmsg[512];
        long *pvector = H->isc_status;
        isc_interprete(errmsg, &pvector);
        zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
                "HY000", (long) H->isc_status[1], errmsg);
    }

    if (!ret) {
        firebird_handle_closer(dbh TSRMLS_CC);
    }

    return ret;
}
/* }}} */


IMHO the _firebird_error() function should be written like the functions in pdo_pgsql and pdo_mysql, which - to mee - look like they are built on the same template - and the firebird version is not.

But the above codeblock containing the zend_throw_exception_ex() does it's job and prints the firebird errormessage.

Hope it at least can serve as a quick fix, until the a more correct approach (better error-handler) has been made.

Greetings,
Lars
 [2007-10-12 20:21 UTC] Lars dot Westermann at privat dot dk
The above mentioned block didn't print the correct error-code; use this instead:

    if (!dbh->methods) {
        char errmsg[512];
        long *pvector = H->isc_status;
        isc_interprete(errmsg, &pvector);
        zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
                "HY000", (short) H->isc_status[1], errmsg);
    }


(Use the (short) typecast to get the correct error-code)

Greetings,
Lars
 [2007-10-30 22:49 UTC] lwe@php.net
Fixed in CVS (PHP_5_3 branch)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 10:03:03 2014 UTC