#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/res_odbc.h"
#include "asterisk/utils.h"
Go to the source code of this file.
Data Structures | |
struct | config_odbc_obj |
struct | custom_prepare_struct |
Functions | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"ODBC Configuration",.load=load_module,.unload=unload_module,) | |
static struct ast_config * | config_odbc (const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments) |
static SQLHSTMT | config_odbc_prepare (struct odbc_obj *obj, void *data) |
static SQLHSTMT | custom_prepare (struct odbc_obj *obj, void *data) |
static int | load_module (void) |
static struct ast_config * | realtime_multi_odbc (const char *database, const char *table, va_list ap) |
static struct ast_variable * | realtime_odbc (const char *database, const char *table, va_list ap) |
static int | unload_module (void) |
static int | update_odbc (const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap) |
Variables | |
static struct ast_config_engine | odbc_engine |
Definition in file res_config_odbc.c.
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_GLOBAL_SYMBOLS | , | |||
"ODBC Configuration" | , | |||
. | load = load_module , |
|||
. | unload = unload_module | |||
) |
static struct ast_config* config_odbc | ( | const char * | database, | |
const char * | table, | |||
const char * | file, | |||
struct ast_config * | cfg, | |||
int | withcomments | |||
) | [static, read] |
Definition at line 449 of file res_config_odbc.c.
References ast_build_string(), ast_category_append(), ast_category_new(), ast_config_get_current_category(), ast_config_internal_load(), ast_log(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), ast_variable_append(), ast_variable_new(), config_odbc_obj::cat_metric, config_odbc_obj::category, config_odbc_prepare(), last, LOG_NOTICE, LOG_WARNING, config_odbc_obj::sql, config_odbc_obj::var_name, and config_odbc_obj::var_val.
00450 { 00451 struct ast_variable *new_v; 00452 struct ast_category *cur_cat; 00453 int res = 0; 00454 struct odbc_obj *obj; 00455 char sqlbuf[1024] = ""; 00456 char *sql = sqlbuf; 00457 size_t sqlleft = sizeof(sqlbuf); 00458 unsigned int last_cat_metric = 0; 00459 SQLSMALLINT rowcount = 0; 00460 SQLHSTMT stmt; 00461 char last[128] = ""; 00462 struct config_odbc_obj q; 00463 00464 memset(&q, 0, sizeof(q)); 00465 00466 if (!file || !strcmp (file, "res_config_odbc.conf")) 00467 return NULL; /* cant configure myself with myself ! */ 00468 00469 obj = ast_odbc_request_obj(database, 0); 00470 if (!obj) 00471 return NULL; 00472 00473 ast_build_string(&sql, &sqlleft, "SELECT cat_metric, category, var_name, var_val FROM %s ", table); 00474 ast_build_string(&sql, &sqlleft, "WHERE filename='%s' AND commented=0 ", file); 00475 ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name "); 00476 q.sql = sqlbuf; 00477 00478 stmt = ast_odbc_prepare_and_execute(obj, config_odbc_prepare, &q); 00479 00480 if (!stmt) { 00481 ast_log(LOG_WARNING, "SQL select error!\n[%s]\n\n", sql); 00482 ast_odbc_release_obj(obj); 00483 return NULL; 00484 } 00485 00486 res = SQLNumResultCols(stmt, &rowcount); 00487 00488 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00489 ast_log(LOG_WARNING, "SQL NumResultCols error!\n[%s]\n\n", sql); 00490 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00491 ast_odbc_release_obj(obj); 00492 return NULL; 00493 } 00494 00495 if (!rowcount) { 00496 ast_log(LOG_NOTICE, "found nothing\n"); 00497 ast_odbc_release_obj(obj); 00498 return cfg; 00499 } 00500 00501 cur_cat = ast_config_get_current_category(cfg); 00502 00503 while ((res = SQLFetch(stmt)) != SQL_NO_DATA) { 00504 if (!strcmp (q.var_name, "#include")) { 00505 if (!ast_config_internal_load(q.var_val, cfg, 0)) { 00506 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00507 ast_odbc_release_obj(obj); 00508 return NULL; 00509 } 00510 continue; 00511 } 00512 if (strcmp(last, q.category) || last_cat_metric != q.cat_metric) { 00513 cur_cat = ast_category_new(q.category); 00514 if (!cur_cat) { 00515 ast_log(LOG_WARNING, "Out of memory!\n"); 00516 break; 00517 } 00518 strcpy(last, q.category); 00519 last_cat_metric = q.cat_metric; 00520 ast_category_append(cfg, cur_cat); 00521 } 00522 00523 new_v = ast_variable_new(q.var_name, q.var_val); 00524 ast_variable_append(cur_cat, new_v); 00525 } 00526 00527 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00528 ast_odbc_release_obj(obj); 00529 return cfg; 00530 }
static SQLHSTMT config_odbc_prepare | ( | struct odbc_obj * | obj, | |
void * | data | |||
) | [static] |
Definition at line 420 of file res_config_odbc.c.
References ast_verbose(), config_odbc_obj::cat_metric, config_odbc_obj::category, odbc_obj::con, config_odbc_obj::err, option_verbose, config_odbc_obj::sql, config_odbc_obj::var_name, config_odbc_obj::var_val, and VERBOSE_PREFIX_4.
Referenced by config_odbc().
00421 { 00422 struct config_odbc_obj *q = data; 00423 SQLHSTMT sth; 00424 int res; 00425 00426 res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &sth); 00427 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00428 if (option_verbose > 3) 00429 ast_verbose( VERBOSE_PREFIX_4 "Failure in AllocStatement %d\n", res); 00430 return NULL; 00431 } 00432 00433 res = SQLPrepare(sth, (unsigned char *)q->sql, SQL_NTS); 00434 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00435 if (option_verbose > 3) 00436 ast_verbose( VERBOSE_PREFIX_4 "Error in PREPARE %d\n", res); 00437 SQLFreeHandle(SQL_HANDLE_STMT, sth); 00438 return NULL; 00439 } 00440 00441 SQLBindCol(sth, 1, SQL_C_ULONG, &q->cat_metric, sizeof(q->cat_metric), &q->err); 00442 SQLBindCol(sth, 2, SQL_C_CHAR, q->category, sizeof(q->category), &q->err); 00443 SQLBindCol(sth, 3, SQL_C_CHAR, q->var_name, sizeof(q->var_name), &q->err); 00444 SQLBindCol(sth, 4, SQL_C_CHAR, q->var_val, sizeof(q->var_val), &q->err); 00445 00446 return sth; 00447 }
static SQLHSTMT custom_prepare | ( | struct odbc_obj * | obj, | |
void * | data | |||
) | [static] |
Definition at line 63 of file res_config_odbc.c.
References custom_prepare_struct::ap, ast_log(), ast_strlen_zero(), odbc_obj::con, custom_prepare_struct::extra, LOG_WARNING, and custom_prepare_struct::sql.
Referenced by realtime_multi_odbc(), realtime_odbc(), and update_odbc().
00064 { 00065 int res, x = 1; 00066 struct custom_prepare_struct *cps = data; 00067 const char *newparam, *newval; 00068 SQLHSTMT stmt; 00069 va_list ap; 00070 00071 va_copy(ap, cps->ap); 00072 00073 res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); 00074 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00075 ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); 00076 return NULL; 00077 } 00078 00079 res = SQLPrepare(stmt, (unsigned char *)cps->sql, SQL_NTS); 00080 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00081 ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", cps->sql); 00082 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00083 return NULL; 00084 } 00085 00086 while ((newparam = va_arg(ap, const char *))) { 00087 newval = va_arg(ap, const char *); 00088 SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL); 00089 } 00090 va_end(ap); 00091 00092 if (!ast_strlen_zero(cps->extra)) 00093 SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(cps->extra), 0, (void *)cps->extra, 0, NULL); 00094 return stmt; 00095 }
static int load_module | ( | void | ) | [static] |
Definition at line 549 of file res_config_odbc.c.
References ast_config_engine_register(), ast_verbose(), and option_verbose.
00550 { 00551 ast_config_engine_register(&odbc_engine); 00552 if (option_verbose) 00553 ast_verbose("res_config_odbc loaded.\n"); 00554 return 0; 00555 }
static struct ast_config* realtime_multi_odbc | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static, read] |
Definition at line 220 of file res_config_odbc.c.
References custom_prepare_struct::ap, ast_category_append(), ast_category_destroy(), ast_category_new(), ast_category_rename(), ast_config_new(), ast_log(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), ast_strdupa, ast_strlen_zero(), ast_variable_append(), ast_variable_new(), custom_prepare(), LOG_WARNING, custom_prepare_struct::sql, strcasestr(), strsep(), and var.
00221 { 00222 struct odbc_obj *obj; 00223 SQLHSTMT stmt; 00224 char sql[1024]; 00225 char coltitle[256]; 00226 char rowdata[2048]; 00227 const char *initfield=NULL; 00228 char *op; 00229 const char *newparam, *newval; 00230 char *stringp; 00231 char *chunk; 00232 SQLSMALLINT collen; 00233 int res; 00234 int x; 00235 struct ast_variable *var=NULL; 00236 struct ast_config *cfg=NULL; 00237 struct ast_category *cat=NULL; 00238 struct ast_realloca ra; 00239 SQLULEN colsize; 00240 SQLSMALLINT colcount=0; 00241 SQLSMALLINT datatype; 00242 SQLSMALLINT decimaldigits; 00243 SQLSMALLINT nullable; 00244 SQLLEN indicator; 00245 struct custom_prepare_struct cps = { .sql = sql }; 00246 va_list aq; 00247 00248 va_copy(cps.ap, ap); 00249 va_copy(aq, ap); 00250 00251 if (!table) 00252 return NULL; 00253 memset(&ra, 0, sizeof(ra)); 00254 00255 obj = ast_odbc_request_obj(database, 0); 00256 if (!obj) 00257 return NULL; 00258 00259 newparam = va_arg(aq, const char *); 00260 if (!newparam) { 00261 ast_odbc_release_obj(obj); 00262 return NULL; 00263 } 00264 initfield = ast_strdupa(newparam); 00265 if ((op = strchr(initfield, ' '))) 00266 *op = '\0'; 00267 newval = va_arg(aq, const char *); 00268 op = !strchr(newparam, ' ') ? " =" : ""; 00269 snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?", table, newparam, op); 00270 while((newparam = va_arg(aq, const char *))) { 00271 op = !strchr(newparam, ' ') ? " =" : ""; 00272 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op, 00273 strcasestr(newparam, "LIKE") ? " ESCAPE '\\'" : ""); 00274 newval = va_arg(aq, const char *); 00275 } 00276 if (initfield) 00277 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield); 00278 va_end(aq); 00279 00280 stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps); 00281 00282 if (!stmt) { 00283 ast_odbc_release_obj(obj); 00284 return NULL; 00285 } 00286 00287 res = SQLNumResultCols(stmt, &colcount); 00288 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00289 ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql); 00290 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00291 ast_odbc_release_obj(obj); 00292 return NULL; 00293 } 00294 00295 cfg = ast_config_new(); 00296 if (!cfg) { 00297 ast_log(LOG_WARNING, "Out of memory!\n"); 00298 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00299 ast_odbc_release_obj(obj); 00300 return NULL; 00301 } 00302 00303 while ((res=SQLFetch(stmt)) != SQL_NO_DATA) { 00304 var = NULL; 00305 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00306 ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); 00307 continue; 00308 } 00309 cat = ast_category_new(""); 00310 if (!cat) { 00311 ast_log(LOG_WARNING, "Out of memory!\n"); 00312 continue; 00313 } 00314 for (x=0;x<colcount;x++) { 00315 rowdata[0] = '\0'; 00316 collen = sizeof(coltitle); 00317 res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen, 00318 &datatype, &colsize, &decimaldigits, &nullable); 00319 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00320 ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql); 00321 ast_category_destroy(cat); 00322 continue; 00323 } 00324 00325 indicator = 0; 00326 res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), &indicator); 00327 if (indicator == SQL_NULL_DATA) 00328 continue; 00329 00330 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00331 ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); 00332 ast_category_destroy(cat); 00333 continue; 00334 } 00335 stringp = rowdata; 00336 while(stringp) { 00337 chunk = strsep(&stringp, ";"); 00338 if (!ast_strlen_zero(ast_strip(chunk))) { 00339 if (initfield && !strcmp(initfield, coltitle)) 00340 ast_category_rename(cat, chunk); 00341 var = ast_variable_new(coltitle, chunk); 00342 ast_variable_append(cat, var); 00343 } 00344 } 00345 } 00346 ast_category_append(cfg, cat); 00347 } 00348 00349 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00350 ast_odbc_release_obj(obj); 00351 return cfg; 00352 }
static struct ast_variable* realtime_odbc | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static, read] |
Definition at line 97 of file res_config_odbc.c.
References custom_prepare_struct::ap, ast_log(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), custom_prepare(), LOG_ERROR, LOG_WARNING, custom_prepare_struct::sql, strcasestr(), strsep(), and var.
00098 { 00099 struct odbc_obj *obj; 00100 SQLHSTMT stmt; 00101 char sql[1024]; 00102 char coltitle[256]; 00103 char rowdata[2048]; 00104 char *op; 00105 const char *newparam, *newval; 00106 char *stringp; 00107 char *chunk; 00108 SQLSMALLINT collen; 00109 int res; 00110 int x; 00111 struct ast_variable *var=NULL, *prev=NULL; 00112 SQLULEN colsize; 00113 SQLSMALLINT colcount=0; 00114 SQLSMALLINT datatype; 00115 SQLSMALLINT decimaldigits; 00116 SQLSMALLINT nullable; 00117 SQLLEN indicator; 00118 va_list aq; 00119 struct custom_prepare_struct cps = { .sql = sql }; 00120 00121 va_copy(cps.ap, ap); 00122 va_copy(aq, ap); 00123 00124 if (!table) 00125 return NULL; 00126 00127 obj = ast_odbc_request_obj(database, 0); 00128 00129 if (!obj) { 00130 ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", database); 00131 return NULL; 00132 } 00133 00134 newparam = va_arg(aq, const char *); 00135 if (!newparam) 00136 return NULL; 00137 newval = va_arg(aq, const char *); 00138 op = !strchr(newparam, ' ') ? " =" : ""; 00139 snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?", table, newparam, op); 00140 while((newparam = va_arg(aq, const char *))) { 00141 op = !strchr(newparam, ' ') ? " =" : ""; 00142 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op, 00143 strcasestr(newparam, "LIKE") ? " ESCAPE '\\'" : ""); 00144 newval = va_arg(aq, const char *); 00145 } 00146 va_end(aq); 00147 00148 stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps); 00149 00150 if (!stmt) { 00151 ast_odbc_release_obj(obj); 00152 return NULL; 00153 } 00154 00155 res = SQLNumResultCols(stmt, &colcount); 00156 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00157 ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql); 00158 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00159 ast_odbc_release_obj(obj); 00160 return NULL; 00161 } 00162 00163 res = SQLFetch(stmt); 00164 if (res == SQL_NO_DATA) { 00165 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00166 ast_odbc_release_obj(obj); 00167 return NULL; 00168 } 00169 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00170 ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); 00171 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00172 ast_odbc_release_obj(obj); 00173 return NULL; 00174 } 00175 for (x = 0; x < colcount; x++) { 00176 rowdata[0] = '\0'; 00177 collen = sizeof(coltitle); 00178 res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen, 00179 &datatype, &colsize, &decimaldigits, &nullable); 00180 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00181 ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql); 00182 if (var) 00183 ast_variables_destroy(var); 00184 ast_odbc_release_obj(obj); 00185 return NULL; 00186 } 00187 00188 indicator = 0; 00189 res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), &indicator); 00190 if (indicator == SQL_NULL_DATA) 00191 continue; 00192 00193 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00194 ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); 00195 if (var) 00196 ast_variables_destroy(var); 00197 ast_odbc_release_obj(obj); 00198 return NULL; 00199 } 00200 stringp = rowdata; 00201 while(stringp) { 00202 chunk = strsep(&stringp, ";"); 00203 if (!ast_strlen_zero(ast_strip(chunk))) { 00204 if (prev) { 00205 prev->next = ast_variable_new(coltitle, chunk); 00206 if (prev->next) 00207 prev = prev->next; 00208 } else 00209 prev = var = ast_variable_new(coltitle, chunk); 00210 } 00211 } 00212 } 00213 00214 00215 SQLFreeHandle(SQL_HANDLE_STMT, stmt); 00216 ast_odbc_release_obj(obj); 00217 return var; 00218 }
static int unload_module | ( | void | ) | [static] |
Definition at line 540 of file res_config_odbc.c.
References ast_config_engine_deregister(), ast_module_user_hangup_all, ast_verbose(), and option_verbose.
00541 { 00542 ast_module_user_hangup_all(); 00543 ast_config_engine_deregister(&odbc_engine); 00544 if (option_verbose) 00545 ast_verbose("res_config_odbc unloaded.\n"); 00546 return 0; 00547 }
static int update_odbc | ( | const char * | database, | |
const char * | table, | |||
const char * | keyfield, | |||
const char * | lookup, | |||
va_list | ap | |||
) | [static] |
Definition at line 354 of file res_config_odbc.c.
References custom_prepare_struct::ap, ast_log(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), custom_prepare(), LOG_WARNING, and custom_prepare_struct::sql.
00355 { 00356 struct odbc_obj *obj; 00357 SQLHSTMT stmt; 00358 char sql[256]; 00359 SQLLEN rowcount=0; 00360 const char *newparam, *newval; 00361 int res; 00362 va_list aq; 00363 struct custom_prepare_struct cps = { .sql = sql, .extra = lookup }; 00364 00365 va_copy(cps.ap, ap); 00366 va_copy(aq, ap); 00367 00368 if (!table) 00369 return -1; 00370 00371 obj = ast_odbc_request_obj(database, 0); 00372 if (!obj) 00373 return -1; 00374 00375 newparam = va_arg(aq, const char *); 00376 if (!newparam) { 00377 ast_odbc_release_obj(obj); 00378 return -1; 00379 } 00380 newval = va_arg(aq, const char *); 00381 snprintf(sql, sizeof(sql), "UPDATE %s SET %s=?", table, newparam); 00382 while((newparam = va_arg(aq, const char *))) { 00383 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s=?", newparam); 00384 newval = va_arg(aq, const char *); 00385 } 00386 va_end(aq); 00387 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s=?", keyfield); 00388 00389 stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps); 00390 00391 if (!stmt) { 00392 ast_odbc_release_obj(obj); 00393 return -1; 00394 } 00395 00396 res = SQLRowCount(stmt, &rowcount); 00397 SQLFreeHandle (SQL_HANDLE_STMT, stmt); 00398 ast_odbc_release_obj(obj); 00399 00400 if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { 00401 ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql); 00402 return -1; 00403 } 00404 00405 if (rowcount >= 0) 00406 return (int)rowcount; 00407 00408 return -1; 00409 }
struct ast_config_engine odbc_engine [static] |
Definition at line 532 of file res_config_odbc.c.