📄 php_odbc.c
字号:
odbc_result *result; int numArgs, i, ne; RETCODE rc; numArgs = ZEND_NUM_ARGS(); switch(numArgs) { case 1: if (zend_get_parameters_ex(1, &pv_res) == FAILURE) WRONG_PARAM_COUNT; break; case 2: if (zend_get_parameters_ex(2, &pv_res, &pv_param_arr) == FAILURE) WRONG_PARAM_COUNT; if (Z_TYPE_PP(pv_param_arr) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No array passed"); RETURN_FALSE; } break; default: WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE(result, odbc_result *, pv_res, -1, "ODBC result", le_result); /* XXX check for already bound parameters*/ if (result->numparams > 0 && numArgs == 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No parameters to SQL statement given"); RETURN_FALSE; } if (result->numparams > 0) { if ((ne = zend_hash_num_elements(Z_ARRVAL_PP(pv_param_arr))) < result->numparams) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Not enough parameters (%d should be %d) given", ne, result->numparams); RETURN_FALSE; } zend_hash_internal_pointer_reset(Z_ARRVAL_PP(pv_param_arr)); params = (params_t *)emalloc(sizeof(params_t) * result->numparams); for(i = 1; i <= result->numparams; i++) { if (zend_hash_get_current_data(Z_ARRVAL_PP(pv_param_arr), (void **) &tmp) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); SQLFreeStmt(result->stmt,SQL_RESET_PARAMS); efree(params); RETURN_FALSE; } otype = (*tmp)->type; convert_to_string(*tmp); if (Z_TYPE_PP(tmp) != IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter"); SQLFreeStmt(result->stmt, SQL_RESET_PARAMS); efree(params); RETURN_FALSE; } SQLDescribeParam(result->stmt, (UWORD)i, &sqltype, &precision, &scale, &nullable); params[i-1].vallen = Z_STRLEN_PP(tmp); params[i-1].fp = -1; if (IS_SQL_BINARY(sqltype)) ctype = SQL_C_BINARY; else ctype = SQL_C_CHAR; if (Z_STRLEN_PP(tmp) > 2 && Z_STRVAL_PP(tmp)[0] == '\'' && Z_STRVAL_PP(tmp)[Z_STRLEN_PP(tmp) - 1] == '\'') { filename = estrndup(&Z_STRVAL_PP(tmp)[1], Z_STRLEN_PP(tmp) - 2); filename[strlen(filename)] = '\0'; /* Check for safe mode. */ if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { efree(filename); efree(params); RETURN_FALSE; } /* Check the basedir */ if (php_check_open_basedir(filename TSRMLS_CC)) { efree(filename); efree(params); RETURN_FALSE; } if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Can't open file %s", filename); SQLFreeStmt(result->stmt, SQL_RESET_PARAMS); for(i = 0; i < result->numparams; i++) { if (params[i].fp != -1) { close(params[i].fp); } } efree(params); efree(filename); RETURN_FALSE; } efree(filename); params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0); rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT, ctype, sqltype, precision, scale, (void *)params[i-1].fp, 0, ¶ms[i-1].vallen); } else {#ifdef HAVE_DBMAKER precision = params[i-1].vallen;#endif if (otype == IS_NULL) { params[i-1].vallen = SQL_NULL_DATA; } rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT, ctype, sqltype, precision, scale, Z_STRVAL_PP(tmp), 0, ¶ms[i-1].vallen); } zend_hash_move_forward(Z_ARRVAL_PP(pv_param_arr)); } } /* Close cursor, needed for doing multiple selects */ rc = SQLFreeStmt(result->stmt, SQL_CLOSE); if (rc == SQL_ERROR) { odbc_sql_error(result->conn_ptr, result->stmt, "SQLFreeStmt"); } rc = SQLExecute(result->stmt); result->fetched = 0; if (rc == SQL_NEED_DATA) { char buf[4096]; int fp, nbytes; while(rc == SQL_NEED_DATA) { rc = SQLParamData(result->stmt, (void*)&fp); if (rc == SQL_NEED_DATA) { while((nbytes = read(fp, &buf, 4096)) > 0) SQLPutData(result->stmt, (void*)&buf, nbytes); } } } else { switch (rc) { case SQL_SUCCESS: break; case SQL_NO_DATA_FOUND: case SQL_SUCCESS_WITH_INFO: odbc_sql_error(result->conn_ptr, result->stmt, "SQLExecute"); break; default: odbc_sql_error(result->conn_ptr, result->stmt, "SQLExecute"); RETVAL_FALSE; } } if (result->numparams > 0) { SQLFreeStmt(result->stmt, SQL_RESET_PARAMS); for(i = 0; i < result->numparams; i++) { if (params[i].fp != -1) close(params[i].fp); } efree(params); } if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO || rc == SQL_NO_DATA_FOUND) { RETVAL_TRUE; } if (result->numcols == 0) { SQLNumResultCols(result->stmt, &(result->numcols)); if (result->numcols > 0) { if (!odbc_bindcols(result TSRMLS_CC)) { efree(result); RETVAL_FALSE; } } else { result->values = NULL; } }}/* }}} *//* {{{ proto string odbc_cursor(resource result_id) Get cursor name */PHP_FUNCTION(odbc_cursor){ pval **pv_res; SWORD len, max_len; char *cursorname; odbc_result *result; RETCODE rc; 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); rc = SQLGetInfo(result->conn_ptr->hdbc,SQL_MAX_CURSOR_NAME_LEN, (void *)&max_len,sizeof(max_len),&len); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { RETURN_FALSE; } if (max_len > 0) { cursorname = emalloc(max_len + 1); rc = SQLGetCursorName(result->stmt,cursorname,(SWORD)max_len,&len); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { char state[6]; /* Not used */ SDWORD error; /* Not used */ char errormsg[255]; SWORD errormsgsize; /* Not used */ SQLError( result->conn_ptr->henv, result->conn_ptr->hdbc, result->stmt, state, &error, errormsg, sizeof(errormsg)-1, &errormsgsize); if (!strncmp(state,"S1015",5)) { sprintf(cursorname,"php_curs_%d", (int)result->stmt); if (SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) { odbc_sql_error(result->conn_ptr, result->stmt, "SQLSetCursorName"); RETVAL_FALSE; } else { RETVAL_STRING(cursorname,1); } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQL error: %s, SQL state %s", errormsg, state); RETVAL_FALSE; } } else { RETVAL_STRING(cursorname,1); } efree(cursorname); } else { RETVAL_FALSE; }}/* }}} */#ifdef HAVE_SQLDATASOURCES/* {{{ proto array odbc_data_source(resource connection_id, int fetch_type) Return information about the currently connected data source */PHP_FUNCTION(odbc_data_source){ zval **zv_fetch_type, **zv_conn; RETCODE rc = 0; /* assume all is good */ odbc_connection *conn; int num_args = ZEND_NUM_ARGS(); UCHAR server_name[100], desc[200]; SQLSMALLINT len1=0, len2=0, fetch_type; if (num_args != 2) { WRONG_PARAM_COUNT; } if (zend_get_parameters_ex(2, &zv_conn, &zv_fetch_type) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to get parameters"); RETURN_FALSE; } convert_to_long_ex(zv_fetch_type); fetch_type = (SQLSMALLINT)Z_LVAL_PP(zv_fetch_type); if (!(fetch_type == SQL_FETCH_FIRST || fetch_type == SQL_FETCH_NEXT)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid fetch type (%d)", fetch_type); RETURN_FALSE; } ZEND_FETCH_RESOURCE2(conn, odbc_connection *, zv_conn, -1, "ODBC-Link", le_conn, le_pconn); /* now we have the "connection" lets call the DataSource object */ rc = SQLDataSources(conn->henv, fetch_type, server_name, (SQLSMALLINT)sizeof(server_name), &len1, desc, (SQLSMALLINT)sizeof(desc), &len2); if (rc != SQL_SUCCESS) { /* ummm.... he did it */ odbc_sql_error(conn, NULL, "SQLDataSources"); RETURN_FALSE; } if (len1 == 0 || len2 == 0) { /* we have a non-valid entry... so stop the looping */ RETURN_FALSE; } array_init(return_value); add_assoc_string_ex(return_value, "server", sizeof("server"), server_name, 1); add_assoc_string_ex(return_value, "description", sizeof("description"), desc, 1);}/* }}} */#endif /* HAVE_SQLDATASOURCES *//* {{{ proto resource odbc_exec(resource connection_id, string query [, int flags]) Prepare and execute an SQL statement *//* XXX Use flags */PHP_FUNCTION(odbc_exec){ pval **pv_conn, **pv_query, **pv_flags; int numArgs; char *query; odbc_result *result = NULL; odbc_connection *conn; RETCODE rc;#ifdef HAVE_SQL_EXTENDED_FETCH UDWORD scrollopts;#endif numArgs = ZEND_NUM_ARGS(); if (numArgs > 2) { if (zend_get_parameters_ex(3, &pv_conn, &pv_query, &pv_flags) == FAILURE) WRONG_PARAM_COUNT; convert_to_long_ex(pv_flags); } else { if (zend_get_parameters_ex(2, &pv_conn, &pv_query) == FAILURE) WRONG_PARAM_COUNT; } ZEND_FETCH_RESOURCE2(conn, odbc_connection *, pv_conn, -1, "ODBC-Link", le_conn, le_pconn); convert_to_string_ex(pv_query); query = Z_STRVAL_PP(pv_query); result = (odbc_result *)emalloc(sizeof(odbc_result)); rc = SQLAllocStmt(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); efree(result); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); efree(result); RETURN_FALSE; } #ifdef HAVE_SQL_EXTENDED_FETCH /* Solid doesn't have ExtendedFetch, if DriverManager is used, get Info, whether Driver supports ExtendedFetch */ rc = SQLGetInfo(conn->hdbc, SQL_FETCH_DIRECTION, (void *) &scrollopts, sizeof(scrollopts), NULL); if (rc == SQL_SUCCESS) { if ((result->fetch_abs = (scrollopts & SQL_FD_FETCH_ABSOLUTE))) { /* Try to set CURSOR_TYPE to dynamic. Driver will replace this with other type if not possible. */ if (SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, SQL_CURSOR_DYNAMIC) == SQL_ERROR) { odbc_sql_error(conn, result->stmt, " SQLSetStmtOption"); SQLFreeStmt(result->stmt, SQL_DROP); efree(result); RETURN_FALSE; } } } else { result->fetch_abs = 0; }#endif rc = SQLExecDirect(result->stmt, query, SQL_NTS); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA_FOUND) { /* XXX FIXME we should really check out SQLSTATE with SQLError * in case rc is SQL_SUCCESS_WITH_INFO here. */ odbc_sql_error(conn, result->stmt, "SQLExecDirect"); SQLFreeStmt(result->stmt, SQL_DROP); efree(result); RETURN_FALSE; } SQLNumResultCols(result->stmt, &(result->numcols)); /* For insert, update etc. cols == 0 */ if (result->numcols > 0) { if (!odbc_bindcols(result TSRMLS_CC)) { efree(result); RETURN_FALSE; } } else { result->values = NULL; } result->id = zend_list_insert(result, le_result); zend_list_addref(conn->id); result->conn_ptr = conn; result->fetched = 0; RETURN_RESOURCE(result->id);}/* }}} */#ifdef PHP_ODBC_HAVE_FETCH_HASH#define ODBC_NUM 1#define ODBC_OBJECT 2/* {{{ php_odbc_fetch_hash */static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type){ int i; odbc_result *result; RETCODE rc; SWORD sql_c_type; char *buf = NULL;#ifdef HAVE_SQL_EXTENDED_FETCH UDWORD crow; UWORD RowStatus[1]; SDWORD rownum = -1; pval **pv_res, **pv_row, *tmp; switch(ZEND_NUM_ARGS()) { case 1: if (zend_get_parameters_ex(1, &pv_res) == FAILURE) { WRONG_PARAM_COUNT; } break; case 2: if (zend_get_parameters_ex(2, &pv_res, &pv_row) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long_ex(pv_row); rownum = Z_LVAL_PP(pv_row); break; default: WRONG_PARAM_COUNT; }#else pval **pv_res, *tmp; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pv_res) == FAILURE) { WRONG_PARAM_COUNT; }#endif 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) { if (rownum > 0) rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,rownum,&crow,RowStatus); else 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) { RETURN_FALSE; } array_init(return_value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -