Wed Oct 28 11:46:17 2009

Asterisk developer's documentation


res_config_odbc.c File Reference

odbc+odbc plugin for portable configuration engine More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/res_odbc.h"
#include "asterisk/utils.h"

Include dependency graph for res_config_odbc.c:

Go to the source code of this file.

Data Structures

struct  config_odbc_obj
struct  custom_prepare_struct

Functions

static void __reg_module (void)
static void __unreg_module (void)
static struct ast_configconfig_odbc (const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked)
static SQLHSTMT config_odbc_prepare (struct odbc_obj *obj, void *data)
static SQLHSTMT custom_prepare (struct odbc_obj *obj, void *data)
static int destroy_odbc (const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
 Excute an DELETE query.
static int load_module (void)
static struct ast_configrealtime_multi_odbc (const char *database, const char *table, va_list ap)
 Excute an Select query and return ast_config list.
static struct ast_variablerealtime_odbc (const char *database, const char *table, va_list ap)
 Excute an SQL query and return ast_variable list.
static int store_odbc (const char *database, const char *table, va_list ap)
 Excute an INSERT query.
static int unload_module (void)
static int update_odbc (const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
 Excute an UPDATE query.

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime ODBC configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static const struct
ast_module_info
ast_module_info = &__mod_info
static struct ast_config_engine odbc_engine


Detailed Description

odbc+odbc plugin for portable configuration engine

Author:
Mark Spencer <markster@digium.com>

Anthony Minessale II <anthmct@yahoo.com>

Definition in file res_config_odbc.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 741 of file res_config_odbc.c.

static void __unreg_module ( void   )  [static]

Definition at line 741 of file res_config_odbc.c.

static struct ast_config* config_odbc ( const char *  database,
const char *  table,
const char *  file,
struct ast_config cfg,
struct ast_flags  flags,
const char *  sugg_incl,
const char *  who_asked 
) [static, read]

Definition at line 630 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.

00631 {
00632    struct ast_variable *new_v;
00633    struct ast_category *cur_cat;
00634    int res = 0;
00635    struct odbc_obj *obj;
00636    char sqlbuf[1024] = "";
00637    char *sql = sqlbuf;
00638    size_t sqlleft = sizeof(sqlbuf);
00639    unsigned int last_cat_metric = 0;
00640    SQLSMALLINT rowcount = 0;
00641    SQLHSTMT stmt;
00642    char last[128] = "";
00643    struct config_odbc_obj q;
00644    struct ast_flags loader_flags = { 0 };
00645 
00646    memset(&q, 0, sizeof(q));
00647 
00648    if (!file || !strcmp (file, "res_config_odbc.conf"))
00649       return NULL;      /* cant configure myself with myself ! */
00650 
00651    obj = ast_odbc_request_obj(database, 0);
00652    if (!obj)
00653       return NULL;
00654 
00655    ast_build_string(&sql, &sqlleft, "SELECT cat_metric, category, var_name, var_val FROM %s ", table);
00656    ast_build_string(&sql, &sqlleft, "WHERE filename='%s' AND commented=0 ", file);
00657    ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ");
00658    q.sql = sqlbuf;
00659 
00660    stmt = ast_odbc_prepare_and_execute(obj, config_odbc_prepare, &q);
00661 
00662    if (!stmt) {
00663       ast_log(LOG_WARNING, "SQL select error!\n[%s]\n\n", sql);
00664       ast_odbc_release_obj(obj);
00665       return NULL;
00666    }
00667 
00668    res = SQLNumResultCols(stmt, &rowcount);
00669 
00670    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00671       ast_log(LOG_WARNING, "SQL NumResultCols error!\n[%s]\n\n", sql);
00672       SQLFreeHandle(SQL_HANDLE_STMT, stmt);
00673       ast_odbc_release_obj(obj);
00674       return NULL;
00675    }
00676 
00677    if (!rowcount) {
00678       ast_log(LOG_NOTICE, "found nothing\n");
00679       ast_odbc_release_obj(obj);
00680       return cfg;
00681    }
00682 
00683    cur_cat = ast_config_get_current_category(cfg);
00684 
00685    while ((res = SQLFetch(stmt)) != SQL_NO_DATA) {
00686       if (!strcmp (q.var_name, "#include")) {
00687          if (!ast_config_internal_load(q.var_val, cfg, loader_flags, "", who_asked)) {
00688             SQLFreeHandle(SQL_HANDLE_STMT, stmt);
00689             ast_odbc_release_obj(obj);
00690             return NULL;
00691          }
00692          continue;
00693       } 
00694       if (strcmp(last, q.category) || last_cat_metric != q.cat_metric) {
00695          cur_cat = ast_category_new(q.category, "", 99999);
00696          if (!cur_cat) {
00697             ast_log(LOG_WARNING, "Out of memory!\n");
00698             break;
00699          }
00700          strcpy(last, q.category);
00701          last_cat_metric   = q.cat_metric;
00702          ast_category_append(cfg, cur_cat);
00703       }
00704 
00705       new_v = ast_variable_new(q.var_name, q.var_val, "");
00706       ast_variable_append(cur_cat, new_v);
00707    }
00708 
00709    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
00710    ast_odbc_release_obj(obj);
00711    return cfg;
00712 }

static SQLHSTMT config_odbc_prepare ( struct odbc_obj obj,
void *  data 
) [static]

Definition at line 603 of file res_config_odbc.c.

References ast_verb, config_odbc_obj::cat_metric, config_odbc_obj::category, odbc_obj::con, config_odbc_obj::err, config_odbc_obj::sql, config_odbc_obj::var_name, and config_odbc_obj::var_val.

Referenced by config_odbc().

00604 {
00605    struct config_odbc_obj *q = data;
00606    SQLHSTMT sth;
00607    int res;
00608 
00609    res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &sth);
00610    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00611       ast_verb(4, "Failure in AllocStatement %d\n", res);
00612       return NULL;
00613    }
00614 
00615    res = SQLPrepare(sth, (unsigned char *)q->sql, SQL_NTS);
00616    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00617       ast_verb(4, "Error in PREPARE %d\n", res);
00618       SQLFreeHandle(SQL_HANDLE_STMT, sth);
00619       return NULL;
00620    }
00621 
00622    SQLBindCol(sth, 1, SQL_C_ULONG, &q->cat_metric, sizeof(q->cat_metric), &q->err);
00623    SQLBindCol(sth, 2, SQL_C_CHAR, q->category, sizeof(q->category), &q->err);
00624    SQLBindCol(sth, 3, SQL_C_CHAR, q->var_name, sizeof(q->var_name), &q->err);
00625    SQLBindCol(sth, 4, SQL_C_CHAR, q->var_val, sizeof(q->var_val), &q->err);
00626 
00627    return sth;
00628 }

