+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation plus additions
+ that are listed in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
/*
* Bacula Catalog Database routines specific to SQLite
*
*
* Version $Id$
*/
-/*
- Copyright (C) 2002-2006 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as amended with additional clauses defined in the
- file LICENSE in the main source directory.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- the file LICENSE for additional details.
-
- */
return "SQLite";
}
+/*
+ * When using mult_db_connections = 1,
+ * sqlite can be BUSY. We just need sleep a little in this case.
+ */
+
+#ifdef HAVE_SQLITE3
+static int my_busy_handler(void *arg, int calls)
+{
+ bmicrosleep(0, 500);
+ return 1;
+}
+#else
+static int my_busy_handler(void *arg, const char* p, int calls)
+{
+ bmicrosleep(0, 500);
+ return 1;
+}
+#endif
+
+
/*
* Initialize database data structure. In principal this should
* never have errors, or it is really fatal.
mdb->fname = get_pool_memory(PM_FNAME);
mdb->path = get_pool_memory(PM_FNAME);
mdb->esc_name = get_pool_memory(PM_FNAME);
+ mdb->esc_path = get_pool_memory(PM_FNAME);
mdb->allow_transactions = mult_db_connections;
qinsert(&db_list, &mdb->bq); /* put db in list */
V(mutex);
int stat = sqlite3_open(db_name, &mdb->db);
if (stat != SQLITE_OK) {
mdb->sqlite_errmsg = (char *)sqlite3_errmsg(mdb->db);
+ sqlite3_close(mdb->db);
+ mdb->db = NULL;
} else {
mdb->sqlite_errmsg = NULL;
}
+#ifdef SQLITE3_INIT_QUERY
+ db_sql_query(mdb, SQLITE3_INIT_QUERY, NULL, NULL);
+#endif
#else
mdb->db = sqlite_open(
free(db_name);
V(mutex);
return 0;
- }
+ }
+ mdb->connected = true;
free(db_name);
if (!check_tables_version(jcr, mdb)) {
V(mutex);
return 0;
}
- mdb->connected = true;
+ /* set busy handler to wait when we use mult_db_connections = 1 */
+#ifdef HAVE_SQLITE3
+ sqlite3_busy_handler(mdb->db, my_busy_handler, NULL);
+#else
+ sqlite_busy_handler(mdb->db, my_busy_handler, NULL);
+#endif
+
V(mutex);
return 1;
}
}
db_end_transaction(jcr, mdb);
P(mutex);
+ sql_free_result(mdb);
mdb->ref_count--;
if (mdb->ref_count == 0) {
qdchain(&mdb->bq);
free_pool_memory(mdb->fname);
free_pool_memory(mdb->path);
free_pool_memory(mdb->esc_name);
+ free_pool_memory(mdb->esc_path);
if (mdb->db_name) {
free(mdb->db_name);
}
V(mutex);
}
+void db_thread_cleanup()
+{
+#ifdef HAVE_SQLITE3
+ sqlite3_thread_cleanup();
+#endif
+}
+
/*
* Return the next unique index (auto-increment) for
* the given table. Return 0 on error.
*/
int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
{
-#ifdef xxxx
- SQL_ROW row;
-
- db_lock(mdb);
-
- Mmsg(mdb->cmd,
-"SELECT id FROM NextId WHERE TableName=\"%s\"", table);
- if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
- Mmsg(mdb->errmsg, _("next_index query error: ERR=%s\n"), sql_strerror(mdb));
- db_unlock(mdb);
- return 0;
- }
- if ((row = sql_fetch_row(mdb)) == NULL) {
- Mmsg(mdb->errmsg, _("Error fetching index: ERR=%s\n"), sql_strerror(mdb));
- db_unlock(mdb);
- return 0;
- }
- bstrncpy(index, row[0], 28);
- sql_free_result(mdb);
-
- Mmsg(mdb->cmd,
-"UPDATE NextId SET id=id+1 WHERE TableName=\"%s\"", table);
- if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
- Mmsg(mdb->errmsg, _("next_index update error: ERR=%s\n"), sql_strerror(mdb));
- db_unlock(mdb);
- return 0;
- }
- sql_free_result(mdb);
-
- db_unlock(mdb);
-#endif
strcpy(index, "NULL");
return 1;
}
{
int stat;
+ my_sqlite_free_table(mdb);
if (mdb->sqlite_errmsg) {
+#ifdef HAVE_SQLITE3
+ sqlite3_free(mdb->sqlite_errmsg);
+#else
actuallyfree(mdb->sqlite_errmsg);
+#endif
mdb->sqlite_errmsg = NULL;
}
stat = sqlite_get_table(mdb->db, (char *)cmd, &mdb->result, &mdb->nrow, &mdb->ncolumn,
free(mdb->fields);
mdb->fields_defined = false;
}
- sqlite_free_table(mdb->result);
+ if (mdb->result) {
+ sqlite_free_table(mdb->result);
+ mdb->result = NULL;
+ }
mdb->nrow = mdb->ncolumn = 0;
}
return mdb->fields[mdb->field++];
}
+char *my_sqlite_batch_lock_query = "BEGIN";
+char *my_sqlite_batch_unlock_query = "COMMIT";
+char *my_sqlite_batch_fill_path_query = "INSERT INTO Path (Path) "
+ " SELECT DISTINCT Path FROM batch "
+ " EXCEPT SELECT Path FROM Path ";
+
+char *my_sqlite_batch_fill_filename_query = "INSERT INTO Filename (Name) "
+ " SELECT DISTINCT Name FROM batch "
+ " EXCEPT SELECT Name FROM Filename ";
+
+
+
#endif /* HAVE_SQLITE */