Diff of /src/core/modules/db_mysql/val.c [000000] .. [80966b] Maximize Restore

  Switch to side-by-side view

--- a
+++ b/src/core/modules/db_mysql/val.c
@@ -0,0 +1,337 @@
+/* 
+ * $Id: val.c 6591 2010-02-11 15:56:13Z bogdan_iancu $ 
+ *
+ * Copyright (C) 2001-2003 FhG Fokus
+ * Copyright (C) 2008 1&1 Internet AG
+ *
+ * This file is part of opensips, a free SIP server.
+ *
+ * opensips 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
+ *
+ * opensips 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 "../../log.h"
+#include "../../db/db_ut.h"
+#include "val.h"
+#include "my_con.h"
+
+#include <string.h>
+#include <stdio.h>
+
+
+/*
+ * Convert str to db value, does not copy strings
+ */
+int db_mysql_str2val( db_type_t _t, db_val_t* _v,  char* _s,  int _l)
+{
+	static str dummy_string = {"", 0};
+	
+	if (!_v) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	if (!_s) {
+		memset(_v, 0, sizeof(db_val_t));
+			/* Initialize the string pointers to a dummy empty
+			 * string so that we do not crash when the NULL flag
+			 * is set but the module does not check it properly
+			 */
+		VAL_STRING(_v) = dummy_string.s;
+		VAL_STR(_v) = dummy_string;
+		VAL_BLOB(_v) = dummy_string;
+		VAL_TYPE(_v) = _t;
+		VAL_NULL(_v) = 1;
+		return 0;
+	}
+	VAL_NULL(_v) = 0;
+
+	switch(_t) {
+	case DB_INT:
+		LM_DBG("converting INT [%s]\n", _s);
+		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
+			LM_ERR("error while converting integer value from string\n");
+			return -2;
+		} else {
+			VAL_TYPE(_v) = DB_INT;
+			return 0;
+		}
+		break;
+
+	case DB_BITMAP:
+		LM_DBG("converting BITMAP [%s]\n", _s);
+		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
+			LM_ERR("error while converting bitmap value from string\n");
+			return -3;
+		} else {
+			VAL_TYPE(_v) = DB_BITMAP;
+			return 0;
+		}
+		break;
+	
+	case DB_DOUBLE:
+		LM_DBG("converting DOUBLE [%s]\n", _s);
+		if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) {
+			LM_ERR("error while converting double value from string\n");
+			return -4;
+		} else {
+			VAL_TYPE(_v) = DB_DOUBLE;
+			return 0;
+		}
+		break;
+
+	case DB_STRING:
+		LM_DBG("converting STRING [%s]\n", _s);
+		VAL_STRING(_v) = _s;
+		VAL_TYPE(_v) = DB_STRING;
+		return 0;
+
+	case DB_STR:
+		LM_DBG("converting STR [%.*s]\n", _l, _s);
+		VAL_STR(_v).s = (char*)_s;
+		VAL_STR(_v).len = _l;
+		VAL_TYPE(_v) = DB_STR;
+		return 0;
+
+	case DB_DATETIME:
+		LM_DBG("converting DATETIME [%s]\n", _s);
+		if (db_str2time(_s, &VAL_TIME(_v)) < 0) {
+			LM_ERR("error while converting datetime value from string\n");
+			return -5;
+		} else {
+			VAL_TYPE(_v) = DB_DATETIME;
+			return 0;
+		}
+		break;
+
+	case DB_BLOB:
+		LM_DBG("converting BLOB [%.*s]\n", _l, _s);
+		VAL_BLOB(_v).s = (char*)_s;
+		VAL_BLOB(_v).len = _l;
+		VAL_TYPE(_v) = DB_BLOB;
+		return 0;
+	}
+	return -6;
+}
+
+
+/*
+ * Used when converting values to be used in a DB query
+ */
+int db_mysql_val2str( db_con_t* _c,  db_val_t* _v, char* _s, int* _len)
+{
+	int l;
+	char* old_s;
+
+	if (!_c || !_v || !_s || !_len || !*_len) {
+		LM_ERR("invalid parameter value\n");
+		return -1;
+	}
+
+	if (VAL_NULL(_v)) {
+		if (*_len < sizeof("NULL")) {
+			LM_ERR("buffer too small\n");
+			return -1;
+		}
+		*_len = snprintf(_s, *_len, "NULL");
+		return 0;
+	}
+	
+	switch(VAL_TYPE(_v)) {
+	case DB_INT:
+		if (db_int2str(VAL_INT(_v), _s, _len) < 0) {
+			LM_ERR("error while converting string to int\n");
+			return -2;
+		} else {
+			return 0;
+		}
+		break;
+
+	case DB_BITMAP:
+		if (db_int2str(VAL_BITMAP(_v), _s, _len) < 0) {
+			LM_ERR("error while converting string to int\n");
+			return -3;
+		} else {
+			return 0;
+		}
+		break;
+
+	case DB_DOUBLE:
+		if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) {
+			LM_ERR("error while converting string to double\n");
+			return -4;
+		} else {
+			return 0;
+		}
+		break;
+
+	case DB_STRING:
+		l = strlen(VAL_STRING(_v));
+		if (*_len < (l * 2 + 3)) {
+			LM_ERR("destination buffer too short\n");
+			return -5;
+		} else {
+			old_s = _s;
+			*_s++ = '\'';
+			_s += mysql_real_escape_string(CON_CONNECTION(_c), _s, VAL_STRING(_v), l);
+			*_s++ = '\'';
+			*_s = '\0'; /* FIXME */
+			*_len = _s - old_s;
+			return 0;
+		}
+		break;
+
+	case DB_STR:
+		if (*_len < (VAL_STR(_v).len * 2 + 3)) {
+			LM_ERR("destination buffer too short\n");
+			return -6;
+		} else {
+			old_s = _s;
+			*_s++ = '\'';
+			_s += mysql_real_escape_string(CON_CONNECTION(_c), _s, VAL_STR(_v).s, VAL_STR(_v).len);
+			*_s++ = '\'';
+			*_s = '\0';
+			*_len = _s - old_s;
+			return 0;
+		}
+		break;
+
+	case DB_DATETIME:
+		if (db_time2str(VAL_TIME(_v), _s, _len) < 0) {
+			LM_ERR("error while converting string to time_t\n");
+			return -7;
+		} else {
+			return 0;
+		}
+		break;
+
+	case DB_BLOB:
+		l = VAL_BLOB(_v).len;
+		if (*_len < (l * 2 + 3)) {
+			LM_ERR("destination buffer too short\n");
+			return -8;
+		} else {
+			old_s = _s;
+			*_s++ = '\'';
+			_s += mysql_real_escape_string(CON_CONNECTION(_c), _s, VAL_STR(_v).s, l);
+			*_s++ = '\'';
+			*_s = '\0';
+			*_len = _s - old_s;
+			return 0;
+		}			
+		break;
+
+	default:
+		LM_DBG("unknown data type\n");
+		return -9;
+	}
+	/*return -8; --not reached*/
+}
+
+
+int db_mysql_val2bind( db_val_t* v, MYSQL_BIND *binds, unsigned int i)
+{
+	struct tm *t;
+	MYSQL_TIME *mt;
+
+	if (VAL_NULL(v)) {
+		*(binds[i].is_null) = 1;
+		*(binds[i].length) = 0;
+		binds[i].buffer= NULL;
+		switch(VAL_TYPE(v)) {
+			case DB_INT:
+				binds[i].buffer_type= MYSQL_TYPE_LONG; break;
+			case DB_BITMAP:
+				binds[i].buffer_type= MYSQL_TYPE_LONG; break;
+			case DB_DOUBLE:
+				binds[i].buffer_type= MYSQL_TYPE_DOUBLE; break;
+			case DB_STRING:
+				binds[i].buffer_type= MYSQL_TYPE_STRING; break;
+			case DB_STR:
+				binds[i].buffer_type= MYSQL_TYPE_STRING; break;
+			case DB_DATETIME:
+				binds[i].buffer_type= MYSQL_TYPE_DATETIME; break;
+			case DB_BLOB:
+				binds[i].buffer_type= MYSQL_TYPE_BLOB; break;
+			default:
+				LM_ERR("unknown NULL data type (%d)\n",VAL_TYPE(v));
+				return -10;
+		}
+		return 0;
+	} else {
+		*(binds[i].is_null) = 0;
+	}
+
+	switch(VAL_TYPE(v)) {
+		case DB_INT:
+			binds[i].buffer_type= MYSQL_TYPE_LONG;
+			binds[i].buffer= (char*)&(VAL_INT(v));
+			*binds[i].length= sizeof(VAL_INT(v));
+			break;
+
+		case DB_BITMAP:
+			binds[i].buffer_type= MYSQL_TYPE_LONG;
+			binds[i].buffer= (char*)&(VAL_BITMAP(v));
+			*binds[i].length= sizeof(VAL_BITMAP(v));
+			break;
+
+		case DB_DOUBLE:
+			binds[i].buffer_type= MYSQL_TYPE_DOUBLE;
+			binds[i].buffer= (char*)&(VAL_DOUBLE(v));
+			*binds[i].length= sizeof(VAL_DOUBLE(v));
+			break;
+
+		case DB_STRING:
+			binds[i].buffer_type= MYSQL_TYPE_STRING;
+			binds[i].buffer= (char*)VAL_STRING(v);
+			*binds[i].length= strlen(VAL_STRING(v));
+			break;
+
+		case DB_STR:
+			binds[i].buffer_type= MYSQL_TYPE_STRING;
+			binds[i].buffer= VAL_STR(v).s;
+			*binds[i].length= VAL_STR(v).len;
+			break;
+
+		case DB_DATETIME:
+			binds[i].buffer_type= MYSQL_TYPE_DATETIME;
+			t = localtime( &VAL_TIME(v) );
+			mt = (MYSQL_TIME*)binds[i].buffer;
+			mt->year = 1900 + t->tm_year;
+			mt->month = (t->tm_mon)+1;
+			mt->day = t->tm_mday;
+			mt->hour = t->tm_hour;
+			mt->minute = t->tm_min;
+			mt->second = t->tm_sec;
+			*binds[i].length= sizeof(MYSQL_TIME);
+			break;
+
+		case DB_BLOB:
+			binds[i].buffer_type= MYSQL_TYPE_BLOB;
+			binds[i].buffer= VAL_BLOB(v).s;
+			*binds[i].length= VAL_BLOB(v).len;
+			break;
+
+		default:
+			LM_ERR("unknown data type (%d)\n",VAL_TYPE(v));
+			return -9;
+	}
+
+	LM_DBG("added val (%d): len=%ld; type=%d; is_null=%d\n", i,
+		*(binds[i].length), binds[i].buffer_type, *(binds[i].is_null));
+
+	return 0;
+}
+