]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sqlite.c
ebl update debug message (last time) :)
[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 /*
257  * Return the next unique index (auto-increment) for
258  * the given table.  Return 0 on error.
259  */
260 int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
261 {
262 #ifdef xxxx
263    SQL_ROW row;
264
265    db_lock(mdb);
266
267    Mmsg(mdb->cmd,
268 "SELECT id FROM NextId WHERE TableName=\"%s\"", table);
269    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
270       Mmsg(mdb->errmsg, _("next_index query error: ERR=%s\n"), sql_strerror(mdb));
271       db_unlock(mdb);
272       return 0;
273    }
274    if ((row = sql_fetch_row(mdb)) == NULL) {
275       Mmsg(mdb->errmsg, _("Error fetching index: ERR=%s\n"), sql_strerror(mdb));
276       db_unlock(mdb);
277       return 0;
278    }
279    bstrncpy(index, row[0], 28);
280    sql_free_result(mdb);
281
282    Mmsg(mdb->cmd,
283 "UPDATE NextId SET id=id+1 WHERE TableName=\"%s\"", table);
284    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
285       Mmsg(mdb->errmsg, _("next_index update error: ERR=%s\n"), sql_strerror(mdb));
286       db_unlock(mdb);
287       return 0;
288    }
289    sql_free_result(mdb);
290
291    db_unlock(mdb);
292 #endif
293    strcpy(index, "NULL");
294    return 1;
295 }
296
297
298 /*
299  * Escape strings so that SQLite is happy
300  *
301  *   NOTE! len is the length of the old string. Your new
302  *         string must be long enough (max 2*old+1) to hold
303  *         the escaped output.
304  */
305 void
306 db_escape_string(char *snew, char *old, int len)
307 {
308    char *n, *o;
309
310    n = snew;
311    o = old;
312    while (len--) {
313       switch (*o) {
314       case '\'':
315          *n++ = '\'';
316          *n++ = '\'';
317          o++;
318          break;
319       case 0:
320          *n++ = '\\';
321          *n++ = 0;
322          o++;
323          break;
324       default:
325          *n++ = *o++;
326          break;
327       }
328    }
329    *n = 0;
330 }
331
332 struct rh_data {
333    DB_RESULT_HANDLER *result_handler;
334    void *ctx;
335 };
336
337 /*
338  * Convert SQLite's callback into Bacula DB callback
339  */
340 static int sqlite_result(void *arh_data, int num_fields, char **rows, char **col_names)
341 {
342    struct rh_data *rh_data = (struct rh_data *)arh_data;
343
344    if (rh_data->result_handler) {
345       (*(rh_data->result_handler))(rh_data->ctx, num_fields, rows);
346    }
347    return 0;
348 }
349
350 /*
351  * Submit a general SQL command (cmd), and for each row returned,
352  *  the sqlite_handler is called with the ctx.
353  */
354 int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx)
355 {
356    struct rh_data rh_data;
357    int stat;
358
359    db_lock(mdb);
360    if (mdb->sqlite_errmsg) {
361 #ifdef HAVE_SQLITE3
362       sqlite3_free(mdb->sqlite_errmsg);
363 #else
364       actuallyfree(mdb->sqlite_errmsg);
365 #endif
366       mdb->sqlite_errmsg = NULL;
367    }
368    rh_data.result_handler = result_handler;
369    rh_data.ctx = ctx;
370    stat = sqlite_exec(mdb->db, query, sqlite_result, (void *)&rh_data, &mdb->sqlite_errmsg);
371    if (stat != 0) {
372       Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb));
373       db_unlock(mdb);
374       return 0;
375    }
376    db_unlock(mdb);
377    return 1;
378 }
379
380 /*
381  * Submit a sqlite query and retrieve all the data
382  */
383 int my_sqlite_query(B_DB *mdb, const char *cmd)
384 {
385    int stat;
386
387    if (mdb->sqlite_errmsg) {
388 #ifdef HAVE_SQLITE3
389       sqlite3_free(mdb->sqlite_errmsg);
390 #else
391       actuallyfree(mdb->sqlite_errmsg);
392 #endif
393       mdb->sqlite_errmsg = NULL;
394    }
395    stat = sqlite_get_table(mdb->db, (char *)cmd, &mdb->result, &mdb->nrow, &mdb->ncolumn,
396             &mdb->sqlite_errmsg);
397    mdb->row = 0;                      /* row fetched */
398    return stat;
399 }
400
401 /* Fetch one row at a time */
402 SQL_ROW my_sqlite_fetch_row(B_DB *mdb)
403 {
404    if (mdb->row >= mdb->nrow) {
405       return NULL;
406    }
407    mdb->row++;
408    return &mdb->result[mdb->ncolumn * mdb->row];
409 }
410
411 void my_sqlite_free_table(B_DB *mdb)
412 {
413    int i;
414
415    if (mdb->fields_defined) {
416       for (i=0; i < sql_num_fields(mdb); i++) {
417          free(mdb->fields[i]);
418       }
419       free(mdb->fields);
420       mdb->fields_defined = false;
421    }
422    sqlite_free_table(mdb->result);
423    mdb->nrow = mdb->ncolumn = 0;
424 }
425
426 void my_sqlite_field_seek(B_DB *mdb, int field)
427 {
428    int i, j;
429    if (mdb->result == NULL) {
430       return;
431    }
432    /* On first call, set up the fields */
433    if (!mdb->fields_defined && sql_num_fields(mdb) > 0) {
434       mdb->fields = (SQL_FIELD **)malloc(sizeof(SQL_FIELD) * mdb->ncolumn);
435       for (i=0; i < sql_num_fields(mdb); i++) {
436          mdb->fields[i] = (SQL_FIELD *)malloc(sizeof(SQL_FIELD));
437          mdb->fields[i]->name = mdb->result[i];
438          mdb->fields[i]->length = cstrlen(mdb->fields[i]->name);
439          mdb->fields[i]->max_length = mdb->fields[i]->length;
440          for (j=1; j <= mdb->nrow; j++) {
441             int len;
442             if (mdb->result[i + mdb->ncolumn *j]) {
443                len = (uint32_t)cstrlen(mdb->result[i + mdb->ncolumn * j]);
444             } else {
445                len = 0;
446             }
447             if (len > mdb->fields[i]->max_length) {
448                mdb->fields[i]->max_length = len;
449             }
450          }
451          mdb->fields[i]->type = 0;
452          mdb->fields[i]->flags = 1;        /* not null */
453       }
454       mdb->fields_defined = TRUE;
455    }
456    if (field > sql_num_fields(mdb)) {
457       field = sql_num_fields(mdb);
458     }
459     mdb->field = field;
460
461 }
462
463 SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb)
464 {
465    return mdb->fields[mdb->field++];
466 }
467
468 char *my_sqlite_batch_lock_query = "BEGIN";
469 char *my_sqlite_batch_unlock_query = "COMMIT";
470 char *my_sqlite_batch_fill_path_query = "INSERT INTO Path (Path)          " 
471                                         " SELECT DISTINCT Path FROM batch "
472                                         " EXCEPT SELECT Path FROM Path    ";
473
474 char *my_sqlite_batch_fill_filename_query = "INSERT INTO Filename (Name)       " 
475                                             " SELECT DISTINCT Name FROM batch  "
476                                             " EXCEPT SELECT Name FROM Filename ";
477
478
479
480 #endif /* HAVE_SQLITE */