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