⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbase.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/*  * $Id: dbase.c,v 1.38 2004/12/06 08:51:44 janakj Exp $  * * MySQL module core functions * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser 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 */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#include <mysql/mysql.h>#include <mysql/errmsg.h>#include "../../mem/mem.h"#include "../../dprint.h"#include "utils.h"#include "val.h"#include "my_con.h"#include "my_pool.h"#include "res.h"#include "db_mod.h"#include "dbase.h"#define SQL_BUF_LEN 65536static char sql_buf[SQL_BUF_LEN];/* * Send an SQL query to the server */static int submit_query(db_con_t* _h, const char* _s){		time_t t;	int i, code;	if ((!_h) || (!_s)) {		LOG(L_ERR, "submit_query(): Invalid parameter value\n");		return -1;	}	if (ping_interval) {		t = time(0);		if ((t - CON_TIMESTAMP(_h)) > ping_interval) {			if (mysql_ping(CON_CONNECTION(_h))) {				DBG("submit_query(): mysql_ping failed\n");			}		}		CON_TIMESTAMP(_h) = t;	}	/* screws up the terminal when the query contains a BLOB :-( (by bogdan)	 * DBG("submit_query(): %s\n", _s);	 */	/* When a server connection is lost and a query is attempted, most of	 * the time the query will return a CR_SERVER_LOST, then at the second	 * attempt to execute it, the mysql lib will reconnect and succeed.	 * However is a few cases, the first attempt returns CR_SERVER_GONE_ERROR	 * the second CR_SERVER_LOST and only the third succeeds.	 * Thus the 3 in the loop count. Increasing the loop count over this	 * value shouldn't be needed, but it doesn't hurt either, since the loop	 * will most of the time stop at the second or sometimes at the third	 * iteration.     */	for (i=0; i<(auto_reconnect ? 3 : 1); i++) {		if (mysql_query(CON_CONNECTION(_h), _s)==0) {			return 0;		}		code = mysql_errno(CON_CONNECTION(_h));		if (code != CR_SERVER_GONE_ERROR && code != CR_SERVER_LOST) {			break;		}	}	LOG(L_ERR, "submit_query(): %s\n", mysql_error(CON_CONNECTION(_h)));	return -2;}/* * 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(MYSQL* _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(MYSQL* _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(MYSQL* _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){	db_con_t* res;	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*));	res->tail = (unsigned long)get_connection(_url);	if (!res->tail) {		LOG(L_ERR, "db_init(): Could not create a connection\n");		pkg_free(res);		return 0;	}	return res;}/* * Shut down database module * No function should be called after this */void db_close(db_con_t* _h){	if (!_h) {		LOG(L_ERR, "db_close(): Invalid parameter value\n");		return;	}	release_connection((struct my_con*)_h->tail);	pkg_free(_h);}/* * Retrieve result set */static int store_result(db_con_t* _h, db_res_t** _r){	if ((!_h) || (!_r)) {		LOG(L_ERR, "store_result(): Invalid parameter value\n");		return -1;	}	*_r = new_result();	if (*_r == 0) {		LOG(L_ERR, "store_result(): No memory left\n");		return -2;	}	CON_RESULT(_h) = mysql_store_result(CON_CONNECTION(_h));	if (!CON_RESULT(_h)) {		if (mysql_field_count(CON_CONNECTION(_h)) == 0) {			(*_r)->col.n = 0;			(*_r)->n = 0;			return 0;		} else {			LOG(L_ERR, "store_result(): %s\n", mysql_error(CON_CONNECTION(_h)));			free_result(*_r);			*_r = 0;			return -3;		}	}        if (convert_result(_h, *_r) < 0) {		LOG(L_ERR, "store_result(): Error while converting result\n");		pkg_free(*_r);		     /* This cannot be used because if convert_result fails,		      * free_result will try to free rows and columns too 		      * and free will be called two times		      */		     /* free_result(*_r); */		return -4;	}		return 0;}/* * Release a result set from memory */int db_free_result(db_con_t* _h, db_res_t* _r){     if ((!_h) || (!_r)) {	     LOG(L_ERR, "db_free_result(): Invalid parameter value\n");	     return -1;     }     if (free_result(_r) < 0) {	     LOG(L_ERR, "db_free_result(): Unable to free result structure\n");	     return -1;     }     mysql_free_result(CON_RESULT(_h));     CON_RESULT(_h) = 0;     return 0;}/* * Query table for specified rows * _h: structure representing database connection * _k: key names * _op: operators * _v: values of the keys that must match * _c: column names to return * _n: number of key=values pairs to compare * _nc: number of columns to return * _o: order by the specified column */int db_query(db_con_t* _h, db_key_t* _k, db_op_t* _op,	     db_val_t* _v, db_key_t* _c, int _n, int _nc,	     db_key_t _o, db_res_t** _r){	int off, ret;	if (!_h) {		LOG(L_ERR, "db_query(): Invalid parameter value\n");		return -1;	}	if (!_c) {		ret = snprintf(sql_buf, SQL_BUF_LEN, "select * from %s ", CON_TABLE(_h));		if (ret < 0 || ret >= SQL_BUF_LEN) goto error;		off = ret;	} else {		ret = snprintf(sql_buf, SQL_BUF_LEN, "select ");		if (ret < 0 || ret >= SQL_BUF_LEN) goto error;		off = ret;		ret = print_columns(sql_buf + off, SQL_BUF_LEN - off, _c, _nc);		if (ret < 0) return -1;		off += ret;		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "from %s ", CON_TABLE(_h));		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;		off += ret;	}	if (_n) {		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "where ");		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;		off += ret;		ret = print_where(CON_CONNECTION(_h), sql_buf + off, SQL_BUF_LEN - off, _k, _op, _v, _n);		if (ret < 0) return -1;;		off += ret;	}	if (_o) {		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, "order by %s", _o);		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;		off += ret;	}		*(sql_buf + off) = '\0';	if (submit_query(_h, sql_buf) < 0) {		LOG(L_ERR, "submit_query(): Error while submitting query\n");		return -2;	}	return store_result(_h, _r); error:	LOG(L_ERR, "submit_query: Error in snprintf\n");	return -1;}/* * Execute a raw SQL query */int db_raw_query(db_con_t* _h, char* _s, db_res_t** _r){	if ((!_h) || (!_s)) {		LOG(L_ERR, "db_raw_query(): Invalid parameter value\n");		return -1;	}	if (submit_query(_h, _s) < 0) {		LOG(L_ERR, "submit_query(): Error while submitting query\n");		return -2;	}	if(_r)	    return store_result(_h, _r);	return 0;}/* * Insert a row into specified table * _h: structure representing database connection * _k: key names * _v: values of the keys * _n: number of key=value pairs */int db_insert(db_con_t* _h, db_key_t* _k, db_val_t* _v, int _n){	int off, ret;	if ((!_h) || (!_k) || (!_v) || (!_n)) {		LOG(L_ERR, "db_insert(): Invalid parameter value\n");		return -1;	}	ret = snprintf(sql_buf, SQL_BUF_LEN, "insert into %s (", CON_TABLE(_h));	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;	off = ret;	ret = print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);	if (ret < 0) return -1;	off += ret;	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;	off += ret;	ret = print_values(CON_CONNECTION(_h), sql_buf + off, SQL_BUF_LEN - off, _v, _n);	if (ret < 0) return -1;	off += ret;	*(sql_buf + off++) = ')';	*(sql_buf + off) = '\0';	if (submit_query(_h, sql_buf) < 0) {	        LOG(L_ERR, "db_insert: Error while submitting query\n");		return -2;	}	return 0; error:	LOG(L_ERR, "db_insert: Error in snprintf\n");	return -1;}/* * Delete a row from the specified table * _h: structure representing database connection * _k: key names * _o: operators * _v: values of the keys that must match * _n: number of key=value pairs */int db_delete(db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v, int _n){	int off, ret;	if (!_h) {		LOG(L_ERR, "db_delete(): Invalid parameter value\n");		return -1;	}	ret = snprintf(sql_buf, SQL_BUF_LEN, "delete from %s", CON_TABLE(_h));	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;	off = ret;	if (_n) {		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;		off += ret;		ret = print_where(CON_CONNECTION(_h), sql_buf + off, SQL_BUF_LEN - off, _k, _o, _v, _n);		if (ret < 0) return -1;		off += ret;	}	*(sql_buf + off) = '\0';	if (submit_query(_h, sql_buf) < 0) {		LOG(L_ERR, "db_delete: Error while submitting query\n");		return -2;	}	return 0; error:	LOG(L_ERR, "db_delete: Error in snprintf\n");	return -1;}/* * Update some rows in the specified table * _h: structure representing database connection * _k: key names * _o: operators * _v: values of the keys that must match * _uk: updated columns * _uv: updated values of the columns * _n: number of key=value pairs * _un: number of columns to update */int db_update(db_con_t* _h, db_key_t* _k, db_op_t* _o, db_val_t* _v,	      db_key_t* _uk, db_val_t* _uv, int _n, int _un){	int off, ret;	if ((!_h) || (!_uk) || (!_uv) || (!_un)) {		LOG(L_ERR, "db_update(): Invalid parameter value\n");		return -1;	}	ret = snprintf(sql_buf, SQL_BUF_LEN, "update %s set ", CON_TABLE(_h));	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;	off = ret;	ret = print_set(CON_CONNECTION(_h), sql_buf + off, SQL_BUF_LEN - off, _uk, _uv, _un);	if (ret < 0) return -1;	off += ret;	if (_n) {		ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " where ");		if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;		off += ret;		ret = print_where(CON_CONNECTION(_h), sql_buf + off, SQL_BUF_LEN - off, _k, _o, _v, _n);		if (ret < 0) return -1;		off += ret;		*(sql_buf + off) = '\0';	}	if (submit_query(_h, sql_buf) < 0) {		LOG(L_ERR, "db_update: Error while submitting query\n");		return -2;	}	return 0; error:	LOG(L_ERR, "db_update: Error in snprintf\n");	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -