#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
Include dependency graph for res_odbc.h:
This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
Data Structures | |
struct | odbc_obj |
Typedefs | |
typedef odbc_obj | odbc_obj |
Enumerations | |
enum | odbc_status { ODBC_SUCCESS = 0, ODBC_FAIL = -1 } |
Functions | |
void | destroy_odbc_obj (odbc_obj **obj) |
odbc_obj * | fetch_odbc_obj (const char *name, int check) |
odbc_obj * | new_odbc_obj (char *name, char *dsn, char *username, char *password) |
int | odbc_dump_fd (int fd, odbc_obj *obj) |
odbc_status | odbc_obj_connect (odbc_obj *obj) |
odbc_status | odbc_obj_disconnect (odbc_obj *obj) |
SQLHSTMT | odbc_prepare_and_execute (odbc_obj *obj, SQLHSTMT(*prepare_cb)(odbc_obj *obj, void *data), void *data) |
int | odbc_sanity_check (odbc_obj *obj) |
int | odbc_smart_direct_execute (odbc_obj *obj, SQLHSTMT stmt, char *sql) |
int | odbc_smart_execute (odbc_obj *obj, SQLHSTMT stmt) |
int | register_odbc_obj (char *name, odbc_obj *obj) |
Definition in file res_odbc.h.
Definition at line 32 of file res_odbc.h.
enum odbc_status |
void destroy_odbc_obj | ( | odbc_obj ** | obj | ) |
Definition at line 468 of file res_odbc.c.
References ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), free, and odbc_obj_disconnect().
Referenced by odbc_destroy().
00469 { 00470 odbc_obj_disconnect(*obj); 00471 00472 ast_mutex_lock(&(*obj)->lock); 00473 SQLFreeHandle(SQL_HANDLE_STMT, (*obj)->stmt); 00474 SQLFreeHandle(SQL_HANDLE_DBC, (*obj)->con); 00475 SQLFreeHandle(SQL_HANDLE_ENV, (*obj)->env); 00476 00477 free((*obj)->name); 00478 free((*obj)->dsn); 00479 if ((*obj)->username) 00480 free((*obj)->username); 00481 if ((*obj)->password) 00482 free((*obj)->password); 00483 ast_mutex_unlock(&(*obj)->lock); 00484 ast_mutex_destroy(&(*obj)->lock); 00485 free(*obj); 00486 }
odbc_obj* fetch_odbc_obj | ( | const char * | name, | |
int | check | |||
) |
Definition at line 417 of file res_odbc.c.
References odbc_read(), ODBC_REGISTRY, and odbc_sanity_check().
Referenced by acf_odbc_read(), acf_odbc_write(), config_odbc(), realtime_multi_odbc(), realtime_odbc(), and update_odbc().
00418 { 00419 odbc_obj *obj = NULL; 00420 if((obj = (odbc_obj *) odbc_read(ODBC_REGISTRY, name))) { 00421 if(check) 00422 odbc_sanity_check(obj); 00423 } 00424 return obj; 00425 }
odbc_obj* new_odbc_obj | ( | char * | name, | |
char * | dsn, | |||
char * | username, | |||
char * | password | |||
) |
Definition at line 427 of file res_odbc.c.
References ast_mutex_init(), calloc, cleanup(), free, and malloc.
Referenced by load_odbc_config().
00428 { 00429 static odbc_obj *new; 00430 00431 if (!(new = calloc(1, sizeof(*new))) || 00432 !(new->name = malloc(strlen(name) + 1)) || 00433 !(new->dsn = malloc(strlen(dsn) + 1))) 00434 goto cleanup; 00435 00436 if (username) { 00437 if (!(new->username = malloc(strlen(username) + 1))) 00438 goto cleanup; 00439 strcpy(new->username, username); 00440 } 00441 00442 if (password) { 00443 if (!(new->password = malloc(strlen(password) + 1))) 00444 goto cleanup; 00445 strcpy(new->password, password); 00446 } 00447 00448 strcpy(new->name, name); 00449 strcpy(new->dsn, dsn); 00450 new->env = SQL_NULL_HANDLE; 00451 new->up = 0; 00452 ast_mutex_init(&new->lock); 00453 return new; 00454 00455 cleanup: 00456 if (new) { 00457 free(new->name); 00458 free(new->dsn); 00459 free(new->username); 00460 free(new->password); 00461 00462 free(new); 00463 } 00464 00465 return NULL; 00466 }
int odbc_dump_fd | ( | int | fd, | |
odbc_obj * | obj | |||
) |
Definition at line 309 of file res_odbc.c.
References ast_cli(), odbc_obj::dsn, odbc_obj::name, odbc_sanity_check(), and odbc_obj::up.
Referenced by odbc_show_command().
00310 { 00311 /* make sure the connection is up before we lie to our master.*/ 00312 odbc_sanity_check(obj); 00313 ast_cli(fd, "Name: %s\nDSN: %s\nConnected: %s\n\n", obj->name, obj->dsn, obj->up ? "yes" : "no"); 00314 return 0; 00315 }
odbc_status odbc_obj_connect | ( | odbc_obj * | obj | ) |
Definition at line 507 of file res_odbc.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), odbc_obj::con, odbc_obj::dsn, odbc_obj::env, odbc_obj::lock, LOG_NOTICE, LOG_WARNING, odbc_obj::name, ODBC_FAIL, odbc_obj_disconnect(), ODBC_SUCCESS, option_verbose, odbc_obj::password, odbc_obj::up, and odbc_obj::username.
Referenced by acf_odbc_write(), load_odbc_config(), odbc_connect_command(), odbc_prepare_and_execute(), odbc_sanity_check(), and odbc_smart_direct_execute().
00508 { 00509 int res; 00510 SQLINTEGER err; 00511 short int mlen; 00512 unsigned char msg[200], stat[10]; 00513 00514 ast_mutex_lock(&obj->lock); 00515 00516 if (obj->env == SQL_NULL_HANDLE) { 00517 res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &obj->env); 00518 00519 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00520 if (option_verbose > 3) 00521 ast_log(LOG_WARNING, "res_odbc: Error AllocHandle\n"); 00522 ast_mutex_unlock(&obj->lock); 00523 return ODBC_FAIL; 00524 } 00525 00526 res = SQLSetEnvAttr(obj->env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0); 00527 00528 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00529 if (option_verbose > 3) 00530 ast_log(LOG_WARNING, "res_odbc: Error SetEnv\n"); 00531 SQLFreeHandle(SQL_HANDLE_ENV, obj->env); 00532 ast_mutex_unlock(&obj->lock); 00533 return ODBC_FAIL; 00534 } 00535 00536 res = SQLAllocHandle(SQL_HANDLE_DBC, obj->env, &obj->con); 00537 00538 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00539 00540 if (option_verbose > 3) 00541 ast_log(LOG_WARNING, "res_odbc: Error AllocHDB %d\n", res); 00542 SQLFreeHandle(SQL_HANDLE_ENV, obj->env); 00543 00544 ast_mutex_unlock(&obj->lock); 00545 return ODBC_FAIL; 00546 } 00547 SQLSetConnectAttr(obj->con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *) 10, 0); 00548 } 00549 if(obj->up) { 00550 odbc_obj_disconnect(obj); 00551 ast_log(LOG_NOTICE,"Re-connecting %s\n", obj->name); 00552 } 00553 00554 ast_log(LOG_NOTICE, "Connecting %s\n", obj->name); 00555 00556 res = SQLConnect(obj->con, 00557 (SQLCHAR *) obj->dsn, SQL_NTS, 00558 (SQLCHAR *) obj->username, SQL_NTS, 00559 (SQLCHAR *) obj->password, SQL_NTS); 00560 00561 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00562 SQLGetDiagRec(SQL_HANDLE_DBC, obj->con, 1, stat, &err, msg, 100, &mlen); 00563 SQLFreeHandle(SQL_HANDLE_ENV, obj->env); 00564 ast_mutex_unlock(&obj->lock); 00565 ast_log(LOG_WARNING, "res_odbc: Error SQLConnect=%d errno=%d %s\n", res, (int)err, msg); 00566 return ODBC_FAIL; 00567 } else { 00568 00569 ast_log(LOG_NOTICE, "res_odbc: Connected to %s [%s]\n", obj->name, obj->dsn); 00570 obj->up = 1; 00571 } 00572 00573 ast_mutex_unlock(&obj->lock); 00574 return ODBC_SUCCESS; 00575 }
odbc_status odbc_obj_disconnect | ( | odbc_obj * | obj | ) |
Definition at line 488 of file res_odbc.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), odbc_obj::con, odbc_obj::dsn, odbc_obj::lock, LOG_WARNING, odbc_obj::name, ODBC_SUCCESS, and odbc_obj::up.
Referenced by acf_odbc_write(), destroy_odbc_obj(), odbc_disconnect_command(), odbc_obj_connect(), odbc_prepare_and_execute(), odbc_sanity_check(), and odbc_smart_direct_execute().
00489 { 00490 int res; 00491 ast_mutex_lock(&obj->lock); 00492 00493 res = SQLDisconnect(obj->con); 00494 00495 00496 if (res == ODBC_SUCCESS) { 00497 ast_log(LOG_WARNING, "res_odbc: disconnected %d from %s [%s]\n", res, obj->name, obj->dsn); 00498 } else { 00499 ast_log(LOG_WARNING, "res_odbc: %s [%s] already disconnected\n", 00500 obj->name, obj->dsn); 00501 } 00502 obj->up = 0; 00503 ast_mutex_unlock(&obj->lock); 00504 return ODBC_SUCCESS; 00505 }
SQLHSTMT odbc_prepare_and_execute | ( | odbc_obj * | obj, | |
SQLHSTMT(*)(odbc_obj *obj, void *data) | prepare_cb, | |||
void * | data | |||
) |
Definition at line 110 of file res_odbc.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, odbc_obj_connect(), and odbc_obj_disconnect().
00111 { 00112 int res = 0, i, attempt; 00113 SQLINTEGER nativeerror=0, numfields=0; 00114 SQLSMALLINT diagbytes=0; 00115 unsigned char state[10], diagnostic[256]; 00116 SQLHSTMT stmt; 00117 00118 for (attempt = 0; attempt < 2; attempt++) { 00119 /* This prepare callback may do more than just prepare -- it may also 00120 * bind parameters, bind results, etc. The real key, here, is that 00121 * when we disconnect, all handles become invalid for most databases. 00122 * We must therefore redo everything when we establish a new 00123 * connection. */ 00124 stmt = prepare_cb(obj, data); 00125 00126 if (stmt) { 00127 res = SQLExecute(stmt); 00128 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO) && (res != SQL_NO_DATA)) { 00129 if (res == SQL_ERROR) { 00130 SQLGetDiagField(SQL_HANDLE_STMT, stmt, 1, SQL_DIAG_NUMBER, &numfields, SQL_IS_INTEGER, &diagbytes); 00131 for (i=0; i< numfields + 1; i++) { 00132 SQLGetDiagRec(SQL_HANDLE_STMT, stmt, i + 1, state, &nativeerror, diagnostic, sizeof(diagnostic), &diagbytes); 00133 ast_log(LOG_WARNING, "SQL Execute returned an error %d: %s: %s (%d)\n", res, state, diagnostic, diagbytes); 00134 if (i > 10) { 00135 ast_log(LOG_WARNING, "Oh, that was good. There are really %d diagnostics?\n", (int)numfields); 00136 break; 00137 } 00138 } 00139 } 00140 00141 ast_log(LOG_WARNING, "SQL Execute error %d! Attempting a reconnect...\n", res); 00142 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00143 00144 ast_mutex_lock(&obj->lock); 00145 obj->up = 0; 00146 ast_mutex_unlock(&obj->lock); 00147 odbc_obj_disconnect(obj); 00148 odbc_obj_connect(obj); 00149 continue; 00150 } 00151 break; 00152 } 00153 } 00154 00155 return stmt; 00156 }
int odbc_sanity_check | ( | odbc_obj * | obj | ) |
Definition at line 211 of file res_odbc.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), odbc_obj::con, odbc_obj::lock, LOG_WARNING, odbc_list::obj, odbc_obj_connect(), odbc_obj_disconnect(), and odbc_obj::up.
Referenced by fetch_odbc_obj(), and odbc_dump_fd().
00212 { 00213 char *test_sql = "select 1"; 00214 SQLHSTMT stmt; 00215 int res = 0; 00216 00217 ast_mutex_lock(&obj->lock); 00218 if(obj->up) { /* so you say... let's make sure */ 00219 res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt); 00220 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00221 obj->up = 0; /* Liar!*/ 00222 } else { 00223 res = SQLPrepare(stmt, (unsigned char *)test_sql, SQL_NTS); 00224 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00225 obj->up = 0; /* Liar!*/ 00226 } else { 00227 res = SQLExecute(stmt); 00228 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00229 obj->up = 0; /* Liar!*/ 00230 } 00231 } 00232 } 00233 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00234 } 00235 ast_mutex_unlock(&obj->lock); 00236 00237 if(!obj->up) { /* Try to reconnect! */ 00238 ast_log(LOG_WARNING, "Connection is down attempting to reconnect...\n"); 00239 odbc_obj_disconnect(obj); 00240 odbc_obj_connect(obj); 00241 } 00242 return obj->up; 00243 }
int odbc_smart_direct_execute | ( | odbc_obj * | obj, | |
SQLHSTMT | stmt, | |||
char * | sql | |||
) |
Definition at line 193 of file res_odbc.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), odbc_obj::lock, LOG_WARNING, odbc_list::obj, odbc_obj_connect(), odbc_obj_disconnect(), and odbc_obj::up.
Referenced by config_odbc().
00194 { 00195 int res = 0; 00196 00197 res = SQLExecDirect (stmt, (unsigned char *)sql, SQL_NTS); 00198 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00199 ast_log(LOG_WARNING, "SQL Execute error! Attempting a reconnect...\n"); 00200 ast_mutex_lock(&obj->lock); 00201 obj->up = 0; 00202 ast_mutex_unlock(&obj->lock); 00203 odbc_obj_disconnect(obj); 00204 odbc_obj_connect(obj); 00205 res = SQLExecDirect (stmt, (unsigned char *)sql, SQL_NTS); 00206 } 00207 00208 return res; 00209 }
int odbc_smart_execute | ( | odbc_obj * | obj, | |
SQLHSTMT | stmt | |||
) |
Definition at line 158 of file res_odbc.c.
References ast_log(), and LOG_WARNING.
Referenced by acf_odbc_read(), realtime_multi_odbc(), realtime_odbc(), and update_odbc().
00159 { 00160 int res = 0, i; 00161 SQLINTEGER nativeerror=0, numfields=0; 00162 SQLSMALLINT diagbytes=0; 00163 unsigned char state[10], diagnostic[256]; 00164 00165 res = SQLExecute(stmt); 00166 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO) && (res != SQL_NO_DATA)) { 00167 if (res == SQL_ERROR) { 00168 SQLGetDiagField(SQL_HANDLE_STMT, stmt, 1, SQL_DIAG_NUMBER, &numfields, SQL_IS_INTEGER, &diagbytes); 00169 for (i=0; i< numfields + 1; i++) { 00170 SQLGetDiagRec(SQL_HANDLE_STMT, stmt, i + 1, state, &nativeerror, diagnostic, sizeof(diagnostic), &diagbytes); 00171 ast_log(LOG_WARNING, "SQL Execute returned an error %d: %s: %s (%d)\n", res, state, diagnostic, diagbytes); 00172 if (i > 10) { 00173 ast_log(LOG_WARNING, "Oh, that was good. There are really %d diagnostics?\n", (int)numfields); 00174 break; 00175 } 00176 } 00177 } 00178 /* 00179 ast_log(LOG_WARNING, "SQL Execute error %d! Attempting a reconnect...\n", res); 00180 ast_mutex_lock(&obj->lock); 00181 obj->up = 0; 00182 ast_mutex_unlock(&obj->lock); 00183 odbc_obj_disconnect(obj); 00184 odbc_obj_connect(obj); 00185 res = SQLExecute(stmt); 00186 */ 00187 } 00188 00189 return res; 00190 }
int register_odbc_obj | ( | char * | name, | |
odbc_obj * | obj | |||
) |
Definition at line 410 of file res_odbc.c.
References ODBC_REGISTRY, and odbc_write().
Referenced by load_odbc_config().
00411 { 00412 if (obj != NULL) 00413 return odbc_write(ODBC_REGISTRY, name, obj); 00414 return 0; 00415 }