Newer
Older
* Asterisk -- An open source telephony toolkit.
* Copyright (c) 2005, 2006 Tilghman Lesher
* Copyright (c) 2008, 2009 Digium, Inc.
*
* Tilghman Lesher <func_odbc__200508@the-tilghman.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
/*!
* \file
*
* \brief ODBC lookups
*
* \author Tilghman Lesher <func_odbc__200508@the-tilghman.com>
Kevin P. Fleming
committed
/*** MODULEINFO
<depend>res_odbc</depend>
<depend>generic_odbc</depend>
<support_level>core</support_level>
Kevin P. Fleming
committed
***/
Kevin P. Fleming
committed
#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/res_odbc.h"
#include "asterisk/res_odbc_transaction.h"
#include "asterisk/app.h"
#include "asterisk/strings.h"
/*** DOCUMENTATION
<function name="ODBC_FETCH" language="en_US">
<synopsis>
Fetch a row from a multirow query.
</synopsis>
<syntax>
<parameter name="result-id" required="true" />
</syntax>
<description>
<para>For queries which are marked as mode=multirow, the original
query returns a <replaceable>result-id</replaceable> from which results
may be fetched. This function implements the actual fetch of the results.</para>
<para>This also sets <variable>ODBC_FETCH_STATUS</variable>.</para>
<variablelist>
<variable name="ODBC_FETCH_STATUS">
<value name="SUCESS">
If rows are available.
</value>
<value name="FAILURE">
If no rows are available.
</value>
</variable>
</variablelist>
</description>
</function>
<application name="ODBCFinish" language="en_US">
<synopsis>
Clear the resultset of a sucessful multirow query.
</synopsis>
<syntax>
<parameter name="result-id" required="true" />
</syntax>
<description>
<para>For queries which are marked as mode=multirow, this will clear
any remaining rows of the specified resultset.</para>
</description>
</application>
<function name="SQL_ESC" language="en_US">
<synopsis>
Escapes single ticks for use in SQL statements.
</synopsis>
<syntax>
<parameter name="string" required="true" />
</syntax>
<description>
<para>Used in SQL templates to escape data which may contain single ticks
<literal>'</literal> which are otherwise used to delimit data.</para>
<example title="Escape example">
SELECT foo FROM bar WHERE baz='${SQL_ESC(${ARG1})}'
</example>
<function name="SQL_ESC_BACKSLASHES" language="en_US">
<synopsis>
Escapes backslashes for use in SQL statements.
</synopsis>
<syntax>
<parameter name="string" required="true" />
</syntax>
<description>
<para>Used in SQL templates to escape data which may contain backslashes
<literal>\</literal> which are otherwise used to escape data.</para>
<example title="Escape with backslashes example">
SELECT foo FROM bar WHERE baz='${SQL_ESC(${SQL_ESC_BACKSLASHES(${ARG1})})}'
</example>
</description>
</function>
static char *config = "func_odbc.conf";
#define DEFAULT_SINGLE_DB_CONNECTION 0
static int single_db_connection;
AST_RWLOCK_DEFINE_STATIC(single_db_connection_lock);
enum odbc_option_flags {
OPT_ESCAPECOMMAS = (1 << 0),
struct acf_odbc_query {
Tilghman Lesher
committed
AST_RWLIST_ENTRY(acf_odbc_query) list;
char readhandle[5][30];
char writehandle[5][30];
Joshua Colp
committed
char *sql_read;
char *sql_write;
char *sql_insert;
unsigned int flags;
int minargs;
struct ast_custom_function *acf;
};
static void odbc_datastore_free(void *data);
static const struct ast_datastore_info odbc_info = {
.type = "FUNC_ODBC",
.destroy = odbc_datastore_free,
};
/* For storing each result row */
struct odbc_datastore_row {
AST_LIST_ENTRY(odbc_datastore_row) list;
char data[0];
};
/* For storing each result set */
struct odbc_datastore {
AST_LIST_HEAD(, odbc_datastore_row);
char names[0];
};
/*! \brief Data source name
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
*
* This holds data that pertains to a DSN
*/
struct dsn {
/*! A connection to the database */
struct odbc_obj *connection;
/*! The name of the DSN as defined in res_odbc.conf */
char name[0];
};
#define DSN_BUCKETS 37
struct ao2_container *dsns;
static int dsn_hash(const void *obj, const int flags)
{
const struct dsn *object;
const char *key;
switch (flags & OBJ_SEARCH_MASK) {
case OBJ_SEARCH_KEY:
key = obj;
break;
case OBJ_SEARCH_OBJECT:
object = obj;
key = object->name;
break;
default:
ast_assert(0);
return 0;
}
return ast_str_hash(key);
}
static int dsn_cmp(void *obj, void *arg, int flags)
{
const struct dsn *object_left = obj;
Loading
Loading full blame...