merge changes from MODLANG-18 fix multiple odbc and spidermonkey odbc issues.
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5289 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
8fe69bb764
commit
da58c31380
|
@ -32,6 +32,7 @@ that much better:
|
||||||
Johny Kadarisman <jkr888 at gmail.com> - mod_python fixups.
|
Johny Kadarisman <jkr888 at gmail.com> - mod_python fixups.
|
||||||
Michael Murdock <mike at mmurdock dot org> - testing, documentation, bug finding and usability enhancements.
|
Michael Murdock <mike at mmurdock dot org> - testing, documentation, bug finding and usability enhancements.
|
||||||
Matt Klein <mklein@nmedia.net>
|
Matt Klein <mklein@nmedia.net>
|
||||||
|
Jonas Gauffin <jonas at gauffin dot org> - Bugfixes and additions in mod_spidermonkey_odbc
|
||||||
|
|
||||||
A big THANK YOU goes to:
|
A big THANK YOU goes to:
|
||||||
|
|
||||||
|
|
|
@ -2114,7 +2114,9 @@ static JSPropertySpec session_props[] = {
|
||||||
{"dialplan", PROFILE_DIALPLAN, JSPROP_READONLY | JSPROP_PERMANENT},
|
{"dialplan", PROFILE_DIALPLAN, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
{"caller_id_name", PROFILE_CID_NAME, JSPROP_READONLY | JSPROP_PERMANENT},
|
{"caller_id_name", PROFILE_CID_NAME, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
{"caller_id_num", PROFILE_CID_NUM, JSPROP_READONLY | JSPROP_PERMANENT},
|
{"caller_id_num", PROFILE_CID_NUM, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
|
{"caller_id_number", PROFILE_CID_NUM, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
{"network_addr", PROFILE_IP, JSPROP_READONLY | JSPROP_PERMANENT},
|
{"network_addr", PROFILE_IP, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
|
{"network_address", PROFILE_IP, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
{"ani", PROFILE_ANI, JSPROP_READONLY | JSPROP_PERMANENT},
|
{"ani", PROFILE_ANI, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
{"aniii", PROFILE_ANI_II, JSPROP_READONLY | JSPROP_PERMANENT},
|
{"aniii", PROFILE_ANI_II, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
{"destination", PROFILE_DEST, JSPROP_READONLY | JSPROP_PERMANENT},
|
{"destination", PROFILE_DEST, JSPROP_READONLY | JSPROP_PERMANENT},
|
||||||
|
|
|
@ -52,6 +52,7 @@ static odbc_obj_t *new_odbc_obj(char *dsn, char *username, char *password)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(new_obj, 0, sizeof(odbc_obj_t));
|
||||||
if (!(new_obj->handle = switch_odbc_handle_new(dsn, username, password))) {
|
if (!(new_obj->handle = switch_odbc_handle_new(dsn, username, password))) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -79,12 +80,12 @@ static void destroy_odbc_obj(odbc_obj_t ** objp)
|
||||||
{
|
{
|
||||||
odbc_obj_t *obj = *objp;
|
odbc_obj_t *obj = *objp;
|
||||||
|
|
||||||
if (obj->handle) {
|
|
||||||
switch_odbc_handle_destroy(&obj->handle);
|
|
||||||
}
|
|
||||||
if (obj->stmt) {
|
if (obj->stmt) {
|
||||||
SQLFreeHandle(SQL_HANDLE_STMT, obj->stmt);
|
SQLFreeHandle(SQL_HANDLE_STMT, obj->stmt);
|
||||||
}
|
}
|
||||||
|
if (obj->handle) {
|
||||||
|
switch_odbc_handle_destroy(&obj->handle);
|
||||||
|
}
|
||||||
switch_safe_free(obj->colbuf);
|
switch_safe_free(obj->colbuf);
|
||||||
switch_safe_free(obj->code);
|
switch_safe_free(obj->code);
|
||||||
switch_safe_free(obj);
|
switch_safe_free(obj);
|
||||||
|
@ -180,6 +181,40 @@ static JSBool odbc_connect(JSContext * cx, JSObject * obj, uintN argc, jsval *ar
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSBool odbc_execute(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
|
||||||
|
{
|
||||||
|
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
|
||||||
|
char *sql;
|
||||||
|
JSBool tf = JS_FALSE;
|
||||||
|
SQLHSTMT stmt;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_odbc_handle_get_state(odbc_obj->handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||||
|
|
||||||
|
if (switch_odbc_handle_exec(odbc_obj->handle, sql, &stmt) != SWITCH_ODBC_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[ODBC] Execute failed for: %s\n", sql);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
|
|
||||||
|
tf = JS_TRUE;
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
*rval = BOOLEAN_TO_JSVAL(tf);
|
||||||
|
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static JSBool odbc_exec(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
|
static JSBool odbc_exec(JSContext * cx, JSObject * obj, uintN argc, jsval *argv, jsval *rval)
|
||||||
{
|
{
|
||||||
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
|
odbc_obj_t *odbc_obj = (odbc_obj_t *) JS_GetPrivate(cx, obj);
|
||||||
|
@ -202,8 +237,8 @@ static JSBool odbc_exec(JSContext * cx, JSObject * obj, uintN argc, jsval *argv,
|
||||||
|
|
||||||
sql = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
sql = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||||
|
|
||||||
|
|
||||||
if (switch_odbc_handle_exec(odbc_obj->handle, sql, &odbc_obj->stmt) != SWITCH_ODBC_SUCCESS) {
|
if (switch_odbc_handle_exec(odbc_obj->handle, sql, &odbc_obj->stmt) != SWITCH_ODBC_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[ODBC] query failed: %s\n", sql);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +300,7 @@ static JSBool odbc_next_row(JSContext * cx, JSObject * obj, uintN argc, jsval *a
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *escape_data(char *in)
|
static char *escape_data(char *in, char escapeChar)
|
||||||
{
|
{
|
||||||
switch_size_t nlen = strlen(in);
|
switch_size_t nlen = strlen(in);
|
||||||
uint32_t qc = 0;
|
uint32_t qc = 0;
|
||||||
|
@ -275,6 +310,9 @@ static char *escape_data(char *in)
|
||||||
if (*p == '"') {
|
if (*p == '"') {
|
||||||
qc += 2;
|
qc += 2;
|
||||||
}
|
}
|
||||||
|
if (*p == '\'') {
|
||||||
|
qc += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nlen += qc + 1;
|
nlen += qc + 1;
|
||||||
|
@ -287,7 +325,10 @@ static char *escape_data(char *in)
|
||||||
qc = 0;
|
qc = 0;
|
||||||
for (p = in; p && *p; p++) {
|
for (p = in; p && *p; p++) {
|
||||||
if (*p == '"') {
|
if (*p == '"') {
|
||||||
*r++ = '\\';
|
*r++ = escapeChar;
|
||||||
|
}
|
||||||
|
if (*p == '\'') {
|
||||||
|
*r++ = escapeChar;
|
||||||
}
|
}
|
||||||
*r++ = *p;
|
*r++ = *p;
|
||||||
if (++qc > nlen) {
|
if (++qc > nlen) {
|
||||||
|
@ -338,7 +379,7 @@ static JSBool odbc_get_data(JSContext * cx, JSObject * obj, uintN argc, jsval *a
|
||||||
SQLGetData(odbc_obj->stmt, x, SQL_C_CHAR, odbc_obj->colbuf, odbc_obj->cblen, NULL);
|
SQLGetData(odbc_obj->stmt, x, SQL_C_CHAR, odbc_obj->colbuf, odbc_obj->cblen, NULL);
|
||||||
|
|
||||||
if (strchr((char *) odbc_obj->colbuf, '"')) { /* please don't */
|
if (strchr((char *) odbc_obj->colbuf, '"')) { /* please don't */
|
||||||
esc = (SQLCHAR *) escape_data((char *) odbc_obj->colbuf);
|
esc = (SQLCHAR *) escape_data((char *) odbc_obj->colbuf, '\\');
|
||||||
data = esc;
|
data = esc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,6 +414,8 @@ enum odbc_tinyid {
|
||||||
static JSFunctionSpec odbc_methods[] = {
|
static JSFunctionSpec odbc_methods[] = {
|
||||||
{"connect", odbc_connect, 1},
|
{"connect", odbc_connect, 1},
|
||||||
{"exec", odbc_exec, 1},
|
{"exec", odbc_exec, 1},
|
||||||
|
{"query", odbc_exec, 1},
|
||||||
|
{"execute", odbc_execute, 1},
|
||||||
{"numRows", odbc_num_rows, 1},
|
{"numRows", odbc_num_rows, 1},
|
||||||
{"nextRow", odbc_next_row, 1},
|
{"nextRow", odbc_next_row, 1},
|
||||||
{"getData", odbc_get_data, 1},
|
{"getData", odbc_get_data, 1},
|
||||||
|
|
|
@ -38,6 +38,8 @@ struct switch_odbc_handle {
|
||||||
SQLHENV env;
|
SQLHENV env;
|
||||||
SQLHDBC con;
|
SQLHDBC con;
|
||||||
switch_odbc_state_t state;
|
switch_odbc_state_t state;
|
||||||
|
char odbc_driver[256];
|
||||||
|
BOOL is_firebird;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,6 +112,8 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand
|
||||||
SQLINTEGER err;
|
SQLINTEGER err;
|
||||||
int16_t mlen;
|
int16_t mlen;
|
||||||
unsigned char msg[200], stat[10];
|
unsigned char msg[200], stat[10];
|
||||||
|
SQLSMALLINT valueLength = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
if (handle->env == SQL_NULL_HANDLE) {
|
if (handle->env == SQL_NULL_HANDLE) {
|
||||||
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env);
|
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handle->env);
|
||||||
|
@ -156,13 +160,25 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_connect(switch_odbc_hand
|
||||||
}
|
}
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
SQLFreeHandle(SQL_HANDLE_ENV, handle->env);
|
||||||
return SWITCH_ODBC_FAIL;
|
return SWITCH_ODBC_FAIL;
|
||||||
} else {
|
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to [%s]\n", handle->dsn);
|
|
||||||
handle->state = SWITCH_ODBC_STATE_CONNECTED;
|
|
||||||
return SWITCH_ODBC_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = SQLGetInfo(handle->con, SQL_DRIVER_NAME, (SQLCHAR*)handle->odbc_driver, 255, &valueLength);
|
||||||
|
if ( result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO)
|
||||||
|
{
|
||||||
|
for (i = 0; i < valueLength; ++i)
|
||||||
|
handle->odbc_driver[i] = (char)toupper(handle->odbc_driver[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Firebird do not support "SELECT 1"
|
||||||
|
if (strstr(handle->odbc_driver, "FIREBIRD") != 0 || strstr(handle->odbc_driver, "FB32") != 0 || strstr(handle->odbc_driver, "FB64") != 0)
|
||||||
|
handle->is_firebird = TRUE;
|
||||||
|
else
|
||||||
|
handle->is_firebird = FALSE;
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to [%s]\n", handle->dsn);
|
||||||
|
handle->state = SWITCH_ODBC_STATE_CONNECTED;
|
||||||
|
return SWITCH_ODBC_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int db_is_up(switch_odbc_handle_t *handle)
|
static int db_is_up(switch_odbc_handle_t *handle)
|
||||||
|
@ -172,9 +188,16 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
||||||
SQLINTEGER m = 0;
|
SQLINTEGER m = 0;
|
||||||
int result;
|
int result;
|
||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
switch_odbc_status_t recon;
|
switch_odbc_status_t recon = 0;
|
||||||
char *err_str = NULL;
|
char *err_str = NULL;
|
||||||
SQLCHAR sql[] = "select 1";
|
SQLCHAR sql[255];
|
||||||
|
|
||||||
|
//Firebird do not support "SELECT 1"
|
||||||
|
sql[0] = 0;
|
||||||
|
if (handle->is_firebird)
|
||||||
|
strcpy((char*)sql, "select first 1 * from RDB$RELATIONS");
|
||||||
|
else
|
||||||
|
strcpy((char*)sql, "select 1");
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n");
|
||||||
|
@ -197,10 +220,15 @@ static int db_is_up(switch_odbc_handle_t *handle)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
||||||
recon = switch_odbc_handle_connect(handle);
|
|
||||||
err_str = switch_odbc_handle_get_error(handle, stmt);
|
err_str = switch_odbc_handle_get_error(handle, stmt);
|
||||||
|
|
||||||
|
// No need to reconnect if we can get the string anyway.
|
||||||
|
if (err_str == 0)
|
||||||
|
{
|
||||||
|
recon = switch_odbc_handle_connect(handle);
|
||||||
|
err_str = switch_odbc_handle_get_error(handle, stmt);
|
||||||
|
}
|
||||||
|
|
||||||
if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
|
if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Failure-Message", "The sql server is not responding for DSN %s [%s]",
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Failure-Message", "The sql server is not responding for DSN %s [%s]",
|
||||||
switch_str_nil(handle->dsn), switch_str_nil(err_str));
|
switch_str_nil(handle->dsn), switch_str_nil(err_str));
|
||||||
|
|
Loading…
Reference in New Issue