static SQLHSTMT custom_prepare ( struct odbc_obj obj,
void *  data 
) [static]

Definition at line 56 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 destroy_odbc(), realtime_multi_odbc(), realtime_odbc(), store_odbc(), and update_odbc().

00057 {
00058    int res, x = 1;
00059    struct custom_prepare_struct *cps = data;
00060    const char *newparam, *newval;
00061    SQLHSTMT stmt;
00062    va_list ap;
00063 
00064    va_copy(ap, cps->ap);
00065 
00066    res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
00067    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00068       ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
00069       return NULL;
00070    }
00071 
00072    res = SQLPrepare(stmt, (unsigned char *)cps->sql, SQL_NTS);
00073    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00074       ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", cps->sql);
00075       SQLFreeHandle (SQL_HANDLE_STMT, stmt);
00076       return NULL;
00077    }
00078 
00079    while ((newparam = va_arg(ap, const char *))) {
00080       newval = va_arg(ap, const char *);
00081       SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL);
00082    }
00083    va_end(ap);
00084 
00085    if (!ast_strlen_zero(cps->extra))
00086       SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(cps->extra), 0, (void *)cps->extra, 0, NULL);
00087    return stmt;
00088 }

static int destroy_odbc ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  lookup,
va_list  ap 
) [static]

Excute an DELETE query.

Parameters:
database 
table 
keyfield where clause field
lookup value of field for where clause
ap list containing one or more field/value set(s)
Delete a row from a database table, prepare the sql statement using keyfield and lookup control the number of records to change. Additional params to match rows are stored in ap list. Sub-in the values to the prepared statement and execute it.

Return values:
number of rows affected
-1 on failure

Definition at line 542 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.

