2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
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 and included
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.
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
23 Bacula® is a registered trademark of Kern Sibbald.
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.
29 * Bacula Catalog Database routines specific to SQLite
31 * Kern Sibbald, January 2002
37 /* The following is necessary so that we do not include
38 * the dummy external definition of DB.
40 #define __SQL_C /* indicate that this is sql.c */
45 #if HAVE_SQLITE || HAVE_SQLITE3
47 /* -----------------------------------------------------------------------
49 * SQLite dependent defines and subroutines
51 * -----------------------------------------------------------------------
54 /* List of open databases */
55 static dlist *db_list = NULL;
57 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
60 * Retrieve database type
73 * When using mult_db_connections = 1,
74 * sqlite can be BUSY. We just need sleep a little in this case.
78 static int my_busy_handler(void *arg, int calls)
84 static int my_busy_handler(void *arg, const char* p, int calls)
93 * Initialize database data structure. In principal this should
94 * never have errors, or it is really fatal.
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)
103 P(mutex); /* lock DB queue */
104 if (db_list == NULL) {
105 db_list = New(dlist(mdb, &mdb->link));
107 /* Look to see if DB already open */
108 if (!mult_db_connections) {
109 foreach_dlist(mdb, db_list) {
110 if (bstrcmp(mdb->db_name, db_name) &&
111 bstrcmp(mdb->db_address, db_address) &&
112 mdb->db_port == db_port) {
113 Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
116 return mdb; /* already open */
120 Dmsg0(300, "db_open first time\n");
121 mdb = (B_DB *)malloc(sizeof(B_DB));
122 memset(mdb, 0, sizeof(B_DB));
123 mdb->db_name = bstrdup(db_name);
124 mdb->errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */
126 mdb->cmd = get_pool_memory(PM_EMSG); /* get command buffer */
127 mdb->cached_path = get_pool_memory(PM_FNAME);
128 mdb->cached_path_id = 0;
130 mdb->fname = get_pool_memory(PM_FNAME);
131 mdb->path = get_pool_memory(PM_FNAME);
132 mdb->esc_name = get_pool_memory(PM_FNAME);
133 mdb->esc_path = get_pool_memory(PM_FNAME);
134 mdb->allow_transactions = mult_db_connections;
135 db_list->append(mdb);
141 * Now actually open the database. This can generate errors,
142 * which are returned in the errmsg
144 * DO NOT close the database or free(mdb) here !!!!
147 db_open_database(JCR *jcr, B_DB *mdb)
156 if (mdb->connected) {
160 mdb->connected = FALSE;
162 if ((errstat=rwl_init(&mdb->lock)) != 0) {
164 Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
165 be.bstrerror(errstat));
170 /* open the database */
171 len = strlen(working_directory) + strlen(mdb->db_name) + 5;
172 db_name = (char *)malloc(len);
173 strcpy(db_name, working_directory);
174 strcat(db_name, "/");
175 strcat(db_name, mdb->db_name);
176 strcat(db_name, ".db");
177 if (stat(db_name, &statbuf) != 0) {
178 Mmsg1(&mdb->errmsg, _("Database %s does not exist, please create it.\n"),
185 for (mdb->db=NULL; !mdb->db && retry++ < 10; ) {
187 int stat = sqlite3_open(db_name, &mdb->db);
188 if (stat != SQLITE_OK) {
189 mdb->sqlite_errmsg = (char *)sqlite3_errmsg(mdb->db);
190 sqlite3_close(mdb->db);
193 mdb->sqlite_errmsg = NULL;
196 mdb->db = sqlite_open(
197 db_name, /* database name */
199 &mdb->sqlite_errmsg); /* error message */
202 Dmsg0(300, "sqlite_open\n");
207 if (mdb->db == NULL) {
208 Mmsg2(&mdb->errmsg, _("Unable to open Database=%s. ERR=%s\n"),
209 db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
214 mdb->connected = true;
217 /* set busy handler to wait when we use mult_db_connections = 1 */
219 sqlite3_busy_handler(mdb->db, my_busy_handler, NULL);
221 sqlite_busy_handler(mdb->db, my_busy_handler, NULL);
224 #if defined(HAVE_SQLITE3) && defined(SQLITE3_INIT_QUERY)
225 db_sql_query(mdb, SQLITE3_INIT_QUERY, NULL, NULL);
228 if (!check_tables_version(jcr, mdb)) {
239 db_close_database(JCR *jcr, B_DB *mdb)
244 db_end_transaction(jcr, mdb);
246 sql_free_result(mdb);
248 if (mdb->ref_count == 0) {
249 db_list->remove(mdb);
250 if (mdb->connected && mdb->db) {
251 sqlite_close(mdb->db);
253 rwl_destroy(&mdb->lock);
254 free_pool_memory(mdb->errmsg);
255 free_pool_memory(mdb->cmd);
256 free_pool_memory(mdb->cached_path);
257 free_pool_memory(mdb->fname);
258 free_pool_memory(mdb->path);
259 free_pool_memory(mdb->esc_name);
260 free_pool_memory(mdb->esc_path);
265 if (db_list->size() == 0) {
273 void db_check_backend_thread_safe()
275 #ifdef HAVE_BATCH_FILE_INSERT
276 # ifdef HAVE_SQLITE3_THREADSAFE
277 if (!sqlite3_threadsafe()) {
278 Emsg0(M_ABORT, 0, _("SQLite3 client library must be thread-safe "
279 "when using BatchMode.\n"));
285 void db_thread_cleanup()
288 sqlite3_thread_cleanup();
293 * Return the next unique index (auto-increment) for
294 * the given table. Return 0 on error.
296 int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
298 strcpy(index, "NULL");
304 * Escape strings so that SQLite is happy
306 * NOTE! len is the length of the old string. Your new
307 * string must be long enough (max 2*old+1) to hold
308 * the escaped output.
311 db_escape_string(JCR *jcr, B_DB *db, char *snew, char *old, int len)
338 DB_RESULT_HANDLER *result_handler;
343 * Convert SQLite's callback into Bacula DB callback
345 static int sqlite_result(void *arh_data, int num_fields, char **rows, char **col_names)
347 struct rh_data *rh_data = (struct rh_data *)arh_data;
349 if (rh_data->result_handler) {
350 (*(rh_data->result_handler))(rh_data->ctx, num_fields, rows);
356 * Submit a general SQL command (cmd), and for each row returned,
357 * the sqlite_handler is called with the ctx.
359 bool db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx)
361 struct rh_data rh_data;
365 if (mdb->sqlite_errmsg) {
367 sqlite3_free(mdb->sqlite_errmsg);
369 actuallyfree(mdb->sqlite_errmsg);
371 mdb->sqlite_errmsg = NULL;
373 rh_data.result_handler = result_handler;
375 stat = sqlite_exec(mdb->db, query, sqlite_result, (void *)&rh_data, &mdb->sqlite_errmsg);
376 if (stat != SQLITE_OK) {
377 Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb));
386 * Submit a sqlite query and retrieve all the data
388 int my_sqlite_query(B_DB *mdb, const char *cmd)
392 my_sqlite_free_table(mdb);
393 if (mdb->sqlite_errmsg) {
395 sqlite3_free(mdb->sqlite_errmsg);
397 actuallyfree(mdb->sqlite_errmsg);
399 mdb->sqlite_errmsg = NULL;
401 stat = sqlite_get_table(mdb->db, (char *)cmd, &mdb->result, &mdb->nrow, &mdb->ncolumn,
402 &mdb->sqlite_errmsg);
403 mdb->row = 0; /* no row fetched yet */
404 if (stat != 0) { /* something went wrong */
405 mdb->nrow = mdb->ncolumn = 0;
410 /* Fetch one row at a time */
411 SQL_ROW my_sqlite_fetch_row(B_DB *mdb)
413 if (!mdb->result || (mdb->row >= mdb->nrow)) {
417 return &mdb->result[mdb->ncolumn * mdb->row];
420 void my_sqlite_free_table(B_DB *mdb)
424 if (mdb->fields_defined) {
425 for (i=0; i < sql_num_fields(mdb); i++) {
426 if (mdb->fields[i]) {
427 free(mdb->fields[i]);
428 mdb->fields[i] = NULL;
435 mdb->fields_defined = false;
438 sqlite_free_table(mdb->result);
441 mdb->nrow = mdb->ncolumn = 0;
444 void my_sqlite_field_seek(B_DB *mdb, int field)
447 if (mdb->result == NULL) {
451 /* On first call, set up the fields */
452 if (!mdb->fields_defined && sql_num_fields(mdb) > 0) {
453 mdb->fields = (SQL_FIELD **)malloc(sizeof(SQL_FIELD) * mdb->ncolumn);
454 for (i=0; i < sql_num_fields(mdb); i++) {
455 mdb->fields[i] = (SQL_FIELD *)malloc(sizeof(SQL_FIELD));
456 /* ***FIXME*** it seems to me that this is wrong
457 * fields has lots of items
459 if (mdb->result[i] == NULL) {
460 mdb->fields_defined = false;
466 mdb->fields[i]->name = mdb->result[i];
467 mdb->fields[i]->length = cstrlen(mdb->fields[i]->name);
468 mdb->fields[i]->max_length = mdb->fields[i]->length;
469 for (j=1; j <= mdb->nrow; j++) {
471 if (mdb->result[i + mdb->ncolumn *j]) {
472 len = (uint32_t)cstrlen(mdb->result[i + mdb->ncolumn * j]);
476 if (len > mdb->fields[i]->max_length) {
477 mdb->fields[i]->max_length = len;
480 mdb->fields[i]->type = 0;
481 mdb->fields[i]->flags = 1; /* not null */
483 mdb->fields_defined = true;
485 if (sql_num_fields(mdb) <= 0) {
487 } else if (field > sql_num_fields(mdb) - 1) {
488 field = sql_num_fields(mdb) - 1;
493 SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb)
495 if (mdb->fields_defined && mdb->field < sql_num_fields(mdb)) {
496 return mdb->fields[mdb->field++];
503 int my_sqlite_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name)
506 * First execute the insert query and then retrieve the currval.
508 if (my_sqlite_query(mdb, query)) {
512 mdb->num_rows = sql_affected_rows(mdb);
513 if (mdb->num_rows != 1) {
520 return sqlite3_last_insert_rowid(mdb->db);
522 return sqlite_last_insert_rowid(mdb->db);
526 #ifdef HAVE_BATCH_FILE_INSERT
527 const char *my_sqlite_batch_lock_query = "BEGIN";
528 const char *my_sqlite_batch_unlock_query = "COMMIT";
530 const char *my_sqlite_batch_fill_path_query =
531 "INSERT INTO Path (Path)"
532 " SELECT DISTINCT Path FROM batch"
533 " EXCEPT SELECT Path FROM Path";
535 const char *my_sqlite_batch_fill_filename_query =
536 "INSERT INTO Filename (Name)"
537 " SELECT DISTINCT Name FROM batch "
538 " EXCEPT SELECT Name FROM Filename";
539 #endif /* HAVE_BATCH_FILE_INSERT */
542 #endif /* HAVE_SQLITE */