]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sqlite.c
c98b571242d547ad49277bcc7f6961a0f9cfce2b
[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-2004 Kern Sibbald and John Walker
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 #ifdef HAVE_SQLITE
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 {
65    B_DB *mdb;
66
67    P(mutex);                          /* lock DB queue */
68    /* Look to see if DB already open */
69    for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
70       if (strcmp(mdb->db_name, db_name) == 0) {
71          Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
72          mdb->ref_count++;
73          V(mutex);
74          return mdb;                  /* already open */
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    qinsert(&db_list, &mdb->bq);            /* put db in list */
92    V(mutex);
93    return mdb;
94 }
95
96 /*
97  * Now actually open the database.  This can generate errors,
98  * which are returned in the errmsg
99  *
100  * DO NOT close the database or free(mdb) here !!!!
101  */
102 int
103 db_open_database(JCR *jcr, B_DB *mdb)
104 {
105    char *db_name;
106    int len;
107    struct stat statbuf;
108    int errstat;
109
110    P(mutex);
111    if (mdb->connected) {
112       V(mutex);
113       return 1;
114    }
115    mdb->connected = FALSE;
116
117    if ((errstat=rwl_init(&mdb->lock)) != 0) {
118       Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), 
119             strerror(errstat));
120       V(mutex);
121       return 0;
122    }
123
124    /* open the database */
125    len = strlen(working_directory) + strlen(mdb->db_name) + 5; 
126    db_name = (char *)malloc(len);
127    strcpy(db_name, working_directory);
128    strcat(db_name, "/");
129    strcat(db_name, mdb->db_name);
130    strcat(db_name, ".db");
131    if (stat(db_name, &statbuf) != 0) {
132       Mmsg1(&mdb->errmsg, _("Database %s does not exist, please create it.\n"), 
133          db_name);
134       free(db_name);
135       V(mutex);
136       return 0;
137    }
138    mdb->db = sqlite_open(
139         db_name,                      /* database name */
140         644,                          /* mode */
141         &mdb->sqlite_errmsg);         /* error message */
142
143    Dmsg0(300, "sqlite_open\n");
144   
145    if (mdb->db == NULL) {
146       Mmsg2(&mdb->errmsg, _("Unable to open Database=%s. ERR=%s\n"),
147          db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
148       free(db_name);
149       V(mutex);
150       return 0;
151    }
152    free(db_name);
153    if (!check_tables_version(jcr, mdb)) {
154       V(mutex);
155       return 0;
156    }
157
158    mdb->connected = TRUE;
159    V(mutex);
160    return 1;
161 }
162
163 void
164 db_close_database(JCR *jcr, B_DB *mdb)
165 {
166    if (!mdb) {
167       return;
168    }
169    P(mutex);
170    mdb->ref_count--;
171    if (mdb->ref_count == 0) {
172       qdchain(&mdb->bq);
173       if (mdb->connected && mdb->db) {
174          sqlite_close(mdb->db);
175       }
176       rwl_destroy(&mdb->lock);       
177       free_pool_memory(mdb->errmsg);
178       free_pool_memory(mdb->cmd);
179       free_pool_memory(mdb->cached_path);
180       free_pool_memory(mdb->fname);
181       free_pool_memory(mdb->path);
182       free_pool_memory(mdb->esc_name);
183       if (mdb->db_name) {
184          free(mdb->db_name);
185       }
186       free(mdb);
187    }
188    V(mutex);
189 }
190
191 /*
192  * Return the next unique index (auto-increment) for
193  * the given table.  Return 0 on error.
194  */
195 int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
196 {
197    SQL_ROW row;
198
199    db_lock(mdb);
200
201    Mmsg(mdb->cmd,
202 "SELECT id FROM NextId WHERE TableName=\"%s\"", table);
203    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
204       Mmsg(mdb->errmsg, _("next_index query error: ERR=%s\n"), sql_strerror(mdb));
205       db_unlock(mdb);
206       return 0;
207    }
208    if ((row = sql_fetch_row(mdb)) == NULL) {
209       Mmsg(mdb->errmsg, _("Error fetching index: ERR=%s\n"), sql_strerror(mdb));
210       db_unlock(mdb);
211       return 0;
212    }
213    bstrncpy(index, row[0], 28);
214    sql_free_result(mdb);
215
216    Mmsg(mdb->cmd,
217 "UPDATE NextId SET id=id+1 WHERE TableName=\"%s\"", table);
218    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
219       Mmsg(mdb->errmsg, _("next_index update error: ERR=%s\n"), sql_strerror(mdb));
220       db_unlock(mdb);
221       return 0;
222    }
223    sql_free_result(mdb);
224
225    db_unlock(mdb);
226    return 1;
227 }   
228
229
230 /*
231  * Escape strings so that SQLite is happy
232  *
233  *   NOTE! len is the length of the old string. Your new
234  *         string must be long enough (max 2*old+1) to hold
235  *         the escaped output.
236  */
237 void
238 db_escape_string(char *snew, char *old, int len)
239 {
240    char *n, *o;
241
242    n = snew;
243    o = old;
244    while (len--) {
245       switch (*o) {
246       case '\'':
247          *n++ = '\'';
248          *n++ = '\'';
249          o++;
250          break;
251       case 0:
252          *n++ = '\\';
253          *n++ = 0;
254          o++;
255          break;
256       default:
257          *n++ = *o++;
258          break;
259       }
260    }
261    *n = 0;
262 }
263
264 struct rh_data {
265    DB_RESULT_HANDLER *result_handler;
266    void *ctx;
267 };
268
269 /*  
270  * Convert SQLite's callback into Bacula DB callback  
271  */
272 static int sqlite_result(void *arh_data, int num_fields, char **rows, char **col_names)
273 {
274    struct rh_data *rh_data = (struct rh_data *)arh_data;   
275
276    if (rh_data->result_handler) {
277       (*(rh_data->result_handler))(rh_data->ctx, num_fields, rows);
278    }
279    return 0;
280 }
281
282 /*
283  * Submit a general SQL command (cmd), and for each row returned,
284  *  the sqlite_handler is called with the ctx.
285  */
286 int db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx)
287 {
288    struct rh_data rh_data;
289    int stat;
290
291    db_lock(mdb);
292    if (mdb->sqlite_errmsg) {
293       actuallyfree(mdb->sqlite_errmsg);
294       mdb->sqlite_errmsg = NULL;
295    }
296    rh_data.result_handler = result_handler;
297    rh_data.ctx = ctx;
298    stat = sqlite_exec(mdb->db, query, sqlite_result, (void *)&rh_data, &mdb->sqlite_errmsg);
299    if (stat != 0) {
300       Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb));
301       db_unlock(mdb);
302       return 0;
303    }
304    db_unlock(mdb);
305    return 1;
306 }
307
308 /*
309  * Submit a sqlite query and retrieve all the data
310  */
311 int my_sqlite_query(B_DB *mdb, char *cmd) 
312 {
313    int stat;
314
315    if (mdb->sqlite_errmsg) {
316       actuallyfree(mdb->sqlite_errmsg);
317       mdb->sqlite_errmsg = NULL;
318    }
319    stat = sqlite_get_table(mdb->db, cmd, &mdb->result, &mdb->nrow, &mdb->ncolumn,
320             &mdb->sqlite_errmsg);
321    mdb->row = 0;                      /* row fetched */
322    return stat;
323 }
324
325 /* Fetch one row at a time */
326 SQL_ROW my_sqlite_fetch_row(B_DB *mdb)
327 {
328    if (mdb->row >= mdb->nrow) {
329       return NULL;
330    }
331    mdb->row++;
332    return &mdb->result[mdb->ncolumn * mdb->row];
333 }
334
335 void my_sqlite_free_table(B_DB *mdb)
336 {
337    int i;
338
339    if (mdb->fields_defined) {
340       for (i=0; i < sql_num_fields(mdb); i++) {
341          free(mdb->fields[i]);
342       }
343       free(mdb->fields);
344       mdb->fields_defined = false;
345    }
346    sqlite_free_table(mdb->result);
347    mdb->nrow = mdb->ncolumn = 0; 
348 }
349
350 void my_sqlite_field_seek(B_DB *mdb, int field)
351 {
352    int i, j;
353    if (mdb->result == NULL) {
354       return;
355    }
356    /* On first call, set up the fields */
357    if (!mdb->fields_defined && sql_num_fields(mdb) > 0) {
358       mdb->fields = (SQL_FIELD **)malloc(sizeof(SQL_FIELD) * mdb->ncolumn);
359       for (i=0; i < sql_num_fields(mdb); i++) {
360          mdb->fields[i] = (SQL_FIELD *)malloc(sizeof(SQL_FIELD));
361          mdb->fields[i]->name = mdb->result[i];
362          mdb->fields[i]->length = strlen(mdb->fields[i]->name);
363          mdb->fields[i]->max_length = mdb->fields[i]->length;
364          for (j=1; j <= mdb->nrow; j++) {
365             int len;
366             if (mdb->result[i + mdb->ncolumn *j]) {
367                len = (uint32_t)strlen(mdb->result[i + mdb->ncolumn * j]);
368             } else {
369                len = 0;
370             }
371             if (len > mdb->fields[i]->max_length) {
372                mdb->fields[i]->max_length = len;
373             }
374          }
375          mdb->fields[i]->type = 0;
376          mdb->fields[i]->flags = 1;        /* not null */
377       }
378       mdb->fields_defined = TRUE;
379    }
380    if (field > sql_num_fields(mdb)) {
381       field = sql_num_fields(mdb);
382     }
383     mdb->field = field;
384
385 }
386
387 SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb)
388 {
389    return mdb->fields[mdb->field++];
390 }
391
392
393
394 #endif /* HAVE_SQLITE */