+/* The decision do change an incr/diff was done before
+ * Full : do nothing
+ * Differential : get the last full id
+ * Incremental : get the last full + last diff + last incr(s) ids
+ *
+ * TODO: look and merge from ua_restore.c
+ */
+bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
+ JOB_DBR *jr, POOLMEM *jobids)
+{
+ bool ret=false;
+ char clientid[50], jobid[50], filesetid[50];
+ char date[MAX_TIME_LENGTH];
+ POOL_MEM query(PM_FNAME);
+ bstrutime(date, sizeof(date), time(NULL) + 1);
+ jobids[0]='\0';
+
+ /* First, find the last good Full backup for this job/client/fileset */
+ Mmsg(query,
+"CREATE TABLE btemp3%s AS "
+ "SELECT JobId, StartTime, EndTime, JobTDate, PurgedFiles "
+ "FROM Job JOIN FileSet USING (FileSetId) "
+ "WHERE ClientId = %s "
+ "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' "
+ "AND StartTime<'%s' "
+ "AND FileSet.FileSet=(SELECT FileSet FROM FileSet WHERE FileSetId = %s) "
+ "ORDER BY Job.JobTDate DESC LIMIT 1",
+ edit_uint64(jcr->JobId, jobid),
+ edit_uint64(jr->ClientId, clientid),
+ date,
+ edit_uint64(jr->FileSetId, filesetid));
+
+ if (!db_sql_query(mdb, query.c_str(), NULL, NULL)) {
+ goto bail_out;
+ }
+
+ if (jr->JobLevel == L_INCREMENTAL || jr->JobLevel == L_VIRTUAL_FULL) {
+ /* Now, find the last differential backup after the last full */
+ Mmsg(query,
+"INSERT INTO btemp3%s (JobId, StartTime, EndTime, JobTDate, PurgedFiles) "
+ "SELECT JobId, StartTime, EndTime, JobTDate, PurgedFiles "
+ "FROM Job JOIN FileSet USING (FileSetId) "
+ "WHERE ClientId = %s "
+ "AND Level='D' AND JobStatus IN ('T','W') AND Type='B' "
+ "AND StartTime > (SELECT EndTime FROM btemp3%s ORDER BY EndTime DESC LIMIT 1) "
+ "AND FileSet.FileSet= (SELECT FileSet FROM FileSet WHERE FileSetId = %s) "
+ "ORDER BY Job.JobTDate DESC LIMIT 1 ",
+ jobid,
+ clientid,
+ jobid,
+ filesetid);
+
+ if (!db_sql_query(mdb, query.c_str(), NULL, NULL)) {
+ goto bail_out;
+ }
+
+ /* We just have to take all incremental after the last Full/Diff */
+ Mmsg(query,
+"INSERT INTO btemp3%s (JobId, StartTime, EndTime, JobTDate, PurgedFiles) "
+ "SELECT JobId, StartTime, EndTime, JobTDate, PurgedFiles "
+ "FROM Job JOIN FileSet USING (FileSetId) "
+ "WHERE ClientId = %s "
+ "AND Level='I' AND JobStatus IN ('T','W') AND Type='B' "
+ "AND StartTime > (SELECT EndTime FROM btemp3%s ORDER BY EndTime DESC LIMIT 1) "
+ "AND FileSet.FileSet= (SELECT FileSet FROM FileSet WHERE FileSetId = %s) "
+ "ORDER BY Job.JobTDate DESC ",
+ jobid,
+ clientid,
+ jobid,
+ filesetid);
+ if (!db_sql_query(mdb, query.c_str(), NULL, NULL)) {
+ goto bail_out;
+ }
+ }
+
+ /* build a jobid list ie: 1,2,3,4 */
+ Mmsg(query, "SELECT JobId FROM btemp3%s ORDER by JobTDate", jobid);
+ db_sql_query(mdb, query.c_str(), db_get_int_handler, jobids);
+ Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids);
+ ret = true;
+
+bail_out:
+ Mmsg(query, "DROP TABLE btemp3%s", jobid);
+ db_sql_query(mdb, query.c_str(), NULL, NULL);
+
+ return ret;
+}
+
+/*
+ * Use to build a string of int list from a query. "10,20,30"
+ */
+int db_get_int_handler(void *ctx, int num_fields, char **row)
+{
+ POOLMEM *ret = (POOLMEM *)ctx;
+ if (num_fields == 1) {
+ if (ret[0]) {
+ pm_strcat(ret, ",");
+ }
+ pm_strcat(ret, row[0]);
+ }
+ return 0;
+}