Browse Source

Merge branch 'PHP-5.5'

* PHP-5.5:
  news for dblib fixes
  FIX BUG #55647, #60512, #60512, #61900, #64338, #64808, #63638
  Fix PDO_DBLIB bugs: #64338, #64808, #63638

Conflicts:
	ext/pdo_dblib/dblib_driver.c
	ext/pdo_dblib/dblib_stmt.c
pull/355/head
Stanislav Malyshev 13 years ago
parent
commit
b144c26319
  1. 66
      ext/pdo_dblib/dblib_driver.c
  2. 59
      ext/pdo_dblib/dblib_stmt.c
  3. 6
      ext/pdo_dblib/php_pdo_dblib_int.h

66
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,14 +265,32 @@ 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, nvars, 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 */
,{ "version", NULL, 0 } /* DBSETLVERSION */
};
nvars = sizeof(vars)/sizeof(vars[0]);
@ -284,6 +305,27 @@ 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) {
if(FAIL == DBSETLUSER(H->login, dbh->username)) {
goto cleanup;
@ -304,9 +346,6 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
DBSETLAPP(H->login, vars[1].optval);
DBERRHANDLE(H->login, (EHANDLEFUNC) error_handler);
DBMSGHANDLE(H->login, (MHANDLEFUNC) msg_handler);
H->link = dbopen(H->login, vars[2].optval);
if (!H->link) {
@ -330,6 +369,23 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
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 < nvars; i++) {
if (vars[i].freeme) {

59
ext/pdo_dblib/dblib_stmt.c

@ -36,35 +36,51 @@
/* {{{ pdo_dblib_get_field_name
*
* Updated for MSSQL 2008 SR2 extended types
* Return the data type name for a given TDS number
*
*/
static char *pdo_dblib_get_field_name(int type)
{
/*
* I don't return dbprtype(type) because it does not fully describe the type
* (example: varchar is reported as char by dbprtype)
*
* FIX ME: Cache datatypes from server systypes table in pdo_dblib_handle_factory()
* to make this future proof.
*/
switch (type) {
case 31: return "nvarchar";
case 34: return "image";
case 35: return "text";
case 36: return "uniqueidentifier";
case 37: return "varbinary"; /* & timestamp - Sybase AS12 */
case 38: return "bigint"; /* & bigintn - Sybase AS12 */
case 39: return "varchar"; /* & sysname & nvarchar - Sybase AS12 */
case 40: return "date";
case 41: return "time";
case 42: return "datetime2";
case 43: return "datetimeoffset";
case 45: return "binary"; /* Sybase AS12 */
case 47: return "char"; /* & nchar & uniqueidentifierstr Sybase AS12 */
case 48: return "tinyint";
case 50: return "bit"; /* Sybase AS12 */
case 52: return "smallint";
case 55: return "decimal"; /* Sybase AS12 */
case 56: return "int";
case 58: return "smalldatetime";
case 59: return "real";
case 60: return "money";
case 61: return "datetime";
case 62: return "float";
case 63: return "numeric"; /* or uint, ubigint, usmallint Sybase AS12 */
case 98: return "sql_variant";
case 99: return "ntext";
case 104: return "bit";
case 106: return "decimal";
case 108: return "numeric";
case 106: return "decimal"; /* decimal n on sybase */
case 108: return "numeric"; /* numeric n on sybase */
case 122: return "smallmoney";
case 127: return "bigint";
case 240: return "geometry";
case 165: return "varbinary";
case 167: return "varchar";
case 173: return "binary";
@ -72,15 +88,14 @@ static char *pdo_dblib_get_field_name(int type)
case 189: return "timestamp";
case 231: return "nvarchar";
case 239: return "nchar";
case 240: return "geometry";
case 241: return "xml";
default:
return "unknown";
break;
default: return "unknown";
}
}
/* }}} */
static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
{
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
pdo_dblib_db_handle *H = S->H;
@ -98,6 +113,9 @@ static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
{
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
efree(stmt->columns);
stmt->columns = NULL;
efree(S);
return 1;
@ -112,7 +130,7 @@ static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
ret = dbresults(H->link);
if (FAIL == ret) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "DBLIB: dbresults() returned FAIL" TSRMLS_CC);
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbresults() returned FAIL" TSRMLS_CC);
return 0;
}
@ -134,7 +152,7 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
dbsetuserdata(H->link, (BYTE*) &S->err);
dblib_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
pdo_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
return 0;
@ -164,7 +182,7 @@ static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
ret = dbnextrow(H->link);
if (FAIL == ret) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "DBLIB: dbnextrow() returned FAIL" TSRMLS_CC);
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbnextrow() returned FAIL" TSRMLS_CC);
return 0;
}
@ -215,11 +233,12 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
}
switch (coltype) {
case SQLCHAR:
case SQLTEXT:
case SQLVARBINARY:
case SQLBINARY:
case SQLIMAGE:
case SQLTEXT:
/* FIXME: Above types should be returned as a stream as they can be VERY large */
case SQLCHAR:
case SQLVARCHAR:
tmp_ptr = emalloc(*len + 1);
memcpy(tmp_ptr, *ptr, *len);
@ -247,14 +266,14 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
}
default:
if (dbwillconvert(coltype, SQLCHAR)) {
tmp_len = 32 + (2 * (*len));
tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */
tmp_ptr = emalloc(tmp_len);
*len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1);
*ptr = tmp_ptr;
} else {
*len = 0;
*ptr = NULL;
}
} else {
*len = 0; /* FIXME: Silently fails and returns null on conversion errors */
*ptr = NULL;
}
}
*caller_frees = 1;
@ -289,6 +308,8 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *re
add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );
add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1), 1);
add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1)), 1);
add_assoc_long(return_value, "native_type_id", dbcoltype(H->link, colno+1));
add_assoc_long(return_value, "native_usertype_id", dbcolutype(H->link, colno+1));
return 1;
}
@ -305,6 +326,6 @@ struct pdo_stmt_methods dblib_stmt_methods = {
NULL, /* get attr */
pdo_dblib_stmt_get_column_meta, /* meta */
pdo_dblib_stmt_next_rowset, /* nextrow */
dblib_dblib_stmt_cursor_closer
pdo_dblib_stmt_cursor_closer
};

6
ext/pdo_dblib/php_pdo_dblib_int.h

@ -120,6 +120,12 @@ typedef struct {
pdo_dblib_err err;
} pdo_dblib_stmt;
typedef struct {
const char* key;
int value;
} pdo_dblib_keyval;
ZEND_BEGIN_MODULE_GLOBALS(dblib)
pdo_dblib_err err;
char sqlstate[6];

Loading…
Cancel
Save