00543 {
00544    struct odbc_obj *obj;
00545    SQLHSTMT stmt;
00546    char sql[256];
00547    SQLLEN rowcount=0;
00548    const char *newparam, *newval;
00549    int res;
00550    va_list aq;
00551    struct custom_prepare_struct cps = { .sql = sql, .extra = lookup };
00552 
00553    va_copy(cps.ap, ap);
00554    va_copy(aq, ap);
00555    
00556    if (!table)
00557       return -1;
00558 
00559    obj = ast_odbc_request_obj(database, 0);
00560    if (!obj)
00561       return -1;
00562 
00563    snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE ", table);
00564    while((newparam = va_arg(aq, const char *))) {
00565       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=? AND ", newparam);
00566       newval = va_arg(aq, const char *);
00567    }
00568    va_end(aq);
00569    snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=?", keyfield);
00570 
00571    stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
00572 
00573    if (!stmt) {
00574       ast_odbc_release_obj(obj);
00575       return -1;
00576    }
00577 
00578    res = SQLRowCount(stmt, &rowcount);
00579    SQLFreeHandle (SQL_HANDLE_STMT, stmt);
00580    ast_odbc_release_obj(obj);
00581 
00582    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00583       ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
00584       return -1;
00585    }
00586 
00587    if (rowcount >= 0)
00588       return (int)rowcount;
00589 
00590    return -1;
00591 }

static int load_module ( void   )  [static]

Definition at line 731 of file res_config_odbc.c.

References ast_config_engine_register(), and ast_verb.

00732 {
00733    ast_config_engine_register(&odbc_engine);
00734    ast_verb(1, "res_config_odbc loaded.\n");
00735    return 0;
00736 }

static struct ast_config* realtime_multi_odbc ( const char *  database,
const char *  table,
va_list  ap 
) [static, read]

Excute an Select query and return ast_config list.

Parameters:
database 
table 
ap list containing one or more field/operator/value set.
Select database and preform query on table, prepare the sql statement Sub-in the values to the prepared statement and execute it. Execute this prepared query against several ODBC connected databases. Return results as an ast_config variable.

Return values:
var on success
NULL on failure

Definition at line 248 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_backslash_is_escape(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), ast_strdupa, ast_strip(), ast_strlen_zero(), ast_variable_append(), ast_variable_new(), custom_prepare(), LOG_WARNING, custom_prepare_struct::sql, strcasestr(), strsep(), and var.

