php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #60703
Patch php-5.3.10-cursor-support-for-pdo_oci.patch revision 2012-03-20 10:19 UTC by psrustik at yandex dot ru
Patch php-5.3.8-cursor-support-for-pdo_oci.patch revision 2012-01-12 22:41 UTC by marcos dot ramirez dot aranda at gmail dot com
revision 2012-01-10 19:56 UTC by marcos dot ramirez dot aranda at gmail dot com

Patch php-5.3.8-cursor-support-for-pdo_oci.patch for PDO OCI Bug #60703

Patch version 2012-01-10 19:56 UTC

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

Developer: marcos.ramirez.aranda@gmail.com

diff -rubB php-5.3.8.old/ext/pdo_oci/oci_statement.c php-5.3.8/ext/pdo_oci/oci_statement.c
--- php-5.3.8.old/ext/pdo_oci/oci_statement.c	2010-12-31 23:19:59.000000000 -0300
+++ php-5.3.8/ext/pdo_oci/oci_statement.c	2012-01-10 15:27:41.276135756 -0300
@@ -97,6 +97,9 @@
 		for (i = 0; i < stmt->column_count; i++) {
 			if (S->cols[i].data) {
 				switch (S->cols[i].dtype) {
+					 case SQLT_RSET:
+						 OCIHandleFree(S->cols[i].data, OCI_HTYPE_STMT);
+						 break;
 					case SQLT_BLOB:
 					case SQLT_CLOB:
 						/* do nothing */
@@ -235,6 +238,14 @@
 		*rcodepp = &P->retcode;
 		*indpp = &P->indicator;
 		return OCI_CONTINUE;
+	} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STMT) {
+		P->actual_len = sizeof(OCIStmt*);               
+		*bufpp = P->thing;
+		*alenpp = &P->actual_len;
+		*piecep = OCI_ONE_PIECE;
+		*rcodepp = &P->retcode;
+		*indpp = &P->indicator;
+		return OCI_CONTINUE;            
 	}
 
 	if (Z_TYPE_P(param->parameter) == IS_OBJECT || Z_TYPE_P(param->parameter) == IS_RESOURCE) {
@@ -258,6 +269,55 @@
 	return OCI_CONTINUE;
 } /* }}} */
 
+zend_object_value *oci_create_rset(pdo_stmt_t *stmt, OCIStmt *oci_stmt) {
+	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
+	//	pdo_oci_column *C = &S->cols[colno];
+
+	ub4 colcount;
+	pdo_oci_stmt *NS = ecalloc(1, sizeof(*NS));
+	zend_object_value *retval = ecalloc(1, sizeof(*retval));
+			
+	*retval = stmt->ce->create_object (stmt->ce);
+	pdo_stmt_t *stm = (pdo_stmt_t*)zend_object_store_get_object_by_handle(retval->handle);
+	
+	//			OCIHandleAlloc( (dvoid *) S->H->env, (dvoid **) &p_err, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0);
+	stm->dbh = stmt->dbh;
+	
+	NS->exec_type = OCI_DEFAULT;
+	NS->H = S->H;
+	
+	stm->supports_placeholders = PDO_PLACEHOLDER_NAMED;
+	efree(NS->stmt);
+	// NS->stmt = *((OCIStmt**)C->data);
+	NS->stmt = oci_stmt;
+	// Allocate new handle 
+
+	stm->driver_data = NS;
+	stm->methods = &oci_stmt_methods;
+	//stm->methods = stmt->methods;
+	
+	/* create our own private error handle */
+	OCIHandleAlloc(S->H->env, (dvoid*)&NS->err, OCI_HTYPE_ERROR, 0, NULL);
+	
+	stm->database_object_handle = stmt->database_object_handle;
+	
+	/* do first-time-only definition of bind/mapping stuff */
+	if (!NS->stmt_type) {
+		STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_STMT_TYPE",
+					  (NS->stmt, OCI_HTYPE_STMT, &NS->stmt_type, 0, OCI_ATTR_STMT_TYPE, S->err));
+	}
+	/* how many columns do we have ? */
+	STMT_CALL_MSG(OCIAttrGet, "ATTR_PARAM_COUNT",
+				  (NS->stmt, OCI_HTYPE_STMT, &colcount, 0, OCI_ATTR_PARAM_COUNT, S->err));
+	stm->column_count = (int)colcount;			
+	stm->executed = 1;
+	NS->cols = ecalloc(colcount, sizeof(pdo_oci_column));
+	pdo_stmt_describe_columns(stm);
+	stm->executed = 1;
+
+	return retval;
+}
+
 static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC) /* {{{ */
 {
 	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
@@ -284,7 +344,10 @@
 				/* figure out what we're doing */
 				switch (PDO_PARAM_TYPE(param->param_type)) {
 					case PDO_PARAM_STMT:
-						return 0;
+						/* P->thing is now an  OCIStmt* */
+						P->oci_type = SQLT_RSET;
+						value_sz = sizeof(OCIStmt*);
+						break;
 
 					case PDO_PARAM_LOB:
 						/* P->thing is now an OCILobLocator * */
@@ -305,15 +368,15 @@
 				if (param->name) {
 					STMT_CALL(OCIBindByName, (S->stmt,
 							&P->bind, S->err, (text*)param->name,
-							param->namelen, 0, value_sz, P->oci_type,
+							param->namelen, P->oci_type == SQLT_RSET ? &P->thing : 0, value_sz, P->oci_type,
 							&P->indicator, 0, &P->retcode, 0, 0,
-							OCI_DATA_AT_EXEC));
+							P->oci_type == SQLT_RSET ? OCI_DEFAULT : OCI_DATA_AT_EXEC));
 				} else {
 					STMT_CALL(OCIBindByPos, (S->stmt,
 							&P->bind, S->err, param->paramno+1,
-							0, value_sz, P->oci_type,
+							P->oci_type == SQLT_RSET ? &P->thing : 0, value_sz, P->oci_type,
 							&P->indicator, 0, &P->retcode, 0, 0,
-							OCI_DATA_AT_EXEC));
+							P->oci_type == SQLT_RSET ? OCI_DEFAULT : OCI_DATA_AT_EXEC));
 				}
 
 				STMT_CALL(OCIBindDynamic, (P->bind,
@@ -331,6 +394,8 @@
 					STMT_CALL(OCIDescriptorAlloc, (S->H->env, &P->thing, OCI_DTYPE_LOB, 0, NULL));
 					STMT_CALL(OCIAttrSet, (P->thing, OCI_DTYPE_LOB, &empty, 0, OCI_ATTR_LOBEMPTY, S->err));
 					S->have_blobs = 1;
+				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STMT) {
+					STMT_CALL(OCIHandleAlloc,(S->H->env, &P->thing, OCI_HTYPE_STMT, 0, 0));
 				}
 				return 1;
 
@@ -358,6 +423,11 @@
 						Z_STRVAL_P(param->parameter) = erealloc(Z_STRVAL_P(param->parameter), P->actual_len+1);
 						Z_STRVAL_P(param->parameter)[P->actual_len] = '\0';
 					}
