FS-2960
This commit is contained in:
parent
3f1a7dc5b5
commit
29daaa07b0
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
|
#define DEFAULT_ODBC_RETRIES 120
|
||||||
|
|
||||||
SWITCH_BEGIN_EXTERN_C struct switch_odbc_handle;
|
SWITCH_BEGIN_EXTERN_C struct switch_odbc_handle;
|
||||||
typedef void *switch_odbc_statement_handle_t;
|
typedef void *switch_odbc_statement_handle_t;
|
||||||
|
|
||||||
|
@ -50,6 +52,7 @@ typedef enum {
|
||||||
} switch_odbc_status_t;
|
} switch_odbc_status_t;
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, const char *username, const char *password);
|
SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, const char *username, const char *password);
|
||||||
|
SWITCH_DECLARE(void) switch_odbc_set_num_retries(switch_odbc_handle_t *handle, int num_retries);
|
||||||
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle);
|
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle);
|
||||||
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_handle_t *handle);
|
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_handle_t *handle);
|
||||||
SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep);
|
SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep);
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct switch_odbc_handle {
|
||||||
char odbc_driver[256];
|
char odbc_driver[256];
|
||||||
BOOL is_firebird;
|
BOOL is_firebird;
|
||||||
int affected_rows;
|
int affected_rows;
|
||||||
|
int num_retries;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, c
|
||||||
new_handle->env = SQL_NULL_HANDLE;
|
new_handle->env = SQL_NULL_HANDLE;
|
||||||
new_handle->state = SWITCH_ODBC_STATE_INIT;
|
new_handle->state = SWITCH_ODBC_STATE_INIT;
|
||||||
new_handle->affected_rows = 0;
|
new_handle->affected_rows = 0;
|
||||||
|
new_handle->num_retries = DEFAULT_ODBC_RETRIES;
|
||||||
|
|
||||||
return new_handle;
|
return new_handle;
|
||||||
|
|
||||||
|
@ -104,6 +106,15 @@ SWITCH_DECLARE(switch_odbc_handle_t *) switch_odbc_handle_new(const char *dsn, c
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWITCH_DECLARE(void) switch_odbc_set_num_retries(switch_odbc_handle_t *handle, int num_retries)
|
||||||
|
{
|
||||||
|
#ifdef SWITCH_HAVE_ODBC
|
||||||
|
if (handle) {
|
||||||
|
handle->num_retries = num_retries;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle)
|
SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_handle_t *handle)
|
||||||
{
|
{
|
||||||
#ifdef SWITCH_HAVE_ODBC
|
#ifdef SWITCH_HAVE_ODBC
|
||||||
|
@ -133,6 +144,53 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_disconnect(switch_odbc_h
|
||||||
|
|
||||||
|
|
||||||
#ifdef SWITCH_HAVE_ODBC
|
#ifdef SWITCH_HAVE_ODBC
|
||||||
|
static switch_odbc_status_t init_odbc_handles(switch_odbc_handle_t *handle, switch_bool_t do_reinit)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
return SWITCH_ODBC_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if handle is already initialized, and we're supposed to reinit - free old handle first */
|
||||||
|
if (do_reinit == SWITCH_TRUE && handle->env != SQL_NULL_HANDLE) {
|
||||||
|
SQLFreeHandle(SQL_HANDLE_DBC, handle->con);
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||||
|
handle->env = SQL_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->env == SQL_NULL_HANDLE) {
|
||||||
|
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env);
|
||||||
|
|
||||||
|
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHandle\n");
|
||||||
|
handle->env = SQL_NULL_HANDLE; /* Reset handle value, just in case */
|
||||||
|
return SWITCH_ODBC_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SQLSetEnvAttr(handle->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
|
||||||
|
|
||||||
|
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SetEnv\n");
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||||
|
handle->env = SQL_NULL_HANDLE; /* Reset handle value after it's freed */
|
||||||
|
return SWITCH_ODBC_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SQLAllocHandle(SQL_HANDLE_DBC, handle->env, &handle->con);
|
||||||
|
|
||||||
|
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHDB %d\n", result);
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||||
|
handle->env = SQL_NULL_HANDLE; /* Reset handle value after it's freed */
|
||||||
|
return SWITCH_ODBC_FAIL;
|
||||||
|
}
|
||||||
|
SQLSetConnectAttr(handle->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_ODBC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int db_is_up(switch_odbc_handle_t *handle)
|
static int db_is_up(switch_odbc_handle_t *handle)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -143,12 +201,18 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
||||||
switch_odbc_status_t recon = 0;
|
switch_odbc_status_t recon = 0;
|
||||||
char *err_str = NULL;
|
char *err_str = NULL;
|
||||||
SQLCHAR sql[255] = "";
|
SQLCHAR sql[255] = "";
|
||||||
int max_tries = 120;
|
int max_tries = DEFAULT_ODBC_RETRIES;
|
||||||
int code = 0;
|
int code = 0;
|
||||||
SQLRETURN rc;
|
SQLRETURN rc;
|
||||||
SQLSMALLINT nresultcols;
|
SQLSMALLINT nresultcols;
|
||||||
|
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
max_tries = handle->num_retries;
|
||||||
|
if (max_tries < 1)
|
||||||
|
max_tries = DEFAULT_ODBC_RETRIES;
|
||||||
|
}
|
||||||
|
|
||||||
top:
|
top:
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
|
@ -199,6 +263,13 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
err_str = switch_odbc_handle_get_error(handle, stmt);
|
err_str = switch_odbc_handle_get_error(handle, stmt);
|
||||||
|
|
||||||
|
/* Make sure to free the handle before we try to reconnect */
|
||||||
|
if (stmt) {
|
||||||
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
|
stmt = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
recon = switch_odbc_handle_connect(handle);
|
recon = switch_odbc_handle_connect(handle);
|
||||||
|
|
||||||
max_tries--;
|
max_tries--;
|
||||||
|
@ -228,11 +299,6 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt) {
|
|
||||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
|
||||||
stmt = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_safe_free(err_str);
|
switch_safe_free(err_str);
|
||||||
switch_yield(1000000);
|
switch_yield(1000000);
|
||||||
goto top;
|
goto top;
|
||||||
|
@ -274,31 +340,8 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand
|
||||||
SQLSMALLINT valueLength = 0;
|
SQLSMALLINT valueLength = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (handle->env == SQL_NULL_HANDLE) {
|
init_odbc_handles(handle, SWITCH_FALSE); /* Init ODBC handles, if they are already initialized, don't do it again */
|
||||||
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env);
|
|
||||||
|
|
||||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHandle\n");
|
|
||||||
return SWITCH_ODBC_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = SQLSetEnvAttr(handle->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
|
|
||||||
|
|
||||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SetEnv\n");
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
|
||||||
return SWITCH_ODBC_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = SQLAllocHandle(SQL_HANDLE_DBC, handle->env, &handle->con);
|
|
||||||
|
|
||||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error AllocHDB %d\n", result);
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
|
||||||
return SWITCH_ODBC_FAIL;
|
|
||||||
}
|
|
||||||
SQLSetConnectAttr(handle->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0);
|
|
||||||
}
|
|
||||||
if (handle->state == SWITCH_ODBC_STATE_CONNECTED) {
|
if (handle->state == SWITCH_ODBC_STATE_CONNECTED) {
|
||||||
switch_odbc_handle_disconnect(handle);
|
switch_odbc_handle_disconnect(handle);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Re-connecting %s\n", handle->dsn);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Re-connecting %s\n", handle->dsn);
|
||||||
|
@ -325,7 +368,9 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand
|
||||||
SQLGetDiagRec(SQL_HANDLE_DBC, handle->con, 1, stat, &err, msg, 100, &mlen);
|
SQLGetDiagRec(SQL_HANDLE_DBC, handle->con, 1, stat, &err, msg, 100, &mlen);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SQLConnect=%d errno=%d %s\n", result, (int) err, msg);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error SQLConnect=%d errno=%d %s\n", result, (int) err, msg);
|
||||||
}
|
}
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
|
||||||
|
/* Deallocate handles again, more chanses to succeed when reconnecting */
|
||||||
|
init_odbc_handles(handle, SWITCH_TRUE); /* Reinit ODBC handles */
|
||||||
return SWITCH_ODBC_FAIL;
|
return SWITCH_ODBC_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,6 +599,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
|
stmt = NULL; /* Make sure we don't try to free this handle again */
|
||||||
|
|
||||||
if (!err_cnt) {
|
if (!err_cnt) {
|
||||||
return SWITCH_ODBC_SUCCESS;
|
return SWITCH_ODBC_SUCCESS;
|
||||||
|
@ -593,8 +639,10 @@ SWITCH_DECLARE(void) switch_odbc_handle_destroy(switch_odbc_handle_t **handlep)
|
||||||
if (handle) {
|
if (handle) {
|
||||||
switch_odbc_handle_disconnect(handle);
|
switch_odbc_handle_disconnect(handle);
|
||||||
|
|
||||||
SQLFreeHandle(SQL_HANDLE_DBC, handle->con);
|
if (handle->env != SQL_NULL_HANDLE) {
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
SQLFreeHandle(SQL_HANDLE_DBC, handle->con);
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||||
|
}
|
||||||
switch_safe_free(handle->dsn);
|
switch_safe_free(handle->dsn);
|
||||||
switch_safe_free(handle->username);
|
switch_safe_free(handle->username);
|
||||||
switch_safe_free(handle->password);
|
switch_safe_free(handle->password);
|
||||||
|
|
Loading…
Reference in New Issue