⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 php_sybase_ct.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* numeric(10) vs numeric(10, 1) */				result->numerics[i] = (result->datafmt[i].scale == 0) ? 3 : 2;				break;			default:				result->datafmt[i].maxlength++;				result->numerics[i] = 0;				break;		}		result->tmp_buffer[i] = (char *)emalloc(result->datafmt[i].maxlength);		result->datafmt[i].datatype = CS_CHAR_TYPE;		result->datafmt[i].format = CS_FMT_NULLTERM;		ct_bind(sybase_ptr->cmd, i+1, &result->datafmt[i], result->tmp_buffer[i], &result->lengths[i], &result->indicators[i]);	}	result->fields = (sybase_field *) safe_emalloc(sizeof(sybase_field), num_fields, 0);	j=0;	for (i=0; i<num_fields; i++) {		char computed_buf[16];		if (result->datafmt[i].namelen>0) {			result->fields[i].name = estrndup(result->datafmt[i].name, result->datafmt[i].namelen);		} else {			if (j>0) {				snprintf(computed_buf, 16, "computed%d", j);			} else {				strcpy(computed_buf, "computed");			}			result->fields[i].name = estrdup(computed_buf);			j++;		}		result->fields[i].column_source = empty_string;		result->fields[i].max_length = result->datafmt[i].maxlength-1;		result->fields[i].numeric = result->numerics[i];		Z_TYPE(result->fields[i]) = result->types[i];	}		if (buffered) {		retcode = CS_SUCCEED;	} else {		if ((retcode = php_sybase_fetch_result_row(result, -1)) == CS_FAIL) {			return NULL;		}	}	result->last_retcode = retcode;	return result;}static void php_sybase_query (INTERNAL_FUNCTION_PARAMETERS, int buffered){	zval **query, **sybase_link_index=NULL;	zval **store_mode= NULL;	int id, deadlock_count, store;	sybase_link *sybase_ptr;	sybase_result *result;	CS_INT restype;	CS_RETCODE retcode;	enum {		Q_RESULT,				/* Success with results. */		Q_SUCCESS,				/* Success but no results. */		Q_FAILURE,				/* Failure, no results. */	} status;	store= 1;	switch(ZEND_NUM_ARGS()) {		case 1:			if (zend_get_parameters_ex(1, &query)==FAILURE) {				RETURN_FALSE;			}			id = SybCtG(default_link);			break;		case 2:			if (zend_get_parameters_ex(2, &query, &sybase_link_index)==FAILURE) {				RETURN_FALSE;			}			id = -1;			break;		case 3:			if (zend_get_parameters_ex(3, &query, &sybase_link_index, &store_mode)==FAILURE) {				RETURN_FALSE;			}			if (!buffered) {				php_error_docref(NULL TSRMLS_CC, E_NOTICE, "cannot use non-storing mode with buffered queries");				store = 1;			} else {				convert_to_long_ex(store_mode);				store= (Z_LVAL_PP(store_mode) != 0);			}			id = -1;			break;		default:			WRONG_PARAM_COUNT;			break;	}	ZEND_FETCH_RESOURCE2(sybase_ptr, sybase_link *, sybase_link_index, id, "Sybase-Link", le_link, le_plink);	convert_to_string_ex(query);	/* Fail if we already marked this connection dead. */	if (sybase_ptr->dead) {		RETURN_FALSE;	}		/* Check to see if a previous sybase_unbuffered_query has read all rows */	if (sybase_ptr->active_result_index) {		zval *tmp = NULL;				php_error_docref(NULL TSRMLS_CC, E_NOTICE, "called without first fetching all rows from a previous unbuffered query");		if (sybase_ptr->cmd) {			ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);		}				/* Get the resultset and free it */		ALLOC_ZVAL(tmp);		Z_LVAL_P(tmp)= sybase_ptr->active_result_index;		Z_TYPE_P(tmp)= IS_RESOURCE;		INIT_PZVAL(tmp);		ZEND_FETCH_RESOURCE(result, sybase_result *, &tmp, -1, "Sybase result", le_result);				/* Causes the following segfault:		   Program received signal SIGSEGV, Segmentation fault.		   0x8144380 in _efree (ptr=0x81fe024, __zend_filename=0x81841a0 "php4/ext/sybase_ct/php_sybase_ct.c", 		   __zend_lineno=946, __zend_orig_filename=0x0, __zend_orig_lineno=0) at php4/Zend/zend_alloc.c:229		   php4/Zend/zend_alloc.c:229:7284:beg:0x8144380		*/		#if O_TIMM		if (result) {			php_sybase_finish_results(result);		}		#endif				zval_ptr_dtor(&tmp);		zend_list_delete(sybase_ptr->active_result_index);		sybase_ptr->active_result_index= 0;	}	/* Repeat until we don't deadlock. */	deadlock_count= 0;	for (;;) {		result = NULL;		sybase_ptr->deadlock = 0;		sybase_ptr->affected_rows = 0;		/* On Solaris 11.5, ct_command() can be moved outside the		 * loop, but not on Linux 11.0.		 */		if (ct_command(sybase_ptr->cmd, CS_LANG_CMD, Z_STRVAL_PP(query), CS_NULLTERM, CS_UNUSED)!=CS_SUCCEED) {			/* If this didn't work, the connection is screwed but			 * ct-lib might not set CS_CONSTAT_DEAD.  So set our own			 * flag.  This happens sometimes when the database is restarted			 * and/or its machine is rebooted, and ct_command() returns			 * CS_BUSY for some reason.			 */			sybase_ptr->dead = 1;			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Connection is dead");			RETURN_FALSE;		}		if (ct_send(sybase_ptr->cmd)!=CS_SUCCEED) {			ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);			sybase_ptr->dead = 1;			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Cannot send command");			RETURN_FALSE;		}		/* Use the first result set or succeed/fail status and discard the		 * others.  Applications really shouldn't be making calls that		 * return multiple result sets, but if they do then we need to		 * properly read or cancel them or the connection will become		 * unusable.		 */		if (ct_results(sybase_ptr->cmd, &restype)!=CS_SUCCEED) {			ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);			sybase_ptr->dead = 1;			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Cannot read results");			RETURN_FALSE;		}		switch ((int) restype) {			case CS_CMD_FAIL:			default:				status = Q_FAILURE;				break;			case CS_CMD_SUCCEED:			case CS_CMD_DONE: {					CS_INT row_count;					if (ct_res_info(sybase_ptr->cmd, CS_ROW_COUNT, &row_count, CS_UNUSED, NULL)==CS_SUCCEED) {						sybase_ptr->affected_rows = (long)row_count;					}				}				/* Fall through */			case CS_COMPUTEFMT_RESULT:			case CS_ROWFMT_RESULT:			case CS_DESCRIBE_RESULT:			case CS_MSG_RESULT:				buffered= 0;				/* These queries have no need for buffering */				status = Q_SUCCESS;				break;			case CS_COMPUTE_RESULT:			case CS_CURSOR_RESULT:			case CS_PARAM_RESULT:			case CS_ROW_RESULT:			case CS_STATUS_RESULT:				result = php_sybase_fetch_result_set(sybase_ptr, buffered, store);				if (result == NULL) {					ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);					RETURN_FALSE;				}				status = Q_RESULT;				break;		}				/* Check for left-over results */		if (!buffered && status != Q_RESULT) {			while ((retcode = ct_results(sybase_ptr->cmd, &restype))==CS_SUCCEED) {				switch ((int) restype) {					case CS_CMD_SUCCEED:					case CS_CMD_DONE:						break;					case CS_CMD_FAIL:						status = Q_FAILURE;						break;					case CS_COMPUTE_RESULT:					case CS_CURSOR_RESULT:					case CS_PARAM_RESULT:					case CS_ROW_RESULT:						if (status != Q_RESULT) {							result = php_sybase_fetch_result_set(sybase_ptr, buffered, store);							if (result == NULL) {								ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);								sybase_ptr->dead = 1;								RETURN_FALSE;							}							status = Q_RESULT;							retcode = result->last_retcode; 						} else {							/* Unexpected results, cancel them. */							ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_CURRENT);						}						break;					case CS_STATUS_RESULT:						/* Unexpected results, cancel them. */						ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_CURRENT);						break;					default:						status = Q_FAILURE;						break;				}				if (status == Q_FAILURE) {					ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);				}				if (retcode == CS_END_RESULTS) {					break;				}			}			switch (retcode) {				case CS_END_RESULTS:					/* Normal. */					break;				case CS_FAIL:					/* Hopefully this either cleans up the connection, or the					 * connection ends up marked dead so it will be reopened					 * if it is persistent.  We may want to do					 * ct_close(CS_FORCE_CLOSE) if ct_cancel() fails; see the					 * doc for ct_results()==CS_FAIL.					 */					ct_cancel(NULL, sybase_ptr->cmd, CS_CANCEL_ALL);					/* Don't take chances with the vagaries of ct-lib.  Mark it					 * dead ourselves.					 */					sybase_ptr->dead = 1;				case CS_CANCELED:				default:					status = Q_FAILURE;					break;			}		}		/* Retry deadlocks up until deadlock_retry_count times */				if (sybase_ptr->deadlock && SybCtG(deadlock_retry_count) != -1 && ++deadlock_count > SybCtG(deadlock_retry_count)) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Retried deadlock %d times [max: %ld], giving up\n", deadlock_count- 1, SybCtG(deadlock_retry_count));			if (result != NULL) {				_free_sybase_result(result);			}			break;		}		/* If query completed without deadlock, break out of the loop.		 * Sometimes deadlock results in failures and sometimes not,		 * it seems to depend on the server flavor.  But we want to		 * retry all deadlocks.		 */		if (sybase_ptr->dead || sybase_ptr->deadlock == 0) {			break;		}		/* Get rid of any results we may have fetched.  This happens:		 * e.g., our result set may be a stored procedure status which		 * is returned even if the stored procedure deadlocks.  As an		 * optimization, we could try not to fetch results in known		 * deadlock conditions, but deadlock is (should be) rare.		 */		if (result != NULL) {			_free_sybase_result(result);		}	}	if (status == Q_SUCCESS) {		RETURN_TRUE;	}	if (status == Q_FAILURE) {		if (result != NULL) {			_free_sybase_result(result);		}		RETURN_FALSE;	}	/* Indicate we have data in case of buffered queries */	id= ZEND_REGISTER_RESOURCE(return_value, result, le_result);	sybase_ptr->active_result_index= buffered ? id : 0;}/* {{{ proto int sybase_query(string query [, int link_id])   Send Sybase query */PHP_FUNCTION(sybase_query){	php_sybase_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto int sybase_unbuffered_query(string query [, int link_id])   Send Sybase query */PHP_FUNCTION(sybase_unbuffered_query){	php_sybase_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* {{{ proto bool sybase_free_result(int result)   Free result memory */PHP_FUNCTION(sybase_free_result){	zval **sybase_result_index;	sybase_result *result;	if (ZEND_NUM_ARGS() !=1 || zend_get_parameters_ex(1, &sybase_result_index) == FAILURE) {		WRONG_PARAM_COUNT;	}	if (Z_TYPE_PP(sybase_result_index) == IS_RESOURCE && Z_LVAL_PP(sybase_result_index) == 0) {		RETURN_FALSE;	}	ZEND_FETCH_RESOURCE(result, sybase_result *, sybase_result_index, -1, "Sybase result", le_result);		/* Did we fetch up until the end? */	if (result->last_retcode != CS_END_DATA && result->last_retcode != CS_END_RESULTS) {		/* php_error_docref(NULL TSRMLS_CC, E_WARNING, "Sybase:  Cancelling the rest of the results\n"); */		ct_cancel(NULL, result->sybase_ptr->cmd, CS_CANCEL_ALL);		php_sybase_finish_results(result);	}		zend_list_delete(Z_LVAL_PP(sybase_result_index));	RETURN_TRUE;}/* }}} *//* {{{ proto string sybase_get_last_message(void)   Returns the last message from server (over min_message_severity) */PHP_FUNCTION(sybase_get_last_message){	RETURN_STRING(SybCtG(server_message), 1);}/* }}} *//* {{{ proto int sybase_num_rows(int result)   Get number of rows in result */PHP_FUNCTION(sybase_num_rows){	zval **sybase_result_index;	sybase_result *result;	if (ZEND_NUM_ARGS() !=1 || zend_get_parameters_ex(1, &sybase_result_index) == FAILURE) {		WRONG_PARAM_COUNT;	}	ZEND_FETCH_RESOURCE(result, sybase_result *, sybase_result_index, -1, "Sybase result", le_result);	Z_LVAL_P(return_value) = result->num_rows;	Z_TYPE_P(return_value) = IS_LONG;}/* }}} *//* {{{ proto int sybase_num_fields(int result)   Get number of fields in result */PHP_FUNCTION(sybase_num_fields){	zval **sybase_result_index;	sybase_result *result;	if (ZEND_NUM_ARGS() !=1 || zend_get_parameters_ex(1, &sybase_result_index) == FAILURE) {		WRONG_PARAM_COUNT;	}	ZEND_FETCH_RESOURCE(result, sybase_result *, sybase_result_index, -1, "Sybase result", le_result);	Z_LVAL_P(return_value) = result->num_fields;	Z_TYPE_P(return_value) = IS_LONG;}/* }}} *//* {{{ proto array sybase_fetch_row(int result)   Get row as enumerated array */PHP_FUNCTION(sybase_fetch_row){	zval **sybase_result_index;	int i;	sybase_result *result;	zval *field_content;	if (ZEND_NUM_ARGS() !=1 || zend_get_parameters_ex(1, &sybase_result_index) == FAILURE) {		WRONG_PARAM_COUNT;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -