]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sqlite.c
ac6b2e62e2cc9e1d605262e452d47cdfbb06832a
[bacula/bacula] / bacula / src / cats / sqlite.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation plus additions
11    that are listed in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    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., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Bacula Catalog Database routines specific to SQLite
30  *
31  *    Kern Sibbald, January 2002
32  *
33  *    Version $Id$
34  */
35
36
37
38 /* The following is necessary so that we do not include
39  * the dummy external definition of DB.
40  */
41 #define __SQL_C                       /* indicate that this is sql.c */
42
43 #include "bacula.h"
44 #include "cats.h"
45
46 #if    HAVE_SQLITE || HAVE_SQLITE3
47
48 /* -----------------------------------------------------------------------
49  *
50  *    SQLite dependent defines and subroutines
51  *
52  * -----------------------------------------------------------------------
53  */
54
55 /* List of open databases */
56 static BQUEUE db_list = {&db_list, &db_list};
57
58 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
59
60 int QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
61
62
63 /*
64  * Retrieve database type
65  */
66 const char *
67 db_get_type(void)
68 {
69    return "SQLite";
70 }
71
72 /*
73  * When using mult_db_connections = 1, 
74  * sqlite can be BUSY. We just need sleep a little in this case.
75  */
76
77 #ifdef HAVE_SQLITE3
78 static int my_busy_handler(void *arg, int calls)
79 {
80    bmicrosleep(0, 500);
81    return 1;
82 }
83 #else
84 static int my_busy_handler(void *arg, const char* p, int calls)
85 {
86    bmicrosleep(0, 500);
87    return 1;
88 }
89 #endif
90
91
92 /*
93  * Initialize database data structure. In principal this should
94  * never have errors, or it is really fatal.
95  */
96 B_DB *
97 db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password,
98                  const char *db_address, int db_port, const char *db_socket,
99                  int mult_db_connections)
100 {
101    B_DB *mdb;
102
103    P(mutex);                          /* lock DB queue */
104    /* Look to see if DB already open */
105    if (!mult_db_connections) {
106       for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
107          if (bstrcmp(mdb->db_name, db_name) &&
108              bstrcmp(mdb->db_address, db_address) &&
109              mdb->db_port == db_port) {
110             Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
111             mdb->ref_count++;
112             V(mutex);
113             return mdb;                  /* already open */
114          }
115       }
116    }
117    Dmsg0(300, "db_open first time\n");
118    mdb = (B_DB *) malloc(sizeof(B_DB));
119    memset(mdb, 0, sizeof(B_DB));
120    mdb->db_name = bstrdup(db_name);
121    mdb->have_insert_id = TRUE;
122    mdb->errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */
123    *mdb->errmsg = 0;
124    mdb->cmd = get_pool_memory(PM_EMSG);    /* get command buffer */
125    mdb->cached_path = get_pool_memory(PM_FNAME);
126    mdb->cached_path_id = 0;
127    mdb->ref_count = 1;
128    mdb->fname = get_pool_memory(PM_FNAME);
129    mdb->path = get_pool_memory(PM_FNAME);
130    mdb->esc_name = get_pool_memory(PM_FNAME);
131    mdb->esc_path = get_pool_memory(PM_FNAME);
132    mdb->allow_transactions = mult_db_connections;
133    qinsert(&db_list, &mdb->bq);            /* put db in list */
134    V(mutex);
135    return mdb;
136 }
137
138 /*
139  * Now actually open the database.  This can generate errors,
140  * which are returned in the errmsg
141  *
142  * DO NOT close the database or free(mdb) here !!!!
143  */
144 int
145 db_open_database(JCR *jcr, B_DB *mdb)
146 {
147    char *db_name;
148    int len;
149    struct stat statbuf;
150    int errstat;
151
152    P(mutex);
153    if (mdb->connected) {
154       V(mutex);
155       return 1;
156    }
157    mdb->connected = FALSE;
158
159    if ((errstat=rwl_init(&mdb->lock)) != 0) {
160       Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
161             strerror(errstat));
162       V(mutex);
163       return 0;
164    }
165
166    /* open the database */
167    len = strlen(working_directory) + strlen(mdb->db_name) + 5;
168    db_name = (char *)malloc(len);
169    strcpy(db_name, working_directory);
170    strcat(db_name, "/");
171    strcat(db_name, mdb->db_name);
172    strcat(db_name, ".db");
173    if (stat(db_name, &statbuf) != 0) {
174       Mmsg1(&mdb->errmsg, _("Database %s does not exist, please create it.\n"),
175          db_name);
176       free(db_name);
177       V(mutex);
178       return 0;
179    }
180
181 #ifdef HAVE_SQLITE3
182    int stat = sqlite3_open(db_name, &mdb->db);
183    if (stat != SQLITE_OK) {
184       mdb->sqlite_errmsg = (char *)sqlite3_errmsg(mdb->db); 
185       sqlite3_close(mdb->db);
186       mdb->db = NULL;
187    } else {
188       mdb->sqlite_errmsg = NULL;
189    }
190
191 #else
192    mdb->db = sqlite_open(
193         db_name,                      /* database name */
194         644,                          /* mode */
195         &mdb->sqlite_errmsg);         /* error message */
196 #endif
197
198    Dmsg0(300, "sqlite_open\n");
199
200    if (mdb->db == NULL) {
201       Mmsg2(&mdb->errmsg, _("Unable to open Database=%s. ERR=%s\n"),
202          db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
203       free(db_name);
204       V(mutex);
205       return 0;
206    }       
207    mdb->connected = true;
208    free(db_name);
209    if (!check_tables_version(jcr, mdb)) {
210       V(mutex);
211       return 0;
212    }
213
214    /* set busy handler to wait when we use mult_db_connections = 1 */
215 #ifdef HAVE_SQLITE3
216    sqlite3_busy_handler(mdb->db, my_busy_handler, NULL);
217 #else
218    sqlite_busy_handler(mdb->db, my_busy_handler, NULL);
219 #endif
220
221    V(mutex);
222    return 1;
223 }
224
225 void
226 db_close_database(JCR *jcr, B_DB *mdb)
227 {
228    if (!mdb) {
229       return;
230    }
231    db_end_transaction(jcr, mdb);
232    P(mutex);
233    sql_free_result(mdb);
234    mdb->ref_count--;
235    if (mdb->ref_count == 0) {
236       qdchain(&mdb->bq);
237       if (mdb->connected && mdb->db) {
238          sqlite_close(mdb->db);
239       }
240       rwl_destroy(&mdb->lock);
241       free_pool_memory(mdb->errmsg);
242       free_pool_memory(mdb->cmd);
243       free_pool_memory(mdb->cached_path);
244       free_pool_memory(mdb->fname);
245       free_pool_memory(mdb->path);
246       free_pool_memory(mdb->esc_name);
247       free_pool_memory(mdb->esc_path);
248       if (mdb->db_name) {
249          free(mdb->db_name);
250       }
251       free(mdb);
252    }
253    V(mutex);
254 }
255
256 void db_thread_cleanup()
257 { }
258
259 /*
260  * Return the next unique index (auto-increment) for
261  * the given table.  Return 0 on error.
262  */
263 int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
264 {
265 #ifdef xxxx
266    SQL_ROW row;
267
268    db_lock(mdb);
269
270    Mmsg(mdb->cmd,
271 "SELECT id FROM NextId WHERE TableName=\"%s\"", table);
272    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
273       Mmsg(mdb->errmsg, _("next_index query error: ERR=%s\n"), sql_strerror(mdb));
274       db_unlock(mdb);
275       return 0;
276    }
277    if ((row = sql_fetch_row(mdb)) == NULL) {
278       Mmsg(mdb->errmsg, _("Error fetching index: ERR=%s\n"), sql_strerror(mdb));
279       db_unlock(mdb);
280       return 0;
281    }
282    bstrncpy(index, row[0], 28);
283    sql_free_result(mdb);
284
285    Mmsg(mdb->cmd,
286 "UPDATE NextId SET id=id+1 WHERE TableName=\"%s\"", table);
287    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
288       Mmsg(mdb->errmsg, _("next_index update error: ERR=%s\n"), sql_strerror(mdb));
289       db_unlock(mdb);
290       return 0;
291    }
292    sql_free_result(mdb);
293
294    db_unlock(mdb);
295 #endif
296    strcpy(index, "NULL");
297    return 1;
298 }
299
300
301 /*
302  * Escape strings so that SQLite is happy
303  *
304  *   NOTE! len is the length of the old string. Your new
305  *         string must be long enough (max 2*old+1) to hold
306  *         the escaped output.
307  */
308 void
309 db_escape_string(char *snew, char *old, int len)
310 {
311    char *n, *o;
312
313    n = snew;
314    o = old;
315    while (len--) {
316       switch (*o) {
317       case '\'':
318          *n++ = '\'';
319          *n++ = '\'';
320          o++;
321          break;
322       case 0:
323          *n++ = '\\';
324          *n++ = 0;
325          o++;
326          break;
327       default:
328          *n++ = *o++;
329          break;
330       }
331    }
332    *n = 0;
333 }
334
335 struct rh_data {
336    DB_RESULT_HANDLER *result_handler;
337    void *ctx;
338 };
339
340 /*
341  * Convert SQLite's callback into Bacula DB callback
342  */
343 static int sqlite_result(void *arh_data, int num_fields, char **rows, char **col_names)
344 {
345    struct rh_data *rh_data = (struct rh_data *)arh_data;
346
347    if (rh_data->result_handler) {
348       (*(rh_data->result_handler))(rh_data->ctx, num_fields, rows);
349    }
350    return 0;
351 }
352
353 /*
354  * Submit a general SQL command (cmd), and for each row returned,
355  *  the sqlite_handler is called with the ctx.
356  */
357 int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx)
358 {
359    struct rh_data rh_data;
360    int stat;
361
362    db_lock(mdb);
363    if (mdb->sqlite_errmsg) {
364 #ifdef HAVE_SQLITE3
365       sqlite3_free(mdb->sqlite_errmsg);
366 #else
367       actuallyfree(mdb->sqlite_errmsg);
368 #endif
369       mdb->sqlite_errmsg = NULL;
370    }
371    rh_data.result_handler = result_handler;
372    rh_data.ctx = ctx;
373    stat = sqlite_exec(mdb->db, query, sqlite_result, (void *)&rh_data, &mdb->sqlite_errmsg);
374    if (stat != 0) {
375       Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb));
376       db_unlock(mdb);
377       return 0;
378    }
379    db_unlock(mdb);
380    return 1;
381 }
382
383 /*
384  * Submit a sqlite query and retrieve all the data
385  */
386 int my_sqlite_query(B_DB *mdb, const char *cmd)
387 {
388    int stat;
389
390    my_sqlite_free_table(mdb);
391    if (mdb->sqlite_errmsg) {
392 #ifdef HAVE_SQLITE3
393       sqlite3_free(mdb->sqlite_errmsg);
394 #else
395       actuallyfree(mdb->sqlite_errmsg);
396 #endif
397       mdb->sqlite_errmsg = NULL;
398    }
399    stat = sqlite_get_table(mdb->db, (char *)cmd, &mdb->result, &mdb->nrow, &mdb->ncolumn,
400             &mdb->sqlite_errmsg);
401    mdb->row = 0;                      /* row fetched */
402    return stat;
403 }
404
405 /* Fetch one row at a time */
406 SQL_ROW my_sqlite_fetch_row(B_DB *mdb)
407 {
408    if (mdb->row >= mdb->nrow) {
409       return NULL;
410    }
411    mdb->row++;
412    return &mdb->result[mdb->ncolumn * mdb->row];
413 }
414
415 void my_sqlite_free_table(B_DB *mdb)
416 {
417    int i;
418
419    if (mdb->fields_defined) {
420       for (i=0; i < sql_num_fields(mdb); i++) {
421          free(mdb->fields[i]);
422       }
423       free(mdb->fields);
424       mdb->fields_defined = false;
425    }
426    if (mdb->result) {
427       sqlite_free_table(mdb->result);
428       mdb->result = NULL;
429    }
430    mdb->nrow = mdb->ncolumn = 0;
431 }
432
433 void my_sqlite_field_seek(B_DB *mdb, int field)
434 {
435    int i, j;
436    if (mdb->result == NULL) {
437       return;
438    }
439    /* On first call, set up the fields */
440    if (!mdb->fields_defined && sql_num_fields(mdb) > 0) {
441       mdb->fields = (SQL_FIELD **)malloc(sizeof(SQL_FIELD) * mdb->ncolumn);
442       for (i=0; i < sql_num_fields(mdb); i++) {
443          mdb->fields[i] = (SQL_FIELD *)malloc(sizeof(SQL_FIELD));
444          mdb->fields[i]->name = mdb->result[i];
445          mdb->fields[i]->length = cstrlen(mdb->fields[i]->name);
446          mdb->fields[i]->max_length = mdb->fields[i]->length;
447          for (j=1; j <= mdb->nrow; j++) {
448             int len;
449             if (mdb->result[i + mdb->ncolumn *j]) {
450                len = (uint32_t)cstrlen(mdb->result[i + mdb->ncolumn * j]);
451             } else {
452                len = 0;
453             }
454             if (len > mdb->fields[i]->max_length) {
455                mdb->fields[i]->max_length = len;
456             }
457          }
458          mdb->fields[i]->type = 0;
459          mdb->fields[i]->flags = 1;        /* not null */
460       }
461       mdb->fields_defined = TRUE;
462    }
463    if (field > sql_num_fields(mdb)) {
464       field = sql_num_fields(mdb);
465     }
466     mdb->field = field;
467
468 }
469
470 SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb)
471 {
472    return mdb->fields[mdb->field++];
473 }
474
475 char *my_sqlite_batch_lock_query = "BEGIN";
476 char *my_sqlite_batch_unlock_query = "COMMIT";
477 char *my_sqlite_batch_fill_path_query = "INSERT INTO Path (Path)          " 
478                                         " SELECT DISTINCT Path FROM batch "
479                                         " EXCEPT SELECT Path FROM Path    ";
480
481 char *my_sqlite_batch_fill_filename_query = "INSERT INTO Filename (Name)       " 
482                                             " SELECT DISTINCT Name FROM batch  "
483                                             " EXCEPT SELECT Name FROM Filename ";
484
485
486
487 #endif /* HAVE_SQLITE */