Fri May 26 01:50:20 2006

Asterisk developer's documentation


res_odbc.c File Reference

ODBC resource manager. More...

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/res_odbc.h"

Include dependency graph for res_odbc.c:

Go to the source code of this file.

Data Structures

struct  odbc_list

Defines

#define MAX_ODBC_HANDLES   25

Functions

char * description (void)
 Provides a description of the module.
void destroy_odbc_obj (odbc_obj **obj)
odbc_objfetch_odbc_obj (const char *name, int check)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static int load_odbc_config (void)
odbc_objnew_odbc_obj (char *name, char *dsn, char *username, char *password)
static int odbc_connect_command (int fd, int argc, char **argv)
static int odbc_connect_usage (int fd)
static void odbc_destroy (void)
static int odbc_disconnect_command (int fd, int argc, char **argv)
static int odbc_disconnect_usage (int fd)
int odbc_dump_fd (int fd, odbc_obj *obj)
static void odbc_init (void)
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)
static odbc_objodbc_read (struct odbc_list *registry, const char *name)
int odbc_sanity_check (odbc_obj *obj)
static int odbc_show_command (int fd, int argc, char **argv)
int odbc_smart_direct_execute (odbc_obj *obj, SQLHSTMT stmt, char *sql)
int odbc_smart_execute (odbc_obj *obj, SQLHSTMT stmt)
static int odbc_write (struct odbc_list *registry, char *name, odbc_obj *obj)
int register_odbc_obj (char *name, odbc_obj *obj)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static char connect_usage []
static char disconnect_usage []
 LOCAL_USER_DECL
static struct ast_cli_entry odbc_connect_struct
static struct ast_cli_entry odbc_disconnect_struct
static struct odbc_list ODBC_REGISTRY [MAX_ODBC_HANDLES]
static struct ast_cli_entry odbc_show_struct
static char show_usage []
 STANDARD_LOCAL_USER
static char * tdesc = "ODBC Resource"


Detailed Description

ODBC resource manager.

Definition in file res_odbc.c.


Define Documentation

#define MAX_ODBC_HANDLES   25
 

Definition at line 50 of file res_odbc.c.

Referenced by odbc_destroy(), odbc_init(), odbc_read(), odbc_show_command(), and odbc_write().


Function Documentation

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 603 of file res_odbc.c.

References tdesc.

00604 {
00605    return tdesc;
00606 }

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 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 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 615 of file res_odbc.c.

References ASTERISK_GPL_KEY.

00616 {
00617    return ASTERISK_GPL_KEY;
00618 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 592 of file res_odbc.c.

References ast_cli_register(), ast_log(), load_odbc_config(), LOG_NOTICE, odbc_connect_struct, odbc_disconnect_struct, odbc_init(), and odbc_show_struct.

00593 {
00594    odbc_init();
00595    load_odbc_config();
00596    ast_cli_register(&odbc_disconnect_struct);
00597    ast_cli_register(&odbc_connect_struct);
00598    ast_cli_register(&odbc_show_struct);
00599    ast_log(LOG_NOTICE, "res_odbc loaded.\n");
00600    return 0;
00601 }

static int load_odbc_config void   )  [static]
 

Definition at line 245 of file res_odbc.c.

References ast_category_browse(), ast_config_load(), ast_log(), ast_variable_browse(), cfg, config, dsn, enabled, free, LOG_NOTICE, malloc, ast_variable::name, ast_variable::next, password, username, and ast_variable::value.

Referenced by load_module().

00246 {
00247    static char *cfg = "res_odbc.conf";
00248    struct ast_config *config;
00249    struct ast_variable *v;
00250    char *cat, *dsn, *username, *password;
00251    int enabled;
00252    int connect = 0;
00253    char *env_var;
00254 
00255    odbc_obj *obj;
00256 
00257    config = ast_config_load(cfg);
00258    if (config) {
00259       for (cat = ast_category_browse(config, NULL); cat; cat=ast_category_browse(config, cat)) {
00260          if (!strcmp(cat, "ENV")) {
00261             for (v = ast_variable_browse(config, cat); v; v = v->next) {
00262                env_var = malloc(strlen(v->name) + strlen(v->value) + 2);
00263                if (env_var) {
00264                   sprintf(env_var, "%s=%s", v->name, v->value);
00265                   ast_log(LOG_NOTICE, "Adding ENV var: %s=%s\n", v->name, v->value);
00266                   putenv(env_var);
00267                   free(env_var);
00268                }
00269             }
00270 
00271          cat = ast_category_browse(config, cat);
00272          }
00273 
00274          dsn = username = password = NULL;
00275          enabled = 1;
00276          connect = 0;
00277          for (v = ast_variable_browse(config, cat); v; v = v->next) {
00278             if (!strcmp(v->name, "enabled"))
00279                enabled = ast_true(v->value);
00280             if (!strcmp(v->name, "pre-connect"))
00281                connect = ast_true(v->value);
00282             if (!strcmp(v->name, "dsn"))
00283                dsn = v->value;
00284             if (!strcmp(v->name, "username"))
00285                username = v->value;
00286             if (!strcmp(v->name, "password"))
00287                password = v->value;
00288          }
00289 
00290          if (enabled && dsn) {
00291             obj = new_odbc_obj(cat, dsn, username, password);
00292             if (obj) {
00293                register_odbc_obj(cat, obj);
00294                ast_log(LOG_NOTICE, "registered database handle '%s' dsn->[%s]\n", cat, obj->dsn);
00295                if (connect) {
00296                   odbc_obj_connect(obj);
00297                }
00298             } else {
00299                ast_log(LOG_WARNING, "Addition of obj %s failed.\n", cat);
00300             }
00301 
00302          }
00303       }
00304       ast_config_destroy(config);
00305    }
00306    return 0;
00307 }

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.

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 }

