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-5.3.patch for PDO related Bug #50755

Patch version 2010-03-09 22:23 UTC

Return to Bug #50755 | Download this patch
This patch is obsolete

Obsoleted by patches:

Patch Revisions:

Developer: ssufficool@gmail.com

Index: 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
 
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 07:01:29 2024 UTC