00249 {
00250    struct odbc_obj *obj;
00251    SQLHSTMT stmt;
00252    char sql[1024];
00253    char coltitle[256];
00254    char rowdata[2048];
00255    const char *initfield=NULL;
00256    char *op;
00257    const char *newparam, *newval;
00258    char *stringp;
00259    char *chunk;
00260    SQLSMALLINT collen;
00261    int res;
00262    int x;
00263    struct ast_variable *var=NULL;
00264    struct ast_config *cfg=NULL;
00265    struct ast_category *cat=NULL;
00266    SQLULEN colsize;
00267    SQLSMALLINT colcount=0;
00268    SQLSMALLINT datatype;
00269    SQLSMALLINT decimaldigits;
00270    SQLSMALLINT nullable;
00271    SQLLEN indicator;
00272    struct custom_prepare_struct cps = { .sql = sql };
00273    va_list aq;
00274 
00275    va_copy(cps.ap, ap);
00276    va_copy(aq, ap);
00277 
00278    if (!table)
00279       return NULL;
00280 
00281    obj = ast_odbc_request_obj(database, 0);
00282    if (!obj)
00283       return NULL;
00284 
00285    newparam = va_arg(aq, const char *);
00286    if (!newparam)  {
00287       ast_odbc_release_obj(obj);
00288       return NULL;
00289    }
00290    initfield = ast_strdupa(newparam);
00291    if ((op = strchr(initfield, ' '))) 
00292       *op = '\0';
00293    newval = va_arg(aq, const char *);
00294    op = !strchr(newparam, ' ') ? " =" : "";
00295    snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, newparam, op,
00296       strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
00297    while((newparam = va_arg(aq, const char *))) {
00298       op = !strchr(newparam, ' ') ? " =" : "";
00299       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op,
00300          strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
00301       newval = va_arg(aq, const char *);
00302    }
00303    if (initfield)
00304       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield);
00305    va_end(aq);
00306 
00307    stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
00308 
00309    if (!stmt) {
00310       ast_odbc_release_obj(obj);
00311       return NULL;
00312    }
00313 
00314    res = SQLNumResultCols(stmt, &colcount);
00315    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00316       ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
00317       SQLFreeHandle(SQL_HANDLE_STMT, stmt);
00318       ast_odbc_release_obj(obj);
00319       return NULL;
00320    }
00321 
00322    cfg = ast_config_new();
00323    if (!cfg) {
00324       ast_log(LOG_WARNING, "Out of memory!\n");
00325       SQLFreeHandle(SQL_HANDLE_STMT, stmt);
00326       ast_odbc_release_obj(obj);
00327       return NULL;
00328    }
00329 
00330    while ((res=SQLFetch(stmt)) != SQL_NO_DATA) {
00331       var = NULL;
00332       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00333          ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
00334          continue;
00335       }
00336       cat = ast_category_new("","",99999);
00337       if (!cat) {
00338          ast_log(LOG_WARNING, "Out of memory!\n");
00339          continue;
00340       }
00341       for (x=0;x<colcount;x++) {
00342          rowdata[0] = '\0';
00343          collen = sizeof(coltitle);
00344          res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen, 
00345                   &datatype, &colsize, &decimaldigits, &nullable);
00346          if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00347             ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
00348             ast_category_destroy(cat);
00349             continue;
00350          }
00351 
00352          indicator = 0;
00353          res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), &indicator);
00354          if (indicator == SQL_NULL_DATA)
00355             continue;
00356 
00357          if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00358             ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
00359             ast_category_destroy(cat);
00360             continue;
00361          }
00362          stringp = rowdata;
00363          while(stringp) {
00364             chunk = strsep(&stringp, ";");
00365             if (!ast_strlen_zero(ast_strip(chunk))) {
00366                if (initfield && !strcmp(initfield, coltitle))
00367                   ast_category_rename(cat, chunk);
00368                var = ast_variable_new(coltitle, chunk, "");
00369                ast_variable_append(cat, var);
00370             }
00371          }
00372       }
00373       ast_category_append(cfg, cat);
00374    }
00375 
00376    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
00377    ast_odbc_release_obj(obj);
00378    return cfg;
00379 }

static struct ast_variable* realtime_odbc ( const char *  database,
const char *  table,
va_list  ap 
) [static, read]

Excute an SQL query and return ast_variable list.

Parameters:
database 
table 
ap list containing one or more field/operator/value set.
Select database and preform query on table, prepare the sql statement Sub-in the values to the prepared statement and execute it. Return results as a ast_variable list.

Return values:
var on success
NULL on failure

Definition at line 103 of file res_config_odbc.c.

References custom_prepare_struct::ap, ast_copy_string(), ast_log(), ast_odbc_backslash_is_escape(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), ast_strip(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), custom_prepare(), LOG_ERROR, LOG_WARNING, custom_prepare_struct::sql, strcasestr(), strsep(), and var.

