ZBX_ODBC_ROW odbc_DBfetch(ZBX_ODBC_RESULT pdbh) { SQLCHAR err_stat[10], err_msg[100]; SQLINTEGER err_int; SQLSMALLINT err_msg_len; SQLRETURN retcode; SQLSMALLINT i; if(pdbh == NULL) return NULL; clean_odbc_strerror(); zabbix_log(LOG_LEVEL_DEBUG, "ODBC fetch"); retcode = SQLFetch(pdbh->hstmt); if (retcode == SQL_ERROR) goto lbl_err_exit; if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) { zabbix_log(LOG_LEVEL_DEBUG, "odbc_DBfetch [end of rows received]"); return NULL; } for(i=0; i < pdbh->col_num; i++) { rtrim_spaces(pdbh->row_data[i]); zabbix_log(LOG_LEVEL_DEBUG, "Featched [%i col]: %s", i, pdbh->row_data[i]); } return pdbh->row_data; lbl_err_exit: SQLGetDiagRec(SQL_HANDLE_STMT, pdbh->hstmt, 1, err_stat, &err_int, err_msg, sizeof(err_msg), &err_msg_len ); set_last_odbc_strerror("Failed data fetching [%s] (%d)", err_msg, err_int); zabbix_log(LOG_LEVEL_ERR, "%s", get_last_odbc_strerror()); return NULL; }
ZBX_ODBC_ROW odbc_DBfetch(ZBX_ODBC_RESULT pdbh) { const char *__function_name = "odbc_DBfetch"; SQLRETURN retcode; SQLSMALLINT i; ZBX_ODBC_ROW result_row = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); clean_odbc_strerror(); if (NULL == pdbh) { set_last_odbc_strerror("cannot fetch row on an empty connection handle"); goto end; } if (SQL_NO_DATA == (retcode = SQLFetch(pdbh->hstmt))) { /* end of rows */ goto end; } if (SQL_SUCCESS != retcode && 0 == odbc_Diag(SQL_HANDLE_STMT, pdbh->hstmt, retcode, "cannot fetch row")) goto end; for (i = 0; i < pdbh->col_num; i++) { /* set NULL column value where appropriate */ if (SQL_NULL_DATA == pdbh->data_len[i]) zbx_free(pdbh->row_data[i]); else zbx_rtrim(pdbh->row_data[i], " "); zabbix_log(LOG_LEVEL_DEBUG, "%s() fetched [%i col]: '%s'", __function_name, i, NULL == pdbh->row_data[i] ? "NULL" : pdbh->row_data[i]); } result_row = pdbh->row_data; end: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return result_row; }
int odbc_DBexecute(ZBX_ODBC_DBH *pdbh, const char *query) { SQLCHAR err_stat[10], err_msg[100]; SQLINTEGER err_int; SQLSMALLINT err_msg_len; SQLRETURN retcode; clean_odbc_strerror(); odbc_free_row_data(pdbh); retcode = SQLExecDirect(pdbh->hstmt, (SQLCHAR*) query, SQL_NTS); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) goto lbl_err_exit; return SUCCEED; lbl_err_exit: SQLGetDiagRec(SQL_HANDLE_STMT, pdbh->hstmt, 1, err_stat, &err_int, err_msg, sizeof(err_msg), &err_msg_len ); set_last_odbc_strerror("Failed select execution [%s] (%d)", err_msg, err_int); zabbix_log(LOG_LEVEL_ERR, "%s", get_last_odbc_strerror()); return FAIL; }
static int odbc_Diag(SQLSMALLINT h_type, SQLHANDLE h, SQLRETURN sql_rc, const char *msg) { const char *__function_name = "odbc_Diag"; SQLCHAR sql_state[SQL_SQLSTATE_SIZE + 1], err_msg[128]; SQLINTEGER native_err_code = 0; int rec_nr = 1; char rc_msg[40]; /* the longest message is "%d (unknown SQLRETURN code)" */ char diag_msg[ODBC_ERR_MSG_LEN]; size_t offset = 0; *sql_state = '\0'; *err_msg = '\0'; *diag_msg = '\0'; switch (sql_rc) { case SQL_ERROR: zbx_strlcpy(rc_msg, "SQL_ERROR", sizeof(rc_msg)); break; case SQL_SUCCESS_WITH_INFO: zbx_strlcpy(rc_msg, "SQL_SUCCESS_WITH_INFO", sizeof(rc_msg)); break; case SQL_NO_DATA: zbx_strlcpy(rc_msg, "SQL_NO_DATA", sizeof(rc_msg)); break; case SQL_INVALID_HANDLE: zbx_strlcpy(rc_msg, "SQL_INVALID_HANDLE", sizeof(rc_msg)); break; case SQL_STILL_EXECUTING: zbx_strlcpy(rc_msg, "SQL_STILL_EXECUTING", sizeof(rc_msg)); break; case SQL_NEED_DATA: zbx_strlcpy(rc_msg, "SQL_NEED_DATA", sizeof(rc_msg)); break; case SQL_SUCCESS: zbx_strlcpy(rc_msg, "SQL_SUCCESS", sizeof(rc_msg)); break; default: zbx_snprintf(rc_msg, sizeof(rc_msg), "%d (unknown SQLRETURN code)", (int)sql_rc); } if (SQL_ERROR == sql_rc || SQL_SUCCESS_WITH_INFO == sql_rc) { while (0 != SQL_SUCCEEDED(SQLGetDiagRec(h_type, h, (SQLSMALLINT)rec_nr, sql_state, &native_err_code, err_msg, sizeof(err_msg), NULL))) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): rc_msg:'%s' rec_nr:%d sql_state:'%s' native_err_code:%ld " "err_msg:'%s'", __function_name, rc_msg, rec_nr, sql_state, (long)native_err_code, err_msg); if (sizeof(diag_msg) > offset) { offset += zbx_snprintf(diag_msg + offset, sizeof(diag_msg) - offset, "[%s][%ld][%s]|", sql_state, (long)native_err_code, err_msg); } rec_nr++; } *(diag_msg + offset) = '\0'; } set_last_odbc_strerror("%s:[%s]:%s", msg, rc_msg, diag_msg); return (int)SQL_SUCCEEDED(sql_rc); }
int odbc_DBconnect(ZBX_ODBC_DBH *pdbh, char *db_dsn, char *user, char *pass, int login_timeout) { const char *__function_name = "odbc_DBconnect"; int ret = FAIL; SQLRETURN rc; zabbix_log(LOG_LEVEL_DEBUG, "In %s() db_dsn:'%s' user:'******'", __function_name, db_dsn, user); clean_odbc_strerror(); memset(pdbh, 0, sizeof(ZBX_ODBC_DBH)); /* allocate environment handle */ if (0 == SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(pdbh->henv)))) { set_last_odbc_strerror("%s", "Cannot create ODBC environment handle."); goto end; } /* set the ODBC version environment attribute */ if (0 != CALLODBC(SQLSetEnvAttr(pdbh->henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0), rc, SQL_HANDLE_ENV, pdbh->henv, "Cannot set ODBC version")) { goto end; } /* allocate connection handle */ if (0 != CALLODBC(SQLAllocHandle(SQL_HANDLE_DBC, pdbh->henv, &(pdbh->hdbc)), rc, SQL_HANDLE_ENV, pdbh->henv, "Cannot create ODBC connection handle")) { goto end; } /* set login timeout */ if (0 != CALLODBC(SQLSetConnectAttr(pdbh->hdbc, (SQLINTEGER)SQL_LOGIN_TIMEOUT, (SQLPOINTER)(intptr_t)login_timeout, (SQLINTEGER)0), rc, SQL_HANDLE_DBC, pdbh->hdbc, "Cannot set ODBC login timeout")) { goto end; } /* connect to data source */ if (0 != CALLODBC(SQLConnect(pdbh->hdbc, (SQLCHAR *)db_dsn, SQL_NTS, (SQLCHAR *)user, SQL_NTS, (SQLCHAR *)pass, SQL_NTS), rc, SQL_HANDLE_DBC, pdbh->hdbc, "Cannot connect to ODBC DSN")) { goto end; } /* allocate statement handle */ if (0 != CALLODBC(SQLAllocHandle(SQL_HANDLE_STMT, pdbh->hdbc, &(pdbh->hstmt)), rc, SQL_HANDLE_DBC, pdbh->hdbc, "Cannot create ODBC statement handle.")) { goto end; } pdbh->connected = 1; ret = SUCCEED; end: if (SUCCEED != ret) odbc_DBclose(pdbh); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int odbc_DBconnect(ZBX_ODBC_DBH *pdbh, const char *db_dsn, const char *user, const char *pass) { SQLCHAR err_stat[10], err_msg[100]; SQLINTEGER err_int; SQLSMALLINT err_msg_len; SQLRETURN retcode; clean_odbc_strerror(); memset(pdbh, 0 , sizeof(ZBX_ODBC_DBH)); zabbix_log(LOG_LEVEL_DEBUG, "ODBC connect [%s] [%s]", db_dsn, user); /*Allocate environment handle */ retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(pdbh->henv)); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { set_last_odbc_strerror("%s","failed environment handle allocation."); } else { /* Set the ODBC version environment attribute */ retcode = SQLSetEnvAttr(pdbh->henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { set_last_odbc_strerror("%s","failed ODBC version setting."); } else { /* Allocate connection handle */ retcode = SQLAllocHandle(SQL_HANDLE_DBC, pdbh->henv, &(pdbh->hdbc)); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { set_last_odbc_strerror("%s","failed connection handle allocation."); } else { /* Set login timeout to 5 seconds. */ SQLSetConnectAttr(pdbh->hdbc, (SQLINTEGER)SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, (SQLINTEGER)0); /* Connect to data source */ retcode = SQLConnect(pdbh->hdbc, (SQLCHAR*) db_dsn, SQL_NTS, (SQLCHAR*) user, SQL_NTS, (SQLCHAR*) pass, SQL_NTS ); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { SQLGetDiagRec(SQL_HANDLE_DBC, pdbh->hdbc, 1, err_stat, &err_int, err_msg, sizeof(err_msg), &err_msg_len ); set_last_odbc_strerror("failed connection [%s] (%d)", err_msg, err_int); } else { pdbh->connected = 1; /* Allocate statement handle */ retcode = SQLAllocHandle(SQL_HANDLE_STMT, pdbh->hdbc, &(pdbh->hstmt)); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { return SUCCEED; } else { SQLFreeHandle(SQL_HANDLE_STMT, pdbh->hstmt); pdbh->hstmt = NULL; } SQLDisconnect(pdbh->hdbc); } SQLFreeHandle(SQL_HANDLE_DBC, pdbh->hdbc); pdbh->hdbc = NULL; } } SQLFreeHandle(SQL_HANDLE_ENV, pdbh->henv); pdbh->henv = NULL; } zabbix_log(LOG_LEVEL_ERR, "Failed to connect to DSN '%s' : Error: %s", db_dsn, get_last_odbc_strerror()); return FAIL; /* error */ }
ZBX_ODBC_RESULT odbc_DBselect(ZBX_ODBC_DBH *pdbh, const char *query) { SQLCHAR err_stat[10], err_msg[100]; SQLINTEGER err_int; SQLSMALLINT err_msg_len; SQLRETURN retcode; SQLSMALLINT i = 0, col_num = 0; clean_odbc_strerror(); odbc_free_row_data(pdbh); zabbix_log(LOG_LEVEL_DEBUG, "ODBC select [%s]", query); retcode = SQLExecDirect(pdbh->hstmt, (SQLCHAR*) query, SQL_NTS); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) goto lbl_err_exit; retcode = SQLNumResultCols(pdbh->hstmt, &col_num); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) goto lbl_err_exit; pdbh->col_num = col_num; pdbh->row_data = zbx_malloc(pdbh->row_data, sizeof(char*) * col_num); memset(pdbh->row_data, 0, sizeof(char*) * col_num); pdbh->data_len = zbx_malloc(pdbh->data_len, sizeof(SQLINTEGER) * col_num); memset(pdbh->data_len, 0, sizeof(SQLINTEGER) * col_num); for(i=0; i < col_num; i++) { pdbh->row_data[i] = zbx_malloc(pdbh->row_data[i], MAX_STRING_LEN); SQLBindCol(pdbh->hstmt, i+1, SQL_C_CHAR, pdbh->row_data[i], MAX_STRING_LEN, &pdbh->data_len[i]); } zabbix_log(LOG_LEVEL_DEBUG, "selected %i cols", col_num); return (ZBX_ODBC_RESULT) pdbh; lbl_err_exit: SQLGetDiagRec(SQL_HANDLE_STMT, pdbh->hstmt, 1, err_stat, &err_int, err_msg, sizeof(err_msg), &err_msg_len ); set_last_odbc_strerror("Failed selection [%s] (%d)", err_msg, err_int); zabbix_log(LOG_LEVEL_ERR, "%s", get_last_odbc_strerror()); return NULL; }