dbase.c
来自「性能优秀的SIP Proxy」· C语言 代码 · 共 746 行 · 第 1/2 页
C
746 行
/* * $Id: dbase.c,v 1.7 2006/05/24 08:53:33 bogdan_iancu Exp $ * * UNIXODBC module core functions * * Copyright (C) 2005-2006 Marco Lorrai * * This file is part of openser, a free SIP server. * * openser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * openser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * History: * -------- * 2005-12-01 initial commit (chgen) * 2006-04-03 fixed invalid handle to extract error (sgupta) * 2006-04-04 removed deprecated ODBC functions, closed cursors on error * (sgupta) * 2006-05-05 Fixed reconnect code to actually work on connection loss * (sgupta) */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#include "../../mem/mem.h"#include "../../dprint.h"#include "../../db/db_pool.h"#include "utils.h"#include "val.h"#include "my_con.h"#include "res.h"#include "db_mod.h"#include "dbase.h"#define SQL_BUF_LEN 65536static char sql_buf[SQL_BUF_LEN];/* * Reconnect if connection is broken */static int reconnect(db_con_t* _h, const char* _s){ int ret = 0; SQLCHAR outstr[1024]; SQLSMALLINT outstrlen; char conn_str[MAX_CONN_STR_LEN]; LOG(L_ERR, "ERROR:unixodbc:reconnect: Attempting DB reconnect\n"); /* Disconnect */ SQLDisconnect (CON_CONNECTION(_h)); /* Reconnect */ if (!build_conn_str(CON_ID(_h), conn_str)) { LOG(L_ERR, "ERROR:unixodbc:reconnect: failed to build " "connection string\n"); return ret; } ret = SQLDriverConnect(CON_CONNECTION(_h), (void *)1, (SQLCHAR*)conn_str, SQL_NTS, outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE); if (!SQL_SUCCEEDED(ret)) { LOG(L_ERR, "ERROR:unixodbc:reconnect: failed to connect\n"); extract_error("SQLDriverConnect", CON_CONNECTION(_h), SQL_HANDLE_DBC, NULL); return ret; } ret = SQLAllocHandle(SQL_HANDLE_STMT, CON_CONNECTION(_h), &CON_RESULT(_h)); if (!SQL_SUCCEEDED(ret)) { LOG(L_ERR, "ERROR:unixodbc:reconnect: Statement allocation " "error %d\n", (int)(long)CON_CONNECTION(_h)); extract_error("SQLAllocStmt", CON_CONNECTION(_h), SQL_HANDLE_DBC,NULL); return ret; } return ret;}/* * Send an SQL query to the server */static int submit_query(db_con_t* _h, const char* _s){ int ret = 0; SQLCHAR sqlstate[7]; /* first do some cleanup if required */ if(CON_RESULT(_h)) { SQLCloseCursor(CON_RESULT(_h)); SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h)); } ret = SQLAllocHandle(SQL_HANDLE_STMT, CON_CONNECTION(_h), &CON_RESULT(_h)); if (!SQL_SUCCEEDED(ret)) { LOG(L_ERR, "ERROR:unixodbc:submit_query: Statement allocation " "error %d\n", (int)(long)CON_CONNECTION(_h)); extract_error("SQLAllocStmt", CON_CONNECTION(_h), SQL_HANDLE_DBC, (char*)sqlstate); /* Connection broken */ if( !strncmp((char*)sqlstate,"08003",5) || !strncmp((char*)sqlstate,"08S01",5) ) { ret = reconnect(_h, _s); if( !SQL_SUCCEEDED(ret) ) return ret; } else { return ret; } } ret=SQLExecDirect(CON_RESULT(_h), (SQLCHAR*)_s, SQL_NTS); if (!SQL_SUCCEEDED(ret)) { SQLCHAR sqlstate[7]; LOG(L_ERR, "unixodbc:SQLExecDirect, rv=%d. Query= %s\n", ret, _s); extract_error("SQLExecDirect", CON_RESULT(_h), SQL_HANDLE_STMT, (char*)sqlstate); /* Connection broken */ if( !strncmp((char*)sqlstate,"08003",5) || !strncmp((char*)sqlstate,"08S01",5) ) { ret = reconnect(_h, _s); if( SQL_SUCCEEDED(ret) ) { /* Try again */ ret=SQLExecDirect(CON_RESULT(_h), (SQLCHAR*)_s, SQL_NTS); if (!SQL_SUCCEEDED(ret)) { LOG(L_ERR, "unixodbc:SQLExecDirect, rv=%d. Query= %s\n", ret, _s); extract_error("SQLExecDirect", CON_RESULT(_h), SQL_HANDLE_STMT, (char*)sqlstate); /* Close the cursor */ SQLCloseCursor(CON_RESULT(_h)); SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h)); } } } else { /* Close the cursor */ SQLCloseCursor(CON_RESULT(_h)); SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h)); } } return ret;}/* * Print list of columns separated by comma */static int print_columns(char* _b, int _l, db_key_t* _c, int _n){ int i, ret; int len = 0; if ((!_c) || (!_n) || (!_b) || (!_l)) { LOG(L_ERR, "print_columns: Invalid parameter value\n"); return -1; } for(i = 0; i < _n; i++) { if (i == (_n - 1)) { ret = snprintf(_b + len, _l - len, "%s ", _c[i]); if (ret < 0 || ret >= (_l - len)) goto error; len += ret; } else { ret = snprintf(_b + len, _l - len, "%s,", _c[i]); if (ret < 0 || ret >= (_l - len)) goto error; len += ret; } } return len; error: LOG(L_ERR, "print_columns: Error in snprintf\n"); return -1;}/* * Print list of values separated by comma */static int print_values(SQLHDBC* _c, char* _b, int _l, db_val_t* _v, int _n){ int i, res = 0, l; if (!_c || !_b || !_l || !_v || !_n) { LOG(L_ERR, "print_values: Invalid parameter value\n"); return -1; } for(i = 0; i < _n; i++) { l = _l - res; if (val2str(_c, _v + i, _b + res, &l) < 0) { LOG(L_ERR, "print_values: Error while converting value to string\n"); return -1; } res += l; if (i != (_n - 1)) { *(_b + res) = ','; res++; } } return res;}/* * Print where clause of SQL statement */static int print_where(SQLHDBC* _c, char* _b, int _l, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n){ int i; int len = 0, ret; int l; if (!_c || !_b || !_l || !_k || !_v || !_n) { LOG(L_ERR, "print_where: Invalid parameter value\n"); return -1; } for(i = 0; i < _n; i++) { if (_o) { ret = snprintf(_b + len, _l - len, "%s%s", _k[i], _o[i]); if (ret < 0 || ret >= (_l - len)) goto error; len += ret; } else { ret = snprintf(_b + len, _l - len, "%s=", _k[i]); if (ret < 0 || ret >= (_l - len)) goto error; len += ret; } l = _l - len; val2str(_c, &(_v[i]), _b + len, &l); len += l; if (i != (_n - 1)) { ret = snprintf(_b + len, _l - len, " AND "); if (ret < 0 || ret >= (_l - len)) goto error; len += ret; } } return len; error: LOG(L_ERR, "print_where: Error in snprintf\n"); return -1;}/* * Print set clause of update SQL statement */static int print_set(SQLHDBC* _c, char* _b, int _l, db_key_t* _k, db_val_t* _v, int _n){ int i; int len = 0, ret; int l; if (!_c || !_b || !_l || !_k || !_v || !_n) { LOG(L_ERR, "print_set: Invalid parameter value\n"); return -1; } for(i = 0; i < _n; i++) { ret = snprintf(_b + len, _l - len, "%s=", _k[i]); if (ret < 0 || ret >= (_l - len)) goto error; len += ret; l = _l - len; val2str(_c, &(_v[i]), _b + len, &l); len += l; if (i != (_n - 1)) { if ((_l - len) >= 1) { *(_b + len++) = ','; } } } return len; error: LOG(L_ERR, "print_set: Error in snprintf\n"); return -1;}/* * Initialize database module * No function should be called before this */db_con_t* db_init(const char* _url){ struct db_id* id; struct my_con* con; db_con_t* res; id = 0; res = 0; if (!_url) { LOG(L_ERR, "db_init: Invalid parameter value\n"); return 0; } res = pkg_malloc(sizeof(db_con_t) + sizeof(struct my_con*)); if (!res) { LOG(L_ERR, "db_init: No memory left\n"); return 0; } memset(res, 0, sizeof(db_con_t) + sizeof(struct my_con*)); id = new_db_id(_url); if (!id) { LOG(L_ERR, "db_init: Cannot parse URL '%s'\n", _url); goto err; }/* Find the connection in the pool */ con = (struct my_con*)pool_get(id); if (!con) { DBG("db_init: Connection '%s' not found in pool\n", _url);/* Not in the pool yet */ con = new_connection(id); if (!con) { goto err; } pool_insert((struct pool_con*)con); } else { DBG("db_init: Connection '%s' found in pool\n", _url); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?