int order;
int orderby; // 0: JobId, FileIndex 1: EmailTime
bool all;
+ bool alljobs; // query all jobs, else return only the last version
char *JobIds;
char Id[MAX_SEARCH_LENGTH];
char errmsg[MAX_NAME_LENGTH];
META_DBR(): MinSize(-1), MaxSize(-1), HasAttachment(-1),
isDraft(-1), isRead(-1), isInline(-1), offset(0), limit(512),
- order(0), orderby(0), all(false)
+ order(0), orderby(0), all(false),alljobs(false)
{
JobIds = NULL;
*Id = *Tenant = *Owner = 0;
POOL_MEM esc(PM_MESSAGE), tmp(PM_MESSAGE), where(PM_MESSAGE), join(PM_MESSAGE);
bdb_lock();
+ /* We use the command line to generate the SQL query with what the user
+ * want to filter
+ */
meta_r->create_db_filter(jcr, this, where.handle());
+
+ /* We also apply ACL via SQL (here on the Client name and the Job name) if we
+ * are in a restricted console
+ */
const char *where_filter = get_acls(DB_ACL_BIT(DB_ACL_JOB) |
DB_ACL_BIT(DB_ACL_CLIENT), strcmp(where.c_str(), "") == 0);
bdb_list_metadata_owner_records(jcr, meta_r, sendit, ctx, type);
return;
}
-
+ const char *k1=""; // set to Attachment if it is appropriate
POOL_MEM esc(PM_MESSAGE), tmp(PM_MESSAGE), where(PM_MESSAGE), join(PM_MESSAGE);
bdb_lock();
//TODO add ACL part
}
if (strcmp(meta_r->Type, "Attachment") == 0) {
+ k1 = "Attachment";
pm_strcat(join, " JOIN MetaEmail ON (EmailId = AttachmentEmailId AND MetaEmail.JobId = MetaAttachment.JobId) ");
}
if (join_filter && *join_filter) {
pm_strcat(join, join_filter);
}
+
+ if (!meta_r->alljobs) {
+ /* The idea is to get only the last occurence of each email. The key differentiator is
+ * the EmailId, and we use the Job table via the StartTime to select the latest version
+ *
+ * should give
+ * AND MetaEmail.JobId = (SELECT JobId FROM Job JOIN MetaEmail AS B USING (JobId) <ACL filters>
+ * WHERE MetaEmail.EmailId=B.EmailId <ACL filters> ORDER BY StartTime DESC LIMIT 1
+ * or
+ * AND MetaAttachment.JobId = (SELECT JobId FROM Job JOIN MetaAttachment AS B USING (JobId) <ACL filters>
+ * WHERE MetaAttachment.AttachmentEmailId=B.AttachmentEmailId <ACL filters> ORDER BY StartTime DESC LIMIT 1
+ */
+ Mmsg(tmp,
+ " AND Meta%s.JobId = (SELECT JobId FROM Job JOIN Meta%s AS B USING (JobId) %s WHERE Meta%s.%sEmailId=B.%sEmailId %s ORDER BY StartTime DESC LIMIT 1) ",
+ meta_r->Type, meta_r->Type, join_filter, meta_r->Type, k1, k1, where_filter);
+ pm_strcat(where, tmp.c_str());
+ }
if (meta_r->orderby == 1) {
Mmsg(tmp, " ORDER BY EmailTime %s ", meta_r->order ? "DESC" : "ASC");
"\t\t source=<str> | code=<str> | type=<str> ]\n"
"\tobjects [jobid=<jobid> client=<cli> type=<str> | category=<str|db|vm> | status=<S> | limit=<int> | order=<asc|desc> ]\n"
"\tmetadata type=<email|attachment> tenant=<str> [owner=<str>]\n"
- "\t [jobid=<jobids> client=<cc> order=<Asc|desc> limit=<nn> orderby=<time> offset=<nn>]\n"
+ "\t [jobid=<jobids> client=<cc> order=<Asc|desc> limit=<nn> orderby=<time> offset=<nn>] alljobs\n"
"\t [from=<str> to=<str> cc=<str> tags=<str> subject=<str> bodypreview=<str> all=<str>\n"
"\t minsize=<int> maxsize=<int> importance=<str> isread=<0|1> isdraft=<0|1> categories=<str>\n"
"\t conversationid=<str> hasattachment=<0|1> starttime=<time> endtime=<time>\n"
"\tfilemedia jobid=<nn> fileindex=<mm> | clients\n"
"\tevents [type=<str> | limit=<int> | order=<asc|desc> | days=<int> | start=<time-specification> | end=<time-specification> ]\n"
"\tobject [jobid=<jobid> client=<cli> type=<name> category=<str> order=<asc/desc> limit=<n>\n"
- "\tmetadata type=<email|attachment> tenant=<str> owner=<str> \n"
+ "\tmetadata type=<email|attachment> tenant=<str> owner=<str> alljobs\n"
"\t [jobid=<jobids> client=<cc> order=<Asc|desc> limit=<nn> orderby=<time> offset=<nn>]\n"
"\t [ from=<str> to=<str> cc=<str> tags=<str> subject=<str> bodypreview=<str> all=<str>\n"
"\t importance=<str> isread=<0|1> isdraft=<0|1> categories=<str>\n"
* importance=<str> isread=<0|1> isdraft=<0|1>
* categories=<str> conversationid=<str> hasattachment=<0|1>
* starttime=<time> endtime=<time>
- * limit=<int> offset=<int> order=<Asc|desc>
+ * limit=<int> offset=<int> order=<Asc|desc> alljobs
* emailid=<str>
*
* Note: keyword "long" is before the first command on the command
META_DBR meta_r;
for (j=i+1; j<ua->argc; j++) {
- if (!ua->argv[j]) {
+ if (strcasecmp(ua->argk[j], NT_("alljobs")) == 0) {
+ meta_r.alljobs = 1;
+ } else if (!ua->argv[j]) {
ua->error_msg(_("Invalid %s argument. Expecting value\n"), ua->argk[j]);
return 1;
} else if (strcasecmp(ua->argk[j], NT_("jobid")) == 0) {