bool bdb_create_batch_file_attributes_record(JCR *jcr, ATTR_DBR *ar);
/* sql_get.c */
+ char *bdb_get_jobids(const char *jobids, POOLMEM **ret, bool append);
bool bdb_get_file_record(JCR *jcr, JOB_DBR *jr, FILE_DBR *fdbr);
bool bdb_get_snapshot_record(JCR *jcr, SNAPSHOT_DBR *snap);
bool bdb_get_volume_jobids(JCR *jcr,
/* sql_list.c */
void bdb_list_pool_records(JCR *jcr, POOL_DBR *pr, DB_LIST_HANDLER sendit, void *ctx, e_list_type type);
alist *bdb_list_job_records(JCR *jcr, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx, e_list_type type);
+ void bdb_list_jobs_for_file(JCR *jcr, const char *client, const char *fname, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
void bdb_list_job_totals(JCR *jcr, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx);
void bdb_list_files_for_job(JCR *jcr, uint32_t jobid, int deleted, DB_LIST_HANDLER sendit, void *ctx);
void bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
ARG_LIST, /* key1=v1 key2=v2 key3=v3 */
JSON_LIST,
FAILED_JOBS,
- INCOMPLETE_JOBS
+ INCOMPLETE_JOBS,
+ LAST_JOBS
};
#include "bdb.h"
if (mdb) mdb->bdb_thread_cleanup()
/* sql.c */
+int db_jobids_handler(void *ctx, int num_fields, char **row);
int db_mint64_handler(void *ctx, int num_fields, char **row);
int db_int64_handler(void *ctx, int num_fields, char **row);
int db_strtime_handler(void *ctx, int num_fields, char **row);
#define db_get_client_pool(jcr, mdb, results) \
mdb->bdb_get_client_pool(jcr, results)
+#define db_get_jobids(jcr, mdb, jobids, ret, append) \
+ mdb->bdb_get_jobids(jobids, ret, append)
+
/* sql_create.c */
#define db_create_log_record(jcr, mdb, jobid, mtime, msg) \
mdb->bdb_create_log_record(jcr, jobid, mtime, msg)
#define db_get_job_statistics(jcr, mdb, jr) \
mdb->bdb_get_job_statistics(jcr, jr)
/* sql_list.c */
+#define db_list_jobs_for_file(jcr, mdb, cli, fname, result_handler, ctx, type) \
+ mdb->bdb_list_jobs_for_file(jcr, cli, fname, result_handler, ctx, type)
#define db_list_pool_records(jcr, mdb, pr, sendit, ctx, type) \
mdb->bdb_list_pool_records(jcr, pr, sendit, ctx, type)
#define db_list_job_records(jcr, mdb, jr, sendit, ctx, type) \
free(DBId);
}
-/*
- * Called here to retrieve an resource name (e.g. Storage name) from the database
- */
+/*
+ * Called here to retrieve a resource name (e.g. Storage name) from the database
+ */
int db_name_handler(void *ctx, int num_fields, char **row)
{
char *name = (char *)ctx;
return 0;
}
+/*
+ * Called here to retrieve a list of jobid x,y,z from the database
+ */
+int db_jobids_handler(void *ctx, int num_fields, char **row)
+{
+ POOLMEM **ret = (POOLMEM **)ctx;
+ if (row[0]) {
+ if (**ret) {
+ pm_strcat(ret, ",");
+ }
+ pm_strcat(ret, row[0]);
+ }
+ return 0;
+}
+
/*
* Called here to retrieve an string list from the database
*/
*/
char *BDB::get_acls(int tables, bool where /* use WHERE or AND */)
{
- POOL_MEM tmp;
pm_strcpy(acl_where, "");
for (int i=0 ; i < DB_ACL_LAST; i++) {
return acl_where;
}
+char *BDB::bdb_get_jobids(const char *jobids, POOLMEM **ret, bool append)
+{
+ if (!ret || !*ret) {
+ return NULL;
+ }
+
+ if (!append) { // Return empty list if append = false
+ pm_strcpy(ret, "");
+ }
+
+ if (!jobids || !*jobids || !is_a_number_list(jobids)) {
+ return *ret;
+ }
+
+ bdb_lock();
+ /* Get optional filters for the SQL query */
+ const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET), false);
+
+ const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET)) : "";
+ /* No filters, no need to run the query */
+ if (!*where && !*join) {
+ if (*ret[0]) {
+ pm_strcat(ret, ",");
+ }
+ pm_strcat(ret, jobids);
+ goto bail_out;
+ }
+ Mmsg(cmd, "SELECT Job.JobId as JobId "
+ "FROM Job %s WHERE JobId IN (%s%s%s) %s ORDER BY JobTDate ASC",
+ join,
+ *ret /* previous list */,
+ *ret[0] ? "," : "" /* comma to separate from the new list */,
+ jobids,
+ where);
+
+ /* We start from a fresh list, previous entries will be listed */
+ pm_strcpy(ret, "");
+
+ Dmsg1(50|DT_SQL, "q=%s\n", cmd);
+ if(!bdb_sql_query(cmd, db_jobids_handler, ret)) {
+ goto bail_out;
+ }
+
+bail_out:
+ sql_free_result();
+ bdb_unlock();
+ return *ret;
+}
+
/* Create the JOIN string that will help to filter queries results */
char *BDB::get_acl_join_filter(int tables)
{
const char *uar_count_files =
"SELECT JobFiles FROM Job WHERE JobId=%s";
-/* List last 20 Jobs */
-const char *uar_list_jobs =
- "SELECT JobId,Client.Name as Client,Job.Name as Name,StartTime,Level as "
- "JobLevel,JobFiles,JobBytes "
- "FROM Client,Job WHERE Client.ClientId=Job.ClientId AND JobStatus IN ('T','W') "
- "AND Type='B' ORDER BY StartTime DESC LIMIT 20";
-
const char *uar_print_jobs =
"SELECT DISTINCT JobId,Level,JobFiles,JobBytes,StartTime,VolumeName"
" FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) "
"AND Path.PathId=File.PathId "
"ORDER BY Job.StartTime DESC LIMIT 1";
-/* Query to get list of files from table -- presuably built by an external program */
+/* Query to get list of files from table -- presuably built by an external program
+ * we expect filters on join and where
+ */
const char *uar_jobid_fileindex_from_table =
- "SELECT JobId, FileIndex FROM %s ORDER BY JobId, FileIndex ASC";
+ "SELECT JobId, FileIndex FROM %s %s %s ORDER BY JobId, FileIndex ASC";
/* Get the list of the last recent version per Delta with a given
* jobid list. This is a tricky part because with SQL the result of:
/* ======= ua_restore.c ====== */
-/* List Jobs where a particular file is saved */
-const char *uar_file[] =
-{
- /* MySQL */
- "SELECT Job.JobId as JobId,"
- "CONCAT(Path.Path,File.Filename) as Name, "
- "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes "
- "FROM Client,Job,File,Path WHERE Client.Name='%s' "
- "AND Client.ClientId=Job.ClientId "
- "AND Job.JobId=File.JobId AND File.FileIndex > 0 "
- "AND Path.PathId=File.PathId "
- "AND File.Filename='%s' ORDER BY StartTime DESC LIMIT 20",
-
- /* PostgreSQL */
- "SELECT Job.JobId as JobId,"
- "Path.Path||File.Filename as Name, "
- "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes "
- "FROM Client,Job,File,Path WHERE Client.Name='%s' "
- "AND Client.ClientId=Job.ClientId "
- "AND Job.JobId=File.JobId AND File.FileIndex > 0 "
- "AND Path.PathId=File.PathId "
- "AND File.Filename='%s' ORDER BY StartTime DESC LIMIT 20",
-
- /* SQLite */
- "SELECT Job.JobId as JobId,"
- "Path.Path||File.Filename as Name, "
- "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes "
- "FROM Client,Job,File,Path WHERE Client.Name='%s' "
- "AND Client.ClientId=Job.ClientId "
- "AND Job.JobId=File.JobId AND File.FileIndex > 0 "
- "AND Path.PathId=File.PathId "
- "AND File.Filename='%s' ORDER BY StartTime DESC LIMIT 20"
-};
-
const char *uar_create_temp[] =
{
/* MySQL */
"FROM Job %s %s ORDER BY StartTime %s,JobId %s %s",
join, where, order, order, limit);
break;
+ case LAST_JOBS:
+ Mmsg(cmd,
+ "SELECT JobId,Client1.Name as Client,Job.Name as Name,StartTime,Level as "
+ "JobLevel,JobFiles,JobBytes "
+ "FROM Client AS Client1 JOIN Job USING (ClientId) %s %s AND JobStatus IN ('T','W') "
+ "ORDER BY StartTime %s %s", join, where, order, limit);
+
default:
break;
}
bdb_unlock();
}
+/* List all file records from a job
+ * "deleted" values are described just below
+ */
+void BDB::bdb_list_jobs_for_file(JCR *jcr, const char *client, const char *fname, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
+{
+ if (!client || !*client || !fname || !*fname) {
+ return;
+ }
+ const char *concat="Path.Path||File.Filename";
+
+ if (bdb_get_type_index() == SQL_TYPE_MYSQL) {
+ concat = " CONCAT(Path.Path,File.Filename) ";
+ }
+
+ bdb_lock();
+ /* Get optional filters for the SQL query */
+ const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET), false);
+
+ const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_FILESET)) : "";
+
+ int len = strlen(fname);
+ char *esc = (char *)malloc(len * 2 + 1);
+ bdb_escape_string(jcr, esc, (char *)fname, len);
+
+ len = strlen(client);
+ char *esc2 = (char *)malloc(len * 2 + 1);
+ bdb_escape_string(jcr, esc2, (char *)client, len);
+
+ Mmsg(cmd, "SELECT Job.JobId as JobId,"
+ "%s as Name, " // Concat of the filename
+ "StartTime, Type as JobType, JobStatus,JobFiles,JobBytes "
+ "FROM Client JOIN Job USING (ClientId) JOIN File USING (JobId) JOIN Path USING (PathId) %s "
+ "WHERE Client.Name = '%s' "
+ "AND File.FileIndex > 0 "
+ "AND File.Filename='%s' %s ORDER BY StartTime DESC LIMIT 20", concat, join, esc2, esc, where);
+
+ free(esc);
+ free(esc2);
+ Dmsg1(DT_SQL|50, "q=%s\n", cmd);
+ if (!QueryDB(jcr, cmd)) {
+ goto bail_out;
+ }
+
+ list_result(jcr, this, "job", sendit, ctx, HORZ_LIST);
+bail_out:
+ sql_free_result();
+ bdb_unlock();
+}
+
#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL */
count = get_prune_list_for_volume(ua, &lmr, &prune_list);
Dmsg1(100, "Num pruned = %d\n", count);
if (count != 0) {
- purge_job_list_from_catalog(ua, prune_list);
+ purge_job_list_from_catalog(ua, prune_list); /* JobId list not coming from outside */
prune_list.num_ids = 0; /* reset count */
}
if (!is_volume_purged(ua, &lmr)) {
if (jcr->job->PurgeMigrateJob) {
/* Purge old Job record */
- purge_jobs_from_catalog(ua, old_jobid);
+ purge_jobs_from_catalog(ua, old_jobid); // JobId is safe
} else {
/* Purge all old file records, but leave Job record */
- purge_files_from_jobs(ua, old_jobid);
+ purge_files_from_jobs(ua, old_jobid); // JobId is safe
}
free_ua_context(ua);
int truncate_cmd(UAContext *ua, const char *cmd);
static const char *select_jobsfiles_from_client =
- "SELECT JobId FROM Job "
- "WHERE ClientId=%s "
+ "SELECT JobId FROM Job %s "
+ "WHERE ClientId=%s %s "
"AND PurgedFiles=0";
static const char *select_jobs_from_client =
- "SELECT JobId, PurgedFiles FROM Job "
- "WHERE ClientId=%s";
+ "SELECT JobId, PurgedFiles FROM Job %s "
+ "WHERE ClientId=%s %s";
/*
* Purge records from database
case 0: /* Job */
case 1: /* JobId */
if (get_job_dbr(ua, &jr)) {
- char jobid[50];
- edit_int64(jr.JobId, jobid);
- purge_files_from_jobs(ua, jobid);
+ if (acl_access_ok(ua, Job_ACL, jr.Name)) {
+ char jobid[50];
+ edit_int64(jr.JobId, jobid);
+ purge_files_from_jobs(ua, jobid);
+ }
}
return 1;
case 2: /* client */
ua->send_events("DC0001", EVENTS_TYPE_COMMAND, "purge files client=%s", cr.Name);
ua->info_msg(_("Begin purging files for Client \"%s\"\n"), cr.Name);
- Mmsg(query, select_jobsfiles_from_client, edit_int64(cr.ClientId, ed1));
- Dmsg1(050, "select sql=%s\n", query.c_str());
- db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del);
+ db_lock(ua->db);
+ {
+ /* Get optional filters for the SQL query */
+ const char *where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET), false);
+
+ const char *join = *where ? ua->db->get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET)) : "";
+
+ Mmsg(query, select_jobsfiles_from_client, join, edit_int64(cr.ClientId, ed1), where);
+ Dmsg1(050, "select sql=%s\n", query.c_str());
+ db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del);
+ }
+ db_unlock(ua->db);
purge_files_from_job_list(ua, del);
del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
del.PurgedFiles = (char *)malloc(del.max_ids);
+ /* We filter the JobId list with ACL console if any */
+ db_lock(ua->db);
+ {
+ /* Get optional filters for the SQL query */
+ const char *where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET), false);
+
+ const char *join = *where ? ua->db->get_acl_join_filter(DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET)) : "";
+
+ if (job) {
+ /* Limit purged jobs to specified job's name */
+ char esc[MAX_ESCAPE_NAME_LENGTH];
+ db_escape_string(ua->jcr, ua->jcr->db, esc, job, strlen(job));
+ Mmsg(query, "SELECT JobId,PurgedFiles FROM Job %s WHERE ClientId=%s AND Name='%s' %s",
+ join, edit_int64(cr.ClientId, ed1), esc, where);
+
+ } else {
+ Mmsg(query, select_jobs_from_client, join, edit_int64(cr.ClientId, ed1), where);
+ }
+ }
+ db_unlock(ua->db);
if (job) {
- /* Limit purged jobs to specified job's name */
- char esc[MAX_ESCAPE_NAME_LENGTH];
- db_escape_string(ua->jcr, ua->jcr->db, esc, job, strlen(job));
- Mmsg(query, "SELECT JobId,PurgedFiles FROM Job WHERE ClientId=%s AND Name='%s'",
- edit_int64(cr.ClientId, ed1), esc);
ua->info_msg(_("Begin purging jobs \"%s\" from Client \"%s\"\n"), job, cr.Name);
-
} else {
- Mmsg(query, select_jobs_from_client, edit_int64(cr.ClientId, ed1));
ua->info_msg(_("Begin purging jobs from Client \"%s\"\n"), cr.Name);
}
-
+
Dmsg1(150, "select sql=%s\n", query.c_str());
db_sql_query(ua->db, query.c_str(), job_delete_handler, (void *)&del);
- purge_job_list_from_catalog(ua, del);
+ purge_job_list_from_catalog(ua, del); /* JobId list secured */
if (del.num_del == 0) {
ua->warning_msg(_("No Jobs found for client %s to purge from %s catalog.\n"),
return 1;
}
-
/*
- * Remove File records from a list of JobIds
+ * Remove File records from a list of JobIds. Jobs must be secured.
*/
void purge_files_from_jobs(UAContext *ua, char *jobs)
{
/*
* Delete jobs (all records) from the catalog in groups of 1000
* at a time.
+ * The JobId list must be secured when entering here
*/
void purge_job_list_from_catalog(UAContext *ua, del_ctx &del)
{
/*
* Remove all records from catalog for a list of JobIds
+ * The code in tools/dbcheck.c has to be updated as well
+ * jobs must be secured.
*/
void purge_jobs_from_catalog(UAContext *ua, char *jobs)
{
jobids = lst.list;
}
+ /* We filter out the list of JobId using the one we are allowed by ACL */
+ jobids = db_get_jobids(ua->jcr, ua->db, jobids, query.handle(), false);
+
+ /* Get the right count of job (count the number of , + 1) */
+ i = (*jobids == 0) ? 1 : 0;
+ for (char *p = jobids; *p ; p++) {
+ if (*p == ',') {
+ i++;
+ }
+ }
+
if (*jobids) {
/* Keep track of this important event */
ua->send_events("DC0003", EVENTS_TYPE_COMMAND, "purge volume=%s", mr->VolumeName);
- purge_jobs_from_catalog(ua, jobids);
+ purge_jobs_from_catalog(ua, jobids); /* JobId list secured */
ua->info_msg(_("%d Job%s on Volume \"%s\" purged from catalog.\n"),
- lst.count, lst.count<=1?"":"s", mr->VolumeName);
+ i, i<=1?"":"s", mr->VolumeName);
}
purged = is_volume_purged(ua, mr, force);
if (!has_value(ua, i)) {
return 0;
}
- if (*rx->JobIds != 0) {
- pm_strcat(rx->JobIds, ",");
- }
- pm_strcat(rx->JobIds, ua->argv[i]);
+ db_get_jobids(ua->jcr, ua->db, ua->argv[i], &rx->JobIds, true /* append the result */);
done = true;
break;
case 1: /* current */
/* If choice not already made above, prompt */
for ( ; !done; ) {
- char *fname;
int len;
bool gui_save;
db_list_ctx jobids;
ua->error_msg(_("SQL query not authorized.\n"));
return 0;
}
- gui_save = ua->jcr->gui;
- ua->jcr->gui = true;
- db_list_sql_query(ua->jcr, ua->db, "job", uar_list_jobs, prtit, ua, 1, HORZ_LIST);
- ua->jcr->gui = gui_save;
- done = false;
+ {
+ memset(&jr, 0, sizeof(jr));
+ jr.limit=20;
+ jr.JobType = 'B';
+ jr.order = 1; // DESC
+ gui_save = ua->jcr->gui;
+ ua->jcr->gui = true;
+ /* db_list_job_records() has builtin console filters */
+ db_list_job_records(ua->jcr, ua->db, &jr, prtit, ua, LAST_JOBS);
+ ua->jcr->gui = gui_save;
+ done = false;
+ }
break;
case 1: /* list where a file is saved */
if (!get_client_name(ua, rx)) {
if (!get_cmd(ua, _("Enter Filename (no path):"))) {
return 0;
}
- len = strlen(ua->cmd);
- fname = (char *)malloc(len * 2 + 1);
- db_escape_string(ua->jcr, ua->db, fname, ua->cmd, len);
- Mmsg(rx->query, uar_file[db_get_type_index(ua->db)], rx->ClientName, fname);
- free(fname);
gui_save = ua->jcr->gui;
ua->jcr->gui = true;
- db_list_sql_query(ua->jcr, ua->db, "job", rx->query, prtit, ua, 1, HORZ_LIST);
+ db_list_jobs_for_file(ua->jcr, ua->db, rx->ClientName, ua->cmd, prtit, ua, HORZ_LIST);
ua->jcr->gui = gui_save;
done = false;
break;
if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
return 0;
}
- pm_strcpy(rx->JobIds, ua->cmd);
+ db_get_jobids(ua->jcr, ua->db, ua->cmd, &rx->JobIds, false /* clear */);
break;
case 3: /* Enter an SQL list command */
if (!acl_access_ok(ua, Command_ACL, NT_("sqlquery"), 8)) {
if (len == 0) {
break;
}
+ if (ua->cmd[0] == '?') {
+ continue; // We do not want to accept a SQL table here
+ }
insert_one_file_or_dir(ua, rx, date, false);
}
return 2;
if (len == 0) {
break;
}
+ if (ua->cmd[0] == '?') {
+ continue; // We do not want to accept a SQL table here
+ }
insert_one_file_or_dir(ua, rx, date, false);
}
return 2;
if (*rx->JobIds != 0) {
ua->send_msg(_("You have already selected the following JobIds: %s\n"),
rx->JobIds);
+
} else if (get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
- if (*rx->JobIds != 0 && *ua->cmd) {
- pm_strcat(rx->JobIds, ",");
+ if (*ua->cmd == '.') {
+ *rx->JobIds = 0;
+ return 0; /* nothing entered, return */
}
- pm_strcat(rx->JobIds, ua->cmd);
- }
- if (*rx->JobIds == 0 || *rx->JobIds == '.') {
- *rx->JobIds = 0;
- return 0; /* nothing entered, return */
+ db_get_jobids(ua->jcr, ua->db, ua->cmd, &rx->JobIds, false /* clear */);
+ if (*rx->JobIds == 0) {
+ ua->error_msg(_("No JobId selected\n"));
+ return 0; /* nothing entered, return */
+ }
+ ua->send_msg(_("You have selected the following JobIds: %s\n"),
+ rx->JobIds);
}
if (!have_date) {
bstrutime(date, sizeof(date), now);
if (ua->cmd[0] != '<' && !IsPathSeparator(ua->cmd[len-1])) {
strcat(ua->cmd, "/");
}
+ if (ua->cmd[0] == '?') {
+ continue; // We do not want to accept a SQL table here
+ }
insert_one_file_or_dir(ua, rx, date, true);
}
return 2;
}
//TODO Validation if id entered matches one from list above would be nice...
- if (!get_pint(ua, "Enter ID of Object to be restored: ")) {
+ if (!get_pint(ua, _("Enter ID of Object to be restored: "))) {
ua->info_msg(_("Selection aborted, nothing done.\n"));
break;
}
{
component_file_ctx ctx;
strip_trailing_junk(table);
- Mmsg(rx->query, uar_jobid_fileindex_from_table, table);
+ if (strcasecmp(table, "file") == 0 || !is_name_valid(table, NULL, "")) {
+ ua->error_msg(_("Incorrect table name\n"));
+ return false;
+ }
+ bool ret;
+ db_lock(ua->db);
+ {
+ /* Get optional filters for the SQL query */
+ const char *where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET), true);
- rx->found = false;
+ const char *join = *where ? ua->db->get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET)) : "";
- /* Find and insert jobid and File Index. The JobIds are stored in rx->JobIds */
- if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) {
+ Mmsg(rx->query, uar_jobid_fileindex_from_table, table, join, where);
+ rx->found = false;
+
+ /* Find and insert jobid and File Index. The JobIds are stored in rx->JobIds */
+ ret = db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx);
+ }
+ db_unlock(ua->db);
+ if (!ret) {
ua->error_msg(_("Query failed: %s. ERR=%s\n"),
- rx->query, db_strerror(ua->db));
+ rx->query, db_strerror(ua->db));
}
if (!rx->found) {
ua->error_msg(_("No table found: %s\n"), table);
}
}
}
+
/*
* Dump out all resources in json format.
* Note!!!! This routine must be in this file rather