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

📄 php_odbc.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			RETURN_FALSE;		}				if (result->values[field_ind].vallen == SQL_NULL_DATA) {			efree(field);			RETURN_NULL();		}		/* chop the trailing \0 by outputing only 4095 bytes */		PHPWRITE(field,(rc == SQL_SUCCESS_WITH_INFO) ? 4095 :						   result->values[field_ind].vallen);		if (rc == SQL_SUCCESS) { /* no more data avail */			efree(field);			RETURN_TRUE;		}	}	RETURN_TRUE;}/* }}} *//* {{{ proto int odbc_result_all(resource result_id [, string format])   Print result as HTML table */PHP_FUNCTION(odbc_result_all){	char *buf = NULL;	int i, numArgs;	odbc_result *result;	RETCODE rc;	pval **pv_res, **pv_format;	SWORD sql_c_type;#ifdef HAVE_SQL_EXTENDED_FETCH	UDWORD crow;	UWORD RowStatus[1];#endif	numArgs = ZEND_NUM_ARGS();	if (numArgs ==  1) {		if (zend_get_parameters_ex(1, &pv_res) == FAILURE)			WRONG_PARAM_COUNT;	} else {		if (zend_get_parameters_ex(2, &pv_res, &pv_format) == FAILURE)			WRONG_PARAM_COUNT;	}					ZEND_FETCH_RESOURCE(result, odbc_result *, pv_res, -1, "ODBC result", le_result);		if (result->numcols == 0) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");		RETURN_FALSE;	}#ifdef HAVE_SQL_EXTENDED_FETCH	if (result->fetch_abs)		rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);	else#endif			rc = SQLFetch(result->stmt);	if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {		php_printf("<h2>No rows found</h2>\n");		RETURN_LONG(0);	}		/* Start table tag */	if (numArgs == 1) {		php_printf("<table><tr>");	} else {		convert_to_string_ex(pv_format);			php_printf("<table %s ><tr>",Z_STRVAL_PP(pv_format)); 	}		for(i = 0; i < result->numcols; i++)		php_printf("<th>%s</th>", result->values[i].name);	php_printf("</tr>\n");	while(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {		result->fetched++;		php_printf("<tr>");		for(i = 0; i < result->numcols; i++) {			sql_c_type = SQL_C_CHAR;			switch(result->values[i].coltype) {				case SQL_BINARY:				case SQL_VARBINARY:				case SQL_LONGVARBINARY:					if (result->binmode <= 0) {						php_printf("<td>Not printable</td>");						break;					}					if (result->binmode <= 1) sql_c_type = SQL_C_BINARY; 				case SQL_LONGVARCHAR:					if (IS_SQL_LONG(result->values[i].coltype) && 						result->longreadlen <= 0) {						php_printf("<td>Not printable</td>"); 						break;					}					if (buf == NULL) buf = emalloc(result->longreadlen);					rc = SQLGetData(result->stmt, (UWORD)(i + 1),sql_c_type,								buf, result->longreadlen, &result->values[i].vallen); 					php_printf("<td>");					if (rc == SQL_ERROR) {						odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData");						php_printf("</td></tr></table>");						efree(buf);						RETURN_FALSE;					}					if (rc == SQL_SUCCESS_WITH_INFO)						PHPWRITE(buf, result->longreadlen);					else if (result->values[i].vallen == SQL_NULL_DATA) {						php_printf("<td>NULL</td>");						break;					} else {						PHPWRITE(buf, result->values[i].vallen);					}					php_printf("</td>");					break;				default:					if (result->values[i].vallen == SQL_NULL_DATA) {						php_printf("<td>NULL</td>");					} else {						php_printf("<td>%s</td>", result->values[i].value);					}					break;			}		}   		php_printf("</tr>\n");#ifdef HAVE_SQL_EXTENDED_FETCH		if (result->fetch_abs)			rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);		else#endif			rc = SQLFetch(result->stmt);			}	php_printf("</table>\n");	if (buf) efree(buf);	RETURN_LONG(result->fetched);}/* }}} *//* {{{ proto bool odbc_free_result(resource result_id)   Free resources associated with a result */PHP_FUNCTION(odbc_free_result){	pval **pv_res;	odbc_result *result;	int i;	if (zend_get_parameters_ex(1, &pv_res) == FAILURE) {		WRONG_PARAM_COUNT;	}	ZEND_FETCH_RESOURCE(result, odbc_result *, pv_res, -1, "ODBC result", le_result);	if (result->values) {		for (i = 0; i < result->numcols; i++) {			if (result->values[i].value) {				efree(result->values[i].value);			}		}		efree(result->values);		result->values = NULL;	}				zend_list_delete(result->id);		RETURN_TRUE;}/* }}} *//* {{{ proto resource odbc_connect(string DSN, string user, string password [, int cursor_option])   Connect to a datasource */PHP_FUNCTION(odbc_connect){	odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto resource odbc_pconnect(string DSN, string user, string password [, int cursor_option])   Establish a persistent connection to a datasource */PHP_FUNCTION(odbc_pconnect){	odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ odbc_sqlconnect */int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int cur_opt, int persistent TSRMLS_DC){	RETCODE rc;		*conn = (odbc_connection *)pemalloc(sizeof(odbc_connection), persistent);	(*conn)->persistent = persistent;	SQLAllocEnv(&((*conn)->henv));	SQLAllocConnect((*conn)->henv, &((*conn)->hdbc));	#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) 	SQLSetConnectOption((*conn)->hdbc, SQL_TRANSLATE_OPTION,			SQL_SOLID_XLATOPT_NOCNV);#endif#ifdef HAVE_OPENLINK	{		char dsnbuf[1024];		short dsnbuflen;		rc = SQLDriverConnect((*conn)->hdbc, NULL, db, SQL_NTS,							dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen,							SQL_DRIVER_NOPROMPT);	}#else	if (cur_opt != SQL_CUR_DEFAULT) {		rc = SQLSetConnectOption((*conn)->hdbc, SQL_ODBC_CURSORS, cur_opt);		if (rc != SQL_SUCCESS) {  /* && rc != SQL_SUCCESS_WITH_INFO ? */			odbc_sql_error(*conn, SQL_NULL_HSTMT, "SQLSetConnectOption");			SQLFreeConnect((*conn)->hdbc);			pefree(*conn, persistent);			return FALSE;		}	}/*  Possible fix for bug #10250 *  Needs testing on UnixODBC < 2.0.5 though. */#if defined(HAVE_EMPRESS) || defined(HAVE_UNIXODBC) || defined(PHP_WIN32)/* *  Uncomment the line above, and comment line below to fully test  * #ifdef HAVE_EMPRESS */	{		int     direct = 0;		char    dsnbuf[1024];		short   dsnbuflen;		char    *ldb = 0;		int		ldb_len = 0;		if (strstr((char*)db, ";")) {			direct = 1;			if (uid && !strstr ((char*)db, "uid") && !strstr((char*)db, "UID")) {				ldb = (char*) emalloc(strlen(db) + strlen(uid) + strlen(pwd) + 12);				sprintf(ldb, "%s;UID=%s;PWD=%s", db, uid, pwd);			} else {				ldb_len = strlen(db)+1;				ldb = (char*) emalloc(ldb_len);				memcpy(ldb, db, ldb_len);			}		}		if (direct) {			rc = SQLDriverConnect((*conn)->hdbc, NULL, ldb, strlen(ldb), dsnbuf, 					              sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT);		} else {			rc = SQLConnect((*conn)->hdbc, db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS);		}		if (ldb) {			efree(ldb);		}	}#else	rc = SQLConnect((*conn)->hdbc, db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS);#endif#endif	if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {		odbc_sql_error(*conn, SQL_NULL_HSTMT, "SQLConnect");		SQLFreeConnect((*conn)->hdbc);		pefree((*conn), persistent);		return FALSE;	}/*	(*conn)->open = 1;*/	return TRUE;}/* }}} *//* Persistent connections: two list-types le_pconn, le_conn and a plist * where hashed connection info is stored together with index pointer to * the actual link of type le_pconn in the list. Only persistent  * connections get hashed up. Normal connections use existing pconnections. * Maybe this has to change with regard to transactions on pconnections? * Possibly set autocommit to on on request shutdown. * * We do have to hash non-persistent connections, and reuse connections. * In the case where two connects were being made, without closing the first * connect, access violations were occuring.  This is because some of the * "globals" in this module should actualy be per-connection variables.  I * simply fixed things to get them working for now.  Shane *//* {{{ odbc_do_connect */void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent){	char    *db = NULL;	char    *uid = NULL;	char    *pwd = NULL;	pval **pv_db, **pv_uid, **pv_pwd, **pv_opt;	odbc_connection *db_conn;	char *hashed_details;	int hashed_len, cur_opt;	/*  Now an optional 4th parameter specifying the cursor type	 *  defaulting to the cursors default	 */	switch(ZEND_NUM_ARGS()) {		case 3:				if (zend_get_parameters_ex(3, &pv_db, &pv_uid, &pv_pwd) == FAILURE) {				WRONG_PARAM_COUNT;			}			/* Use Default: Probably a better way to do this */			cur_opt = SQL_CUR_DEFAULT;			break;		case 4:			if (zend_get_parameters_ex(4, &pv_db, &pv_uid, &pv_pwd, &pv_opt) == FAILURE) {				WRONG_PARAM_COUNT;			}			convert_to_long_ex(pv_opt);			cur_opt = Z_LVAL_PP(pv_opt);			/* Confirm the cur_opt range */			if (! (cur_opt == SQL_CUR_USE_IF_NEEDED || 				cur_opt == SQL_CUR_USE_ODBC || 				cur_opt == SQL_CUR_USE_DRIVER || 				cur_opt == SQL_CUR_DEFAULT) ) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Cursor type (%d)", cur_opt);				RETURN_FALSE;			}			break;		default:			WRONG_PARAM_COUNT;			break;	}	convert_to_string_ex(pv_db);	convert_to_string_ex(pv_uid);	convert_to_string_ex(pv_pwd);	db = Z_STRVAL_PP(pv_db);	uid = Z_STRVAL_PP(pv_uid);	pwd = Z_STRVAL_PP(pv_pwd);	if (ODBCG(allow_persistent) <= 0) {		persistent = 0;	}	hashed_len = spprintf(&hashed_details, 0, "%s_%s_%s_%s_%d", ODBC_TYPE, db, uid, pwd, cur_opt);	/* FIXME the idea of checking to see if our connection is already persistent		is good, but it adds a lot of overhead to non-persistent connections.  We		should look and see if we can fix that somehow */	/* try to find if we already have this link in our persistent list,	 * no matter if it is to be persistent or not	 */try_and_get_another_connection:	if (persistent) {		list_entry *le;				if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_len + 1, (void **) &le)		  					== FAILURE) { /* the link is not in the persistent list */			list_entry new_le;						if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", ODBCG(num_links));				efree(hashed_details);				RETURN_FALSE;			}			if (ODBCG(max_persistent) != -1 && ODBCG(num_persistent) >= ODBCG(max_persistent)) {				php_error_docref(NULL TSRMLS_CC, E_WARNING,"Too many open persistent links (%ld)", ODBCG(num_persistent));				efree(hashed_details);				RETURN_FALSE;			}						if (!odbc_sqlconnect(&db_conn, db, uid, pwd, cur_opt, 1 TSRMLS_CC)) {				efree(hashed_details);				RETURN_FALSE;			}						Z_TYPE(new_le) = le_pconn;			new_le.ptr = db_conn;			if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_len + 1, &new_le,						sizeof(list_entry), NULL) == FAILURE) {				free(db_conn);				efree(hashed_details);				RETURN_FALSE;			}			ODBCG(num_persistent)++;			ODBCG(num_links)++;			db_conn->id = ZEND_REGISTER_RESOURCE(return_value, db_conn, le_pconn);		} else { /* found connection */			if (Z_TYPE_P(le) != le_pconn) {				RETURN_FALSE;			}			/*			 * check to see if the connection is still valid			 */			db_conn = (odbc_connection *)le->ptr;			/*			 * check to see if the connection is still in place (lurcher)			 */			if(ODBCG(check_persistent)){				RETCODE ret;				UCHAR d_name[32];				SWORD len;				ret = SQLGetInfo(db_conn->hdbc, 					SQL_DATA_SOURCE_READ_ONLY, 					d_name, sizeof(d_name), &len);				if(ret != SQL_SUCCESS || len == 0) {					zend_hash_del(&EG(persistent_list), hashed_details, hashed_len + 1);					/* Commented out to fix a possible double closure error 					 * when working with persistent connections as submitted by					 * bug #15758					 *					 * safe_odbc_disconnect(db_conn->hdbc);					 * SQLFreeConnect(db_conn->hdbc);					 */					goto try_and_get_another_connection;				}			}		}		db_conn->id = ZEND_REGISTER_RESOURCE(return_value, db_conn, le_pconn);	} else { /* non persistent */		list_entry *index_ptr, new_index_ptr;				if (zend_hash_find(&EG(regular_list), hashed_details, hashed_len + 1, 					(void **) &index_ptr) == SUCCESS) {			int type, conn_id;			void *ptr;					if (Z_TYPE_P(index_ptr) != le_index_ptr) {				RETURN_FALSE;			}			conn_id = (int)index_ptr->ptr;			ptr = zend_list_find(conn_id, &type);   /* check if the connection is still there */			if (ptr && (type == le_conn || type == le_pconn)) {				zend_list_addref(conn_id);				Z_LVAL_P(return_value) = conn_id;				Z_TYPE_P(return_value) = IS_RESOURCE;				efree(hashed_details);				return;			} else {				zend_hash_del(&EG(regular_list), hashed_details, hashed_len + 1);			}		}		if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) {			php_error_docref(NULL TSRMLS_CC, E_WARNING,"Too many open connections (%ld)",ODBCG(num_links));			efree(hashed_details);			RETURN_FALSE;		}		if (!odbc_sqlconnect(&db_conn, db, uid, pwd, cur_opt, 0 TSRMLS_CC)) {			efree(hashed_details);			RETURN_FALSE;		}		db_conn->id = ZEND_REGISTER_RESOURCE(return_value, db_conn, le_conn);		new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);		Z_TYPE(new_index_ptr) = le_index_ptr;		if (zend_hash_update(&EG(regular_list), hashed_details, hashed_len + 1, (void *) &new_index_ptr,				   sizeof(list_entry), NULL) == FAILURE) {			efree(hashed_details);			RETURN_FALSE;			/* XXX Free Connection */		}		ODBCG(num_links)++;	}	efree(hashed_details);}/* }}} *//* {{{ proto void odbc_close(resource connection_id)   Close an ODBC con

⌨️ 快捷键说明

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