diff -a -r -d -u apps/app_voicemail.c apps/app_voicemail.c --- apps/app_voicemail.c 2006-05-19 19:03:33.000000000 +0300 +++ apps/app_voicemail.c 2006-06-22 22:14:02.000000000 +0300 @@ -852,8 +852,10 @@ char msgnums[80]; odbc_obj *obj; + odbc_obj_con *obj_con; obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { + obj_con = fetch_odbc_con(obj); + if (obj && obj_con) { ast_copy_string(fmt, vmfmts, sizeof(fmt)); c = strchr(fmt, '|'); if (c) @@ -868,7 +870,7 @@ snprintf(full_fn, sizeof(full_fn), "%s.txt", fn); f = fopen(full_fn, "w+"); snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt); - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + res = SQLAllocHandle(SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; @@ -882,7 +884,7 @@ } SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(dir), 0, (void *)dir, 0, NULL); SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL); - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -960,6 +962,8 @@ } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: + if(obj && obj_con) + release_odbc_con(obj, obj_con); if (f) fclose(f); if (fdm) @@ -995,9 +999,11 @@ char rowdata[20]; odbc_obj *obj; + odbc_obj_con *obj_con; obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + obj_con = fetch_odbc_con(obj); + if (obj && obj_con) { + res = SQLAllocHandle(SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; @@ -1010,7 +1016,7 @@ goto yuck; } SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(dir), 0, (void *)dir, 0, NULL); - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -1033,7 +1039,10 @@ SQLFreeHandle (SQL_HANDLE_STMT, stmt); } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); -yuck: +yuck: + if(obj && obj_con) + release_odbc_con(obj, obj_con); + return x - 1; } @@ -1047,10 +1056,12 @@ char msgnums[20]; odbc_obj *obj; + odbc_obj_con *obj_con; obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { + obj_con = fetch_odbc_con(obj); + if (obj && obj_con) { snprintf(msgnums, sizeof(msgnums), "%d", msgnum); - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + res = SQLAllocHandle(SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; @@ -1064,7 +1075,7 @@ } SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(dir), 0, (void *)dir, 0, NULL); SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL); - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -1088,6 +1099,9 @@ } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: + if(obj && obj_con) + release_odbc_con(obj, obj_con); + return x; } @@ -1104,10 +1118,12 @@ char msgnums[20]; odbc_obj *obj; + odbc_obj_con *obj_con; obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { + obj_con = fetch_odbc_con(obj); + if (obj && obj_con) { snprintf(msgnums, sizeof(msgnums), "%d", smsg); - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + res = SQLAllocHandle(SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; @@ -1121,7 +1137,7 @@ } SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(sdir), 0, (void *)sdir, 0, NULL); SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL); - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -1131,6 +1147,9 @@ } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: + if(obj && obj_con) + release_odbc_con(obj, obj_con); + return; } @@ -1142,13 +1161,15 @@ char msgnums[20]; char msgnumd[20]; odbc_obj *obj; + odbc_obj_con *obj_con; delete_file(ddir, dmsg); obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { + obj_con = fetch_odbc_con(obj); + if (obj && obj_con) { snprintf(msgnums, sizeof(msgnums), "%d", smsg); snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg); - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + res = SQLAllocHandle(SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; @@ -1175,7 +1196,7 @@ SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(sdir), 0, (void *)sdir, 0, NULL); SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL); #endif - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -1185,6 +1206,9 @@ } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: + if(obj && obj_con) + release_odbc_con(obj, obj_con); + return; } @@ -1207,10 +1231,12 @@ char *category = ""; struct ast_config *cfg=NULL; odbc_obj *obj; + odbc_obj_con *obj_con; delete_file(dir, msgnum); obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { + obj_con = fetch_odbc_con(obj); + if (obj && obj_con) { ast_copy_string(fmt, vmfmts, sizeof(fmt)); c = strchr(fmt, '|'); if (c) @@ -1252,7 +1278,7 @@ ast_log(LOG_WARNING, "Memory map failed!\n"); goto yuck; } - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + res = SQLAllocHandle(SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; @@ -1293,7 +1319,7 @@ if (!ast_strlen_zero(category)) SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(category), 0, (void *)category, 0, NULL); #endif - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -1303,6 +1329,8 @@ } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: + if(obj && obj_con) + release_odbc_con(obj, obj_con); if (cfg) ast_config_destroy(cfg); if (fdm) @@ -1320,13 +1348,15 @@ char msgnums[20]; char msgnumd[20]; odbc_obj *obj; + odbc_obj_con *obj_con; delete_file(ddir, dmsg); obj = fetch_odbc_obj(odbc_database, 0); - if (obj) { + obj_con = fetch_odbc_con(obj); + if (obj && obj_con) { snprintf(msgnums, sizeof(msgnums), "%d", smsg); snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg); - res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); + res = SQLAllocHandle(SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); goto yuck; @@ -1353,7 +1383,7 @@ SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(sdir), 0, (void *)sdir, 0, NULL); SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(msgnums), 0, (void *)msgnums, 0, NULL); #endif - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); @@ -1363,6 +1393,8 @@ } else ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); yuck: + if(obj && obj_con) + release_odbc_con(obj, obj_con); return; } diff -a -r -d -u include/asterisk/res_odbc.h include/asterisk/res_odbc.h --- include/asterisk/res_odbc.h 2005-11-29 20:24:39.000000000 +0200 +++ include/asterisk/res_odbc.h 2006-06-23 13:54:56.000000000 +0300 @@ -30,33 +30,61 @@ #include typedef struct odbc_obj odbc_obj; +typedef struct odbc_obj_con odbc_obj_con; typedef enum { ODBC_SUCCESS=0,ODBC_FAIL=-1} odbc_status; +struct odbc_obj_con { + SQLHENV env; /* ODBC Environment */ + SQLHDBC con; /* ODBC Connection Handle */ + SQLHSTMT stmt; /* ODBC Statement Handle */ + ast_mutex_t lock; + int id; + int up; + int available; + + const char *owner_func; + const char *owner_file; + int owner_line; + + time_t lock_time; +}; + + struct odbc_obj { char *name; char *dsn; char *username; char *password; - SQLHENV env; /* ODBC Environment */ - SQLHDBC con; /* ODBC Connection Handle */ - SQLHSTMT stmt; /* ODBC Statement Handle */ + int pooled; + int poolsize; + int poolavailable; + int executes; + odbc_obj_con *pool; + ast_mutex_t poollock; + ast_cond_t poolcond; ast_mutex_t lock; - int up; }; /* functions */ -odbc_obj *new_odbc_obj(char *name,char *dsn,char *username, char *password); -odbc_status odbc_obj_connect(odbc_obj *obj); -odbc_status odbc_obj_disconnect(odbc_obj *obj); +odbc_obj *new_odbc_obj(char *name,char *dsn,char *username, char *password, int poolsize); +odbc_status odbc_obj_connect(odbc_obj *obj, odbc_obj_con *obj_con); +void odbc_obj_connect_all(odbc_obj *obj); +odbc_status odbc_obj_disconnect(odbc_obj *obj, odbc_obj_con *obj_con); +void odbc_obj_disconnect_all(odbc_obj *obj); void destroy_odbc_obj(odbc_obj **obj); int register_odbc_obj(char *name,odbc_obj *obj); odbc_obj *fetch_odbc_obj(const char *name, int check); -int odbc_dump_fd(int fd,odbc_obj *obj); -int odbc_sanity_check(odbc_obj *obj); -SQLHSTMT odbc_prepare_and_execute(odbc_obj *obj, SQLHSTMT (*prepare_cb)(odbc_obj *obj, void *data), void *data); -int odbc_smart_execute(odbc_obj *obj, SQLHSTMT stmt); -int odbc_smart_direct_execute(odbc_obj *obj, SQLHSTMT stmt, char *sql); +void release_odbc_con(odbc_obj *obj, odbc_obj_con *obj_con); +int odbc_dump_fd(int fd,odbc_obj *obj, int showpool); +int odbc_sanity_check(odbc_obj *obj, odbc_obj_con *obj_con); +void odbc_sanity_check_all(odbc_obj *obj); +SQLHSTMT odbc_prepare_and_execute(odbc_obj *obj, odbc_obj_con *obj_con, SQLHSTMT (*prepare_cb)(odbc_obj *obj, void *data), void *data); +int odbc_smart_execute(odbc_obj *obj, odbc_obj_con *obj_con, SQLHSTMT stmt); +int odbc_smart_direct_execute(odbc_obj *obj, odbc_obj_con *obj_con, SQLHSTMT stmt, char *sql); + +odbc_obj_con *__fetch_odbc_con(const char *file, int line, const char *function, odbc_obj *obj); +#define fetch_odbc_con(obj) __fetch_odbc_con(__FILE__, __LINE__, __PRETTY_FUNCTION__, obj) #endif /* _ASTERISK_RES_ODBC_H */ diff -a -r -d -u res/res_config_odbc.c res/res_config_odbc.c --- res/res_config_odbc.c 2006-03-01 19:41:52.000000000 +0200 +++ res/res_config_odbc.c 2006-06-23 13:26:59.000000000 +0300 @@ -53,6 +53,7 @@ static struct ast_variable *realtime_odbc(const char *database, const char *table, va_list ap) { odbc_obj *obj; + odbc_obj_con *obj_con; SQLHSTMT stmt; char sql[1024]; char coltitle[256]; @@ -83,15 +84,21 @@ if (!obj) return NULL; - res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt); + obj_con = fetch_odbc_con(obj); + if (!obj_con) + return NULL; + + res = SQLAllocHandle (SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); + release_odbc_con(obj, obj_con); return NULL; } newparam = va_arg(aq, const char *); if (!newparam) { SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } newval = va_arg(aq, const char *); @@ -107,6 +114,7 @@ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } @@ -118,11 +126,12 @@ SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL); } - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } @@ -130,17 +139,20 @@ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } res = SQLFetch(stmt); if (res == SQL_NO_DATA) { SQLFreeHandle (SQL_HANDLE_STMT, stmt); - return NULL; + release_odbc_con(obj, obj_con); + return NULL; } if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } for (x=0;xcon, &stmt); + obj_con = fetch_odbc_con(obj); + if (!obj_con) + return NULL; + + res = SQLAllocHandle (SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); + release_odbc_con(obj, obj_con); return NULL; } newparam = va_arg(aq, const char *); if (!newparam) { SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } initfield = ast_strdupa(newparam); @@ -253,6 +277,7 @@ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } @@ -264,11 +289,12 @@ SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL); } - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } @@ -276,6 +302,7 @@ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } @@ -283,6 +310,7 @@ if (!cfg) { ast_log(LOG_WARNING, "Out of memory!\n"); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } @@ -333,12 +361,16 @@ } SQLFreeHandle (SQL_HANDLE_STMT, stmt); + + release_odbc_con(obj, obj_con); + return cfg; } static int update_odbc(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap) { odbc_obj *obj; + odbc_obj_con *obj_con; SQLHSTMT stmt; char sql[256]; SQLLEN rowcount=0; @@ -356,15 +388,21 @@ if (!obj) return -1; - res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt); + obj_con = fetch_odbc_con (obj); + if (!obj_con) + return -1; + + res = SQLAllocHandle (SQL_HANDLE_STMT, obj_con->con, &stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); + release_odbc_con(obj, obj_con); return -1; } newparam = va_arg(aq, const char *); if (!newparam) { SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return -1; } newval = va_arg(aq, const char *); @@ -380,6 +418,7 @@ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return -1; } @@ -393,7 +432,7 @@ SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(lookup), 0, (void *)lookup, 0, NULL); - res = odbc_smart_execute(obj, stmt); + res = odbc_smart_execute(obj, obj_con, stmt); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); @@ -403,6 +442,7 @@ res = SQLRowCount(stmt, &rowcount); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql); @@ -421,6 +461,7 @@ struct ast_category *cur_cat; int res = 0; odbc_obj *obj; + odbc_obj_con *obj_con; SQLINTEGER err=0, commented=0, cat_metric=0, var_metric=0, last_cat_metric=0; SQLBIGINT id; char sql[255] = "", filename[128], category[128], var_name[128], var_val[512]; @@ -435,7 +476,11 @@ if (!obj) return NULL; - res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt); + obj_con = fetch_odbc_con(obj); + if (!obj_con) + return NULL; + + res = SQLAllocHandle (SQL_HANDLE_STMT, obj_con->con, &stmt); SQLBindCol (stmt, 1, SQL_C_ULONG, &id, sizeof (id), &err); SQLBindCol (stmt, 2, SQL_C_ULONG, &cat_metric, sizeof (cat_metric), &err); @@ -448,11 +493,12 @@ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE filename='%s' and commented=0 ORDER BY filename,cat_metric desc,var_metric asc,category,var_name,var_val,id", table, file); - res = odbc_smart_direct_execute(obj, stmt, sql); + res = odbc_smart_direct_execute(obj, obj_con, stmt, sql); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log (LOG_WARNING, "SQL select error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } @@ -461,11 +507,13 @@ if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { ast_log (LOG_WARNING, "SQL NumResultCols error!\n[%s]\n\n", sql); SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } if (!rowcount) { ast_log (LOG_NOTICE, "found nothing\n"); + release_odbc_con(obj, obj_con); return cfg; } @@ -475,6 +523,7 @@ if (!strcmp (var_name, "#include")) { if (!ast_config_internal_load(var_val, cfg)) { SQLFreeHandle (SQL_HANDLE_STMT, stmt); + release_odbc_con(obj, obj_con); return NULL; } continue; @@ -495,6 +544,9 @@ } SQLFreeHandle (SQL_HANDLE_STMT, stmt); + + release_odbc_con(obj, obj_con); + return cfg; }