139    if (iso == SQL_TXN_READ_COMMITTED) {
 
  140        return "read_committed";
 
  141    } 
else if (iso == SQL_TXN_READ_UNCOMMITTED) {
 
  142        return "read_uncommitted";
 
  143    } 
else if (iso == SQL_TXN_SERIALIZABLE) {
 
  144        return "serializable";
 
  145    } 
else if (iso == SQL_TXN_REPEATABLE_READ) {
 
  146        return "repeatable_read";
 
 
  154    if (strncasecmp(txt, 
"read_", 5) == 0) {
 
  155        if (strncasecmp(txt + 5, 
"c", 1) == 0) {
 
  156            return SQL_TXN_READ_COMMITTED;
 
  157        } 
else if (strncasecmp(txt + 5, 
"u", 1) == 0) {
 
  158            return SQL_TXN_READ_UNCOMMITTED;
 
  162    } 
else if (strncasecmp(txt, 
"ser", 3) == 0) {
 
  163        return SQL_TXN_SERIALIZABLE;
 
  164    } 
else if (strncasecmp(txt, 
"rep", 3) == 0) {
 
  165        return SQL_TXN_REPEATABLE_READ;
 
 
  179    if (class->username) {
 
  182    if (class->password) {
 
  185    if (class->sanitysql) {
 
  193    SQLFreeHandle(SQL_HANDLE_ENV, class->env);
 
 
  243    SQLHSTMT stmt = 
NULL;
 
  244    int res = 0, 
error = 0;
 
  249        if (strcmp(tableptr->
connection, database) == 0 && strcmp(tableptr->
table, tablename) == 0) {
 
  260        ast_log(
LOG_WARNING, 
"Unable to retrieve database handle for table description '%s@%s'\n", tablename, database);
 
  267        res = SQLAllocHandle(SQL_HANDLE_STMT, obj->
con, &stmt);
 
  268        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 
  273        res = SQLColumns(stmt, 
NULL, 0, 
NULL, 0, (
unsigned char *)tablename, SQL_NTS, (
unsigned char *)
"%", SQL_NTS);
 
  274        if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 
  275            SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
  276            ast_log(
LOG_ERROR, 
"Unable to query database columns on connection '%s'.\n", database);
 
  280        if (!(tableptr = 
ast_calloc(
sizeof(
char), 
sizeof(*tableptr) + strlen(database) + 1 + strlen(tablename) + 1))) {
 
  281            ast_log(
LOG_ERROR, 
"Out of memory creating entry for table '%s' on connection '%s'\n", tablename, database);
 
  285        tableptr->
connection = (
char *)tableptr + 
sizeof(*tableptr);
 
  286        tableptr->
table = (
char *)tableptr + 
sizeof(*tableptr) + strlen(database) + 1;
 
  288        strcpy(tableptr->
table, tablename); 
 
  291        while ((res = SQLFetch(stmt)) != SQL_NO_DATA && res != SQL_ERROR) {
 
  292            SQLGetData(stmt,  4, SQL_C_CHAR, columnname, 
sizeof(columnname), &sqlptr);
 
  294            if (!(entry = 
ast_calloc(
sizeof(
char), 
sizeof(*entry) + strlen(columnname) + 1))) {
 
  295                ast_log(
LOG_ERROR, 
"Out of memory creating entry for column '%s' in table '%s' on connection '%s'\n", columnname, tablename, database);
 
  299            entry->
name = (
char *)entry + 
sizeof(*entry);
 
  300            strcpy(entry->
name, columnname);
 
  302            SQLGetData(stmt,  5, SQL_C_SHORT, &entry->
type, 
sizeof(entry->
type), 
NULL);
 
  303            SQLGetData(stmt,  7, SQL_C_LONG, &entry->
size, 
sizeof(entry->
size), 
NULL);
 
  305            SQLGetData(stmt, 10, SQL_C_SHORT, &entry->
radix, 
sizeof(entry->
radix), 
NULL);
 
  316            ast_debug(3, 
"Found %s column with type %hd with len %ld, octetlen %ld, and numlen (%hd,%hd)\n", entry->
name, entry->
type, (
long) entry->
size, (
long) entry->
octetlen, entry->
decimals, entry->
radix);
 
  320        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
 
  341        if (strcasecmp(col->
name, colname) == 0) {
 
 
  354        if (strcmp(tableptr->
connection, database) == 0 && strcmp(tableptr->
table, tablename) == 0) {
 
  362    return tableptr ? 0 : -1;
 
 
  367    struct timeval start;
 
  374    stmt = exec_cb(obj, data);
 
  380            ast_log(
LOG_WARNING, 
"SQL query '%s' took %ld milliseconds to execute on class '%s', this may indicate a database problem\n",
 
 
  405    struct timeval start;
 
  418    stmt = prepare_cb(obj, data);
 
  423    res = SQLExecute(stmt);
 
  424    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO) && (res != SQL_NO_DATA)) {
 
  425        if (res == SQL_ERROR) {
 
  430        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
  436            ast_log(
LOG_WARNING, 
"SQL query '%s' took %ld milliseconds to execute on class '%s', this may indicate a database problem\n",
 
 
  471    return SQLPrepare(stmt, (
unsigned char *)sql, SQL_NTS);
 
 
  482    return SQLExecDirect(stmt, (
unsigned char *)sql, SQL_NTS);
 
 
  489    res = SQLExecute(stmt);
 
  490    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO) && (res != SQL_NO_DATA)) {
 
  491        if (res == SQL_ERROR) {
 
 
  508        if (SQLGetData(StatementHandle, ColumnNumber, TargetType, 
ast_str_buffer(*
buf), 0, StrLen_or_Ind) == SQL_SUCCESS_WITH_INFO) {
 
  511    } 
else if (pmaxlen > 0) {
 
 
  523    SQLINTEGER nativeerror = 0;
 
  524    SQLSMALLINT diagbytes = 0;
 
  526    unsigned char state[10];
 
  527    unsigned char diagnostic[256];
 
  531    while (SQLGetDiagRec(handle_type, handle, ++i, 
state, &nativeerror,
 
  532        diagnostic, 
sizeof(diagnostic), &diagbytes) == SQL_SUCCESS) {
 
  537            ast_log(
LOG_WARNING, 
"There are more than 10 diagnostic records! Ignore the rest.\n");
 
 
  547    return class->isolation;
 
 
  552    return class->forcecommit;
 
 
  562    static char *cfg = 
"res_odbc.conf";
 
  566    const char *
dsn, *username, *password, *sanitysql;
 
  567    int enabled, bse, conntimeout, forcecommit, isolation, maxconnections, logging, slowquerylimit;
 
  568    struct timeval ncache = { 0, 0 };
 
  569    int preconnect = 0, res = 0, cache_is_queue = 0;
 
  571    unsigned int max_cache_size;
 
  581        if (!strcasecmp(cat, 
"ENV")) {
 
  601                if (!strcasecmp(v->
name, 
"pooling") ||
 
  602                        !strncasecmp(v->
name, 
"share", 5) ||
 
  603                        !strcasecmp(v->
name, 
"limit") ||
 
  604                        !strcasecmp(v->
name, 
"idlecheck")) {
 
  605                    ast_log(
LOG_WARNING, 
"The 'pooling', 'shared_connections', 'limit', and 'idlecheck' options were replaced by 'max_connections'.  See res_odbc.conf.sample.\n");
 
  606                } 
else if (!strcasecmp(v->
name, 
"enabled")) {
 
  608                } 
else if (!strcasecmp(v->
name, 
"pre-connect")) {
 
  610                } 
else if (!strcasecmp(v->
name, 
"dsn")) {
 
  612                } 
else if (!strcasecmp(v->
name, 
"username")) {
 
  614                } 
else if (!strcasecmp(v->
name, 
"password")) {
 
  616                } 
else if (!strcasecmp(v->
name, 
"sanitysql")) {
 
  618                } 
else if (!strcasecmp(v->
name, 
"backslash_is_escape")) {
 
  620                } 
else if (!strcasecmp(v->
name, 
"connect_timeout")) {
 
  625                } 
else if (!strcasecmp(v->
name, 
"negative_connection_cache")) {
 
  627                    if (sscanf(v->
value, 
"%lf", &dncache) != 1 || dncache < 0) {
 
  633                        ncache.tv_sec = (int)dncache;
 
  634                        ncache.tv_usec = (dncache - ncache.tv_sec) * 1000000;
 
  636                } 
else if (!strcasecmp(v->
name, 
"forcecommit")) {
 
  638                } 
else if (!strcasecmp(v->
name, 
"isolation")) {
 
  643                } 
else if (!strcasecmp(v->
name, 
"max_connections")) {
 
  648                } 
else if (!strcasecmp(v->
name, 
"logging")) {
 
  650                } 
else if (!strcasecmp(v->
name, 
"slow_query_limit")) {
 
  655                } 
else if (!strcasecmp(v->
name, 
"cache_type")) {
 
  657                        !strcasecmp(v->
value, 
"roundrobin") ||
 
  658                        !strcasecmp(v->
value, 
"queue");
 
  659                } 
else if (!strcasecmp(v->
name, 
"cache_size")) {
 
  660                    if (!strcasecmp(v->
value, 
"-1")) {
 
  676                SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &new->env);
 
  677                res = SQLSetEnvAttr(new->env, SQL_ATTR_ODBC_VERSION, (
void *) SQL_OV_ODBC3, 0);
 
  679                if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 
  685                new->backslash_is_escape = bse ? 1 : 0;
 
  689                new->negative_connection_cache = ncache;
 
 
  740                "Usage: odbc show [class]\n" 
  741                "       List settings of a particular ODBC class or,\n" 
  742                "       if not specified, all classes.\n";
 
  747        length = strlen(
a->word);
 
  750            if (!strncasecmp(
a->word, class->
name, length) && ++which > 
a->n) {
 
  759        if (!ret && !strncasecmp(
a->word, 
"all", length) && ++which > 
a->n) {
 
  765    ast_cli(
a->fd, 
"\nODBC DSN Settings\n");
 
  766    ast_cli(
a->fd,   
"-----------------\n\n");
 
  769        if ((
a->argc == 2) || (
a->argc == 3 && !strcmp(
a->argv[2], 
"all")) || (!strcmp(
a->argv[2], class->
name))) {
 
  773            ast_cli(
a->fd, 
"  Name:   %s\n  DSN:    %s\n", class->
name, class->dsn);
 
  775            if (class->last_negative_connect.tv_sec > 0) {
 
  777                ast_strftime(timestr, 
sizeof(timestr), 
"%Y-%m-%d %T", &tm);
 
  778                ast_cli(
a->fd, 
"    Last fail connection attempt: %s\n", timestr);
 
  781            ast_cli(
a->fd, 
"    Number of active connections: %zd (out of %d)\n", class->connection_cnt, class->maxconnections);
 
  782            ast_cli(
a->fd, 
"    Cache Type: %s\n", class->cache_is_queue ? 
"round-robin queue" : 
"stack (last release, first re-use)");
 
  783            ast_cli(
a->fd, 
"    Cache Usage: %u cached out of %u\n", class->cur_cache,
 
  784                    class->max_cache_size < class->maxconnections ? class->max_cache_size : 
class->maxconnections);
 
  785            ast_cli(
a->fd, 
"    Logging: %s\n", class->logging ? 
"Enabled" : 
"Disabled");
 
  786            if (class->logging) {
 
  787                ast_cli(
a->fd, 
"    Number of prepares executed: %d\n", class->prepares_executed);
 
  788                ast_cli(
a->fd, 
"    Number of queries executed: %d\n", class->queries_executed);
 
  790                if (class->sql_text) {
 
  791                    ast_cli(
a->fd, 
"    Longest running SQL query: %s (%ld milliseconds)\n", class->sql_text, class->longest_query_execution_time);
 
 
  832    ast_debug(2, 
"Releasing ODBC handle %p into pool\n", obj);
 
  850    if (class->cache_is_queue) {
 
  856    if (class->cur_cache >= class->max_cache_size) {
 
  858        if (class->cache_is_queue) {
 
  866        --
class->connection_cnt;
 
  869        ast_debug(2, 
"ODBC Pool '%s' exceeded cache size, dropping '%p', connection count is %zd (%u cached)\n",
 
  870            class->name, obj, class->connection_cnt, class->cur_cache);
 
 
  893    if (!strcmp(class->name, 
name) && !class->delme) {
 
 
  902    unsigned int max_connections;
 
  912    return max_connections;
 
 
  925    char *test_sql = 
"select 1";
 
  930    res = SQLGetConnectAttr(connection->
con, SQL_ATTR_CONNECTION_DEAD, &dead, 0, 0);
 
  931    if (SQL_SUCCEEDED(res)) {
 
  932        return dead == SQL_CD_TRUE ? 1 : 0;
 
  938    res = SQLAllocHandle(SQL_HANDLE_STMT, connection->
con, &stmt);
 
  939    if (!SQL_SUCCEEDED(res)) {
 
  944        test_sql = 
class->sanitysql;
 
  947    res = SQLPrepare(stmt, (
unsigned char *)test_sql, SQL_NTS);
 
  948    if (!SQL_SUCCEEDED(res)) {
 
  949        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
  953    res = SQLExecute(stmt);
 
  954    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 
  956    return SQL_SUCCEEDED(res) ? 0 : 1;
 
 
  982            if (class->connection_cnt < class->maxconnections) {
 
  995                class->connection_cnt++;
 
 1001                    class->connection_cnt--;
 
 1012                ast_debug(2, 
"Created ODBC handle %p on class '%s', new count is %zd\n", obj,
 
 1013                    name, class->connection_cnt);
 
 1031            class->connection_cnt--;
 
 1034            ast_debug(2, 
"ODBC handle %p dead - removing from class '%s', new count is %zd\n",
 
 1035                obj, 
name, class->connection_cnt);
 
 1045            ast_debug(2, 
"Reusing ODBC handle %p from class '%s'\n", obj, 
name);
 
 
 1070    unsigned char msg[200], 
state[10];
 
 1080    res = SQLDisconnect(con);
 
 1082    if ((res = SQLFreeHandle(SQL_HANDLE_DBC, con)) == SQL_SUCCESS) {
 
 1083        ast_debug(3, 
"Database handle %p (connection %p) deallocated\n", obj, con);
 
 1085        SQLGetDiagRec(SQL_HANDLE_DBC, con, 1, 
state, &err, msg, 100, &mlen);
 
 1086        ast_log(
LOG_WARNING, 
"Unable to deallocate database handle %p? %d errno=%d %s\n", con, res, (
int)err, msg);
 
 
 1097    unsigned char msg[200], 
state[10];
 
 1099    SQLINTEGER enable = 1;
 
 1100    char *tracefile = 
"/tmp/odbc.trace";
 
 1103    long int negative_cache_expiration;
 
 1110    if (time(
NULL) < negative_cache_expiration) {
 
 1117    res = SQLAllocHandle(SQL_HANDLE_DBC, obj->
parent->
env, &con);
 
 1119    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 
 1124    SQLSetConnectAttr(con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)(
long) obj->
parent->
conntimeout, 0);
 
 1125    SQLSetConnectAttr(con, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER *)(
long) obj->
parent->
conntimeout, 0);
 
 1127    SQLSetConnectAttr(con, SQL_ATTR_TRACE, &enable, SQL_IS_INTEGER);
 
 1128    SQLSetConnectAttr(con, SQL_ATTR_TRACEFILE, tracefile, strlen(tracefile));
 
 1131    res = SQLConnect(con,
 
 1136    if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 
 1137        SQLGetDiagRec(SQL_HANDLE_DBC, con, 1, 
state, &err, msg, 100, &mlen);
 
 1139        ast_log(
LOG_WARNING, 
"res_odbc: Error SQLConnect=%d errno=%d %s\n", res, (
int)err, msg);
 
 1140        if ((res = SQLFreeHandle(SQL_HANDLE_DBC, con)) != SQL_SUCCESS) {
 
 1141            SQLGetDiagRec(SQL_HANDLE_DBC, con, 1, 
state, &err, msg, 100, &mlen);
 
 1142            ast_log(
LOG_WARNING, 
"Unable to deallocate database handle %p? %d errno=%d %s\n", con, res, (
int)err, msg);
 
 
 1218    .
requires = 
"res_odbc_transaction",
 
void ast_cli_unregister_multiple(void)
int setenv(const char *name, const char *value, int overwrite)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_MUTEX
int ao2_match_by_addr(void *obj, void *arg, int flags)
A common ao2_callback is one that matches by address.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
#define ao2_unlink(container, obj)
Remove an object from a container.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
#define ao2_alloc(data_size, destructor_fn)
static const char config[]
General Asterisk PBX channel definitions.
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Generic File Format Support. Should be included by clients of the file handling routines....
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_HEAD_INIT(head)
Initializes an rwlist head structure.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized.
#define AST_RWLIST_REMOVE_HEAD
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_RWLIST_TRAVERSE_SAFE_END
#define AST_RWLIST_TRAVERSE
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_RWLIST_INSERT_TAIL
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_RWLIST_HEAD_DESTROY(head)
Destroys an rwlist head structure.
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Asterisk locking-related definitions:
#define ast_cond_destroy(cond)
#define ast_cond_wait(cond, mutex)
#define ast_cond_init(cond, attr)
#define ast_mutex_init(pmutex)
#define ast_mutex_unlock(a)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
pthread_cond_t ast_cond_t
#define ast_mutex_destroy(a)
#define ast_mutex_lock(a)
#define ast_cond_signal(cond)
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_REALTIME_DEPEND
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Core PBX routines and definitions.
static char * handle_cli_odbc_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_cli_entry cli_odbc[]
static void odbc_register_class(struct odbc_class *class, int connect)
static int load_odbc_config(void)
static int aoro2_class_cb(void *obj, void *arg, int flags)
static void odbc_obj_destructor(void *data)
static odbc_status odbc_obj_connect(struct odbc_obj *obj)
int ast_odbc_prepare(struct odbc_obj *obj, SQLHSTMT *stmt, const char *sql)
Prepares a SQL query on a statement.
unsigned int ast_odbc_class_get_isolation(struct odbc_class *class)
Get the transaction isolation setting for an ODBC class.
void ast_odbc_release_obj(struct odbc_obj *obj)
Releases an ODBC object previously allocated by ast_odbc_request_obj()
struct odbc_cache_tables * ast_odbc_find_table(const char *database, const char *tablename)
Find or create an entry describing the table specified.
unsigned int ast_odbc_get_max_connections(const char *name)
Return the current configured maximum number of connections for a class.
int ast_odbc_clear_cache(const char *database, const char *tablename)
Remove a cache entry from memory This function may be called to clear entries created and cached by t...
struct odbc_cache_columns * ast_odbc_find_column(struct odbc_cache_tables *table, const char *colname)
Find a column entry within a cached table structure.
static void odbc_class_destructor(void *data)
struct odbc_obj * _ast_odbc_request_obj(const char *name, int check, const char *file, const char *function, int lineno)
static struct ao2_container * class_container
struct ast_str * ast_odbc_print_errors(SQLSMALLINT handle_type, SQLHANDLE handle, const char *operation)
Shortcut for printing errors to logs after a failed SQL operation.
static void destroy_table_cache(struct odbc_cache_tables *table)
int ast_odbc_backslash_is_escape(struct odbc_obj *obj)
Checks if the database natively supports backslash as an escape character.
const char * ast_odbc_isolation2text(int iso)
Convert from numeric transaction isolation values to their textual counterparts.
const char * ast_odbc_class_get_name(struct odbc_class *class)
Get the name of an ODBC class.
SQLRETURN ast_odbc_ast_str_SQLGetData(struct ast_str **buf, int pmaxlen, SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLLEN *StrLen_or_Ind)
Wrapper for SQLGetData to use with dynamic strings.
SQLHSTMT ast_odbc_direct_execute(struct odbc_obj *obj, SQLHSTMT(*exec_cb)(struct odbc_obj *obj, void *data), void *data)
Executes an non prepared statement and returns the resulting statement handle.
unsigned int ast_odbc_class_get_forcecommit(struct odbc_class *class)
Get the transaction forcecommit setting for an ODBC class.
static int load_module(void)
SQLRETURN ast_odbc_execute_sql(struct odbc_obj *obj, SQLHSTMT *stmt, const char *sql)
Execute a unprepared SQL query.
static odbc_status odbc_obj_disconnect(struct odbc_obj *obj)
static int unload_module(void)
SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT(*prepare_cb)(struct odbc_obj *obj, void *data), void *data)
Prepares, executes, and returns the resulting statement handle.
int ast_odbc_text2isolation(const char *txt)
Convert from textual transaction isolation values to their numeric constants.
static int connection_dead(struct odbc_obj *connection, struct odbc_class *class)
Determine if the connection has died.
struct odbc_obj * _ast_odbc_request_obj2(const char *name, struct ast_flags flags, const char *file, const char *function, int lineno)
int ast_odbc_smart_execute(struct odbc_obj *obj, SQLHSTMT stmt)
Executes a prepared statement handle.
#define ast_odbc_request_obj(name, check)
Get a ODBC connection object.
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define ast_str_make_space(buf, new_len)
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
size_t attribute_pure ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Main Channel structure associated with a channel.
descriptor for a cli entry.
Structure used to handle boolean flags.
Structure for mutex and tracking information.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
These structures are used for adaptive capabilities.
struct odbc_cache_columns::@272 list
struct odbc_cache_tables::@273 list
struct odbc_cache_tables::_columns columns
unsigned int slowquerylimit
unsigned int max_cache_size
unsigned int maxconnections
struct timeval negative_connection_cache
unsigned int backslash_is_escape
struct odbc_class::@478 list
struct odbc_class::@479 connections
unsigned int cache_is_queue
long longest_query_execution_time
struct timeval last_negative_connect
struct odbc_obj::@271 list
struct odbc_class * parent
struct ast_channel * owner
struct odbc_txn_frame::@480 list
unsigned int active
Is this record the current active transaction within the channel? Note that the active flag is really...
Definitions to aid in the use of thread local storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Time-related functions and macros.
int ast_time_t_to_string(time_t time, char *buf, size_t length)
Converts to a string representation of a time_t as decimal seconds since the epoch....
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)