aboutsummaryrefslogtreecommitdiffstats
path: root/funcs/func_odbc.c
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-19 00:26:01 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-19 00:26:01 +0000
commit48707e53d9739d1d361914b72a9d65faefe58860 (patch)
tree5da85f585b6be426b1abc5404491d76541f48716 /funcs/func_odbc.c
parent99772af4aa503bbe3fe90a113291a89fe34875aa (diff)
ODBC transaction support
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@177320 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'funcs/func_odbc.c')
-rw-r--r--funcs/func_odbc.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c
index d56a1df27..fb733a421 100644
--- a/funcs/func_odbc.c
+++ b/funcs/func_odbc.c
@@ -2,6 +2,7 @@
* Asterisk -- An open source telephony toolkit.
*
* Copyright (c) 2005, 2006 Tilghman Lesher
+ * Copyright (c) 2008 Digium, Inc.
*
* Tilghman Lesher <func_odbc__200508@the-tilghman.com>
*
@@ -205,6 +206,7 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
struct acf_odbc_query *query;
char *t, varname[15];
int i, dsn, bogus_chan = 0;
+ int transactional = 0;
AST_DECLARE_APP_ARGS(values,
AST_APP_ARG(field)[100];
);
@@ -293,16 +295,32 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
}
pbx_builtin_setvar_helper(chan, "VALUE", NULL);
+ /*!\note
+ * Okay, this part is confusing. Transactions belong to a single database
+ * handle. Therefore, when working with transactions, we CANNOT failover
+ * to multiple DSNs. We MUST have a single handle all the way through the
+ * transaction, or else we CANNOT enforce atomicity.
+ */
for (dsn = 0; dsn < 5; dsn++) {
+ if (transactional) {
+ /* This can only happen second time through or greater. */
+ ast_log(LOG_WARNING, "Transactions do not work well with multiple DSNs for 'writehandle'\n");
+ }
+
if (!ast_strlen_zero(query->writehandle[dsn])) {
- obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
- if (obj)
- stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf));
+ if ((obj = ast_odbc_retrieve_transaction_obj(chan, query->writehandle[dsn]))) {
+ transactional = 1;
+ } else {
+ obj = ast_odbc_request_obj(query->writehandle[dsn], 0);
+ transactional = 0;
+ }
+ if (obj && (stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf)))) {
+ break;
+ }
}
- if (stmt) {
- status = "SUCCESS";
- SQLRowCount(stmt, &rows);
- break;
+
+ if (obj && !transactional) {
+ ast_odbc_release_obj(obj);
}
}
@@ -322,6 +340,9 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
break;
}
}
+ } else if (stmt) {
+ status = "SUCCESS";
+ SQLRowCount(stmt, &rows);
}
AST_RWLIST_UNLOCK(&queries);
@@ -338,7 +359,7 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co
SQLCloseCursor(stmt);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}
- if (obj) {
+ if (obj && !transactional) {
ast_odbc_release_obj(obj);
obj = NULL;
}