2 * Bacula Catalog Database routines specific to MySQL
3 * These are MySQL specific routines -- hopefully all
4 * other files are generic.
6 * Kern Sibbald, March 2000
11 Copyright (C) 2000-2006 Kern Sibbald
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License
15 version 2 as amended with additional clauses defined in the
16 file LICENSE in the main source directory.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 the file LICENSE for additional details.
26 /* The following is necessary so that we do not include
27 * the dummy external definition of DB.
29 #define __SQL_C /* indicate that this is sql.c */
36 /* -----------------------------------------------------------------------
38 * MySQL dependent defines and subroutines
40 * -----------------------------------------------------------------------
43 /* List of open databases */
44 static BQUEUE db_list = {&db_list, &db_list};
46 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
49 * Initialize database data structure. In principal this should
50 * never have errors, or it is really fatal.
53 db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password,
54 const char *db_address, int db_port, const char *db_socket,
55 int mult_db_connections)
60 Jmsg(jcr, M_FATAL, 0, _("A user name for MySQL must be supplied.\n"));
63 P(mutex); /* lock DB queue */
64 /* Look to see if DB already open */
65 if (!mult_db_connections) {
66 for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
67 if (strcmp(mdb->db_name, db_name) == 0) {
68 Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name);
71 return mdb; /* already open */
75 Dmsg0(100, "db_open first time\n");
76 mdb = (B_DB *) malloc(sizeof(B_DB));
77 memset(mdb, 0, sizeof(B_DB));
78 mdb->db_name = bstrdup(db_name);
79 mdb->db_user = bstrdup(db_user);
81 mdb->db_password = bstrdup(db_password);
84 mdb->db_address = bstrdup(db_address);
87 mdb->db_socket = bstrdup(db_socket);
89 mdb->db_port = db_port;
90 mdb->have_insert_id = TRUE;
91 mdb->errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */
93 mdb->cmd = get_pool_memory(PM_EMSG); /* get command buffer */
94 mdb->cached_path = get_pool_memory(PM_FNAME);
95 mdb->cached_path_id = 0;
97 mdb->fname = get_pool_memory(PM_FNAME);
98 mdb->path = get_pool_memory(PM_FNAME);
99 mdb->esc_name = get_pool_memory(PM_FNAME);
100 qinsert(&db_list, &mdb->bq); /* put db in list */
106 * Now actually open the database. This can generate errors,
107 * which are returned in the errmsg
109 * DO NOT close the database or free(mdb) here !!!!
112 db_open_database(JCR *jcr, B_DB *mdb)
117 if (mdb->connected) {
121 mdb->connected = FALSE;
123 if ((errstat=rwl_init(&mdb->lock)) != 0) {
124 Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
130 /* connect to the database */
131 #ifdef HAVE_EMBEDDED_MYSQL
132 mysql_server_init(0, NULL, NULL);
134 mysql_init(&(mdb->mysql));
135 mdb->mysql.reconnect = 1; /* so connection does not timeout */
136 Dmsg0(50, "mysql_init done\n");
137 /* If connection fails, try at 5 sec intervals for 30 seconds. */
138 for (int retry=0; retry < 6; retry++) {
139 mdb->db = mysql_real_connect(
140 &(mdb->mysql), /* db */
141 mdb->db_address, /* default = localhost */
142 mdb->db_user, /* login name */
143 mdb->db_password, /* password */
144 mdb->db_name, /* database name */
145 mdb->db_port, /* default port */
146 mdb->db_socket, /* default = socket */
147 CLIENT_FOUND_ROWS); /* flags */
149 /* If no connect, try once more in case it is a timing problem */
150 if (mdb->db != NULL) {
156 Dmsg0(50, "mysql_real_connect done\n");
157 Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", mdb->db_user, mdb->db_name,
158 mdb->db_password==NULL?"(NULL)":mdb->db_password);
160 if (mdb->db == NULL) {
161 Mmsg2(&mdb->errmsg, _("Unable to connect to MySQL server. \n"
162 "Database=%s User=%s\n"
163 "It is probably not running or your password is incorrect.\n"),
164 mdb->db_name, mdb->db_user);
169 if (!check_tables_version(jcr, mdb)) {
174 #ifdef HAVE_THREAD_SAFE_MYSQL
178 mdb->connected = TRUE;
184 db_close_database(JCR *jcr, B_DB *mdb)
189 db_end_transaction(jcr, mdb);
192 #ifdef HAVE_TREAD_SAFE_MYSQL
195 if (mdb->ref_count == 0) {
197 if (mdb->connected && mdb->db) {
199 #ifdef HAVE_EMBEDDED_MYSQL
203 rwl_destroy(&mdb->lock);
204 free_pool_memory(mdb->errmsg);
205 free_pool_memory(mdb->cmd);
206 free_pool_memory(mdb->cached_path);
207 free_pool_memory(mdb->fname);
208 free_pool_memory(mdb->path);
209 free_pool_memory(mdb->esc_name);
216 if (mdb->db_password) {
217 free(mdb->db_password);
219 if (mdb->db_address) {
220 free(mdb->db_address);
222 if (mdb->db_socket) {
223 free(mdb->db_socket);
231 * Return the next unique index (auto-increment) for
232 * the given table. Return NULL on error.
234 * For MySQL, NULL causes the auto-increment value
237 int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
239 strcpy(index, "NULL");
245 * Escape strings so that MySQL is happy
247 * NOTE! len is the length of the old string. Your new
248 * string must be long enough (max 2*old+1) to hold
249 * the escaped output.
252 db_escape_string(char *snew, char *old, int len)
254 mysql_escape_string(snew, old, len);
258 /* Should use mysql_real_escape_string ! */
259 unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length);
311 * Submit a general SQL command (cmd), and for each row returned,
312 * the sqlite_handler is called with the ctx.
314 int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx)
320 if (sql_query(mdb, query) != 0) {
321 Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb));
325 if (result_handler != NULL) {
326 if ((mdb->result = sql_use_result(mdb)) != NULL) {
329 /* We *must* fetch all rows */
330 while ((row = sql_fetch_row(mdb)) != NULL) {
332 /* the result handler returns 1 when it has
333 * seen all the data it wants. However, we
334 * loop to the end of the data.
337 if (result_handler(ctx, num_fields, row)) {
343 sql_free_result(mdb);
351 #endif /* HAVE_MYSQL */