Browse code

- rename database modules to use the 'db_' prefix

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@3638 689a6050-402a-0410-94f2-e92a70836424

Henning Westerholt authored on 06/02/2008 13:10:03
Showing 19 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,41 @@
1
+# $Id$
2
+#
3
+# WARNING: do not run this directly, it should be run by the master Makefile
4
+
5
+include ../../Makefile.defs
6
+auto_gen=
7
+NAME=mysql.so
8
+
9
+# set CROSS_COMPILE to true if you want to skip
10
+# the autodetection
11
+# CROSS_COMPILE=true
12
+
13
+ifeq ($(CROSS_COMPILE),)
14
+MYSQLCFG=$(shell which mysql_config)
15
+endif
16
+
17
+ifneq ($(MYSQLCFG),)
18
+
19
+	# use autodetection
20
+	DEFS += $(shell $(MYSQLCFG) --include | sed 's/\(-I.*\)\/mysql/\1/g' )
21
+	LIBS = $(shell $(MYSQLCFG) --libs)
22
+
23
+else
24
+
25
+	# use standard know paths
26
+	# mysql.h locations (freebsd,openbsd  solaris)
27
+	DEFS +=-I$(LOCALBASE)/include -I$(LOCALBASE)/include/mysql \
28
+		-I$(LOCALBASE)/mysql/include/mysql -I$(LOCALBASE)/mysql/include \
29
+		-I$(SYSBASE)/include/mysql
30
+
31
+	# libmysqlclient locations on RH/Suse, Solaris /OpenBSD, FreeBSD
32
+	# (Debian does the right thing and puts it in /usr/lib)
33
+	LIBS=-L$(SYSBASE)/lib/mysql -L$(LOCALBASE)/lib -L$(LOCALBASE)/lib/mysql \
34
+		-L$(LOCALBASE)/mysql/lib/mysql/ \
35
+		-L$(LOCALBASE)/mysql/lib \
36
+		-L$(SYSBASE)/lib64/mysql \
37
+		-lm -lmysqlclient -lz
38
+
39
+endif
40
+
41
+include ../../Makefile.modules
0 42
new file mode 100644
... ...
@@ -0,0 +1,168 @@
1
+mysql Module
2
+
3
+Daniel-Constantin Mierla
4
+
5
+   voice-system.ro
6
+
7
+Edited by
8
+
9
+Daniel-Constantin Mierla
10
+
11
+   Copyright � 2006 voice-system.ro
12
+     __________________________________________________________
13
+
14
+   Table of Contents
15
+   1. User's Guide
16
+
17
+        1.1. Overview
18
+        1.2. Dependencies
19
+
20
+              1.2.1. OpenSER Modules
21
+              1.2.2. External Libraries or Applications
22
+
23
+        1.3. Exported Parameters
24
+
25
+              1.3.1. ping_interval (integer)
26
+              1.3.2. timeout_interval (integer)
27
+              1.3.3. auto_reconnect (integer)
28
+
29
+        1.4. Exported Functions
30
+        1.5. Installation
31
+
32
+   2. Developer's Guide
33
+   3. Frequently Asked Questions
34
+
35
+   List of Examples
36
+   1-1. Set ping_interval parameter
37
+   1-2. Set timeout_interval parameter
38
+   1-3. Set auto_reconnect parameter
39
+     __________________________________________________________
40
+
41
+Chapter 1. User's Guide
42
+
43
+1.1. Overview
44
+
45
+   This is a module which provides MySQL connectivity for OpenSER.
46
+   It implements the DB API defined in OpenSER.
47
+     __________________________________________________________
48
+
49
+1.2. Dependencies
50
+
51
+1.2.1. OpenSER Modules
52
+
53
+   The following modules must be loaded before this module:
54
+
55
+     * No dependencies on other OpenSER modules.
56
+     __________________________________________________________
57
+
58
+1.2.2. External Libraries or Applications
59
+
60
+   The following libraries or applications must be installed
61
+   before running OpenSER with this module loaded:
62
+
63
+     * libmysqlclient-dev - the development libraries of
64
+       mysql-client.
65
+     __________________________________________________________
66
+
67
+1.3. Exported Parameters
68
+
69
+1.3.1. ping_interval (integer)
70
+
71
+   Time interval to send ping messages to MySQL server in order to
72
+   keep the connection open.
73
+
74
+   Default value is 300 (5 min).
75
+
76
+   Example 1-1. Set ping_interval parameter
77
+...
78
+modparam("mysql", "ping_interval", 600)
79
+...
80
+     __________________________________________________________
81
+
82
+1.3.2. timeout_interval (integer)
83
+
84
+   Time interval after that an connection attempt, read or write
85
+   request is aborted. The value counts three times, as several
86
+   retries are done from the driver before it gives up.
87
+
88
+   The read timeout parameter is ignored on driver versions prior
89
+   to "5.1.12", "5.0.25" and "4.1.22". The write timeout parameter
90
+   is ignored on version prior to "5.1.12" and "5.0.25", the "4.1"
91
+   release don't support it at all.
92
+
93
+   Default value is 2 (6 sec).
94
+
95
+   Example 1-2. Set timeout_interval parameter
96
+...
97
+modparam("mysql", "timeout_interval", 2)
98
+...
99
+     __________________________________________________________
100
+
101
+1.3.3. auto_reconnect (integer)
102
+
103
+   Configure the module to auto reconnect to MySQL server if the
104
+   connection was lost.
105
+
106
+   Default value is 1 (1 - on / 0 - off).
107
+
108
+   Example 1-3. Set auto_reconnect parameter
109
+...
110
+modparam("auto_reconnect", "auto_reconnect", 0)
111
+...
112
+     __________________________________________________________
113
+
114
+1.4. Exported Functions
115
+
116
+   No function exported to be used from configuration file.
117
+     __________________________________________________________
118
+
119
+1.5. Installation
120
+
121
+   Because it dependes on an external library, the mysql module is
122
+   not compiled and installed by default. You can use one of the
123
+   next options.
124
+
125
+     * - edit the "Makefile" and remove "mysql" from
126
+       "excluded_modules" list. Then follow the standard procedure
127
+       to install OpenSER: "make all; make install".
128
+     * - from command line use: 'make all include_modules="mysql";
129
+       make install include_modules="mysql"'.
130
+     __________________________________________________________
131
+
132
+Chapter 2. Developer's Guide
133
+
134
+   The module does not provide any API to use in other OpenSER
135
+   modules.
136
+     __________________________________________________________
137
+
138
+Chapter 3. Frequently Asked Questions
139
+
140
+   3.1. Where can I find more about OpenSER?
141
+   3.2. Where can I post a question about this module?
142
+   3.3. How can I report a bug?
143
+
144
+   3.1. Where can I find more about OpenSER?
145
+
146
+   Take a look at http://openser.org/.
147
+
148
+   3.2. Where can I post a question about this module?
149
+
150
+   First at all check if your question was already answered on one
151
+   of our mailing lists:
152
+
153
+     * User Mailing List -
154
+       http://openser.org/cgi-bin/mailman/listinfo/users
155
+     * Developer Mailing List -
156
+       http://openser.org/cgi-bin/mailman/listinfo/devel
157
+
158
+   E-mails regarding any stable OpenSER release should be sent to
159
+   <users@openser.org> and e-mails regarding development versions
160
+   should be sent to <devel@openser.org>.
161
+
162
+   If you want to keep the mail private, send it to
163
+   <team@openser.org>.
164
+
165
+   3.3. How can I report a bug?
166
+
167
+   Please follow the guidelines provided at:
168
+   http://sourceforge.net/tracker/?group_id=139143.
0 169
new file mode 100644
... ...
@@ -0,0 +1,99 @@
1
+/* 
2
+ * $Id$ 
3
+ *
4
+ * MySQL module interface
5
+ *
6
+ * Copyright (C) 2001-2003 FhG Fokus
7
+ * Copyright (C) 2008 1&1 Internet AG
8
+ *
9
+ * This file is part of openser, a free SIP server.
10
+ *
11
+ * openser is free software; you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation; either version 2 of the License, or
14
+ * (at your option) any later version
15
+ *
16
+ * openser is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License 
22
+ * along with this program; if not, write to the Free Software 
23
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
+ */
25
+/*
26
+ * History:
27
+ * --------
28
+ *  2003-03-11  updated to the new module exports interface (andrei)
29
+ *  2003-03-16  flags export parameter added (janakj)
30
+ */
31
+
32
+#include "../../sr_module.h"
33
+#include "dbase.h"
34
+#include "db_mod.h"
35
+
36
+#include <mysql/mysql.h>
37
+
38
+unsigned int db_mysql_ping_interval = 5 * 60; /* Default is 5 minutes */
39
+unsigned int db_mysql_timeout_interval = 2;   /* Default is 6 seconds */
40
+unsigned int db_mysql_auto_reconnect = 1;     /* Default is enabled   */
41
+
42
+static int mysql_mod_init(void);
43
+
44
+MODULE_VERSION
45
+
46
+
47
+/*
48
+ * MySQL database module interface
49
+ */
50
+static cmd_export_t cmds[] = {
51
+	{"db_use_table",        (cmd_function)db_mysql_use_table,     2, 0, 0, 0},
52
+	{"db_init",             (cmd_function)db_mysql_init,          1, 0, 0, 0},
53
+	{"db_close",            (cmd_function)db_mysql_close,         2, 0, 0, 0},
54
+	{"db_query",            (cmd_function)db_mysql_query,         2, 0, 0, 0},
55
+	{"db_fetch_result",     (cmd_function)db_mysql_fetch_result,  2, 0, 0, 0},
56
+	{"db_raw_query",        (cmd_function)db_mysql_raw_query,     2, 0, 0, 0},
57
+	{"db_free_result",      (cmd_function)db_mysql_free_result,   2, 0, 0, 0},
58
+	{"db_insert",           (cmd_function)db_mysql_insert,        2, 0, 0, 0},
59
+	{"db_delete",           (cmd_function)db_mysql_delete,        2, 0, 0, 0},
60
+	{"db_update",           (cmd_function)db_mysql_update,        2, 0, 0, 0},
61
+	{"db_replace",          (cmd_function)db_mysql_replace,       2, 0, 0, 0},
62
+	{"db_last_inserted_id", (cmd_function)db_last_inserted_id,    1, 0, 0, 0},
63
+	{"db_insert_update",    (cmd_function)db_insert_update,       2, 0, 0, 0},
64
+	{0, 0, 0, 0, 0, 0}
65
+};
66
+
67
+
68
+/*
69
+ * Exported parameters
70
+ */
71
+static param_export_t params[] = {
72
+	{"ping_interval",    INT_PARAM, &db_mysql_ping_interval},
73
+	{"timeout_interval", INT_PARAM, &db_mysql_timeout_interval},
74
+	{"auto_reconnect",   INT_PARAM, &db_mysql_auto_reconnect},
75
+	{0, 0, 0}
76
+};
77
+
78
+
79
+struct module_exports exports = {	
80
+	"mysql",
81
+	DEFAULT_DLFLAGS, /* dlopen flags */
82
+	cmds,
83
+	params,          /*  module parameters */
84
+	0,               /* exported statistics */
85
+	0,               /* exported MI functions */
86
+	0,               /* exported pseudo-variables */
87
+	0,               /* extra processes */
88
+	mysql_mod_init,  /* module initialization function */
89
+	0,               /* response function*/
90
+	0,               /* destroy function */
91
+	0                /* per-child init function */
92
+};
93
+
94
+
95
+static int mysql_mod_init(void)
96
+{
97
+	LM_DBG("mysql: MySQL client version is %s\n", mysql_get_client_info());
98
+	return 0;
99
+}
0 100
new file mode 100644
... ...
@@ -0,0 +1,38 @@
1
+/* 
2
+ * $Id$ 
3
+ *
4
+ * MySQL module interface
5
+ *
6
+ * Copyright (C) 2001-2003 FhG Fokus
7
+ * Copyright (C) 2008 1&1 Internet AG
8
+ *
9
+ * This file is part of openser, a free SIP server.
10
+ *
11
+ * openser is free software; you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation; either version 2 of the License, or
14
+ * (at your option) any later version
15
+ *
16
+ * openser is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License 
22
+ * along with this program; if not, write to the Free Software 
23
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
+ *
25
+ * History:
26
+ * --------
27
+ *  2003-03-11  updated to the new module exports interface (andrei)
28
+ *  2003-03-16  flags export parameter added (janakj)
29
+ */
30
+
31
+#ifndef DB_MOD_H
32
+#define DB_MOD_H
33
+
34
+extern unsigned int db_mysql_ping_interval;
35
+extern unsigned int db_mysql_timeout_interval;
36
+extern unsigned int db_mysql_auto_reconnect;
37
+
38
+#endif /* DB_MOD_H */
0 39
new file mode 100644
... ...
@@ -0,0 +1,489 @@
1
+/* 
2
+ * $Id$ 
3
+ *
4
+ * MySQL module core functions
5
+ *
6
+ * Copyright (C) 2001-2003 FhG Fokus
7
+ * Copyright (C) 2007-2008 1&1 Internet AG
8
+ *
9
+ * This file is part of openser, a free SIP server.
10
+ *
11
+ * openser is free software; you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation; either version 2 of the License, or
14
+ * (at your option) any later version
15
+ *
16
+ * openser is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License 
22
+ * along with this program; if not, write to the Free Software 
23
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
+ */
25
+
26
+/**
27
+ * \class mysql/dbase.c
28
+ * \brief Implementation of core functions for the MySQL driver.
29
+ *
30
+ * This file contains the implementation of core functions for the MySQL
31
+ * database driver, for example to submit a query or fetch a result.
32
+ */
33
+
34
+#include <stdio.h>
35
+#include <string.h>
36
+#include <mysql/mysql.h>
37
+#include <mysql/errmsg.h>
38
+#include <mysql/mysql_version.h>
39
+#include "../../mem/mem.h"
40
+#include "../../dprint.h"
41
+#include "../../db/db_query.h"
42
+#include "../../db/db_ut.h"
43
+#include "val.h"
44
+#include "my_con.h"
45
+#include "res.h"
46
+#include "row.h"
47
+#include "db_mod.h"
48
+#include "dbase.h"
49
+
50
+
51
+/**
52
+ * \brief Send a SQL query to the server.
53
+ *
54
+ * Send a SQL query to the database server. This methods tries to reconnect
55
+ * to the server if the connection is gone and the auto_reconnect parameter is
56
+ * enabled. It also issues a mysql_ping before the query to connect again after
57
+ * a long waiting period because for some older mysql versions the auto reconnect
58
+ * don't work sufficient. If auto_reconnect is enabled and the server supports it,
59
+ * then the mysql_ping is probably not necessary, but its safer to do it in this
60
+ * cases too.
61
+ *
62
+ * \param _h handle for the db
63
+ * \param _s executed query
64
+ * \return zero on success, negative value on failure
65
+ */
66
+static int db_mysql_submit_query(const db_con_t* _h, const str* _s)
67
+{	
68
+	time_t t;
69
+	int i, code;
70
+
71
+	if (!_h || !_s || !_s->s) {
72
+		LM_ERR("invalid parameter value\n");
73
+		return -1;
74
+	}
75
+
76
+	if (db_mysql_ping_interval) {
77
+		t = time(0);
78
+		if ((t - CON_TIMESTAMP(_h)) > db_mysql_ping_interval) {
79
+			if (mysql_ping(CON_CONNECTION(_h))) {
80
+				LM_WARN("driver error on ping: %s\n", mysql_error(CON_CONNECTION(_h)));
81
+			}
82
+		}
83
+		/*
84
+		 * We're doing later a query anyway that will reset the timout of the server,
85
+		 * so it makes sense to set the timestamp value to the actual time in order
86
+		 * to prevent unnecessary pings.
87
+		 */
88
+		CON_TIMESTAMP(_h) = t;
89
+	}
90
+
91
+	/* screws up the terminal when the query contains a BLOB :-( (by bogdan)
92
+	 * LM_DBG("submit_query(): %.*s\n", _s->len, _s->s);
93
+	 */
94
+
95
+	/* When a server connection is lost and a query is attempted, most of
96
+	 * the time the query will return a CR_SERVER_LOST, then at the second
97
+	 * attempt to execute it, the mysql lib will reconnect and succeed.
98
+	 * However is a few cases, the first attempt returns CR_SERVER_GONE_ERROR
99
+	 * the second CR_SERVER_LOST and only the third succeeds.
100
+	 * Thus the 3 in the loop count. Increasing the loop count over this
101
+	 * value shouldn't be needed, but it doesn't hurt either, since the loop
102
+	 * will most of the time stop at the second or sometimes at the third
103
+	 * iteration.
104
+	 */
105
+	for (i=0; i < (db_mysql_auto_reconnect ? 3 : 1); i++) {
106
+		if (mysql_real_query(CON_CONNECTION(_h), _s->s, _s->len) == 0) {
107
+			return 0;
108
+		}
109
+		code = mysql_errno(CON_CONNECTION(_h));
110
+		if (code != CR_SERVER_GONE_ERROR && code != CR_SERVER_LOST) {
111
+			break;
112
+		}
113
+	}
114
+	LM_ERR("driver error on query: %s\n", mysql_error(CON_CONNECTION(_h)));
115
+	return -2;
116
+}
117
+
118
+
119
+
120
+/*
121
+ * Initialize database module
122
+ * No function should be called before this
123
+ */
124
+db_con_t* db_mysql_init(const str* _url)
125
+{
126
+	return db_do_init(_url, (void *)db_mysql_new_connection);
127
+}
128
+
129
+
130
+/*
131
+ * Shut down database module
132
+ * No function should be called after this
133
+ */
134
+void db_mysql_close(db_con_t* _h)
135
+{
136
+	db_do_close(_h, db_mysql_free_connection);
137
+}
138
+
139
+
140
+/*
141
+ * Retrieve result set
142
+ */
143
+static int db_mysql_store_result(const db_con_t* _h, db_res_t** _r)
144
+{
145
+	if ((!_h) || (!_r)) {
146
+		LM_ERR("invalid parameter value\n");
147
+		return -1;
148
+	}
149
+
150
+	*_r = db_new_result();
151
+	if (*_r == 0) {
152
+		LM_ERR("no memory left\n");
153
+		return -2;
154
+	}
155
+
156
+	CON_RESULT(_h) = mysql_store_result(CON_CONNECTION(_h));
157
+	if (!CON_RESULT(_h)) {
158
+		if (mysql_field_count(CON_CONNECTION(_h)) == 0) {
159
+			(*_r)->col.n = 0;
160
+			(*_r)->n = 0;
161
+			goto done;
162
+		} else {
163
+			LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h)));
164
+			db_free_result(*_r);
165
+			*_r = 0;
166
+			return -3;
167
+		}
168
+	}
169
+
170
+	if (db_mysql_convert_result(_h, *_r) < 0) {
171
+		LM_ERR("error while converting result\n");
172
+		pkg_free(*_r);
173
+		*_r = 0;
174
+		/* all mem on openser API side is already freed by
175
+		 * db_mysql_convert_result in case of error, but we also need
176
+		 * to free the mem from the mysql lib side */
177
+		mysql_free_result(CON_RESULT(_h));
178
+#if (MYSQL_VERSION_ID >= 40100)
179
+		while( mysql_next_result( CON_CONNECTION(_h) ) > 0 ) {
180
+			MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
181
+			mysql_free_result(res);
182
+		}
183
+#endif
184
+		CON_RESULT(_h) = 0;
185
+		return -4;
186
+	}
187
+
188
+done:
189
+#if (MYSQL_VERSION_ID >= 40100)
190
+	while( mysql_next_result( CON_CONNECTION(_h) ) > 0 ) {
191
+		MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
192
+		mysql_free_result(res);
193
+	}
194
+#endif
195
+
196
+	return 0;
197
+}
198
+
199
+
200
+/*
201
+ * Release a result set from memory
202
+ */
203
+int db_mysql_free_result(db_con_t* _h, db_res_t* _r)
204
+{
205
+     if ((!_h) || (!_r)) {
206
+	     LM_ERR("invalid parameter value\n");
207
+	     return -1;
208
+     }
209
+
210
+     if (db_free_result(_r) < 0) {
211
+	     LM_ERR("unable to free result structure\n");
212
+	     return -1;
213
+     }
214
+     mysql_free_result(CON_RESULT(_h));
215
+     CON_RESULT(_h) = 0;
216
+     return 0;
217
+}
218
+
219
+
220
+/*
221
+ * Query table for specified rows
222
+ * _h: structure representing database connection
223
+ * _k: key names
224
+ * _op: operators
225
+ * _v: values of the keys that must match
226
+ * _c: column names to return
227
+ * _n: number of key=values pairs to compare
228
+ * _nc: number of columns to return
229
+ * _o: order by the specified column
230
+ */
231
+int db_mysql_query(const db_con_t* _h, const db_key_t* _k, const db_op_t* _op,
232
+	     const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
233
+	     const db_key_t _o, db_res_t** _r)
234
+{
235
+	return db_do_query(_h, _k, _op, _v, _c, _n, _nc, _o, _r,
236
+	db_mysql_val2str, db_mysql_submit_query, db_mysql_store_result);
237
+}
238
+
239
+/*
240
+ * gets a partial result set
241
+ * _h: structure representing the database connection
242
+ * _r: pointer to a structure representing the result
243
+ * nrows: number of fetched rows
244
+ */
245
+int db_mysql_fetch_result(const db_con_t* _h, db_res_t** _r, const int nrows)
246
+{
247
+	int n;
248
+	int i;
249
+
250
+	if (!_h || !_r || nrows < 0) {
251
+		LM_ERR("Invalid parameter value\n");
252
+		return -1;
253
+	}
254
+
255
+	/* exit if the fetch count is zero */
256
+	if (nrows == 0) {
257
+		db_free_result(*_r);
258
+		*_r = 0;
259
+		return 0;
260
+	}
261
+
262
+	if(*_r==0) {
263
+		/* Allocate a new result structure */
264
+		*_r = db_new_result();
265
+		if (*_r == 0) {
266
+			LM_ERR("no memory left\n");
267
+			return -2;
268
+		}
269
+
270
+		CON_RESULT(_h) = mysql_store_result(CON_CONNECTION(_h));
271
+		if (!CON_RESULT(_h)) {
272
+			if (mysql_field_count(CON_CONNECTION(_h)) == 0) {
273
+				(*_r)->col.n = 0;
274
+				(*_r)->n = 0;
275
+				return 0;
276
+			} else {
277
+				LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h)));
278
+				db_free_result(*_r);
279
+				*_r = 0;
280
+				return -3;
281
+			}
282
+		}
283
+		if (db_mysql_get_columns(_h, *_r) < 0) {
284
+			LM_ERR("error while getting column names\n");
285
+			return -4;
286
+		}
287
+
288
+		RES_NUM_ROWS(*_r) = mysql_num_rows(CON_RESULT(_h));
289
+		if (!RES_NUM_ROWS(*_r)) {
290
+			RES_ROWS(*_r) = 0;
291
+			return 0;
292
+		}
293
+	} else {
294
+		/* free old rows */
295
+		if(RES_ROWS(*_r)!=0)
296
+			db_free_rows(*_r);
297
+		RES_ROWS(*_r) = 0;
298
+		RES_ROW_N(*_r) = 0;
299
+	}
300
+
301
+	/* determine the number of rows remaining to be processed */
302
+	n = RES_NUM_ROWS(*_r) - RES_LAST_ROW(*_r);
303
+
304
+	/* If there aren't any more rows left to process, exit */
305
+	if(n<=0)
306
+		return 0;
307
+
308
+	/* if the fetch count is less than the remaining rows to process                 */
309
+	/* set the number of rows to process (during this call) equal to the fetch count */
310
+	if(nrows < n)
311
+		n = nrows;
312
+
313
+	RES_LAST_ROW(*_r) += n;
314
+	RES_ROW_N(*_r) = n;
315
+
316
+	RES_ROWS(*_r) = (struct db_row*)pkg_malloc(sizeof(db_row_t) * n);
317
+	if (!RES_ROWS(*_r)) {
318
+		LM_ERR("no memory left\n");
319
+		return -5;
320
+	}
321
+
322
+	for(i = 0; i < n; i++) {
323
+		CON_ROW(_h) = mysql_fetch_row(CON_RESULT(_h));
324
+		if (!CON_ROW(_h)) {
325
+			LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h)));
326
+			RES_ROW_N(*_r) = i;
327
+			db_free_rows(*_r);
328
+			return -6;
329
+		}
330
+		if (db_mysql_convert_row(_h, *_r, &(RES_ROWS(*_r)[i])) < 0) {
331
+			LM_ERR("error while converting row #%d\n", i);
332
+			RES_ROW_N(*_r) = i;
333
+			db_free_rows(*_r);
334
+			return -7;
335
+		}
336
+	}
337
+	return 0;
338
+}
339
+
340
+/*
341
+ * Execute a raw SQL query
342
+ */
343
+int db_mysql_raw_query(const db_con_t* _h, const str* _s, db_res_t** _r)
344
+{
345
+	return db_do_raw_query(_h, _s, _r, db_mysql_submit_query,
346
+	db_mysql_store_result);
347
+}
348
+
349
+
350
+/*
351
+ * Insert a row into specified table
352
+ * _h: structure representing database connection
353
+ * _k: key names
354
+ * _v: values of the keys
355
+ * _n: number of key=value pairs
356
+ */
357
+int db_mysql_insert(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n)
358
+{
359
+	return db_do_insert(_h, _k, _v, _n, db_mysql_val2str,
360
+	db_mysql_submit_query);
361
+}
362
+
363
+
364
+/*
365
+ * Delete a row from the specified table
366
+ * _h: structure representing database connection
367
+ * _k: key names
368
+ * _o: operators
369
+ * _v: values of the keys that must match
370
+ * _n: number of key=value pairs
371
+ */
372
+int db_mysql_delete(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
373
+	const db_val_t* _v, const int _n)
374
+{
375
+	return db_do_delete(_h, _k, _o, _v, _n, db_mysql_val2str,
376
+	db_mysql_submit_query);
377
+}
378
+
379
+
380
+/*
381
+ * Update some rows in the specified table
382
+ * _h: structure representing database connection
383
+ * _k: key names
384
+ * _o: operators
385
+ * _v: values of the keys that must match
386
+ * _uk: updated columns
387
+ * _uv: updated values of the columns
388
+ * _n: number of key=value pairs
389
+ * _un: number of columns to update
390
+ */
391
+int db_mysql_update(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o, 
392
+	const db_val_t* _v, const db_key_t* _uk, const db_val_t* _uv, const int _n, 
393
+	const int _un)
394
+{
395
+	return db_do_update(_h, _k, _o, _v, _uk, _uv, _n, _un, db_mysql_val2str,
396
+	db_mysql_submit_query);
397
+}
398
+
399
+
400
+/*
401
+ * Just like insert, but replace the row if it exists
402
+ */
403
+int db_mysql_replace(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n)
404
+{
405
+	return db_do_replace(_h, _k, _v, _n, db_mysql_val2str,
406
+	db_mysql_submit_query);
407
+}
408
+
409
+
410
+/*
411
+ * Returns the last inserted ID
412
+ */
413
+int db_last_inserted_id(const db_con_t* _h)
414
+{
415
+	if (!_h) {
416
+		LM_ERR("invalid parameter value\n");
417
+		return -1;
418
+	}
419
+	return mysql_insert_id(CON_CONNECTION(_h));
420
+}
421
+
422
+ 
423
+ /*
424
+  * Insert a row into specified table, update on duplicate key
425
+  * _h: structure representing database connection
426
+  * _k: key names
427
+  * _v: values of the keys
428
+  * _n: number of key=value pairs
429
+ */
430
+ int db_insert_update(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
431
+	const int _n)
432
+ {
433
+	int off, ret;
434
+	static str  sql_str;
435
+	static char sql_buf[SQL_BUF_LEN];
436
+ 
437
+	if ((!_h) || (!_k) || (!_v) || (!_n)) {
438
+		LM_ERR("invalid parameter value\n");
439
+		return -1;
440
+	}
441
+ 
442
+	ret = snprintf(sql_buf, SQL_BUF_LEN, "insert into %.*s (", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
443
+	if (ret < 0 || ret >= SQL_BUF_LEN) goto error;
444
+	off = ret;
445
+
446
+	ret = db_print_columns(sql_buf + off, SQL_BUF_LEN - off, _k, _n);
447
+	if (ret < 0) return -1;
448
+	off += ret;
449
+
450
+	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, ") values (");
451
+	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
452
+	off += ret;
453
+	ret = db_print_values(_h, sql_buf + off, SQL_BUF_LEN - off, _v, _n, db_mysql_val2str);
454
+	if (ret < 0) return -1;
455
+	off += ret;
456
+
457
+	*(sql_buf + off++) = ')';
458
+	
459
+	ret = snprintf(sql_buf + off, SQL_BUF_LEN - off, " on duplicate key update ");
460
+	if (ret < 0 || ret >= (SQL_BUF_LEN - off)) goto error;
461
+	off += ret;
462
+	
463
+	ret = db_print_set(_h, sql_buf + off, SQL_BUF_LEN - off, _k, _v, _n, db_mysql_val2str);
464
+	if (ret < 0) return -1;
465
+	off += ret;
466
+	
467
+	sql_str.s = sql_buf;
468
+	sql_str.len = off;
469
+ 
470
+	if (db_mysql_submit_query(_h, &sql_str) < 0) {
471
+		LM_ERR("error while submitting query\n");
472
+		return -2;
473
+	}
474
+	return 0;
475
+
476
+error:
477
+	LM_ERR("error while preparing insert_update operation\n");
478
+	return -1;
479
+}
480
+
481
+
482
+/*
483
+ * Store name of table that will be used by
484
+ * subsequent database functions
485
+ */
486
+int db_mysql_use_table(db_con_t* _h, const str* _t)
487
+{
488
+	return db_use_table(_h, _t);
489
+}
0 490
new file mode 100644
... ...
@@ -0,0 +1,121 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * MySQL module core functions
5
+ *
6
+ * Copyright (C) 2001-2003 FhG Fokus
7
+ * Copyright (C) 2008 1&1 Internet AG
8
+ *
9
+ * This file is part of openser, a free SIP server.
10
+ *
11
+ * openser is free software; you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation; either version 2 of the License, or
14
+ * (at your option) any later version
15
+ *
16
+ * openser is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License 
22
+ * along with this program; if not, write to the Free Software 
23
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
+ */
25
+
26
+
27
+#ifndef DBASE_H
28
+#define DBASE_H
29
+
30
+
31
+#include "../../db/db_con.h"
32
+#include "../../db/db_res.h"
33
+#include "../../db/db_key.h"
34
+#include "../../db/db_op.h"
35
+#include "../../db/db_val.h"
36
+#include "../../str.h"
37
+
38
+/*
39
+ * Initialize database connection
40
+ */
41
+db_con_t* db_mysql_init(const str* _sqlurl);
42
+
43
+
44
+/*
45
+ * Close a database connection
46
+ */
47
+void db_mysql_close(db_con_t* _h);
48
+
49
+
50
+/*
51
+ * Free all memory allocated by get_result
52
+ */
53
+int db_mysql_free_result(db_con_t* _h, db_res_t* _r);
54
+
55
+
56
+/*
57
+ * Do a query
58
+ */
59
+int db_mysql_query(const db_con_t* _h, const db_key_t* _k, const db_op_t* _op,
60
+	     const db_val_t* _v, const db_key_t* _c, const int _n, const int _nc,
61
+	     const db_key_t _o, db_res_t** _r);
62
+
63
+
64
+/*
65
+ * fetch rows from a result
66
+ */
67
+int db_mysql_fetch_result(const db_con_t* _h, db_res_t** _r, const int nrows);
68
+
69
+
70
+/*
71
+ * Raw SQL query
72
+ */
73
+int db_mysql_raw_query(const db_con_t* _h, const str* _s, db_res_t** _r);
74
+
75
+
76
+/*
77
+ * Insert a row into table
78
+ */
79
+int db_mysql_insert(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n);
80
+
81
+
82
+/*
83
+ * Delete a row from table
84
+ */
85
+int db_mysql_delete(const db_con_t* _h, const db_key_t* _k, const 
86
+	db_op_t* _o, const db_val_t* _v, const int _n);
87
+
88
+
89
+/*
90
+ * Update a row in table
91
+ */
92
+int db_mysql_update(const db_con_t* _h, const db_key_t* _k, const db_op_t* _o,
93
+	const db_val_t* _v, const db_key_t* _uk, const db_val_t* _uv, const int _n,
94
+	const int _un);
95
+
96
+
97
+/*
98
+ * Just like insert, but replace the row if it exists
99
+ */
100
+int db_mysql_replace(const db_con_t* handle, const db_key_t* keys, const db_val_t* 	vals, const int n);
101
+
102
+/*
103
+ * Returns the last inserted ID
104
+ */
105
+int db_last_inserted_id(const db_con_t* _h);
106
+
107
+/*
108
+ * Insert a row into table, update on duplicate key
109
+ */
110
+int db_insert_update(const db_con_t* _h, const db_key_t* _k, const db_val_t* _v,
111
+	const int _n);
112
+
113
+
114
+/*
115
+ * Store name of table that will be used by
116
+ * subsequent database functions
117
+ */
118
+int db_mysql_use_table(db_con_t* _h, const str* _t);
119
+
120
+
121
+#endif /* DBASE_H */
0 122
new file mode 100644
... ...
@@ -0,0 +1,55 @@
1
+<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
2
+
3
+
4
+<!ENTITY user SYSTEM "mysql_user.sgml">
5
+<!ENTITY devel SYSTEM "mysql_devel.sgml">
6
+<!ENTITY faq SYSTEM "mysql_faq.sgml">
7
+
8
+<!-- Include general documentation entities -->
9
+<!ENTITY % docentities SYSTEM "../../../doc/entities.sgml">
10
+%docentities;
11
+
12
+]>
13
+
14
+<book>
15
+    <bookinfo>
16
+	<title>mysql Module</title>
17
+	<productname class="trade">&sername;</productname>
18
+	<authorgroup>
19
+	    <author>
20
+		<firstname>Daniel-Constantin</firstname>
21
+		<surname>Mierla</surname>
22
+		<affiliation><orgname>&voicesystem;</orgname></affiliation>
23
+		<address>
24
+		<email>daniel@voice-system.ro</email>
25
+		<otheraddr>
26
+		<ulink url="http://www.voice-system.ro">http://www.voice-system.ro</ulink>
27
+		</otheraddr>
28
+		</address>
29
+	    </author>
30
+	    <editor>
31
+		<firstname>Daniel-Constantin</firstname>
32
+		<surname>Mierla</surname>
33
+		<address>
34
+		    <email>danile@voice-system.ro</email>
35
+		</address>
36
+	    </editor>
37
+	</authorgroup>
38
+	<copyright>
39
+	    <year>2006</year>
40
+	    <holder>&voicesystem;</holder>
41
+	</copyright>
42
+	<revhistory>
43
+	    <revision>
44
+		<revnumber>$Revision$</revnumber>
45
+		<date>$Date$</date>
46
+	    </revision>
47
+	</revhistory>
48
+    </bookinfo>
49
+    <toc></toc>
50
+    
51
+    &user;
52
+    &devel;
53
+    &faq;
54
+    
55
+</book>
0 56
new file mode 100644
... ...
@@ -0,0 +1,22 @@
1
+<!-- Module Developer's Guide -->
2
+
3
+<chapter>
4
+    <chapterinfo>
5
+	<revhistory>
6
+	    <revision>
7
+		<revnumber>$Revision$</revnumber>
8
+		<date>$Date$</date>
9
+	    </revision>
10
+	</revhistory>
11
+    </chapterinfo>
12
+    <title>Developer's Guide</title>
13
+    <para>
14
+	The module does not provide any <acronym>API</acronym> to use in other &ser; modules.
15
+    </para>
16
+</chapter>
17
+
18
+<!-- Keep this element at the end of the file
19
+Local Variables:
20
+sgml-parent-document: ("mysql.sgml" "book" "chapter")
21
+End:
22
+-->
0 23
new file mode 100644
... ...
@@ -0,0 +1,70 @@
1
+<!-- Module FAQ -->
2
+
3
+<chapter>
4
+    <chapterinfo>
5
+	<revhistory>
6
+	    <revision>
7
+		<revnumber>$Revision$</revnumber>
8
+		<date>$Date$</date>
9
+	    </revision>
10
+	</revhistory>
11
+    </chapterinfo>
12
+    <title>Frequently Asked Questions</title>
13
+    <qandaset defaultlabel="number">
14
+	<qandaentry>
15
+	    <question>
16
+		<para>Where can I find more about OpenSER?</para>
17
+	    </question>
18
+	    <answer>
19
+		<para>
20
+			Take a look at &serhomelink;.
21
+		</para>
22
+	    </answer>
23
+	</qandaentry>
24
+	<qandaentry>
25
+	    <question>
26
+		<para>Where can I post a question about this module?</para>
27
+	    </question>
28
+	    <answer>
29
+		<para>
30
+			First at all check if your question was already answered on one of
31
+			our mailing lists: 
32
+		</para>
33
+		<itemizedlist>
34
+		    <listitem>
35
+			<para>User Mailing List - &seruserslink;</para>
36
+		    </listitem>
37
+		    <listitem>
38
+			<para>Developer Mailing List - &serdevlink;</para>
39
+		    </listitem>
40
+		</itemizedlist>
41
+		<para>
42
+			E-mails regarding any stable &ser; release should be sent to 
43
+			&serusersmail; and e-mails regarding development versions
44
+			should be sent to &serdevmail;.
45
+		</para>
46
+		<para>
47
+			If you want to keep the mail private, send it to 
48
+			&serhelpmail;.
49
+		</para>
50
+	    </answer>
51
+	</qandaentry>
52
+	<qandaentry>
53
+	    <question>
54
+		<para>How can I report a bug?</para>
55
+	    </question>
56
+	    <answer>
57
+		<para>
58
+			Please follow the guidelines provided at:
59
+			&serbugslink;.
60
+		</para>
61
+	    </answer>
62
+	</qandaentry>
63
+    </qandaset>
64
+</chapter>
65
+
66
+<!-- Keep this element at the end of the file
67
+Local Variables:
68
+sgml-parent-document: ("mysql.sgml" "Book" "chapter")
69
+End:
70
+-->
0 71
new file mode 100644
1 72
Binary files /dev/null and b/modules/db_mysql/km_doc/mysql_parser.dia differ
2 73
new file mode 100644
... ...
@@ -0,0 +1,156 @@
1
+<!-- Module User's Guide -->
2
+
3
+<chapter>
4
+	<chapterinfo>
5
+	<revhistory>
6
+		<revision>
7
+		<revnumber>$Revision$</revnumber>
8
+		<date>$Date$</date>
9
+		</revision>
10
+	</revhistory>
11
+	</chapterinfo>
12
+	<title>User's Guide</title>
13
+	
14
+	<section>
15
+	<title>Overview</title>
16
+	<para>
17
+		This is a module which provides MySQL connectivity for OpenSER.
18
+		It implements the DB API defined in OpenSER.
19
+	</para>
20
+	</section>
21
+
22
+	<section>
23
+	<title>Dependencies</title>
24
+	<section>
25
+		<title>&ser; Modules</title>
26
+		<para>
27
+		The following modules must be loaded before this module:
28
+			<itemizedlist>
29
+			<listitem>
30
+			<para>
31
+				<emphasis>No dependencies on other &ser; modules</emphasis>.
32
+			</para>
33
+			</listitem>
34
+			</itemizedlist>
35
+		</para>
36
+	</section>
37
+	<section>
38
+		<title>External Libraries or Applications</title>
39
+		<para>
40
+		The following libraries or applications must be installed before running
41
+		&ser; with this module loaded:
42
+			<itemizedlist>
43
+			<listitem>
44
+			<para>
45
+				<emphasis>libmysqlclient-dev</emphasis> - the development libraries of mysql-client.
46
+			</para>
47
+			</listitem>
48
+			</itemizedlist>
49
+		</para>
50
+	</section>
51
+	</section>
52
+	<section>
53
+	<title>Exported Parameters</title>
54
+	<section>
55
+		<title><varname>ping_interval</varname> (integer)</title>
56
+		<para>
57
+		Time interval to send ping messages to MySQL server in order to keep
58
+		the connection open.
59
+		</para>
60
+		<para>
61
+		<emphasis>
62
+			Default value is 300 (5 min).
63
+		</emphasis>
64
+		</para>
65
+		<example>
66
+		<title>Set <varname>ping_interval</varname> parameter</title>
67
+		<programlisting format="linespecific">
68
+...
69
+modparam("mysql", "ping_interval", 600)
70
+...
71
+</programlisting>
72
+		</example>
73
+	</section>
74
+		<section>
75
+		<title><varname>timeout_interval</varname> (integer)</title>
76
+		<para>
77
+		Time interval after that an connection attempt, read or write request
78
+		is aborted. The value counts three times, as several retries are done
79
+		from the driver before it gives up.
80
+		</para>
81
+		<para>
82
+		The read timeout parameter is ignored on driver versions prior to
83
+		<quote>5.1.12</quote>, <quote>5.0.25</quote> and <quote>4.1.22</quote>.
84
+		The write timeout parameter is ignored on version prior to <quote>5.1.12</quote>
85
+		and <quote>5.0.25</quote>, the <quote>4.1</quote> release don't support it at all.
86
+		</para>
87
+		<para>
88
+		<emphasis>
89
+			Default value is 2 (6 sec).
90
+		</emphasis>
91
+		</para>
92
+		<example>
93
+		<title>Set <varname>timeout_interval</varname> parameter</title>
94
+		<programlisting format="linespecific">
95
+...
96
+modparam("mysql", "timeout_interval", 2)
97
+...
98
+</programlisting>
99
+		</example>
100
+	</section>
101
+	<section>
102
+		<title><varname>auto_reconnect</varname> (integer)</title>
103
+		<para>
104
+		Configure the module to auto reconnect to MySQL server if the
105
+		connection was lost.
106
+		</para>
107
+		<para>
108
+		<emphasis>
109
+			Default value is 1 (1 - on / 0 - off).
110
+		</emphasis>
111
+		</para>
112
+		<example>
113
+		<title>Set <varname>auto_reconnect</varname> parameter</title>
114
+		<programlisting format="linespecific">
115
+...
116
+modparam("auto_reconnect", "auto_reconnect", 0)
117
+...
118
+</programlisting>
119
+		</example>
120
+	</section>
121
+	</section>
122
+	<section>
123
+	<title>Exported Functions</title>
124
+		<para>
125
+		No function exported to be used from configuration file.
126
+		</para>
127
+	</section>
128
+	<section>
129
+	<title>Installation</title>
130
+		<para>
131
+		Because it dependes on an external library, the mysql module is not
132
+		compiled and installed by default. You can use one of the next options.
133
+		</para>
134
+		<itemizedlist>
135
+			<listitem>
136
+			<para>
137
+			- edit the "Makefile" and remove "mysql" from "excluded_modules"
138
+			list. Then follow the standard procedure to install &ser;:
139
+			"make all; make install".
140
+			</para>
141
+			</listitem>
142
+			<listitem>
143
+			<para>
144
+			- from command line use: 'make all include_modules="mysql";
145
+			make install include_modules="mysql"'.
146
+			</para>
147
+			</listitem>
148
+		</itemizedlist>
149
+	</section>
150
+</chapter>
151
+
152
+<!-- Keep this element at the end of the file
153
+Local Variables:
154
+sgml-parent-document: "mysql.sgml" "Book" "chapter")
155
+End:
156
+-->
0 157
new file mode 100644
... ...
@@ -0,0 +1,124 @@
1
+/* 
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2001-2004 iptel.org
5
+ * Copyright (C) 2008 1&1 Internet AG
6
+ *
7
+ * This file is part of openser, a free SIP server.
8
+ *
9
+ * openser is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * openser is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License 
20
+ * along with this program; if not, write to the Free Software 
21
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
+ */
23
+
24
+#include "my_con.h"
25
+#include "db_mod.h"
26
+#include <mysql/mysql_version.h>
27
+#include "../../mem/mem.h"
28
+#include "../../dprint.h"
29
+#include "../../ut.h"
30
+
31
+
32
+/*
33
+ * Create a new connection structure,
34
+ * open the MySQL connection and set reference count to 1
35
+ */
36
+struct my_con* db_mysql_new_connection(const struct db_id* id)
37
+{
38
+	struct my_con* ptr;
39
+
40
+	if (!id) {
41
+		LM_ERR("invalid parameter value\n");
42
+		return 0;
43
+	}
44
+
45
+	ptr = (struct my_con*)pkg_malloc(sizeof(struct my_con));
46
+	if (!ptr) {
47
+		LM_ERR("no private memory left\n");
48
+		return 0;
49
+	}
50
+
51
+	memset(ptr, 0, sizeof(struct my_con));
52
+	ptr->ref = 1;
53
+	
54
+	ptr->con = (MYSQL*)pkg_malloc(sizeof(MYSQL));
55
+	if (!ptr->con) {
56
+		LM_ERR("no private memory left\n");
57
+		goto err;
58
+	}
59
+
60
+	mysql_init(ptr->con);
61
+
62
+	if (id->port) {
63
+		LM_DBG("opening connection: mysql://xxxx:xxxx@%s:%d/%s\n", ZSW(id->host),
64
+			id->port, ZSW(id->database));
65
+	} else {
66
+		LM_DBG("opening connection: mysql://xxxx:xxxx@%s/%s\n", ZSW(id->host),
67
+			ZSW(id->database));
68
+	}
69
+
70
+	// set connect, read and write timeout, the value counts three times
71
+	mysql_options(ptr->con, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&db_mysql_timeout_interval);
72
+	mysql_options(ptr->con, MYSQL_OPT_READ_TIMEOUT, (const char *)&db_mysql_timeout_interval);
73
+	mysql_options(ptr->con, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&db_mysql_timeout_interval);
74
+
75
+#if (MYSQL_VERSION_ID >= 40100)
76
+	if (!mysql_real_connect(ptr->con, id->host, id->username, id->password,
77
+				id->database, id->port, 0, CLIENT_MULTI_STATEMENTS)) {
78
+#else
79
+	if (!mysql_real_connect(ptr->con, id->host, id->username, id->password,
80
+				id->database, id->port, 0, 0)) {
81
+#endif
82
+		LM_ERR("driver error: %s\n", mysql_error(ptr->con));
83
+		mysql_close(ptr->con);
84
+		goto err;
85
+	}
86
+	/* force reconnection if enabled */
87
+	if (db_mysql_auto_reconnect)
88
+		ptr->con->reconnect = 1;
89
+	else 
90
+		ptr->con->reconnect = 0;
91
+
92
+	LM_DBG("connection type is %s\n", mysql_get_host_info(ptr->con));
93
+	LM_DBG("protocol version is %d\n", mysql_get_proto_info(ptr->con));
94
+	LM_DBG("server version is %s\n", mysql_get_server_info(ptr->con));
95
+
96
+	ptr->timestamp = time(0);
97
+	ptr->id = (struct db_id*)id;
98
+	return ptr;
99
+
100
+ err:
101
+	if (ptr && ptr->con) pkg_free(ptr->con);
102
+	if (ptr) pkg_free(ptr);
103
+	return 0;
104
+}
105
+
106
+
107
+/*
108
+ * Close the connection and release memory
109
+ */
110
+void db_mysql_free_connection(struct pool_con* con)
111
+{
112
+	if (!con) return;
113
+
114
+	struct my_con * _c;
115
+	_c = (struct my_con*) con;
116
+
117
+	if (_c->res) mysql_free_result(_c->res);
118
+	if (_c->id) free_db_id(_c->id);
119
+	if (_c->con) {
120
+		mysql_close(_c->con);
121
+		pkg_free(_c->con);
122
+	}
123
+	pkg_free(_c);
124
+}
0 125
new file mode 100644
... ...
@@ -0,0 +1,67 @@
1
+/* 
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2001-2003