]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sql_list.c
- Correct typo in Copyright
[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-2005 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, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
73 {
74    db_lock(mdb);
75    if (type == VERT_LIST) {
76       Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,UseOnce,UseCatalog,"
77          "AcceptAnyVolume,VolRetention,VolUseDuration,MaxVolJobs,MaxVolBytes,"
78          "AutoPrune,Recycle,PoolType,LabelFormat,Enabled,ScratchPoolId,"
79          "RecyclePoolId,LabelType "
80          " FROM Pool ORDER BY PoolId");
81    } else {
82       Mmsg(mdb->cmd, "SELECT PoolId,Name,NumVols,MaxVols,PoolType,LabelFormat "
83         "FROM Pool ORDER BY PoolId");
84    }
85
86    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
87       db_unlock(mdb);
88       return;
89    }
90
91    list_result(jcr, mdb, sendit, ctx, type);
92
93    sql_free_result(mdb);
94    db_unlock(mdb);
95 }
96
97 void
98 db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
99 {
100    db_lock(mdb);
101    if (type == VERT_LIST) {
102       Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,"
103          "JobRetention "
104          "FROM Client ORDER BY ClientId");
105    } else {
106       Mmsg(mdb->cmd, "SELECT ClientId,Name,FileRetention,JobRetention "
107          "FROM Client ORDER BY ClientId");
108    }
109
110    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
111       db_unlock(mdb);
112       return;
113    }
114
115    list_result(jcr, mdb, sendit, ctx, type);
116
117    sql_free_result(mdb);
118    db_unlock(mdb);
119 }
120
121
122 /*
123  * If VolumeName is non-zero, list the record for that Volume
124  *   otherwise, list the Volumes in the Pool specified by PoolId
125  */
126 void
127 db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
128                       DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
129 {
130    char ed1[50];
131    db_lock(mdb);
132    if (type == VERT_LIST) {
133       if (mdbr->VolumeName[0] != 0) {
134          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
135             "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs,"
136             "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
137             "VolCapacityBytes,VolStatus,Recycle,VolRetention,"
138             "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
139             "EndFile,EndBlock,VolParts,LabelType,StorageId"
140             " FROM Media WHERE Media.VolumeName='%s'", mdbr->VolumeName);
141       } else {
142          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
143             "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs,"
144             "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
145             "VolCapacityBytes,VolStatus,Recycle,VolRetention,"
146             "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
147             "EndFile,EndBlock,VolParts,LabelType,StorageId"
148             " FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", 
149             edit_int64(mdbr->PoolId, ed1));
150       }
151    } else {
152       if (mdbr->VolumeName[0] != 0) {
153          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,"
154             "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten "
155             "FROM Media WHERE Media.VolumeName='%s'", mdbr->VolumeName);
156       } else {
157          Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,"
158             "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten "
159             "FROM Media WHERE Media.PoolId=%s ORDER BY MediaId", 
160             edit_int64(mdbr->PoolId, ed1));
161       }
162    }
163
164    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
165       db_unlock(mdb);
166       return;
167    }
168
169    list_result(jcr, mdb, sendit, ctx, type);
170
171    sql_free_result(mdb);
172    db_unlock(mdb);
173 }
174
175 void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
176                               DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
177 {
178    char ed1[50];
179    db_lock(mdb);
180    if (type == VERT_LIST) {
181       if (JobId > 0) {                   /* do by JobId */
182          Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
183             "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
184             "JobMedia.EndBlock,Copy,Stripe "
185             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
186             "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
187       } else {
188          Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
189             "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
190             "JobMedia.EndBlock,Copy,Stripe "
191             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId");
192       }
193
194    } else {
195       if (JobId > 0) {                   /* do by JobId */
196          Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
197             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
198             "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
199       } else {
200          Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
201             "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId");
202       }
203    }
204    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
205       db_unlock(mdb);
206       return;
207    }
208
209    list_result(jcr, mdb, sendit, ctx, type);
210
211    sql_free_result(mdb);
212    db_unlock(mdb);
213 }
214
215
216
217 /*
218  * List Job record(s) that match JOB_DBR
219  *
220  *  Currently, we return all jobs or if jr->JobId is set,
221  *  only the job with the specified id.
222  */
223 void
224 db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
225                     void *ctx, e_list_type type)
226 {
227    char ed1[50];
228    char limit[100];
229    db_lock(mdb);
230    if (jr->limit > 0) {
231       snprintf(limit, sizeof(limit), " LIMIT %d", jr->limit);
232    } else {
233       limit[0] = 0;
234    }
235    if (type == VERT_LIST) {
236       if (jr->JobId == 0 && jr->Job[0] == 0) {
237          Mmsg(mdb->cmd,
238             "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level,"
239             "Job.ClientId,Client.Name,JobStatus,SchedTime,"
240             "StartTime,EndTime,JobTDate,"
241             "VolSessionId,VolSessionTime,JobFiles,JobErrors,"
242             "JobMissingFiles,Job.PoolId,Pool.Name,Job.FileSetId,FileSet.FileSet "
243             "FROM Job,Client,Pool,FileSet WHERE "
244             "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId "
245             "AND FileSet.FileSetId=Job.FileSetId  ORDER BY StartTime%s", limit);
246       } else {                           /* single record */
247          Mmsg(mdb->cmd,
248             "SELECT JobId,Job,Job.Name,PurgedFiles,Type,Level,"
249             "Job.ClientId,Client.Name,JobStatus,SchedTime,"
250             "StartTime,EndTime,JobTDate,"
251             "VolSessionId,VolSessionTime,JobFiles,JobErrors,"
252             "JobMissingFiles,Job.PoolId,Pool.Name,Job.FileSetId,FileSet.FileSet "
253             "FROM Job,Client,Pool,FileSet WHERE Job.JobId=%s AND "
254             "Client.ClientId=Job.ClientId AND Pool.PoolId=Job.PoolId "
255             "AND FileSet.FileSetId=Job.FileSetId", 
256             edit_int64(jr->JobId, ed1));
257       }
258    } else {
259       if (jr->JobId == 0 && jr->Job[0] == 0) {
260          Mmsg(mdb->cmd,
261            "SELECT JobId,Name,StartTime,Type,Level,JobFiles,JobBytes,JobStatus "
262            "FROM Job ORDER BY StartTime%s", limit);
263       } else {                           /* single record */
264          Mmsg(mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,"
265             "JobFiles,JobBytes,JobStatus FROM Job WHERE JobId=%s", 
266             edit_int64(jr->JobId, ed1));
267       }
268    }
269    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
270       db_unlock(mdb);
271       return;
272    }
273    list_result(jcr, mdb, sendit, ctx, type);
274
275    sql_free_result(mdb);
276    db_unlock(mdb);
277 }
278
279 /*
280  * List Job totals
281  *
282  */
283 void
284 db_list_job_totals(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx)
285 {
286    db_lock(mdb);
287
288    /* List by Job */
289    Mmsg(mdb->cmd, "SELECT  count(*) AS Jobs,sum(JobFiles) "
290       "AS Files,sum(JobBytes) AS Bytes,Name AS Job FROM Job GROUP BY Name");
291
292    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
293       db_unlock(mdb);
294       return;
295    }
296
297    list_result(jcr, mdb, sendit, ctx, HORZ_LIST);
298
299    sql_free_result(mdb);
300
301    /* Do Grand Total */
302    Mmsg(mdb->cmd, "SELECT count(*) AS Jobs,sum(JobFiles) "
303         "AS Files,sum(JobBytes) As Bytes FROM Job");
304
305    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
306       db_unlock(mdb);
307       return;
308    }
309
310    list_result(jcr, mdb, sendit, ctx, HORZ_LIST);
311
312    sql_free_result(mdb);
313    db_unlock(mdb);
314 }
315
316 /*
317  * Stupid MySQL is NON-STANDARD !
318  */
319 #ifdef HAVE_MYSQL
320 #define FN "CONCAT(Path.Path,Filename.Name)"
321 #else
322 #define FN "Path.Path||Filename.Name"
323 #endif
324
325 void
326 db_list_files_for_job(JCR *jcr, B_DB *mdb, JobId_t jobid, DB_LIST_HANDLER *sendit, void *ctx)
327 {
328    char ed1[50];
329    db_lock(mdb);
330
331    Mmsg(mdb->cmd, "SELECT " FN " AS Filename FROM File,"
332 "Filename,Path WHERE File.JobId=%s AND Filename.FilenameId=File.FilenameId "
333 "AND Path.PathId=File.PathId",
334       edit_int64(jobid, ed1));
335
336    if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
337       db_unlock(mdb);
338       return;
339    }
340
341    list_result(jcr, mdb, sendit, ctx, HORZ_LIST);
342
343    sql_free_result(mdb);
344    db_unlock(mdb);
345 }
346
347
348 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/