+				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STMT && P->thing) {
+					zend_object_value *retval = oci_create_rset(stmt, (OCIStmt*)P->thing);
+					//      STMT_CALL(OCIHandleAlloc,(S->H->env, &P->thing, OCI_HTYPE_STMT, 0, 0));
+					Z_TYPE_P(param->parameter) = IS_OBJECT;
+					param->parameter->value.obj = *retval;
 				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) {
 					php_stream *stm;
 
@@ -537,6 +607,16 @@
 
 	/* how much room do we need to store the field */
 	switch (dtype) {
+		case SQLT_RSET:
+			col->param_type = PDO_PARAM_STMT;
+			S->cols[colno].data = ecalloc(1,sizeof(OCIStmt*));
+			//S->cols[colno].datalen = sizeof(OCIStmt*);
+			S->cols[colno].datalen = 0;
+			STMT_CALL(OCIHandleAlloc,
+					  (S->H->env, (dvoid **) S->cols[colno].data,
+					   OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));
+			dyn = FALSE;
+			break;
 		case SQLT_LBI:
 		case SQLT_LNG:
 			if (dtype == SQLT_LBI) {
@@ -654,7 +734,7 @@
 
 	if (close_handle) {
 		OCILobClose(self->S->H->svc, self->S->err, self->lob);
-		OCIDescriptorFree(self->lob, OCI_DTYPE_LOB);
+		// OCIDescriptorFree(self->lob, OCI_DTYPE_LOB);
 		efree(self);
 	}
 
@@ -734,6 +814,20 @@
 			}
 			*len = 0;
 			return *ptr ? 1 : 0;
+		} else if (C->dtype == SQLT_RSET) {
+			zend_object_value *retval = oci_create_rset(stmt, *((OCIStmt**)C->data));
+			// Allocate new handle 
+			STMT_CALL(OCIHandleAlloc,
+					  (S->H->env, (dvoid **) C->data,
+					   OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));                  
+			// not needed
+			// STMT_CALL(OCIDefineByPos, (S->stmt, &C->def, S->err, colno+1,
+			// 						   C->data, 0, SQLT_RSET, &C->indicator,
+			//						   &C->fetched_len, &C->retcode, OCI_DEFAULT));
+			*ptr = (char *)retval;
+			*len = C->fetched_len;
+			*caller_frees = 0;
+			return 1;
 		}
 
 		*ptr = C->data;
diff -rubB php-5.3.8.old/ext/pdo/pdo_stmt.c php-5.3.8/ext/pdo/pdo_stmt.c
--- php-5.3.8.old/ext/pdo/pdo_stmt.c	2011-06-18 11:56:14.000000000 -0400
+++ php-5.3.8/ext/pdo/pdo_stmt.c	2012-01-10 14:45:06.400977840 -0300
@@ -574,6 +574,18 @@
 				type = new_type;
 			}
 			break;
+		case PDO_PARAM_STMT:
+			if (!value) {
+				ZVAL_NULL(dest);
+				break;
+			}
+ 
+			zend_object_value *retval ;
+			retval = (zend_object_value *)value;
+			Z_TYPE_P(dest) = IS_OBJECT;
+			dest->value.obj = *retval;
+			
+			break;
 			
 		case PDO_PARAM_INT:
 			if (value && value_len == sizeof(long)) {
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 22:01:28 2024 UTC