php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #50755
Patch pdo_dblib_unbuffer-5.3.patch revision 2010-04-05 17:35 UTC by ssufficool at gmail dot com
revision 2010-03-19 23:33 UTC by ssufficool at gmail dot com
revision 2010-03-09 22:23 UTC by ssufficool at gmail dot com
Patch pdo_dblib_unbuffer-6.patch revision 2010-03-09 22:24 UTC by ssufficool at gmail dot com
Patch pdo_dblib_unbuffer-5.2.patch revision 2010-03-09 22:23 UTC by ssufficool at gmail dot com

Patch pdo_dblib_unbuffer-6.patch for PDO related Bug #50755

Patch version 2010-03-09 22:24 UTC

Return to Bug #50755 | Download this patch
Patch Revisions:

Developer: ssufficool@gmail.com

Index: ext/pdo_dblib/pdo_dblib.c
===================================================================
--- ext/pdo_dblib/pdo_dblib.c	(revision 296010)
+++ ext/pdo_dblib/pdo_dblib.c	(working copy)
@@ -70,7 +70,7 @@
 	NULL,
 	PHP_RSHUTDOWN(pdo_dblib),
 	PHP_MINFO(pdo_dblib),
-	"0.9",
+	"1.0.1",
 	PHP_MODULE_GLOBALS(dblib),
 	PHP_GINIT(dblib),
 	NULL,
@@ -127,7 +127,7 @@
 #if 0
 	php_error_docref(NULL TSRMLS_CC, E_WARNING,
 		"dblib error: %d %s (severity %d)",
-		dberr, dberrstr, severity);	
+		dberr, dberrstr, severity);
 #endif
 
 	return INT_CANCEL;
@@ -187,18 +187,18 @@
 	if (FAIL == dbinit()) {
 		return FAILURE;
 	}
-	
+
 	if (FAILURE == php_pdo_register_driver(&pdo_dblib_driver)) {
 		return FAILURE;
 	}
-	
-	/* TODO: 
-	
+
+	/* TODO:
+
 	dbsetifile()
 	dbsetmaxprocs()
 	dbsetlogintime()
 	dbsettime()
-	
+
 	 */
 
 #if !PHP_DBLIB_IS_MSSQL
Index: ext/pdo_dblib/dblib_stmt.c
===================================================================
--- ext/pdo_dblib/dblib_stmt.c	(revision 296010)
+++ ext/pdo_dblib/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,7 +235,17 @@
 	return 1;
 }
 
+static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
+{
+	pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
 
+	pdo_dblib_stmt_cursor_closer(stmt);
+
+	efree(S);
+
+	return 1;
+}
+
 struct pdo_stmt_methods dblib_stmt_methods = {
 	pdo_dblib_stmt_dtor,
 	pdo_dblib_stmt_execute,
@@ -276,6 +255,8 @@
 	pdo_dblib_stmt_param_hook,
 	NULL, /* set attr */
 	NULL, /* get attr */
-	NULL, /* meta */
+	NULL, /* get column meta */
+	NULL, /* next rowset */
+	pdo_dblib_stmt_cursor_closer
 };
 
Index: ext/pdo_dblib/php_pdo_dblib_int.h
===================================================================
--- ext/pdo_dblib/php_pdo_dblib_int.h	(revision 296010)
+++ ext/pdo_dblib/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: ext/pdo_dblib/dblib_driver.c
===================================================================
--- ext/pdo_dblib/dblib_driver.c	(revision 296010)
+++ ext/pdo_dblib/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
 };
 
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Wed Apr 23 18:01:55 2014 UTC