git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@3638 689a6050-402a-0410-94f2-e92a70836424
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 |
+--> |
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 |
+} |