]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Modify list metadata to return only the last occurence of the data by default
authorEric Bollengier <eric@baculasystems.com>
Thu, 17 Mar 2022 15:22:14 +0000 (16:22 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:58 +0000 (13:56 +0200)
bacula/src/cats/cats.h
bacula/src/cats/sql_list.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_output.c

index 6974f99e104653d194ee105dd062577f815e12e3..17153255cc3db525964145c4c054a2533f3160bc 100644 (file)
@@ -656,6 +656,7 @@ public:
    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];
@@ -680,7 +681,7 @@ public:
    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;
index d0454b87a14a9933ca2d59231d454711201aa541..2fa7b33cfff957d21c662964e7df3bad3e7f32d4 100644 (file)
@@ -1301,7 +1301,14 @@ void BDB::bdb_list_metadata_owner_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HA
    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);
 
@@ -1373,7 +1380,7 @@ void BDB::bdb_list_metadata_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER
       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
@@ -1394,6 +1401,7 @@ void BDB::bdb_list_metadata_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER
    }
 
    if (strcmp(meta_r->Type, "Attachment") == 0) {
+      k1 = "Attachment";
       pm_strcat(join, " JOIN MetaEmail ON (EmailId = AttachmentEmailId AND MetaEmail.JobId = MetaAttachment.JobId) ");
    }
    
@@ -1404,6 +1412,23 @@ void BDB::bdb_list_metadata_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER
    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");
index fc9859bdcdb8db509d615c4a485f3fd78ce30e94..e790cebe78c139562da1ec87bfda6c4063d183c0 100644 (file)
@@ -139,7 +139,7 @@ static struct cmdstruct commands[] = {                                      /* C
        "\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"
@@ -153,7 +153,7 @@ static struct cmdstruct commands[] = {                                      /* C
        "\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"
index ae6343cb2156758765ec033c0b83e1941607ddf3..133e09461c6bd6755bf64b9cc9cb7cf8262b45f5 100644 (file)
@@ -343,7 +343,7 @@ bail_out:
  *             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 
@@ -951,7 +951,9 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
          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) {