00104 {
00105    struct odbc_obj *obj;
00106    SQLHSTMT stmt;
00107    char sql[1024];
00108    char coltitle[256];
00109    char rowdata[2048];
00110    char *op;
00111    const char *newparam, *newval;
00112    char *stringp;
00113    char *chunk;
00114    SQLSMALLINT collen;
00115    int res;
00116    int x;
00117    struct ast_variable *var=NULL, *prev=NULL;
00118    SQLULEN colsize;
00119    SQLSMALLINT colcount=0;
00120    SQLSMALLINT datatype;
00121    SQLSMALLINT decimaldigits;
00122    SQLSMALLINT nullable;
00123    SQLLEN indicator;
00124    va_list aq;
00125    struct custom_prepare_struct cps = { .sql = sql };
00126 
00127    va_copy(cps.ap, ap);
00128    va_copy(aq, ap);
00129 
00130    if (!table)
00131       return NULL;
00132 
00133    obj = ast_odbc_request_obj(database, 0);
00134 
00135    if (!obj) {
00136       ast_log(LOG_ERROR, "No database handle available with the name of '%s' (check res_odbc.conf)\n", database);
00137       return NULL;
00138    }
00139 
00140    newparam = va_arg(aq, const char *);
00141    if (!newparam) {
00142       ast_odbc_release_obj(obj);
00143       return NULL;
00144    }
00145    newval = va_arg(aq, const char *);
00146    op = !strchr(newparam, ' ') ? " =" : "";
00147    snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, newparam, op,
00148       strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
00149    while((newparam = va_arg(aq, const char *))) {
00150       op = !strchr(newparam, ' ') ? " =" : "";
00151       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op,
00152          strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
00153       newval = va_arg(aq, const char *);
00154    }
00155    va_end(aq);
00156 
00157    stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
00158 
00159    if (!stmt) {
00160       ast_odbc_release_obj(obj);
00161       return NULL;
00162    }
00163 
00164    res = SQLNumResultCols(stmt, &colcount);
00165    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00166       ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
00167       SQLFreeHandle (SQL_HANDLE_STMT, stmt);
00168       ast_odbc_release_obj(obj);
00169       return NULL;
00170    }
00171 
00172    res = SQLFetch(stmt);
00173    if (res == SQL_NO_DATA) {
00174       SQLFreeHandle (SQL_HANDLE_STMT, stmt);
00175       ast_odbc_release_obj(obj);
00176       return NULL;
00177    }
00178    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00179       ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
00180       SQLFreeHandle (SQL_HANDLE_STMT, stmt);
00181       ast_odbc_release_obj(obj);
00182       return NULL;
00183    }
00184    for (x = 0; x < colcount; x++) {
00185       rowdata[0] = '\0';
00186       collen = sizeof(coltitle);
00187       res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen, 
00188                &datatype, &colsize, &decimaldigits, &nullable);
00189       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00190          ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
00191          if (var)
00192             ast_variables_destroy(var);
00193          ast_odbc_release_obj(obj);
00194          return NULL;
00195       }
00196 
00197       indicator = 0;
00198       res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), &indicator);
00199       if (indicator == SQL_NULL_DATA)
00200          rowdata[0] = '\0';
00201       else if (ast_strlen_zero(rowdata)) {
00202          /* Because we encode the empty string for a NULL, we will encode
00203           * actual empty strings as a string containing a single whitespace. */
00204          ast_copy_string(rowdata, " ", sizeof(rowdata));
00205       }
00206 
00207       if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00208          ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
00209          if (var)
00210             ast_variables_destroy(var);
00211          ast_odbc_release_obj(obj);
00212          return NULL;
00213       }
00214       stringp = rowdata;
00215       while(stringp) {
00216          chunk = strsep(&stringp, ";");
00217          if (!ast_strlen_zero(ast_strip(chunk))) {
00218             if (prev) {
00219                prev->next = ast_variable_new(coltitle, chunk, "");
00220                if (prev->next)
00221                   prev = prev->next;
00222             } else 
00223                prev = var = ast_variable_new(coltitle, chunk, "");
00224          }
00225       }
00226    }
00227 
00228 
00229    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
00230    ast_odbc_release_obj(obj);
00231    return var;
00232 }

static int store_odbc ( const char *  database,
const char *  table,
va_list  ap 
) [static]

Excute an INSERT query.

Parameters:
database 
table 
ap list containing one or more field/value set(s)
Insert a new record into database table, prepare the sql statement. All values to be changed are stored in ap list. Sub-in the values to the prepared statement and execute it.

Return values:
number of rows affected
-1 on failure

Definition at line 466 of file res_config_odbc.c.

References custom_prepare_struct::ap, ast_copy_string(), ast_log(), ast_odbc_prepare_and_execute(), ast_odbc_release_obj(), ast_odbc_request_obj(), custom_prepare(), LOG_WARNING, and custom_prepare_struct::sql.