static int odbc_connect_command int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 366 of file res_odbc.c.

References odbc_connect_usage(), odbc_obj_connect(), odbc_read(), and ODBC_REGISTRY.

00367 {
00368    odbc_obj *obj;
00369    if (!argv[1])
00370       return odbc_connect_usage(fd);
00371 
00372    if (!strcmp(argv[1], "connect") || !strcmp(argv[1], "disconnect")) {
00373       if (!argv[2])
00374          return odbc_connect_usage(fd);
00375 
00376       obj = odbc_read(ODBC_REGISTRY, argv[2]);
00377       if (obj) {
00378          odbc_obj_connect(obj);
00379       }
00380    }
00381    return 0;
00382 }

static int odbc_connect_usage int  fd  )  [static]
 

Definition at line 317 of file res_odbc.c.

References ast_cli().

Referenced by odbc_connect_command().

00318 {
00319    ast_cli(fd, "usage odbc connect <DSN>\n");
00320    return 0;
00321 }

static void odbc_destroy void   )  [static]
 

Definition at line 62 of file res_odbc.c.

References destroy_odbc_obj(), MAX_ODBC_HANDLES, odbc_list::obj, and ODBC_REGISTRY.

Referenced by unload_module().

00063 {
00064    int x = 0;
00065 
00066    for (x = 0; x < MAX_ODBC_HANDLES; x++) {
00067       if (ODBC_REGISTRY[x].obj) {
00068          destroy_odbc_obj(&ODBC_REGISTRY[x].obj);
00069          ODBC_REGISTRY[x].obj = NULL;
00070       }
00071    }
00072 }

static int odbc_disconnect_command int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 351 of file res_odbc.c.

References odbc_disconnect_usage(), odbc_obj_disconnect(), odbc_read(), and ODBC_REGISTRY.

00352 {
00353    odbc_obj *obj;
00354    if (!strcmp(argv[1], "disconnect")) {
00355       if (!argv[2])
00356          return odbc_disconnect_usage(fd);
00357 
00358       obj = odbc_read(ODBC_REGISTRY, argv[2]);
00359       if (obj) {
00360          odbc_obj_disconnect(obj);
00361       }
00362    } 
00363    return 0;
00364 }

static int odbc_disconnect_usage int  fd  )  [static]
 

Definition at line 323 of file res_odbc.c.

References ast_cli().

Referenced by odbc_disconnect_command().

00324 {
00325    ast_cli(fd, "usage odbc disconnect <DSN>\n");
00326    return 0;
00327 }

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 }

static void odbc_init void   )  [static]
 

Definition at line 99 of file res_odbc.c.

References MAX_ODBC_HANDLES, and ODBC_REGISTRY.

00100 {
00101    int x = 0;
00102    for (x = 0; x < MAX_ODBC_HANDLES; x++) {
00103       memset(&ODBC_REGISTRY[x], 0, sizeof(struct odbc_list));
00104    }
00105 }

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 odbc_connect_command(), 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 destroy_odbc_obj(), odbc_disconnect_command(), odbc_obj_connect(), 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(), and LOG_WARNING.

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 }

static odbc_obj* odbc_read struct odbc_list registry,
const char *  name
[static]
 

Definition at line 74 of file res_odbc.c.

References MAX_ODBC_HANDLES, odbc_list::obj, and odbc_list::used.

Referenced by fetch_odbc_obj(), odbc_connect_command(), odbc_disconnect_command(), and odbc_show_command().

00075 {
00076    int x = 0;
00077    for (x = 0; x < MAX_ODBC_HANDLES; x++) {
00078       if (registry[x].used && !strcmp(registry[x].name, name)) {
00079          return registry[x].obj;
00080       }
00081    }
00082    return NULL;
00083 }

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 }

static int odbc_show_command int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 329 of file res_odbc.c.

