X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fcats%2Fsql_find.c;h=e4bd80e817c2cb3c49d750c4f0217c24b28e08f0;hb=cd7acc68ac7b79a612e3c3ce64fa191e303e2c72;hp=5894a60325e1f89c3dc9427ba12574ffe4c97cf5;hpb=219c3361ea84d506c46876a067e1292db93af9fb;p=bacula%2Fbacula diff --git a/bacula/src/cats/sql_find.c b/bacula/src/cats/sql_find.c index 5894a60325..e4bd80e817 100644 --- a/bacula/src/cats/sql_find.c +++ b/bacula/src/cats/sql_find.c @@ -1,23 +1,12 @@ -/* - * Bacula Catalog Database Find record interface routines - * - * Note, generally, these routines are more complicated - * that a simple search by name or id. Such simple - * request are in get.c - * - * Kern Sibbald, December 2000 - * - * Version $Id$ - */ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 Free Software Foundation Europe e.V. + Copyright (C) 2000-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or - modify it under the terms of version two of the GNU General Public + modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. @@ -26,16 +15,26 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of John Walker. + Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. */ +/* + * Bacula Catalog Database Find record interface routines + * + * Note, generally, these routines are more complicated + * that a simple search by name or id. Such simple + * request are in get.c + * + * Kern Sibbald, December 2000 + * + */ /* The following is necessary so that we do not include @@ -46,7 +45,7 @@ #include "bacula.h" #include "cats.h" -#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL +#if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI /* ----------------------------------------------------------------------- * @@ -57,7 +56,7 @@ /* * Find job start time if JobId specified, otherwise - * find last full save for Incremental and Differential saves. + * find last Job start time Incremental and Differential saves. * * StartTime is returned in stime * @@ -76,8 +75,8 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) /* If no Id given, we must find corresponding job */ if (jr->JobId == 0) { /* Differential is since last Full backup */ - Mmsg(mdb->cmd, -"SELECT StartTime FROM Job WHERE JobStatus='T' AND Type='%c' AND " + Mmsg(mdb->cmd, +"SELECT StartTime FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND " "Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s " "ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_FULL, jr->Name, @@ -107,7 +106,7 @@ db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime) sql_free_result(mdb); /* Now edit SQL command for Incremental Job */ Mmsg(mdb->cmd, -"SELECT StartTime FROM Job WHERE JobStatus='T' AND Type='%c' AND " +"SELECT StartTime FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND " "Level IN ('%c','%c','%c') AND Name='%s' AND ClientId=%s " "AND FileSetId=%s ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_INCREMENTAL, L_DIFFERENTIAL, L_FULL, jr->Name, @@ -148,6 +147,52 @@ bail_out: return false; } + +/* + * Find the last job start time for the specified JobLevel + * + * StartTime is returned in stime + * + * Returns: false on failure + * true on success, jr is unchanged, but stime is set + */ +bool +db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, int JobLevel) +{ + SQL_ROW row; + char ed1[50], ed2[50]; + + db_lock(mdb); + + pm_strcpy(stime, "0000-00-00 00:00:00"); /* default */ + + Mmsg(mdb->cmd, +"SELECT StartTime FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND " +"Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s " +"ORDER BY StartTime DESC LIMIT 1", + jr->JobType, JobLevel, jr->Name, + edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2)); + if (!QUERY_DB(jcr, mdb, mdb->cmd)) { + Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"), + sql_strerror(mdb), mdb->cmd); + goto bail_out; + } + if ((row = sql_fetch_row(mdb)) == NULL) { + sql_free_result(mdb); + Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n")); + goto bail_out; + } + Dmsg1(100, "Got start time: %s\n", row[0]); + pm_strcpy(stime, row[0]); + sql_free_result(mdb); + db_unlock(mdb); + return true; + +bail_out: + db_unlock(mdb); + return false; +} + /* * Find last failed job since given start-time * it must be either Full or Diff. @@ -165,14 +210,13 @@ db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int & db_lock(mdb); /* Differential is since last Full backup */ Mmsg(mdb->cmd, -"SELECT Level FROM Job WHERE JobStatus!='T' AND Type='%c' AND " -"Level IN ('%c','%c') AND Name='%s' AND ClientId=%s " +"SELECT Level FROM Job WHERE JobStatus NOT IN ('T','W') AND " +"Type='%c' AND Level IN ('%c','%c') AND Name='%s' AND ClientId=%s " "AND FileSetId=%s AND StartTime>'%s' " "ORDER BY StartTime DESC LIMIT 1", jr->JobType, L_FULL, L_DIFFERENTIAL, jr->Name, edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2), stime); - if (!QUERY_DB(jcr, mdb, mdb->cmd)) { db_unlock(mdb); return false; @@ -211,7 +255,7 @@ db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr) if (jr->JobLevel == L_VERIFY_CATALOG) { Mmsg(mdb->cmd, "SELECT JobId FROM Job WHERE Type='V' AND Level='%c' AND " -" JobStatus='T' AND Name='%s' AND " +" JobStatus IN ('T','W') AND Name='%s' AND " "ClientId=%s ORDER BY StartTime DESC LIMIT 1", L_VERIFY_INIT, jr->Name, edit_int64(jr->ClientId, ed1)); @@ -220,11 +264,11 @@ db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr) jr->JobType == JT_BACKUP) { if (Name) { Mmsg(mdb->cmd, -"SELECT JobId FROM Job WHERE Type='B' AND JobStatus='T' AND " +"SELECT JobId FROM Job WHERE Type='B' AND JobStatus IN ('T','W') AND " "Name='%s' ORDER BY StartTime DESC LIMIT 1", Name); } else { Mmsg(mdb->cmd, -"SELECT JobId FROM Job WHERE Type='B' AND JobStatus='T' AND " +"SELECT JobId FROM Job WHERE Type='B' AND JobStatus IN ('T','W') AND " "ClientId=%s ORDER BY StartTime DESC LIMIT 1", edit_int64(jr->ClientId, ed1)); } @@ -285,26 +329,24 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,VolParts,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," - "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime " + "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge " "FROM Media WHERE PoolId=%s AND MediaType='%s' AND VolStatus IN ('Full'," "'Recycle','Purged','Used','Append') AND Enabled=1 " "ORDER BY LastWritten LIMIT 1", edit_int64(mr->PoolId, ed1), mr->MediaType); item = 1; } else { - char changer[100]; + POOL_MEM changer(PM_FNAME); /* Find next available volume */ if (InChanger) { - bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s", - edit_int64(mr->StorageId, ed1)); - } else { - changer[0] = 0; + Mmsg(changer, "AND InChanger=1 AND StorageId=%s", + edit_int64(mr->StorageId, ed1)); } if (strcmp(mr->VolStatus, "Recycle") == 0 || strcmp(mr->VolStatus, "Purged") == 0) { - order = "ORDER BY LastWritten ASC,MediaId"; /* take oldest */ + order = "AND Recycle=1 ORDER BY LastWritten ASC,MediaId"; /* take oldest that can be recycled */ } else { - order = "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId"; /* take most recently written */ + order = sql_media_order_most_recently_written[db_type]; /* take most recently written */ } Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks," "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes," @@ -312,13 +354,13 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr "MaxVolFiles,Recycle,Slot,FirstWritten,LastWritten,InChanger," "EndFile,EndBlock,VolParts,LabelType,LabelDate,StorageId," "Enabled,LocationId,RecycleCount,InitialWrite," - "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime " + "ScratchPoolId,RecyclePoolId,VolReadTime,VolWriteTime,ActionOnPurge " "FROM Media WHERE PoolId=%s AND MediaType='%s' AND Enabled=1 " "AND VolStatus='%s' " "%s " "%s LIMIT %d", edit_int64(mr->PoolId, ed1), mr->MediaType, - mr->VolStatus, changer, order, item); + mr->VolStatus, changer.c_str(), order, item); } Dmsg1(050, "fnextvol=%s\n", mdb->cmd); if (!QUERY_DB(jcr, mdb, mdb->cmd)) { @@ -393,6 +435,7 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr mr->RecyclePoolId = str_to_int64(row[34]); mr->VolReadTime = str_to_int64(row[35]); mr->VolWriteTime = str_to_int64(row[36]); + mr->ActionOnPurge = str_to_int64(row[37]); sql_free_result(mdb);