]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sql_list.c
- ========= Remove Accept Any Volume ========= directive.
[bacula/bacula] / bacula / src / cats / sql_list.c
1 /*
2  * Bacula Catalog Database List records interface routines
3  *
4  *    Kern Sibbald, March 2000
5  *
6  *    Version $Id$
7  */
8 /*
9    Copyright (C) 2000-2006 Kern Sibbald
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    version 2 as amended with additional clauses defined in the
14    file LICENSE in the main source directory.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
19    the file LICENSE for additional details.
20
21  */
22
23 /* The following is necessary so that we do not include
24  * the dummy external definition of DB.
25  */
26 #define __SQL_C                       /* indicate that this is sql.c */
27
28 #include "bacula.h"
29 #include "cats.h"
30
31 #if    HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
32
33 /* -----------------------------------------------------------------------
34  *
35  *   Generic Routines (or almost generic)
36  *
37  * -----------------------------------------------------------------------
38  */
39
40 /* Imported subroutines */
41 extern void list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
42 extern int QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
43
44
45 /*
46  * Submit general SQL query
47  */
48 int db_list_sql_query(JCR *jcr, B_DB *mdb, char *query, DB_LIST_HANDLER *sendit,
49                       void *ctx, int verbose, e_list_type type)
50 {
51    db_lock(mdb);
52    if (sql_query(mdb, query) != 0) {
53       Mmsg(mdb->errmsg, _("Query failed: %s\n"), sql_strerror(mdb));
54       if (verbose) {
55          sendit(ctx, mdb->errmsg);
56       }
57       db_unlock(mdb);
58       return 0;
59    }
60
61    mdb->result = sql_store_result(mdb);
62
63    if (mdb->result) {
64       list_result(jcr, mdb, sendit, ctx, type);
65       sql_free_result(mdb);
66    }
67    db_unlock(mdb);
68    return 1;
69 }
70
71 void
72 db_list_pool_records(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr, 
73                      DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
74 {
75    db_lock(mdb);
76    if (type == VERT_LIST) {
77       if (pdbr->Name[0] != 0) {
78          Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,"
79             "AcceptAnyVolume,VolRetention,VolUseDuration,MaxVolJobs,MaxVolBytes,"
80             "AutoPrune,Recycle,PoolType,LabelFormat,Enabled,ScratchPoolId,"
81             "RecyclePoolId,LabelType "
82             " FROM Pool WHERE Name='%s'", pdbr->Name);
83       } else {
84          Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,"
85             "AcceptAnyVolume,VolRetention,VolUseDuration,MaxVolJobs,MaxVolBytes,"
86             "AutoPrune,Recycle,PoolType,LabelFormat,Enabled,ScratchPoolId,"
87             "RecyclePoolId,LabelType "
88             " FROM Pool ORDER BY PoolId");
89       }
90    } else {
91       if (pdbr->Name[0] != 0) {
92          Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,PoolType,LabelFormat "
93            "FROM Pool WHERE Name='%s'", pdbr->Name);
94       } else {
95          Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,PoolType,LabelFormat "
96            "FROM Pool ORDER BY PoolId");
97       }
98    }
99
100    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
101       db_unlock(mdb);
102       return;
103    }
104
105    list_result(jcr, mdb, sendit, ctx, type);
106
107    sql_free_result(mdb);
108    db_unlock(mdb);
109 }
110
111 void
112 db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
113 {
114    db_lock(mdb);
115    if (type == VERT_LIST) {
116       Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,"
117          "JobRetention "
118          "FROM Client ORDER BY ClientId");
119    } else {
120       Mmsg(mdb->cmd, "SELECT ClientId,Name,FileRetention,JobRetention "
121          "FROM Client ORDER BY ClientId");
122    }
123
124    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
125       db_unlock(mdb);
126       return;
127    }
128
129    list_result(jcr, mdb, sendit, ctx, type);
130
131    sql_free_result(mdb);
132    db_unlock(mdb);
133 }
134
135
136 /*
137  * If VolumeName is non-zero, list the record for that Volume
138  *   otherwise, list the Volumes in the Pool specified by PoolId
139  */
140 void
141 db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
142                       DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
143 {
144    char ed1[50];
145    db_lock(mdb);
146    if (type == VERT_LIST) {
147       if (mdbr->VolumeName[0] != 0) {
148          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
149             "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs,"
150             "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
151             "VolCapacityBytes,VolStatus,Enabled,Recycle,VolRetention,"
152             "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
153             "EndFile,EndBlock,VolParts,LabelType,StorageId,DeviceId,"
154             "LocationId,RecycleCount,InitialWrite,ScratchPoolId,RecyclePoolId"
155             " FROM Media WHERE Media.VolumeName='%s'", mdbr->VolumeName);
156       } else {
157          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
158             "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs,"
159             "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
160             "VolCapacityBytes,VolStatus,Enabled,Recycle,VolRetention,"
161             "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
162             "EndFile,EndBlock,VolParts,LabelType,StorageId,DeviceId,"
163             "LocationId,RecycleCount,InitialWrite,ScratchPoolId,RecyclePoolId"
164             " FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", 
165             edit_int64(mdbr->PoolId, ed1));
166       }
167    } else {
168       if (mdbr->VolumeName[0] != 0) {
169          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,Enabled,"
170             "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten "
171             "FROM Media WHERE Media.VolumeName='%s'", mdbr->VolumeName);
172       } else {
173          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,Enabled,"
174             "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten "
175             "FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", 
176             edit_int64(mdbr->PoolId, ed1));
177       }
178    }
179
180    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
181       db_unlock(mdb);
182       return;
183    }
184
185    list_result(jcr, mdb, sendit, ctx, type);
186
187    sql_free_result(mdb);
188    db_unlock(mdb);
189 }
190
191 void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
192                               DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
193 {
194    char ed1[50];
195    db_lock(mdb);
196    if (type == VERT_LIST) {
197       if (JobId > 0) {                   /* do by JobId */
198          Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
199             "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
200             "JobMedia.EndBlock,Copy "
201             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
202             "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
203       } else {
204          Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
205             "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
206             "JobMedia.EndBlock,Copy "
207             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId");
208       }
209
210    } else {
211       if (JobId > 0) {                   /* do by JobId */
212          Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
213             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
214             "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
215       } else {
216          Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
217             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId");
218       }
219    }
220    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
221       db_unlock(mdb);
222       return;
223    }
224
225    list_result(jcr, mdb, sendit, ctx, type);
226
227    sql_free_result(mdb);
228    db_unlock(mdb);
229 }
230
231
232
233 /*
234  * List Job record(s) that match JOB_DBR
235  *
236  *  Currently, we return all jobs or if jr->JobId is set,
237  *  only the job with the specified id.
238  */
239 void
240 db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
241                     void *ctx, e_list_type type)
242 {
243    char ed1[50];
244    char limit[100];
245    db_lock(mdb);
246    if (jr->limit > 0) {
247       snprintf(limit, sizeof(limit), " LIMIT %d", jr->limit);
248    } else {
249       limit[0] = 0;
250    }
251    if (type == VERT_LIST) {
252       if (jr->JobId == 0 && jr->Job[0] == 0) {
253          Mmsg(mdb->cmd,
254             "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level,"
255             "Job.ClientId,Client.Name,JobStatus,SchedTime,"
256             "StartTime,EndTime,JobTDate,"
257             "VolSessionId,VolSessionTime,JobFiles,JobErrors,"
258             "JobMissingFiles,Job.PoolId,Pool.Name,Job.FileSetId,FileSet.FileSet "
259             "FROM Job,Client,Pool,FileSet WHERE "
260             "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId "
261             "AND FileSet.FileSetId=Job.FileSetId  ORDER BY StartTime%s", limit);
262       } else {                           /* single record */
263          Mmsg(mdb->cmd,
264             "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level,"
265             "Job.ClientId,Client.Name,JobStatus,SchedTime,"
266             "StartTime,EndTime,JobTDate,"
267             "VolSessionId,VolSessionTime,JobFiles,JobErrors,"
268             "JobMissingFiles,Job.PoolId,Pool.Name,Job.FileSetId,FileSet.FileSet "
269             "FROM Job,Client,Pool,FileSet WHERE Job.JobId=%s AND "
270             "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId "
271             "AND FileSet.FileSetId=Job.FileSetId", 
272             edit_int64(jr->JobId, ed1));
273       }
274    } else {
275       if (jr->Name[0] != 0) {
276          Mmsg(mdb->cmd,
277             "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus "
278             "FROM Job WHERE Name='%s' ORDER BY StartTime,JobId ASC", jr->Name);
279       } else if (jr->Job[0] != 0) {
280          Mmsg(mdb->cmd,
281             "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus "
282             "FROM Job WHERE Job='%s' ORDER BY StartTime,JobId ASC", jr->Job);
283       } else if (jr->JobId != 0) {
284          Mmsg(mdb->cmd, 
285             "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus "
286             "FROM Job WHERE JobId=%s", edit_int64(jr->JobId, ed1));
287       } else {                           /* all records */
288          Mmsg(mdb->cmd,
289            "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus "
290            "FROM Job ORDER BY StartTime,JobId ASC%s", limit);
291       }
292    }
293    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
294       db_unlock(mdb);
295       return;
296    }
297    list_result(jcr, mdb, sendit, ctx, type);
298
299    sql_free_result(mdb);
300    db_unlock(mdb);
301 }
302
303 /*
304  * List Job totals
305  *
306  */
307 void
308 db_list_job_totals(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx)
309 {
310    db_lock(mdb);
311
312    /* List by Job */
313    Mmsg(mdb->cmd, "SELECT  count(*) AS Jobs,sum(JobFiles) "
314       "AS Files,sum(JobBytes) AS Bytes,Name AS Job FROM Job GROUP BY Name");
315
316    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
317       db_unlock(mdb);
318       return;
319    }
320
321    list_result(jcr, mdb, sendit, ctx, HORZ_LIST);
322
323    sql_free_result(mdb);
324
325    /* Do Grand Total */
326    Mmsg(mdb->cmd, "SELECT count(*) AS Jobs,sum(JobFiles) "
327         "AS Files,sum(JobBytes) As Bytes FROM Job");
328
329    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
330       db_unlock(mdb);
331       return;
332    }
333
334    list_result(jcr, mdb, sendit, ctx, HORZ_LIST);
335
336    sql_free_result(mdb);
337    db_unlock(mdb);
338 }
339
340 /*
341  * Stupid MySQL is NON-STANDARD !
342  */
343 #ifdef HAVE_MYSQL
344 #define FN "CONCAT(Path.Path,Filename.Name)"
345 #else
346 #define FN "Path.Path||Filename.Name"
347 #endif
348
349 void
350 db_list_files_for_job(JCR *jcr, B_DB *mdb, JobId_t jobid, DB_LIST_HANDLER *sendit, void *ctx)
351 {
352    char ed1[50];
353    db_lock(mdb);
354
355    Mmsg(mdb->cmd, "SELECT " FN " AS Filename FROM File,"
356 "Filename,Path WHERE File.JobId=%s AND Filename.FilenameId=File.FilenameId "
357 "AND Path.PathId=File.PathId",
358       edit_int64(jobid, ed1));
359
360    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
361       db_unlock(mdb);
362       return;
363    }
364
365    list_result(jcr, mdb, sendit, ctx, HORZ_LIST);
366
367    sql_free_result(mdb);
368    db_unlock(mdb);
369 }
370
371
372 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/