php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch pdo_dblib_unbuffer-5.3.patch for PDO related Bug #50755Patch version 2010-03-09 22:23 UTC Return to Bug #50755 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:
Developer: ssufficool@gmail.comIndex: dblib_stmt.c =================================================================== --- dblib_stmt.c (revision 295996) +++ dblib_stmt.c (working copy) @@ -32,36 +32,22 @@ #include "php_pdo_dblib_int.h" #include "zend_exceptions.h" -static void free_rows(pdo_dblib_stmt *S TSRMLS_DC) +static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC) { - int i, j; - - for (i = 0; i < S->nrows; i++) { - for (j = 0; j < S->ncols; j++) { - pdo_dblib_colval *val = &S->rows[i] + j; - if (val->data) { - efree(val->data); - val->data = NULL; - } - } - } - efree(S->rows); - S->rows = NULL; - S->nrows = 0; -} - -static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) -{ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; + pdo_dblib_db_handle *H = S->H; - if (S->rows) { - free_rows(S TSRMLS_CC); - } - if (S->cols) { - efree(S->cols); - } - efree(S); + /* Cancel any pending results */ + dbcancel(H->link); + /* + * We do not want PDO efreeing this since + * columns has pointers to driver data and will segfault + * -Stan S- + */ + efree(stmt->columns); + stmt->columns = NULL; + return 1; } @@ -70,193 +56,176 @@ pdo_dbh_t *dbh = stmt->dbh; pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_db_handle *H = S->H; - RETCODE resret, ret; - int i, j; - int arows; - unsigned int size; - - dbsetuserdata(H->link, &S->err); + RETCODE ret; - if (S->rows) { - /* clean them up */ - free_rows(S TSRMLS_CC); - } + //pdo_dblib_stmt_cursor_closer(stmt); + dbsetuserdata(H->link, (BYTE*) &S->err); + if (FAIL == dbcmd(H->link, stmt->active_query_string)) { return 0; } + if (FAIL == dbsqlexec(H->link)) { return 0; } - - resret = dbresults(H->link); - if (resret == FAIL) { + + ret = dbresults(H->link); + + if (ret == FAIL) { return 0; } - ret = dbnextrow(H->link); - stmt->row_count = DBCOUNT(H->link); + stmt->column_count = dbnumcols(H->link); - if (ret == NO_MORE_ROWS) { - return 1; - } - - if (!S->cols) { - S->ncols = dbnumcols(H->link); + return 1; +} - if (S->ncols <= 0) { - return 1; - } - S->cols = ecalloc(S->ncols, sizeof(pdo_dblib_col)); - stmt->column_count = S->ncols; - - for (i = 0, j = 0; i < S->ncols; i++) { - char *tmp = NULL; +static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt) +{ + pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; + pdo_dblib_db_handle *H = S->H; + RETCODE ret; - S->cols[i].coltype = dbcoltype(H->link, i+1); - S->cols[i].name = (char*)dbcolname(H->link, i+1); + ret = dbresults(H->link); - if (!strlen(S->cols[i].name)) { - if (j) { - spprintf(&tmp, 0, "computed%d", j++); - strlcpy(S->cols[i].name, tmp, strlen(tmp)+1); - efree(tmp); - } else { - S->cols[i].name = "computed"; - j++; - } - } - - S->cols[i].source = (char*)dbcolsource(H->link, i+1); - tmp = estrdup(S->cols[i].source ? S->cols[i].source : ""); - S->cols[i].source = tmp; - efree(tmp); - - S->cols[i].maxlen = dbcollen(H->link, i+1); - } + if (ret == FAIL) { + return 0; } - arows = 100; - size = S->ncols * sizeof(pdo_dblib_colval); - S->rows = safe_emalloc(arows, size, 0); + stmt->row_count = DBCOUNT(H->link); + stmt->column_count = dbnumcols(H->link); - /* let's fetch all the data */ - do { - if (S->nrows >= arows) { - arows *= 2; - S->rows = erealloc(S->rows, arows * size); - } - for (i = 0; i < S->ncols; i++) { - pdo_dblib_colval *val = &S->rows[S->nrows * S->ncols + i]; - - if (dbdatlen(H->link, i+1) == 0 && dbdata(H->link, i+1) == NULL) { - val->len = 0; - val->data = NULL; - } else { - switch (S->cols[i].coltype) { - case SQLCHAR: - case SQLTEXT: - case SQLVARBINARY: - case SQLBINARY: - case SQLIMAGE: - val->len = dbdatlen(H->link, i+1); - val->data = emalloc(val->len + 1); - memcpy(val->data, dbdata(H->link, i+1), val->len); - val->data[val->len] = '\0'; - break; - case SQLMONEY: - case SQLMONEY4: - case SQLMONEYN: { - DBFLT8 money_value; - dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLFLT8, (LPBYTE)&money_value, val->len); - val->len = spprintf(val->data, 0, "%.4f", money_value); - } - break; - default: - if (dbwillconvert(S->cols[i].coltype, SQLCHAR)) { - val->len = 32 + (2 * dbdatlen(H->link, i+1)); - val->data = emalloc(val->len); - - val->len = dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1), - dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len); - - if (val->len >= 0) { - val->data[val->len] = '\0'; - } - } else { - val->len = 0; - val->data = NULL; - } - } - } - } - - S->nrows++; - - ret = dbnextrow(H->link); - - if (ret == BUF_FULL) { - dbclrbuf(H->link, DBLASTROW(H->link)-1); - } - } while (ret != FAIL && ret != NO_MORE_ROWS); - - if (resret != NO_MORE_RESULTS) { - /* there are additional result sets available */ - dbresults(H->link); - /* cancel pending rows */ - dbcanquery(H->link); - - /* TODO: figure out a sane solution */ - } - - S->current = -1; - - return 1; + return 1; } static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, long offset TSRMLS_DC) { + + RETCODE ret; + int i; + pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; + pdo_dblib_db_handle *H = S->H; - if (!S->rows) { + /* fetch the first/next row */ + ret = dbnextrow(H->link); + + if (ret == FAIL || ret == NO_MORE_ROWS) { return 0; } - - if (++S->current < S->nrows) { - return 1; + + /* + * This check is only valid with dbsetopt(DBBUFFER) + * and can be removed + */ + if (ret == BUF_FULL) { + dbclrbuf(H->link, DBLASTROW(H->link)-1); + /* retry dbnextrow, no row was returned from server */ + ret = dbnextrow(H->link); + if (ret != REG_ROW) + return 0; } - return 0; + return 1; } static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; + pdo_dblib_db_handle *H = S->H; + struct pdo_column_data *col = &stmt->columns[colno]; + char *tmp = NULL; - if (!S->rows) { - return 0; + col->name = (char*)dbcolname(H->link, colno+1); + + if (!strlen(col->name)) { + spprintf(&tmp, 0, "computed%d", colno); + strlcpy(col->name, tmp, strlen(tmp)+1); + efree(tmp); } - col->maxlen = S->cols[colno].maxlen; - col->namelen = strlen(S->cols[colno].name); - col->name = estrdup(S->cols[colno].name); + col->maxlen = dbcollen(H->link, colno+1); + col->namelen = strlen(col->name); col->param_type = PDO_PARAM_STR; - + return 1; } static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC) { + pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; - pdo_dblib_colval *val = &S->rows[S->current * S->ncols + colno]; + pdo_dblib_db_handle *H = S->H; - *ptr = val->data; - *len = val->len; + int coltype; + unsigned int tmp_len; + char *tmp_ptr; + + coltype = dbcoltype(H->link, colno+1); + + *len = dbdatlen(H->link, colno+1); + *ptr = dbdata(H->link, colno+1); + + if (*len == 0 && *ptr == NULL) { + return 1; + } + + switch (coltype) { + case SYBVARBINARY: + case SYBBINARY: + case SYBIMAGE: + /* TODO: Return above as php stream */ + case SYBTEXT: + case SYBCHAR: + case SYBVARCHAR: + tmp_ptr = emalloc(*len + 1); + memcpy(tmp_ptr, *ptr, *len); + tmp_ptr[*len] = '\0'; + *ptr = tmp_ptr; + ++(*len); + break; + case SYBINTN: + case SYBINT1: + case SYBINT4: + case SYBINT8: + case SYBFLT8: + case SYBDATETIME: + case SYBBIT: + case SYBMONEY4: + case SYBMONEY: + case SYBDATETIME4: + case SYBREAL: + case SYBNUMERIC: + case SYBDECIMAL: + case SYBFLTN: + case SYBMONEYN: + case SYBDATETIMN: + /* See ext/mssql for decoding these magic numbers */ + tmp_len = 32 + (2 * (*len)); + tmp_ptr = emalloc(tmp_len); + + *len = dbconvert(NULL, coltype, *ptr, *len, SYBCHAR, + tmp_ptr, tmp_len); + + if (*len >= 0) { + tmp_ptr[*len] = '\0'; + } + *ptr = tmp_ptr; + *len = tmp_len; + break; + default: + *len = 0; + *ptr = NULL; + } + + *caller_frees = 1; + return 1; } @@ -266,15 +235,14 @@ return 1; } -static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC) +static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; - if (S->rows) { - free_rows(S TSRMLS_CC); - S->rows = NULL; - } + pdo_dblib_stmt_cursor_closer(stmt); + efree(S); + return 1; } @@ -287,8 +255,8 @@ pdo_dblib_stmt_param_hook, NULL, /* set attr */ NULL, /* get attr */ - NULL, /* meta */ - NULL, /* nextrow */ - dblib_dblib_stmt_cursor_closer + NULL, /* get column meta */ + NULL, /* next rowset */ + pdo_dblib_stmt_cursor_closer }; Index: php_pdo_dblib_int.h =================================================================== --- php_pdo_dblib_int.h (revision 295996) +++ php_pdo_dblib_int.h (working copy) @@ -35,44 +35,12 @@ # define EHANDLEFUNC DBERRHANDLE_PROC # define MHANDLEFUNC DBMSGHANDLE_PROC # define DBSETOPT(a, b, c) dbsetopt(a, b, c) -# define SYBESMSG SQLESMSG -# define SYBESEOF SQLESEOF -# define SYBEFCON SQLECONN // SQLEFCON does not exist in MS SQL Server. -# define SYBEMEM SQLEMEM -# define SYBEPWD SQLEPWD #else # include <sybfront.h> # include <sybdb.h> # include <syberror.h> -/* alias some types */ -# define SQLTEXT SYBTEXT -# define SQLCHAR SYBCHAR -# define SQLVARCHAR SYBVARCHAR -# define SQLINT1 SYBINT1 -# define SQLINT2 SYBINT2 -# define SQLINT4 SYBINT4 -# define SQLINTN SYBINTN -# define SQLBIT SYBBIT -# define SQLFLT4 SYBREAL -# define SQLFLT8 SYBFLT8 -# define SQLFLTN SYBFLTN -# define SQLDECIMAL SYBDECIMAL -# define SQLNUMERIC SYBNUMERIC -# define SQLDATETIME SYBDATETIME -# define SQLDATETIM4 SYBDATETIME4 -# define SQLDATETIMN SYBDATETIMN -# define SQLMONEY SYBMONEY -# define SQLMONEY4 SYBMONEY4 -# define SQLMONEYN SYBMONEYN -# define SQLIMAGE SYBIMAGE -# define SQLBINARY SYBBINARY -# define SQLVARBINARY SYBVARBINARY -# ifdef SYBUNIQUE -# define SQLUNIQUE SYBUNIQUE -# endif - # define DBERRHANDLE(a, b) dberrhandle(b) # define DBMSGHANDLE(a, b) dbmsghandle(b) # define DBSETOPT(a, b, c) dbsetopt(a, b, c, -1) @@ -109,33 +77,11 @@ typedef struct { LOGINREC *login; DBPROCESS *link; - pdo_dblib_err err; } pdo_dblib_db_handle; typedef struct { - int coltype; - char *name; - int maxlen; - char *source; -} pdo_dblib_col; - -typedef struct { - unsigned long len; - char *data; -} pdo_dblib_colval; - -typedef struct { pdo_dblib_db_handle *H; - - int ncols; - pdo_dblib_col *cols; - - pdo_dblib_colval *rows; - int nrows; - - int current; - pdo_dblib_err err; } pdo_dblib_stmt; Index: dblib_driver.c =================================================================== --- dblib_driver.c (revision 295996) +++ dblib_driver.c (working copy) @@ -92,7 +92,7 @@ { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; pdo_dblib_stmt *S = ecalloc(1, sizeof(*S)); - + S->H = H; stmt->driver_data = S; stmt->methods = &dblib_stmt_methods; @@ -116,7 +116,7 @@ if (FAIL == dbsqlexec(H->link)) { return -1; } - + resret = dbresults(H->link); if (resret == FAIL) { @@ -162,7 +162,7 @@ *q++ = '\''; *q++ = '\0'; *quotedlen = l+1; - + return 1; } @@ -171,14 +171,16 @@ dblib_handle_preparer, dblib_handle_doer, dblib_handle_quoter, - NULL, - NULL, - NULL, - NULL, - NULL, /* last insert */ + NULL, /* begin */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* set attribute */ + NULL, /* last insert id */ dblib_fetch_error, /* fetch error */ - NULL, /* get attr */ + NULL, /* get attribute */ NULL, /* check liveness */ + NULL, /* get driver methods */ + NULL, /* persistent shutdown */ }; static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) @@ -210,7 +212,7 @@ if (dbh->password) { DBSETLPWD(H->login, dbh->password); } - + #if !PHP_DBLIB_IS_MSSQL if (vars[0].optval) { DBSETLCHARSET(H->login, vars[0].optval); @@ -231,10 +233,10 @@ } /* dblib do not return more than this length from text/image */ - DBSETOPT(H->link, DBTEXTLIMIT, "2147483647"); - + dbsetopt(H->link, DBTEXTLIMIT, "2147483647", -1); + /* limit text/image from network */ - DBSETOPT(H->link, DBTEXTSIZE, "2147483647"); + dbsetopt(H->link, DBTEXTSIZE, "2147483647", -1); if (vars[3].optval && FAIL == dbuse(H->link, vars[3].optval)) { goto cleanup; @@ -266,13 +268,7 @@ } pdo_driver_t pdo_dblib_driver = { -#if PDO_DBLIB_IS_MSSQL - PDO_DRIVER_HEADER(mssql), -#elif defined(PHP_WIN32) - PDO_DRIVER_HEADER(sybase), -#else PDO_DRIVER_HEADER(dblib), -#endif pdo_dblib_handle_factory }; Index: README =================================================================== --- README (revision 295996) +++ README (working copy) @@ -5,18 +5,12 @@ - MSSQL DB lib - FreeTDS DB lib -This extension will compile and register itself as 'mssql' when built against -the mssql libraries (and be named php_pdo_mssql.dll), or 'sybase' otherwise -(php_pdo_sybase.dll) +This extension will compile and register itself as 'dblib'. -If you want to try out the free "desktop" version of SQL Server, known as the MSDE, google to obtain the appropriate download link. Here are some short tips on getting it running: +If you want to try out the free "desktop" version of SQL Server, known as SQL Server Express, +google to obtain the appropriate download link. Here are some short tips on getting it running: - Download it and run it to extract it -- Open up a command prompt -- cd \MSDERelA -- setup.exe SQLSECURITY=1 SAPWD=yoursecretpassword -- cd \Program Files\Microsoft SQL Server\80\Tools\Binn -- SVRNETCN.exe - enable TCP (you MUST do this if you want to access it via FreeTDS/Sybase libs) - net start mssqlserver |
Copyright © 2001-2025 The PHP Group All rights reserved. |
Last updated: Thu Jan 30 18:01:29 2025 UTC |