diff options
| author | Stanley Sufficool <ssufficool@php.net> | 2013-06-03 20:02:08 -0700 |
|---|---|---|
| committer | Stanley Sufficool <ssufficool@php.net> | 2013-06-03 20:02:08 -0700 |
| commit | 5a04ab9a54f529f4197bed6f17599604266cdb35 (patch) | |
| tree | f8ecd80c92159255e84616b56d0399b0da4dd6c7 /ext/pdo_dblib/dblib_driver.c | |
| parent | 7360f0f1e6c4b49e89bd3c2cf1f524e9cf7f9dcc (diff) | |
| download | php-git-5a04ab9a54f529f4197bed6f17599604266cdb35.tar.gz | |
Fix PDO_DBLIB bugs: #64338, #64808, #63638
Synchronize with master
Diffstat (limited to 'ext/pdo_dblib/dblib_driver.c')
| -rw-r--r-- | ext/pdo_dblib/dblib_driver.c | 103 |
1 files changed, 82 insertions, 21 deletions
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index ffc910177f..9ed5087369 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -32,6 +32,9 @@ #include "php_pdo_dblib_int.h" #include "zend_exceptions.h" +/* Cache of the server supported datatypes, initialized in handle_factory */ +zval* pdo_dblib_datatypes; + static int dblib_fetch_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; @@ -262,17 +265,37 @@ static struct pdo_dbh_methods dblib_methods = { static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) { pdo_dblib_db_handle *H; - int i, ret = 0; + int i, nvars, nvers, ret = 0; + int *val; + + const pdo_dblib_keyval tdsver[] = { + {"4.2",DBVERSION_42} + ,{"4.6",DBVERSION_46} + ,{"5.0",DBVERSION_70} /* FIXME: This does not work with Sybase, but environ will */ + ,{"6.0",DBVERSION_70} + ,{"7.0",DBVERSION_70} + ,{"7.1",DBVERSION_71} + ,{"7.2",DBVERSION_72} + ,{"8.0",DBVERSION_72} + ,{"10.0",DBVERSION_100} + ,{"auto",0} /* Only works with FreeTDS. Other drivers will bork */ + + }; + + nvers = sizeof(tdsver)/sizeof(tdsver[0]); + struct pdo_data_src_parser vars[] = { - { "charset", NULL, 0 }, - { "appname", "PHP " PDO_DBLIB_FLAVOUR, 0 }, - { "host", "127.0.0.1", 0 }, - { "dbname", NULL, 0 }, - { "secure", NULL, 0 }, /* DBSETLSECURE */ - /* TODO: DBSETLVERSION ? */ + { "charset", NULL, 0 } + ,{ "appname", "PHP " PDO_DBLIB_FLAVOUR, 0 } + ,{ "host", "127.0.0.1", 0 } + ,{ "dbname", NULL, 0 } + ,{ "secure", NULL, 0 } /* DBSETLSECURE */ + ,{ "version", NULL, 0 } /* DBSETLVERSION */ }; - - php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5); + + nvars = sizeof(vars)/sizeof(vars[0]); + + php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars); H = pecalloc(1, sizeof(*H), dbh->is_persistent); H->login = dblogin(); @@ -282,11 +305,37 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ goto cleanup; } + DBERRHANDLE(H->login, (EHANDLEFUNC) error_handler); + DBMSGHANDLE(H->login, (MHANDLEFUNC) msg_handler); + + if(vars[5].optval) { + for(i=0;i<nvers;i++) { + if(strcmp(vars[5].optval,tdsver[i].key) == 0) { + if(FAIL==dbsetlversion(H->login, tdsver[i].value)) { + pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Failed to set version specified in connection string." TSRMLS_CC); + goto cleanup; + } + break; + } + } + + if (i==nvers) { + printf("Invalid version '%s'\n", vars[5].optval); + pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Invalid version specified in connection string." TSRMLS_CC); + goto cleanup; /* unknown version specified */ + } + } + if (dbh->username) { - DBSETLUSER(H->login, dbh->username); + if(FAIL == DBSETLUSER(H->login, dbh->username)) { + goto cleanup; + } } + if (dbh->password) { - DBSETLPWD(H->login, dbh->password); + if(FAIL == DBSETLPWD(H->login, dbh->password)) { + goto cleanup; + } } #if !PHP_DBLIB_IS_MSSQL @@ -297,14 +346,9 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ DBSETLAPP(H->login, vars[1].optval); -#if PHP_DBLIB_IS_MSSQL - dbprocerrhandle(H->login, (EHANDLEFUNC) error_handler); - dbprocmsghandle(H->login, (MHANDLEFUNC) msg_handler); -#endif - H->link = dbopen(H->login, vars[2].optval); - if (H->link == NULL) { + if (!H->link) { goto cleanup; } @@ -315,18 +359,35 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ DBSETOPT(H->link, DBTEXTSIZE, "2147483647"); /* allow double quoted indentifiers */ - DBSETOPT(H->link, DBQUOTEDIDENT, NULL); + DBSETOPT(H->link, DBQUOTEDIDENT, "1"); - if (vars[3].optval && FAIL == dbuse(H->link, vars[3].optval)) { - goto cleanup; + if (vars[3].optval) { + DBSETLDBNAME(H->login, vars[3].optval); } ret = 1; dbh->max_escaped_char_length = 2; dbh->alloc_own_columns = 1; +#if 0 + /* Cache the supported data types from the servers systypes table */ + if(dbcmd(H->link, "select usertype, name from systypes order by usertype") != FAIL) { + if(dbsqlexec(H->link) != FAIL) { + dbresults(H->link); + while (dbnextrow(H->link) == SUCCESS) { + val = dbdata(H->link, 1); + add_index_string(pdo_dblib_datatypes, *val, dbdata(H->link, 2), 1); + } + } + /* Throw out any remaining resultsets */ + dbcancel(H-link); + } +#endif + + + cleanup: - for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) { + for (i = 0; i < nvars; i++) { if (vars[i].freeme) { efree(vars[i].optval); } |
