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