]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/bdb.c
Merge branch 'master' of ssh://bacula.git.sourceforge.net/gitroot/bacula/bacula
[bacula/bacula] / bacula / src / cats / bdb.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Bacula Catalog Database routines written specifically
30  *  for Bacula.  Note, these routines are VERY dumb and
31  *  do not provide all the functionality of an SQL database.
32  *  The purpose of these routines is to ensure that Bacula
33  *  can limp along if no real database is loaded on the
34  *  system.
35  *
36  *    Kern Sibbald, January MMI
37  *
38  *    Version $Id$
39  *
40  */
41
42
43 /* The following is necessary so that we do not include
44  * the dummy external definition of DB.
45  */
46 #define __SQL_C                       /* indicate that this is sql.c */
47
48 #include "bacula.h"
49 #include "cats.h"
50
51 #ifdef HAVE_BACULA_DB
52
53 uint32_t bacula_db_version = 0;
54
55 int db_type = 0;
56
57 /* List of open databases */
58 static BQUEUE db_list = {&db_list, &db_list};
59 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
60
61 /* -----------------------------------------------------------------------
62  *
63  *   Bacula specific defines and subroutines
64  *
65  * -----------------------------------------------------------------------
66  */
67
68
69 #define DB_CONTROL_FILENAME  "control.db"
70 #define DB_JOBS_FILENAME     "jobs.db"
71 #define DB_POOLS_FILENAME    "pools.db"
72 #define DB_MEDIA_FILENAME    "media.db"
73 #define DB_JOBMEDIA_FILENAME "jobmedia.db"
74 #define DB_CLIENT_FILENAME   "client.db"
75 #define DB_FILESET_FILENAME  "fileset.db"
76
77
78 B_DB *db_init(JCR *jcr, const char *db_driver, const char *db_name, const char *db_user, 
79               const char *db_password, const char *db_address, int db_port, 
80               const char *db_socket, int mult_db_connections)
81 {              
82    return db_init_database(jcr, db_name, db_user, db_password, db_address,
83              db_port, db_socket, mult_db_connections);
84 }
85
86
87 dbid_list::dbid_list() 
88 {
89    memset(this, 0, sizeof(dbid_list));
90    max_ids = 1000;
91    DBId = (DBId_t *)malloc(max_ids * sizeof(DBId_t));
92    num_ids = num_seen = tot_ids = 0;
93    PurgedFiles = NULL;
94 }
95
96 dbid_list::~dbid_list() 
97
98    free(DBId);
99 }
100
101 static POOLMEM *make_filename(B_DB *mdb, const char *name)
102 {
103    char sep;
104    POOLMEM *dbf;
105
106    dbf = get_pool_memory(PM_FNAME);
107    if (IsPathSeparator(working_directory[strlen(working_directory)-1])) {
108       sep = 0;
109    } else {
110       sep = '/';
111    }
112    Mmsg(dbf, "%s%c%s-%s", working_directory, sep, mdb->db_name, name);
113    return dbf;
114 }
115
116 int bdb_write_control_file(B_DB *mdb)
117 {
118    mdb->control.time = time(NULL);
119    lseek(mdb->cfd, 0, SEEK_SET);
120    if (write(mdb->cfd, &mdb->control, sizeof(mdb->control)) != sizeof(mdb->control)) {
121       Mmsg1(&mdb->errmsg, "Error writing control file. ERR=%s\n", strerror(errno));
122       Emsg0(M_FATAL, 0, mdb->errmsg);
123       return 0;
124    }
125    return 1;
126 }
127
128 /*
129  * Retrieve database type
130  */
131 const char *
132 db_get_type(void)
133 {
134    return "Internal";
135 }
136
137 /*
138  * Initialize database data structure. In principal this should
139  * never have errors, or it is really fatal.
140  */
141 B_DB *
142 db_init_database(JCR *jcr, char const *db_name, char const *db_user, char const *db_password,
143                  char const *db_address, int db_port, char const *db_socket,
144                  int mult_db_connections)
145 {
146    B_DB *mdb;
147    P(mutex);                          /* lock DB queue */
148    /* Look to see if DB already open */
149    for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
150       if (strcmp(mdb->db_name, db_name) == 0) {
151          Dmsg2(200, "DB REopen %d %s\n", mdb->ref_count, db_name);
152          mdb->ref_count++;
153          V(mutex);
154          return mdb;                  /* already open */
155       }
156    }
157
158    Dmsg0(200, "db_open first time\n");
159    mdb = (B_DB *)malloc(sizeof(B_DB));
160    memset(mdb, 0, sizeof(B_DB));
161    Dmsg0(200, "DB struct init\n");
162    mdb->db_name = bstrdup(db_name);
163    mdb->errmsg = get_pool_memory(PM_EMSG);
164    *mdb->errmsg = 0;
165    mdb->cmd = get_pool_memory(PM_EMSG);  /* command buffer */
166    mdb->ref_count = 1;
167    mdb->cached_path = get_pool_memory(PM_FNAME);
168    mdb->cached_path_id = 0;
169    qinsert(&db_list, &mdb->bq);       /* put db in list */
170    Dmsg0(200, "Done db_open_database()\n");
171    mdb->cfd = -1;
172    V(mutex);
173    Jmsg(jcr, M_WARNING, 0, _("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"));
174    Jmsg(jcr, M_WARNING, 0, _("WARNING!!!! The Internal Database is NOT OPERATIONAL!\n"));
175    Jmsg(jcr, M_WARNING, 0, _("You should use SQLite, PostgreSQL, or MySQL\n"));
176
177    return mdb;
178 }
179
180 /*
181  * Now actually open the database.  This can generate errors,
182  * which are returned in the errmsg
183  */
184 int
185 db_open_database(JCR *jcr, B_DB *mdb)
186 {
187    char *dbf;
188    int fd, badctl;
189    off_t filend;
190    int errstat;
191
192    Dmsg1(200, "db_open_database() %s\n", mdb->db_name);
193
194    P(mutex);
195
196    if ((errstat=rwl_init(&mdb->lock)) != 0) {
197       Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"), strerror(errstat));
198       V(mutex);
199       return 0;
200    }
201
202    Dmsg0(200, "make_filename\n");
203    dbf = make_filename(mdb, DB_CONTROL_FILENAME);
204    mdb->cfd = open(dbf, O_CREAT|O_RDWR, 0600);
205    free_memory(dbf);
206    if (mdb->cfd < 0) {
207       Mmsg2(&mdb->errmsg, _("Unable to open Catalog DB control file %s: ERR=%s\n"),
208          dbf, strerror(errno));
209       V(mutex);
210       return 0;
211    }
212    Dmsg0(200, "DB open\n");
213    /* See if the file was previously written */
214    filend = lseek(mdb->cfd, 0, SEEK_END);
215    if (filend == 0) {                 /* No, initialize everything */
216       Dmsg0(200, "Init DB files\n");
217       memset(&mdb->control, 0, sizeof(mdb->control));
218       mdb->control.bdb_version = BDB_VERSION;
219       bdb_write_control_file(mdb);
220
221       /* Create Jobs File */
222       dbf = make_filename(mdb, DB_JOBS_FILENAME);
223       fd = open(dbf, O_CREAT|O_RDWR, 0600);
224       free_memory(dbf);
225       close(fd);
226
227       /* Create Pools File */
228       dbf = make_filename(mdb, DB_POOLS_FILENAME);
229       fd = open(dbf, O_CREAT|O_RDWR, 0600);
230       free_memory(dbf);
231       close(fd);
232
233       /* Create Media File */
234       dbf = make_filename(mdb, DB_MEDIA_FILENAME);
235       fd = open(dbf, O_CREAT|O_RDWR, 0600);
236       free_memory(dbf);
237       close(fd);
238
239       /* Create JobMedia File */
240       dbf = make_filename(mdb, DB_JOBMEDIA_FILENAME);
241       fd = open(dbf, O_CREAT|O_RDWR, 0600);
242       free_memory(dbf);
243       close(fd);
244
245       /* Create Client File */
246       dbf = make_filename(mdb, DB_CLIENT_FILENAME);
247       fd = open(dbf, O_CREAT|O_RDWR, 0600);
248       free_memory(dbf);
249       close(fd);
250
251       /* Create FileSet File */
252       dbf = make_filename(mdb, DB_FILESET_FILENAME);
253       fd = open(dbf, O_CREAT|O_RDWR, 0600);
254       free_memory(dbf);
255       close(fd);
256    }
257
258    Dmsg0(200, "Read control file\n");
259    badctl = 0;
260    lseek(mdb->cfd, 0, SEEK_SET);      /* seek to begining of control file */
261    if (read(mdb->cfd, &mdb->control, sizeof(mdb->control)) != sizeof(mdb->control)) {
262       Mmsg1(&mdb->errmsg, _("Error reading catalog DB control file. ERR=%s\n"), strerror(errno));
263       badctl = 1;
264    } else if (mdb->control.bdb_version != BDB_VERSION) {
265       Mmsg2(&mdb->errmsg, _("Error, catalog DB control file wrong version. "
266 "Wanted %d, got %d\n"
267 "Please reinitialize the working directory.\n"),
268          BDB_VERSION, mdb->control.bdb_version);
269       badctl = 1;
270    }
271    bacula_db_version = mdb->control.bdb_version;
272    if (badctl) {
273       V(mutex);
274       return 0;
275    }
276    V(mutex);
277    return 1;
278 }
279
280 void db_close_database(JCR *jcr, B_DB *mdb)
281 {
282    P(mutex);
283    mdb->ref_count--;
284    if (mdb->ref_count == 0) {
285       qdchain(&mdb->bq);
286       /*  close file descriptors */
287       if (mdb->cfd >= 0) {
288          close(mdb->cfd);
289       }
290       free(mdb->db_name);
291       if (mdb->jobfd) {
292          fclose(mdb->jobfd);
293       }
294       if (mdb->poolfd) {
295          fclose(mdb->poolfd);
296       }
297       if (mdb->mediafd) {
298          fclose(mdb->mediafd);
299       }
300       if (mdb->jobmediafd) {
301          fclose(mdb->jobmediafd);
302       }
303       if (mdb->clientfd) {
304          fclose(mdb->clientfd);
305       }
306       if (mdb->filesetfd) {
307          fclose(mdb->filesetfd);
308       }
309       rwl_destroy(&mdb->lock);
310       free_pool_memory(mdb->errmsg);
311       free_pool_memory(mdb->cmd);
312       free_pool_memory(mdb->cached_path);
313       free(mdb);
314    }
315    V(mutex);
316 }
317
318 void db_thread_cleanup()
319 { }
320
321
322 void db_escape_string(JCR *jcr, B_DB *db, char *snew, char *old, int len)
323 {
324    memset(snew, 0, len);
325    bstrncpy(snew, old, len);
326 }
327
328 char *db_strerror(B_DB *mdb)
329 {
330    return mdb->errmsg;
331 }
332
333 bool db_sql_query(B_DB *mdb, char const *query, DB_RESULT_HANDLER *result_handler, void *ctx)
334 {
335    return true;
336 }
337
338 /*
339  * Open the Jobs file for reading/writing
340  */
341 int bdb_open_jobs_file(B_DB *mdb)
342 {
343    char *dbf;
344
345    if (!mdb->jobfd) {
346       dbf = make_filename(mdb, DB_JOBS_FILENAME);
347       mdb->jobfd = fopen(dbf, "r+b");
348       if (!mdb->jobfd) {
349          Mmsg2(&mdb->errmsg, "Error opening DB Jobs file %s: ERR=%s\n",
350             dbf, strerror(errno));
351          Emsg0(M_FATAL, 0, mdb->errmsg);
352          free_memory(dbf);
353          return 0;
354       }
355       free_memory(dbf);
356    }
357    return 1;
358 }
359
360 /*
361  * Open the JobMedia file for reading/writing
362  */
363 int bdb_open_jobmedia_file(B_DB *mdb)
364 {
365    char *dbf;
366
367    if (!mdb->jobmediafd) {
368       dbf = make_filename(mdb, DB_JOBMEDIA_FILENAME);
369       mdb->jobmediafd = fopen(dbf, "r+b");
370       if (!mdb->jobmediafd) {
371          Mmsg2(&mdb->errmsg, "Error opening DB JobMedia file %s: ERR=%s\n",
372             dbf, strerror(errno));
373          Emsg0(M_FATAL, 0, mdb->errmsg);
374          free_memory(dbf);
375          return 0;
376       }
377       free_memory(dbf);
378    }
379    return 1;
380 }
381
382
383 /*
384  * Open the Pools file for reading/writing
385  */
386 int bdb_open_pools_file(B_DB *mdb)
387 {
388    char *dbf;
389
390    if (!mdb->poolfd) {
391       dbf = make_filename(mdb, DB_POOLS_FILENAME);
392       mdb->poolfd = fopen(dbf, "r+b");
393       if (!mdb->poolfd) {
394          Mmsg2(&mdb->errmsg, "Error opening DB Pools file %s: ERR=%s\n",
395             dbf, strerror(errno));
396          Emsg0(M_FATAL, 0, mdb->errmsg);
397          free_memory(dbf);
398          return 0;
399       }
400       Dmsg1(200, "Opened pool file %s\n", dbf);
401       free_memory(dbf);
402    }
403    return 1;
404 }
405
406 /*
407  * Open the Client file for reading/writing
408  */
409 int bdb_open_client_file(B_DB *mdb)
410 {
411    char *dbf;
412
413    if (!mdb->clientfd) {
414       dbf = make_filename(mdb, DB_CLIENT_FILENAME);
415       mdb->clientfd = fopen(dbf, "r+b");
416       if (!mdb->clientfd) {
417          Mmsg2(&mdb->errmsg, "Error opening DB Clients file %s: ERR=%s\n",
418             dbf, strerror(errno));
419          Emsg0(M_FATAL, 0, mdb->errmsg);
420          free_memory(dbf);
421          return 0;
422       }
423       free_memory(dbf);
424    }
425    return 1;
426 }
427
428 /*
429  * Open the FileSet file for reading/writing
430  */
431 int bdb_open_fileset_file(B_DB *mdb)
432 {
433    char *dbf;
434
435    if (!mdb->filesetfd) {
436       dbf = make_filename(mdb, DB_CLIENT_FILENAME);
437       mdb->filesetfd = fopen(dbf, "r+b");
438       if (!mdb->filesetfd) {
439          Mmsg2(&mdb->errmsg, "Error opening DB FileSet file %s: ERR=%s\n",
440             dbf, strerror(errno));
441          Emsg0(M_FATAL, 0, mdb->errmsg);
442          free_memory(dbf);
443          return 0;
444       }
445       free_memory(dbf);
446    }
447    return 1;
448 }
449
450
451
452 /*
453  * Open the Media file for reading/writing
454  */
455 int bdb_open_media_file(B_DB *mdb)
456 {
457    char *dbf;
458
459    if (!mdb->mediafd) {
460       dbf = make_filename(mdb, DB_MEDIA_FILENAME);
461       mdb->mediafd = fopen(dbf, "r+b");
462       if (!mdb->mediafd) {
463          Mmsg2(&mdb->errmsg, "Error opening DB Media file %s: ERR=%s\n",
464             dbf, strerror(errno));
465          free_memory(dbf);
466          return 0;
467       }
468       free_memory(dbf);
469    }
470    return 1;
471 }
472
473
474 void _db_lock(const char *file, int line, B_DB *mdb)
475 {
476    int errstat;
477    if ((errstat=rwl_writelock(&mdb->lock)) != 0) {
478       e_msg(file, line, M_ABORT, 0, "rwl_writelock failure. ERR=%s\n",
479            strerror(errstat));
480    }
481 }
482
483 void _db_unlock(const char *file, int line, B_DB *mdb)
484 {
485    int errstat;
486    if ((errstat=rwl_writeunlock(&mdb->lock)) != 0) {
487       e_msg(file, line, M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n",
488            strerror(errstat));
489    }
490 }
491
492 /*
493  * Start a transaction. This groups inserts and makes things
494  *  much more efficient. Usually started when inserting
495  *  file attributes.
496  */
497 void db_start_transaction(JCR *jcr, B_DB *mdb)
498 {
499 }
500
501 void db_end_transaction(JCR *jcr, B_DB *mdb)
502 {
503 }
504
505 bool db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
506 { return true; }
507
508 void
509 db_list_pool_records(JCR *jcr, B_DB *mdb, POOL_DBR *pdbr, 
510                      DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
511 { }
512
513 int db_int64_handler(void *ctx, int num_fields, char **row)
514 { return 0; }
515
516 bool db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
517 {
518    return true;
519 }
520
521 int db_create_file_item(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
522 {
523    return 1;
524 }
525
526
527 /*
528  * Create a new record for the Job
529  *   This record is created at the start of the Job,
530  *   it is updated in bdb_update.c when the Job terminates.
531  *
532  * Returns: 0 on failure
533  *          1 on success
534  */
535 bool db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
536 {
537    return 0;
538 }
539
540 /* Create a JobMedia record for Volume used this job
541  * Returns: 0 on failure
542  *          record-id on success
543  */
544 bool db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
545 {
546    return 0;
547 }
548
549
550 /*
551  *  Create a unique Pool record
552  * Returns: 0 on failure
553  *          1 on success
554  */
555 bool db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
556 {
557    return 0;
558 }
559
560 bool db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
561 { return false; }
562
563 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *dr)
564 { return false; }
565
566 bool db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *dr)
567 { return false; }
568
569
570 /*
571  * Create Unique Media record.  This record
572  *   contains all the data pertaining to a specific
573  *   Volume.
574  *
575  * Returns: 0 on failure
576  *          1 on success
577  */
578 int db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
579 {
580    return 0;
581 }
582
583 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
584 {
585    return 0;
586 }
587
588 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
589 {
590    return false;
591 }
592
593 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
594 { return 0; }
595
596 bool db_write_batch_file_records(JCR *jcr) { return false; }
597 bool my_batch_start(JCR *jcr, B_DB *mdb) { return false; }
598 bool my_batch_end(JCR *jcr, B_DB *mdb, const char *error) { return false; }
599 bool my_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar) { return false; }
600     
601 int db_delete_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
602 {
603    return 0;
604 }
605
606 int db_delete_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
607 {
608    return 0;
609 }
610
611 bool db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime)
612 {
613    return 0;
614 }
615
616 int
617 db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr)
618 {
619    return 0;
620 }
621
622 bool
623 db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr)
624 { return false; }
625
626 bool
627 db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
628 { return false; }
629
630 bool db_get_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
631 {
632    return 0;
633 }
634
635 int db_get_num_pool_records(JCR *jcr, B_DB *mdb)
636 {
637    return -1;
638 }
639
640 int db_get_pool_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
641 { return 0; }
642
643 bool db_get_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
644 { return 0; }
645
646 int db_get_num_media_records(JCR *jcr, B_DB *mdb)
647 { return -1; }
648
649 bool db_get_media_ids(JCR *jcr, B_DB *mdb, uint32_t PoolId, int *num_ids, uint32_t *ids[])
650 { return false; }
651
652 bool db_get_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
653 { return false; }
654
655 int db_get_job_volume_names(JCR *jcr, B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
656 { return 0; }
657
658 int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
659 { return 0; }
660
661 int db_get_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
662 { return 0; }
663
664 bool db_get_query_dbids(JCR *jcr, B_DB *mdb, POOL_MEM &query, dbid_list &ids)
665 { return false; }
666
667 int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr, FILE_DBR *fdbr)
668 { return 0; }
669
670 int db_get_job_volume_parameters(JCR *jcr, B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolParams)
671 { return 0; }
672
673 int db_get_client_ids(JCR *jcr, B_DB *mdb, int *num_ids, uint32_t *ids[])
674 { return 0; }
675
676 int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
677 { return 0; }
678
679 int db_list_sql_query(JCR *jcr, B_DB *mdb, const char *query, DB_LIST_HANDLER *sendit,
680                       void *ctx, int verbose)
681 { return 0; }
682
683 void db_list_pool_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx)
684 { }
685
686 void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
687                            DB_LIST_HANDLER *sendit, void *ctx)
688 { }
689
690 void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
691                               DB_LIST_HANDLER *sendit, void *ctx)
692 {  }
693    
694 void db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr,
695                          DB_LIST_HANDLER *sendit, void *ctx)
696 { }
697
698 void db_list_job_totals(JCR *jcr, B_DB *mdb, JOB_DBR *jr,
699                         DB_LIST_HANDLER *sendit, void *ctx)
700 { }
701
702 void db_list_files_for_job(JCR *jcr, B_DB *mdb, uint32_t jobid, DB_LIST_HANDLER *sendit, void *ctx)
703 { }
704
705 void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx)
706 { }
707
708 int db_list_sql_query(JCR *jcr, B_DB *mdb, const char *query, DB_LIST_HANDLER *sendit,
709                       void *ctx, int verbose, e_list_type type)
710 {
711    return 0;
712 }
713
714 void
715 db_list_pool_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
716 { }
717
718 void
719 db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
720                       DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
721 { }
722
723 void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
724                               DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
725 { }
726
727 void
728 db_list_job_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
729                     void *ctx, e_list_type type)
730 { }
731
732 void
733 db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
734 { }
735
736 bool db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
737 {
738    return false;
739 }
740
741 /*
742  * This is called at Job termination time to add all the
743  * other fields to the job record.
744  */
745 int db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, bool stats_enabled)
746 {
747    return 0;
748 }
749
750
751 int db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
752 {
753    return 0;
754 }
755
756 int db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
757 {
758    return 0;
759 }
760
761 int db_add_digest_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *digest, int type)
762 {
763    return 1;
764 }
765
766 int db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId)
767 {
768    return 1;
769 }
770
771 int db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
772 {
773    return 1;
774 }
775
776 int db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
777 {
778    return 0;
779 }
780
781 int db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
782 {
783    return 1;
784 }
785
786 void db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
787 {
788   return;
789 }
790
791
792 #endif /* HAVE_BACULA_DB */