X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fcats%2Fsqlite.c;h=acf91cde323c98d503c79bdb475193eded1195be;hb=056ffd4e26e1cc48e82a9f24c621ec8ef5844f3b;hp=bbe0d09f1050ddf42dc77fefde77d687fe8da400;hpb=288ea8ab889d58c06cc1b95aeca0485082a63bb9;p=bacula%2Fbacula diff --git a/bacula/src/cats/sqlite.c b/bacula/src/cats/sqlite.c index bbe0d09f10..acf91cde32 100644 --- a/bacula/src/cats/sqlite.c +++ b/bacula/src/cats/sqlite.c @@ -2,10 +2,12 @@ * Bacula Catalog Database routines specific to SQLite * * Kern Sibbald, January 2002 + * + * Version $Id$ */ /* - Copyright (C) 2002 Kern Sibbald and John Walker + Copyright (C) 2002-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -49,7 +51,7 @@ static BQUEUE db_list = {&db_list, &db_list}; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -int QueryDB(char *file, int line, B_DB *db, char *select_cmd); +int QueryDB(char *file, int line, void *jcr, B_DB *db, char *select_cmd); /* @@ -57,7 +59,8 @@ int QueryDB(char *file, int line, B_DB *db, char *select_cmd); * never have errors, or it is really fatal. */ B_DB * -db_init_database(char *db_name, char *db_user, char *db_password) +db_init_database(void *jcr, char *db_name, char *db_user, char *db_password, + char *db_address, int db_port, char *db_socket) { B_DB *mdb; @@ -76,10 +79,15 @@ db_init_database(char *db_name, char *db_user, char *db_password) memset(mdb, 0, sizeof(B_DB)); mdb->db_name = bstrdup(db_name); mdb->have_insert_id = TRUE; - mdb->errmsg = (char *) get_pool_memory(PM_EMSG); /* get error message buffer */ + mdb->errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */ *mdb->errmsg = 0; - mdb->cmd = (char *) get_pool_memory(PM_EMSG); /* get command buffer */ + mdb->cmd = get_pool_memory(PM_EMSG); /* get command buffer */ + mdb->cached_path = get_pool_memory(PM_FNAME); + mdb->cached_path_id = 0; mdb->ref_count = 1; + mdb->fname = get_pool_memory(PM_FNAME); + mdb->path = get_pool_memory(PM_FNAME); + mdb->esc_name = get_pool_memory(PM_FNAME); qinsert(&db_list, &mdb->bq); /* put db in list */ V(mutex); return mdb; @@ -90,11 +98,12 @@ db_init_database(char *db_name, char *db_user, char *db_password) * which are returned in the errmsg */ int -db_open_database(B_DB *mdb) +db_open_database(void *jcr, B_DB *mdb) { char *db_name; int len; struct stat statbuf; + int errstat; P(mutex); if (mdb->connected) { @@ -102,8 +111,10 @@ db_open_database(B_DB *mdb) return 1; } mdb->connected = FALSE; - if (pthread_mutex_init(&mdb->mutex, NULL) != 0) { - Mmsg1(&mdb->errmsg, _("Unable to initialize DB mutex. ERR=%s\n"), strerror(errno)); + + if ((errstat=rwl_init(&mdb->lock)) != 0) { + Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), + strerror(errstat)); V(mutex); return 0; } @@ -137,7 +148,7 @@ db_open_database(B_DB *mdb) return 0; } free(db_name); - if (!check_tables_version(mdb)) { + if (!check_tables_version(jcr, mdb)) { V(mutex); return 0; } @@ -148,7 +159,7 @@ db_open_database(B_DB *mdb) } void -db_close_database(B_DB *mdb) +db_close_database(void *jcr, B_DB *mdb) { P(mutex); mdb->ref_count--; @@ -157,9 +168,13 @@ db_close_database(B_DB *mdb) if (mdb->connected && mdb->db) { sqlite_close(mdb->db); } - pthread_mutex_destroy(&mdb->mutex); + rwl_destroy(&mdb->lock); free_pool_memory(mdb->errmsg); free_pool_memory(mdb->cmd); + free_pool_memory(mdb->cached_path); + free_pool_memory(mdb->fname); + free_pool_memory(mdb->path); + free_pool_memory(mdb->esc_name); if (mdb->db_name) { free(mdb->db_name); } @@ -170,48 +185,50 @@ db_close_database(B_DB *mdb) /* * Return the next unique index (auto-increment) for - * the given table. Return NULL on error. + * the given table. Return 0 on error. */ -char *db_next_index(B_DB *mdb, char *table) +int db_next_index(void *jcr, B_DB *mdb, char *table, char *index) { SQL_ROW row; - static char id[20]; - QUERY_DB(mdb, "BEGIN TRANSACTION"); - sql_free_result(mdb); + db_lock(mdb); Mmsg(&mdb->cmd, "SELECT id FROM NextId WHERE TableName=\"%s\"", table); - if (!QUERY_DB(mdb, mdb->cmd)) { + if (!QUERY_DB(jcr, mdb, mdb->cmd)) { Mmsg(&mdb->errmsg, _("next_index query error: ERR=%s\n"), sql_strerror(mdb)); - QUERY_DB(mdb, "ROLLBACK"); - return NULL; + db_unlock(mdb); + return 0; } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg(&mdb->errmsg, _("Error fetching index: ERR=%s\n"), sql_strerror(mdb)); - QUERY_DB(mdb, "ROLLBACK"); - return NULL; + db_unlock(mdb); + return 0; } - strncpy(id, row[0], sizeof(id)); - id[sizeof(id)-1] = 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(mdb, mdb->cmd)) { + if (!QUERY_DB(jcr, mdb, mdb->cmd)) { Mmsg(&mdb->errmsg, _("next_index update error: ERR=%s\n"), sql_strerror(mdb)); - QUERY_DB(mdb, "ROLLBACK"); - return NULL; + db_unlock(mdb); + return 0; } sql_free_result(mdb); - QUERY_DB(mdb, "COMMIT"); - sql_free_result(mdb); - return id; + db_unlock(mdb); + return 1; } - +/* + * Escape strings so that SQLite is happy + * + * NOTE! len is the length of the old string. Your new + * string must be long enough (max 2*old) to hold + * the escaped output. + */ void db_escape_string(char *snew, char *old, int len) { @@ -222,13 +239,8 @@ db_escape_string(char *snew, char *old, int len) while (len--) { switch (*o) { case '\'': - *n++ = '\\'; *n++ = '\''; - o++; - break; - case '"': - *n++ = '\\'; - *n++ = '"'; + *n++ = '\''; o++; break; case 0: @@ -271,7 +283,7 @@ int db_sql_query(B_DB *mdb, char *query, DB_RESULT_HANDLER *result_handler, void struct rh_data rh_data; int stat; - P(mdb->mutex); + db_lock(mdb); if (mdb->sqlite_errmsg) { actuallyfree(mdb->sqlite_errmsg); mdb->sqlite_errmsg = NULL; @@ -281,10 +293,10 @@ int db_sql_query(B_DB *mdb, char *query, DB_RESULT_HANDLER *result_handler, void stat = sqlite_exec(mdb->db, query, sqlite_result, (void *)&rh_data, &mdb->sqlite_errmsg); if (stat != 0) { Mmsg(&mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb)); - V(mdb->mutex); + db_unlock(mdb); return 0; } - V(mdb->mutex); + db_unlock(mdb); return 1; } @@ -389,30 +401,47 @@ list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx) send(ctx, "\n"); } +/* + * If full_list is set, we list vertically, otherwise, we + * list on one line horizontally. + */ void -list_result(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx) +list_result(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, int full_list) { SQL_FIELD *field; SQL_ROW row; - unsigned int i, col_len; + unsigned int i, col_len, max_len = 0; char buf[2000], ewc[30]; if (mdb->result == NULL || mdb->nrow == 0) { + send(ctx, _("No results to list.\n")); return; } /* determine column display widths */ sql_field_seek(mdb, 0); for (i = 0; i < sql_num_fields(mdb); i++) { field = sql_fetch_field(mdb); - if (IS_NUM(field->type) && field->max_length > 0) { /* fixup for commas */ - field->max_length += (field->max_length - 1) / 3; - } col_len = strlen(field->name); - if (col_len < field->max_length) - col_len = field->max_length; - if (col_len < 4 && !IS_NOT_NULL(field->flags)) - col_len = 4; /* 4 = length of the word "NULL" */ - field->max_length = col_len; /* reset column info */ + if (full_list) { + if (col_len > max_len) { + max_len = col_len; + } + } else { + if (IS_NUM(field->type) && field->max_length > 0) { /* fixup for commas */ + field->max_length += (field->max_length - 1) / 3; + } + if (col_len < field->max_length) { + col_len = field->max_length; + } + if (col_len < 4 && !IS_NOT_NULL(field->flags)) { + col_len = 4; /* 4 = length of the word "NULL" */ + } + field->max_length = col_len; /* reset column info */ + } + } + + if (full_list) { + goto horizontal_list; } list_dashes(mdb, send, ctx); @@ -420,7 +449,7 @@ list_result(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx) sql_field_seek(mdb, 0); for (i = 0; i < sql_num_fields(mdb); i++) { field = sql_fetch_field(mdb); - sprintf(buf, " %-*s |", field->max_length, field->name); + bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, field->name); send(ctx, buf); } send(ctx, "\n"); @@ -432,18 +461,39 @@ list_result(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx) for (i = 0; i < sql_num_fields(mdb); i++) { field = sql_fetch_field(mdb); if (row[i] == NULL) { - sprintf(buf, " %-*s |", field->max_length, "NULL"); + bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, "NULL"); } else if (IS_NUM(field->type)) { - sprintf(buf, " %*s |", field->max_length, + bsnprintf(buf, sizeof(buf), " %*s |", (int)field->max_length, add_commas(row[i], ewc)); } else { - sprintf(buf, " %-*s |", field->max_length, row[i]); + bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, row[i]); } send(ctx, buf); } send(ctx, "\n"); } list_dashes(mdb, send, ctx); + return; + +horizontal_list: + + while ((row = sql_fetch_row(mdb)) != NULL) { + sql_field_seek(mdb, 0); + for (i = 0; i < sql_num_fields(mdb); i++) { + field = sql_fetch_field(mdb); + if (row[i] == NULL) { + bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL"); + } else if (IS_NUM(field->type)) { + bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, + add_commas(row[i], ewc)); + } else { + bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]); + } + send(ctx, buf); + } + send(ctx, "\n"); + } + return; }