00467 {
00468    struct odbc_obj *obj;
00469    SQLHSTMT stmt;
00470    char sql[256];
00471    char keys[256];
00472    char vals[256];
00473    SQLLEN rowcount=0;
00474    const char *newparam, *newval;
00475    int res;
00476    va_list aq;
00477    struct custom_prepare_struct cps = { .sql = sql, .extra = NULL };
00478 
00479    va_copy(cps.ap, ap);
00480    va_copy(aq, ap);
00481    
00482    if (!table)
00483       return -1;
00484 
00485    obj = ast_odbc_request_obj(database, 0);
00486    if (!obj)
00487       return -1;
00488 
00489    newparam = va_arg(aq, const char *);
00490    if (!newparam)  {
00491       ast_odbc_release_obj(obj);
00492       return -1;
00493    }
00494    newval = va_arg(aq, const char *);
00495    snprintf(keys, sizeof(keys), "%s", newparam);
00496    ast_copy_string(vals, "?", sizeof(vals));
00497    while ((newparam = va_arg(aq, const char *))) {
00498       snprintf(keys + strlen(keys), sizeof(keys) - strlen(keys), ", %s", newparam);
00499       snprintf(vals + strlen(vals), sizeof(vals) - strlen(vals), ", ?");
00500       newval = va_arg(aq, const char *);
00501    }
00502    va_end(aq);
00503    snprintf(sql, sizeof(sql), "INSERT INTO %s (%s) VALUES (%s)", table, keys, vals);
00504 
00505    stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
00506 
00507    if (!stmt) {
00508       ast_odbc_release_obj(obj);
00509       return -1;
00510    }
00511 
00512    res = SQLRowCount(stmt, &rowcount);
00513    SQLFreeHandle (SQL_HANDLE_STMT, stmt);
00514    ast_odbc_release_obj(obj);
00515 
00516    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00517       ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
00518       return -1;
00519    }
00520 
00521    if (rowcount >= 0)
00522       return (int)rowcount;
00523 
00524    return -1;
00525 }

static int unload_module ( void   )  [static]

Definition at line 724 of file res_config_odbc.c.

References ast_config_engine_deregister(), and ast_verb.

00725 {
00726    ast_config_engine_deregister(&odbc_engine);
00727    ast_verb(1, "res_config_odbc unloaded.\n");
00728    return 0;
00729 }

static int update_odbc ( const char *  database,
const char *  table,
const char *  keyfield,
const char *  lookup,
va_list  ap 
) [static]

Excute an UPDATE query.

Parameters:
database 
table 
keyfield where clause field
lookup value of field for where clause
ap list containing one or more field/value set(s).
Update a database table, prepare the sql statement using keyfield and lookup control the number of records to change. All values to be changed are stored in ap list. Sub-in the values to the prepared statement and execute it.

Return values:
number of rows affected
-1 on failure

Definition at line 396 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.

00397 {
00398    struct odbc_obj *obj;
00399    SQLHSTMT stmt;
00400    char sql[256];
00401    SQLLEN rowcount=0;
00402    const char *newparam, *newval;
00403    int res;
00404    va_list aq;
00405    struct custom_prepare_struct cps = { .sql = sql, .extra = lookup };
00406 
00407    va_copy(cps.ap, ap);
00408    va_copy(aq, ap);
00409    
00410    if (!table)
00411       return -1;
00412 
00413    obj = ast_odbc_request_obj(database, 0);
00414    if (!obj)
00415       return -1;
00416 
00417    newparam = va_arg(aq, const char *);
00418    if (!newparam)  {
00419       ast_odbc_release_obj(obj);
00420       return -1;
00421    }
00422    newval = va_arg(aq, const char *);
00423    snprintf(sql, sizeof(sql), "UPDATE %s SET %s=?", table, newparam);
00424    while((newparam = va_arg(aq, const char *))) {
00425       snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s=?", newparam);
00426       newval = va_arg(aq, const char *);
00427    }
00428    va_end(aq);
00429    snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s=?", keyfield);
00430 
00431    stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
00432 
00433    if (!stmt) {
00434       ast_odbc_release_obj(obj);
00435       return -1;
00436    }
00437 
00438    res = SQLRowCount(stmt, &rowcount);
00439    SQLFreeHandle (SQL_HANDLE_STMT, stmt);
00440    ast_odbc_release_obj(obj);
00441 
00442    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
00443       ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
00444       return -1;
00445    }
00446 
00447    if (rowcount >= 0)
00448       return (int)rowcount;
00449 
00450    return -1;
00451 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Realtime ODBC configuration" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 741 of file res_config_odbc.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 741 of file res_config_odbc.c.

struct ast_config_engine odbc_engine [static]

Definition at line 714 of file res_config_odbc.c.


Generated on Wed Oct 28 11:46:17 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6