void bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
void bdb_list_jobmedia_records(JCR *jcr, JobId_t JobId, char *volume, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
void bdb_list_filemedia_records(JCR *jcr, JobId_t JobId, uint32_t FileIndex, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
- void bdb_list_joblog_records(JCR *jcr, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
+ void bdb_list_joblog_records(JCR *jcr, JobId_t JobId, const char *pattern, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
int bdb_list_sql_query(JCR *jcr, const char *title, const char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type);
void bdb_list_client_records(JCR *jcr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
void bdb_list_copies_records(JCR *jcr, uint32_t limit, char *jobids, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
bool bdb_update_snapshot_record(JCR *jcr, SNAPSHOT_DBR *sr);
/* Pure virtual low level methods */
- virtual void bdb_escape_string(JCR *jcr, char *snew, char *old, int len) = 0;
+ virtual void bdb_escape_string(JCR *jcr, char *snew, const char *old, int len) = 0;
virtual char *bdb_escape_object(JCR *jcr, char *old, int len) = 0;
virtual void bdb_unescape_object(JCR *jcr, char *from, int32_t expected_len,
POOLMEM **dest, int32_t *len) = 0;
bool bdb_open_database(JCR *jcr);
void bdb_close_database(JCR *jcr);
void bdb_thread_cleanup(void);
- void bdb_escape_string(JCR *jcr, char *snew, char *old, int len);
+ void bdb_escape_string(JCR *jcr, char *snew, const char *old, int len);
char *bdb_escape_object(JCR *jcr, char *old, int len);
void bdb_unescape_object(JCR *jcr, char *from, int32_t expected_len,
POOLMEM **dest, int32_t *len);
bool bdb_open_database(JCR *jcr);
void bdb_close_database(JCR *jcr);
void bdb_thread_cleanup(void);
- void bdb_escape_string(JCR *jcr, char *snew, char *old, int len);
+ void bdb_escape_string(JCR *jcr, char *snew, const char *old, int len);
char *bdb_escape_object(JCR *jcr, char *old, int len);
void bdb_unescape_object(JCR *jcr, char *from, int32_t expected_len,
POOLMEM **dest, int32_t *len);
* string must be long enough (max 2*old+1) to hold
* the escaped output.
*/
-void BDB_MYSQL::bdb_escape_string(JCR *jcr, char *snew, char *old, int len)
+void BDB_MYSQL::bdb_escape_string(JCR *jcr, char *snew, const char *old, int len)
{
BDB_MYSQL *mdb = this;
mysql_real_escape_string(mdb->m_db_handle, snew, old, len);
* string must be long enough (max 2*old+1) to hold
* the escaped output.
*/
-void BDB_POSTGRESQL::bdb_escape_string(JCR *jcr, char *snew, char *old, int len)
+void BDB_POSTGRESQL::bdb_escape_string(JCR *jcr, char *snew, const char *old, int len)
{
BDB_POSTGRESQL *mdb = this;
int failed;
mdb->bdb_list_jobmedia_records(jcr, JobId, volume, sendit, ctx, type)
#define db_list_filemedia_records(jcr, mdb, JobId, FI, sendit, ctx, type) \
mdb->bdb_list_filemedia_records(jcr, JobId, FI, sendit, ctx, type)
-#define db_list_joblog_records(jcr, mdb, JobId, sendit, ctx, type) \
- mdb->bdb_list_joblog_records(jcr, JobId, sendit, ctx, type)
+#define db_list_joblog_records(jcr, mdb, JobId, pattern, sendit, ctx, type) \
+ mdb->bdb_list_joblog_records(jcr, JobId, pattern, sendit, ctx, type)
#define db_list_sql_query(jcr, mdb, title, query, sendit, ctx, verbose, type) \
mdb->bdb_list_sql_query(jcr, title, query, sendit, ctx, verbose, type)
#define db_list_client_records(jcr, mdb, sendit, ctx, type) \
bdb_unlock();
}
-void BDB::bdb_list_joblog_records(JCR *jcr, uint32_t JobId,
+void BDB::bdb_list_joblog_records(JCR *jcr, uint32_t JobId, const char *pattern,
DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
{
- char ed1[50];
-
- if (JobId <= 0) {
+ if (JobId <= 0 && !pattern) {
return;
}
+
+ POOL_MEM tmp, where2;
+ char ed1[50];
bdb_lock();
+ if (JobId > 0) {
+ Mmsg(tmp, "Log.JobId=%s", edit_int64(JobId, ed1));
+ append_filter(where2.handle(), tmp.c_str());
+ }
+
+ if (pattern) {
+ POOL_MEM esc;
+ esc.check_size(strlen(pattern) * 2 + 1);
+ bdb_escape_string(jcr, esc.c_str(), pattern, strlen(pattern));
+ Mmsg(tmp, "Log.LogText ILIKE '%%%s%%' ", esc.c_str());
+ append_filter(where2.handle(), tmp.c_str());
+ }
+
const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB) |
DB_ACL_BIT(DB_ACL_FILESET) |
- DB_ACL_BIT(DB_ACL_CLIENT), false);
+ DB_ACL_BIT(DB_ACL_CLIENT), where2.c_str()[0] == '\0');
const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) |
DB_ACL_BIT(DB_ACL_FILESET) |
DB_ACL_BIT(DB_ACL_CLIENT)) : "";
-
- if (type == VERT_LIST || type == JSON_LIST) {
+
+ if (type == VERT_LIST) {
Mmsg(cmd, "SELECT Time,LogText FROM Log %s "
- "WHERE Log.JobId=%s %s ORDER BY LogId ASC",
+ "%s %s ORDER BY LogId ASC",
join,
- edit_int64(JobId, ed1),
+ where2.c_str(),
+ where);
+
+ } else if (type == JSON_LIST) {
+ Mmsg(cmd, "SELECT JobId, Time,LogText FROM Log %s "
+ "%s %s ORDER BY LogId ASC",
+ join,
+ where2.c_str(),
where);
} else {
Mmsg(cmd, "SELECT LogText FROM Log %s "
- "WHERE Log.JobId=%s %s ORDER BY LogId ASC",
+ "%s %s ORDER BY LogId ASC",
join,
- edit_int64(JobId, ed1),
+ where2.c_str(),
where);
}
Dmsg1(DT_SQL|50, "q=%s\n", cmd);
* string must be long enough (max 2*old+1) to hold
* the escaped output.
*/
-void BDB_SQLITE::bdb_escape_string(JCR *jcr, char *snew, char *sold, int len)
+void BDB_SQLITE::bdb_escape_string(JCR *jcr, char *snew, const char *sold, int len)
{
char *n, *o;
{ NT_("list"), list_cmd, _("List objects from catalog"),
NT_("jobs [client=<cli>] [jobid=<nn>] [ujobid=<name>] [job=<name>] [tag=<name>] [joberrors] [jobstatus=<s>] [level=<l>] [jobtype=<t>] [days=<n>] [hours=<n>] [limit=<n>] [order=<asc|desc>]|\n"
"\tjobtotals | pools | volume | media <pool=pool-name> | files [type=<deleted|all>] jobid=<nn> | copies jobid=<nn> |\n"
- "\tjoblog jobid=<nn> | pluginrestoreconf jobid=<nn> restoreobjectid=<nn> | snapshot | \n"
+ "\tjoblog [pattern=<str>] jobid=<nn> | pluginrestoreconf jobid=<nn> restoreobjectid=<nn> | snapshot | \n"
"\tfilemedia jobid=<nn> fileindex=<mm> | clients | jobmedia [jobid=<nn> volume=<s>] |\n"
"\tevents [type=<str> | limit=<int> | order=<asc|desc> | days=<int> | start=<time-specification> | end=<time-specification> |\n"
"\t\t source=<str> | code=<str> | type=<str> ]\n"
* list jobname=name - same as above
* list jobmedia jobid=<nn>
* list jobmedia job=name
- * list joblog jobid=<nn>
+ * list joblog pattern=xxx jobid=<nn>
+ * list joblog pattern=xxx jobid=<nn>
* list joblog job=name
* list files [type=<deleted|all>] jobid=<nn> - list files saved for job nn
* list files [type=<deleted|all>] job=name
/* List JOBLOG */
} else if (strcasecmp(ua->argk[i], NT_("joblog")) == 0) {
bool done = false;
+ const char *pattern=NULL;
for (j=i+1; j<ua->argc; j++) {
if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j]) {
bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
jr.JobId = 0;
db_get_job_record(ua->jcr, ua->db, &jr);
jobid = jr.JobId;
+
} else if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
jobid = str_to_int64(ua->argv[j]);
+
+ } else if (strcasecmp(ua->argk[j], NT_("pattern")) == 0 && ua->argv[j]) {
+ pattern = ua->argv[j];
+ continue;
+
} else {
continue;
}
- db_list_joblog_records(ua->jcr, ua->db, jobid, prtit, ua, llist);
+ db_list_joblog_records(ua->jcr, ua->db, jobid, pattern, prtit, ua, llist);
done = true;
}
if (!done) {
/* List for all jobs (jobid=0) */
- db_list_joblog_records(ua->jcr, ua->db, 0, prtit, ua, llist);
+ db_list_joblog_records(ua->jcr, ua->db, 0, pattern, prtit, ua, llist);
}
-
/* List POOLS */
} else if (strcasecmp(ua->argk[i], NT_("pool")) == 0 ||
strcasecmp(ua->argk[i], NT_("pools")) == 0) {
|| strcasecmp(ua->argk[i], NT_("daemon")) == 0
|| strcasecmp(ua->argk[i], NT_("code")) == 0
|| strcasecmp(ua->argk[i], NT_("offset")) == 0
+ || strcasecmp(ua->argk[i], NT_("pattern")) == 0
) {
/* Ignore it */
} else if (strcasecmp(ua->argk[i], NT_("snapshot")) == 0 ||