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