References MAX_ODBC_HANDLES, odbc_dump_fd(), odbc_read(), and ODBC_REGISTRY.

00330 {
00331    odbc_obj *obj;
00332    int x = 0;
00333    
00334    if (!strcmp(argv[1], "show")) {
00335       if (!argv[2] || (argv[2] && !strcmp(argv[2], "all"))) {
00336          for (x = 0; x < MAX_ODBC_HANDLES; x++) {
00337             if (!ODBC_REGISTRY[x].used)
00338                break;
00339             if (ODBC_REGISTRY[x].obj)
00340                odbc_dump_fd(fd, ODBC_REGISTRY[x].obj);
00341          }
00342       } else {
00343          obj = odbc_read(ODBC_REGISTRY, argv[2]);
00344          if (obj)
00345             odbc_dump_fd(fd, obj);
00346       }
00347    }
00348    return 0;
00349 }

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 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 }

static int odbc_write struct odbc_list registry,
char *  name,
odbc_obj obj
[static]
 

Definition at line 85 of file res_odbc.c.

References MAX_ODBC_HANDLES, odbc_list::obj, and odbc_list::used.

Referenced by register_odbc_obj().

00086 {
00087    int x = 0;
00088    for (x = 0; x < MAX_ODBC_HANDLES; x++) {
00089       if (!registry[x].used) {
00090          ast_copy_string(registry[x].name, name, sizeof(registry[x].name));
00091          registry[x].obj = obj;
00092          registry[x].used = 1;
00093          return 1;
00094       }
00095    }
00096    return 0;
00097 }

int register_odbc_obj char *  name,
odbc_obj obj
 

Definition at line 410 of file res_odbc.c.

References ODBC_REGISTRY, and odbc_write().

00411 {
00412    if (obj != NULL)
00413       return odbc_write(ODBC_REGISTRY, name, obj);
00414    return 0;
00415 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

Standard module functions ...

Definition at line 581 of file res_odbc.c.

References ast_cli_unregister(), ast_log(), LOG_NOTICE, odbc_connect_struct, odbc_destroy(), odbc_disconnect_struct, odbc_show_struct, and STANDARD_HANGUP_LOCALUSERS.

00582 {
00583    STANDARD_HANGUP_LOCALUSERS;
00584    odbc_destroy();
00585    ast_cli_unregister(&odbc_disconnect_struct);
00586    ast_cli_unregister(&odbc_connect_struct);
00587    ast_cli_unregister(&odbc_show_struct);
00588    ast_log(LOG_NOTICE, "res_odbc unloaded.\n");
00589    return 0;
00590 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 608 of file res_odbc.c.

References STANDARD_USECOUNT.

00609 {
00610    int res;
00611    STANDARD_USECOUNT(res);
00612    return res;
00613 }


Variable Documentation

char connect_usage[] [static]
 

Initial value:

"Usage: odbc connect <DSN>\n"
"       Connect to ODBC DSN\n"

Definition at line 385 of file res_odbc.c.

char disconnect_usage[] [static]
 

Initial value:

"Usage: odbc connect <DSN>\n"
"       Disconnect from ODBC DSN\n"

Definition at line 389 of file res_odbc.c.

LOCAL_USER_DECL
 

Definition at line 579 of file res_odbc.c.

struct ast_cli_entry odbc_connect_struct [static]
 

Initial value:

        { { "odbc", "connect", NULL }, odbc_connect_command, "Connect to ODBC DSN", connect_usage }

Definition at line 398 of file res_odbc.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry odbc_disconnect_struct [static]
 

Initial value:

        { { "odbc", "disconnect", NULL }, odbc_disconnect_command, "Disconnect from ODBC DSN", disconnect_usage }

Definition at line 402 of file res_odbc.c.

Referenced by load_module(), and unload_module().

struct odbc_list ODBC_REGISTRY[MAX_ODBC_HANDLES] [static]
 

Definition at line 59 of file res_odbc.c.

Referenced by fetch_odbc_obj(), odbc_connect_command(), odbc_destroy(), odbc_disconnect_command(), odbc_init(), odbc_show_command(), and register_odbc_obj().

struct ast_cli_entry odbc_show_struct [static]
 

Initial value:

        { { "odbc", "show", NULL }, odbc_show_command, "Show ODBC DSN(s)", show_usage }

Definition at line 405 of file res_odbc.c.

Referenced by load_module(), and unload_module().

char show_usage[] [static]
 

Initial value:

"Usage: odbc show {DSN}\n"
"       Show ODBC {DSN}\n"
"       Specifying DSN will show that DSN else, all DSNs are shown\n"

Definition at line 393 of file res_odbc.c.

STANDARD_LOCAL_USER
 

Definition at line 577 of file res_odbc.c.

char* tdesc = "ODBC Resource" [static]
 

Definition at line 107 of file res_odbc.c.


Generated on Fri May 26 01:50:20 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6