]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/cats.h
Implement db_big_sql_query() that uses cursor on PostgreSQL and limit memory usage...
[bacula/bacula] / bacula / src / cats / cats.h
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2011 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 three of the GNU Affero 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 Affero 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  * Catalog header file
30  *
31  * by Kern E. Sibbald
32  *
33  * Anyone who accesses the database will need to include
34  * this file.
35  */
36
37 /*
38    Here is how database versions work.
39
40    While I am working on a new release with database changes, the
41    update scripts are in the src/cats directory under the names
42    update_xxx_tables.in.  Most of the time, I make database updates
43    in one go and immediately update the version, but not always.  If
44    there are going to be several updates as is the case with version
45    1.37, then I will often forgo changing the version until the last
46    update otherwise I will end up with too many versions and a lot
47    of confusion.
48
49    When I am pretty sure there will be no more updates, I will
50    change the version from 8 to 9 (in the present case), and when I
51    am 100% sure there will be no more changes, the update script
52    will be copied to the updatedb directory with the correct name
53    (in the present case 8 to 9).
54  */
55 #ifndef __CATS_H_
56 #define __CATS_H_ 1
57
58 /* ==============================================================
59  *
60  *  What follows are definitions that are used "globally" for all
61  *   the different SQL engines and both inside and external to the
62  *   cats directory.
63  */
64
65 #define faddr_t long
66
67 /*
68  * Structure used when calling db_get_query_ids()
69  *  allows the subroutine to return a list of ids.
70  */
71 class dbid_list : public SMARTALLOC {
72 public:
73    DBId_t *DBId;                      /* array of DBIds */
74    char *PurgedFiles;                 /* Array of PurgedFile flags */
75    int num_ids;                       /* num of ids actually stored */
76    int max_ids;                       /* size of id array */
77    int num_seen;                      /* number of ids processed */
78    int tot_ids;                       /* total to process */
79
80    dbid_list();                       /* in sql.c */
81    ~dbid_list();                      /* in sql.c */
82 };
83
84 /* Job information passed to create job record and update
85  * job record at end of job. Note, although this record
86  * contains all the fields found in the Job database record,
87  * it also contains fields found in the JobMedia record.
88  */
89 /* Job record */
90 struct JOB_DBR {
91    JobId_t JobId;
92    char Job[MAX_NAME_LENGTH];         /* Job unique name */
93    char Name[MAX_NAME_LENGTH];        /* Job base name */
94    int JobType;                       /* actually char(1) */
95    int JobLevel;                      /* actually char(1) */
96    int JobStatus;                     /* actually char(1) */
97    DBId_t ClientId;                   /* Id of client */
98    DBId_t PoolId;                     /* Id of pool */
99    DBId_t FileSetId;                  /* Id of FileSet */
100    DBId_t PriorJobId;                 /* Id of migrated (prior) job */
101    time_t SchedTime;                  /* Time job scheduled */
102    time_t StartTime;                  /* Job start time */
103    time_t EndTime;                    /* Job termination time of orig job */
104    time_t RealEndTime;                /* Job termination time of this job */
105    utime_t JobTDate;                  /* Backup time/date in seconds */
106    uint32_t VolSessionId;
107    uint32_t VolSessionTime;
108    uint32_t JobFiles;
109    uint32_t JobErrors;
110    uint32_t JobMissingFiles;
111    uint64_t JobBytes;
112    uint64_t ReadBytes;
113    int PurgedFiles;
114    int HasBase;
115
116    /* Note, FirstIndex, LastIndex, Start/End File and Block
117     * are only used in the JobMedia record.
118     */
119    uint32_t FirstIndex;               /* First index this Volume */
120    uint32_t LastIndex;                /* Last index this Volume */
121    uint32_t StartFile;
122    uint32_t EndFile;
123    uint32_t StartBlock;
124    uint32_t EndBlock;
125
126    char cSchedTime[MAX_TIME_LENGTH];
127    char cStartTime[MAX_TIME_LENGTH];
128    char cEndTime[MAX_TIME_LENGTH];
129    char cRealEndTime[MAX_TIME_LENGTH];
130    /* Extra stuff not in DB */
131    int limit;                         /* limit records to display */
132    faddr_t rec_addr;
133    uint32_t FileIndex;                /* added during Verify */
134 };
135
136 /* Job Media information used to create the media records
137  * for each Volume used for the job.
138  */
139 /* JobMedia record */
140 struct JOBMEDIA_DBR {
141    DBId_t JobMediaId;                 /* record id */
142    JobId_t  JobId;                    /* JobId */
143    DBId_t MediaId;                    /* MediaId */
144    uint32_t FirstIndex;               /* First index this Volume */
145    uint32_t LastIndex;                /* Last index this Volume */
146    uint32_t StartFile;                /* File for start of data */
147    uint32_t EndFile;                  /* End file on Volume */
148    uint32_t StartBlock;               /* start block on tape */
149    uint32_t EndBlock;                 /* last block */
150 // uint32_t Copy;                     /* identical copy */
151 };
152
153
154 /* Volume Parameter structure */
155 struct VOL_PARAMS {
156    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
157    char MediaType[MAX_NAME_LENGTH];   /* Media Type */
158    char Storage[MAX_NAME_LENGTH];     /* Storage name */
159    uint32_t VolIndex;                 /* Volume seqence no. */
160    uint32_t FirstIndex;               /* First index this Volume */
161    uint32_t LastIndex;                /* Last index this Volume */
162    int32_t Slot;                      /* Slot */
163    uint64_t StartAddr;                /* Start address */
164    uint64_t EndAddr;                  /* End address */
165    int32_t InChanger;                 /* InChanger flag */
166 // uint32_t Copy;                     /* identical copy */
167 // uint32_t Stripe;                   /* RAIT strip number */
168 };
169
170
171 /* Attributes record -- NOT same as in database because
172  *  in general, this "record" creates multiple database
173  *  records (e.g. pathname, filename, fileattributes).
174  */
175 struct ATTR_DBR {
176    char *fname;                       /* full path & filename */
177    char *link;                        /* link if any */
178    char *attr;                        /* attributes statp */
179    uint32_t FileIndex;
180    uint32_t Stream;
181    uint32_t FileType;
182    uint32_t DeltaSeq;
183    JobId_t  JobId;
184    DBId_t ClientId;
185    DBId_t PathId;
186    DBId_t FilenameId;
187    FileId_t FileId;
188    char *Digest;
189    int DigestType;
190 };
191
192 struct ROBJECT_DBR {
193    char *object_name;
194    char *object;
195    char *plugin_name;
196    uint32_t object_len;
197    uint32_t object_full_len;
198    uint32_t object_index;
199    int32_t  object_compression;
200    uint32_t FileIndex;
201    uint32_t Stream;
202    uint32_t FileType;
203    JobId_t  JobId;
204    DBId_t RestoreObjectId;
205 };
206
207
208 /* File record -- same format as database */
209 struct FILE_DBR {
210    FileId_t FileId;
211    uint32_t FileIndex;
212    JobId_t  JobId;
213    DBId_t FilenameId;
214    DBId_t PathId;
215    JobId_t  MarkId;
216    char LStat[256];
217    char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)];
218    int DigestType;                    /* NO_SIG/MD5_SIG/SHA1_SIG */
219 };
220
221 /* Pool record -- same format as database */
222 struct POOL_DBR {
223    DBId_t PoolId;
224    char Name[MAX_NAME_LENGTH];        /* Pool name */
225    uint32_t NumVols;                  /* total number of volumes */
226    uint32_t MaxVols;                  /* max allowed volumes */
227    int32_t LabelType;                 /* Bacula/ANSI/IBM */
228    int32_t UseOnce;                   /* set to use once only */
229    int32_t UseCatalog;                /* set to use catalog */
230    int32_t AcceptAnyVolume;           /* set to accept any volume sequence */
231    int32_t AutoPrune;                 /* set to prune automatically */
232    int32_t Recycle;                   /* default Vol recycle flag */
233    uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
234    utime_t  VolRetention;             /* retention period in seconds */
235    utime_t  VolUseDuration;           /* time in secs volume can be used */
236    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
237    uint32_t MaxVolFiles;              /* Max files on Volume */
238    uint64_t MaxVolBytes;              /* Max bytes on Volume */
239    DBId_t RecyclePoolId;              /* RecyclePool destination when media is purged */
240    DBId_t ScratchPoolId;              /* ScratchPool source when media is needed */
241    char PoolType[MAX_NAME_LENGTH];
242    char LabelFormat[MAX_NAME_LENGTH];
243    /* Extra stuff not in DB */
244    faddr_t rec_addr;
245 };
246
247 class DEVICE_DBR {
248 public:
249    DBId_t DeviceId;
250    char Name[MAX_NAME_LENGTH];        /* Device name */
251    DBId_t MediaTypeId;                /* MediaType */
252    DBId_t StorageId;                  /* Storage id if autochanger */
253    uint32_t DevMounts;                /* Number of times mounted */
254    uint32_t DevErrors;                /* Number of read/write errors */
255    uint64_t DevReadBytes;             /* Number of bytes read */
256    uint64_t DevWriteBytes;            /* Number of bytew written */
257    uint64_t DevReadTime;              /* time spent reading volume */
258    uint64_t DevWriteTime;             /* time spent writing volume */
259    uint64_t DevReadTimeSincCleaning;  /* read time since cleaning */
260    uint64_t DevWriteTimeSincCleaning; /* write time since cleaning */
261    time_t   CleaningDate;             /* time last cleaned */
262    utime_t  CleaningPeriod;           /* time between cleanings */
263 };
264
265 class STORAGE_DBR {
266 public:
267    DBId_t StorageId;
268    char Name[MAX_NAME_LENGTH];        /* Device name */
269    int AutoChanger;                   /* Set if autochanger */
270
271    /* Not in database */
272    bool created;                      /* set if created by db_create ... */
273 };
274
275 class MEDIATYPE_DBR {
276 public:
277    DBId_t MediaTypeId;
278    char MediaType[MAX_NAME_LENGTH];   /* MediaType string */
279    int ReadOnly;                      /* Set if read-only */
280 };
281
282
283 /* Media record -- same as the database */
284 struct MEDIA_DBR {
285    DBId_t MediaId;                    /* Unique volume id */
286    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
287    char MediaType[MAX_NAME_LENGTH];   /* Media type */
288    DBId_t PoolId;                     /* Pool id */
289    time_t   FirstWritten;             /* Time Volume first written this usage */
290    time_t   LastWritten;              /* Time Volume last written */
291    time_t   LabelDate;                /* Date/Time Volume labeled */
292    time_t   InitialWrite;             /* Date/Time Volume first written */
293    int32_t  LabelType;                /* Label (Bacula/ANSI/IBM) */
294    uint32_t VolJobs;                  /* number of jobs on this medium */
295    uint32_t VolFiles;                 /* Number of files */
296    uint32_t VolBlocks;                /* Number of blocks */
297    uint32_t VolMounts;                /* Number of times mounted */
298    uint32_t VolErrors;                /* Number of read/write errors */
299    uint32_t VolWrites;                /* Number of writes */
300    uint32_t VolReads;                 /* Number of reads */
301    uint64_t VolBytes;                 /* Number of bytes written */
302    uint32_t VolParts;                 /* Number of parts written */
303    uint64_t MaxVolBytes;              /* Max bytes to write to Volume */
304    uint64_t VolCapacityBytes;         /* capacity estimate */
305    uint64_t VolReadTime;              /* time spent reading volume */
306    uint64_t VolWriteTime;             /* time spent writing volume */
307    utime_t  VolRetention;             /* Volume retention in seconds */
308    utime_t  VolUseDuration;           /* time in secs volume can be used */
309    uint32_t ActionOnPurge;            /* action on purge, e.g. truncate the disk volume */
310    uint32_t MaxVolJobs;               /* Max Jobs on Volume */
311    uint32_t MaxVolFiles;              /* Max files on Volume */
312    int32_t  Recycle;                  /* recycle yes/no */
313    int32_t  Slot;                     /* slot in changer */
314    int32_t  Enabled;                  /* 0=disabled, 1=enabled, 2=archived */
315    int32_t  InChanger;                /* Volume currently in changer */
316    DBId_t   StorageId;                /* Storage record Id */
317    uint32_t EndFile;                  /* Last file on volume */
318    uint32_t EndBlock;                 /* Last block on volume */
319    uint32_t RecycleCount;             /* Number of times recycled */
320    char     VolStatus[20];            /* Volume status */
321    DBId_t   DeviceId;                 /* Device where Vol last written */
322    DBId_t   LocationId;               /* Where Volume is -- user defined */
323    DBId_t   ScratchPoolId;            /* Where to move if scratch */
324    DBId_t   RecyclePoolId;            /* Where to move when recycled */
325    /* Extra stuff not in DB */
326    faddr_t rec_addr;                  /* found record address */
327    /* Since the database returns times as strings, this is how we pass
328     *   them back.
329     */
330    char    cFirstWritten[MAX_TIME_LENGTH]; /* FirstWritten returned from DB */
331    char    cLastWritten[MAX_TIME_LENGTH];  /* LastWritten returned from DB */
332    char    cLabelDate[MAX_TIME_LENGTH];    /* LabelData returned from DB */
333    char    cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */
334    bool    set_first_written;
335    bool    set_label_date;
336 };
337
338 /* Client record -- same as the database */
339 struct CLIENT_DBR {
340    DBId_t ClientId;                   /* Unique Client id */
341    int AutoPrune;
342    utime_t FileRetention;
343    utime_t JobRetention;
344    char Name[MAX_NAME_LENGTH];        /* Client name */
345    char Uname[256];                   /* Uname for client */
346 };
347
348 /* Counter record as in database */
349 struct COUNTER_DBR {
350    char Counter[MAX_NAME_LENGTH];
351    int32_t MinValue;
352    int32_t MaxValue;
353    int32_t CurrentValue;
354    char WrapCounter[MAX_NAME_LENGTH];
355 };
356
357
358 /* FileSet record -- same as the database */
359 struct FILESET_DBR {
360    DBId_t FileSetId;                  /* Unique FileSet id */
361    char FileSet[MAX_NAME_LENGTH];     /* FileSet name */
362    char MD5[50];                      /* MD5 signature of include/exclude */
363    time_t CreateTime;                 /* date created */
364    /*
365     * This is where we return CreateTime
366     */
367    char cCreateTime[MAX_TIME_LENGTH]; /* CreateTime as returned from DB */
368    /* Not in DB but returned by db_create_fileset() */
369    bool created;                      /* set when record newly created */
370 };
371
372 /* Call back context for getting a 32/64 bit value from the database */
373 struct db_int64_ctx {
374    int64_t value;                     /* value returned */
375    int count;                         /* number of values seen */
376 };
377
378 /* Call back context for getting a list of comma separated strings from the
379  * database 
380  */
381 class db_list_ctx {
382 public:
383    POOLMEM *list;                     /* list */
384    int count;                         /* number of values seen */
385
386    db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); }
387    ~db_list_ctx() { free_pool_memory(list); list = NULL; }
388    void reset() { *list = 0; count = 0;}
389    void cat(const db_list_ctx &str) {
390       if (str.count > 0) {
391          if (*list) {
392             pm_strcat(list, ",");
393          }
394          pm_strcat(list, str.list);
395          count += str.count;
396       }
397    }
398 private:
399    db_list_ctx(const db_list_ctx&);            /* prohibit pass by value */
400    db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */
401 };
402
403 typedef enum {
404    SQL_INTERFACE_TYPE_MYSQL      = 0,
405    SQL_INTERFACE_TYPE_POSTGRESQL = 1,
406    SQL_INTERFACE_TYPE_SQLITE3    = 2,
407    SQL_INTERFACE_TYPE_INGRES     = 3,
408    SQL_INTERFACE_TYPE_DBI        = 4
409 } SQL_INTERFACETYPE;
410
411 typedef enum {
412    SQL_TYPE_MYSQL      = 0,
413    SQL_TYPE_POSTGRESQL = 1,
414    SQL_TYPE_SQLITE3    = 2,
415    SQL_TYPE_INGRES     = 3,
416    SQL_TYPE_UNKNOWN    = 99
417 } SQL_DBTYPE;
418
419 typedef void (DB_LIST_HANDLER)(void *, const char *);
420 typedef int (DB_RESULT_HANDLER)(void *, int, char **);
421
422 #define db_lock(mdb)   mdb->_db_lock(__FILE__, __LINE__)
423 #define db_unlock(mdb) mdb->_db_unlock(__FILE__, __LINE__)
424
425 /* Current database version number for all drivers */
426 #define BDB_VERSION 13
427
428 class B_DB: public SMARTALLOC {
429 protected:
430    brwlock_t m_lock;                      /* transaction lock */
431    dlink m_link;                          /* queue control */
432    SQL_INTERFACETYPE m_db_interface_type; /* type of backend used */
433    SQL_DBTYPE m_db_type;                  /* database type */
434    int m_ref_count;                       /* reference count */
435    bool m_connected;                      /* connection made to db */
436    bool m_have_batch_insert;              /* have batch insert support ? */
437    char *m_db_driver;                     /* database driver */
438    char *m_db_driverdir;                  /* database driver dir */
439    char *m_db_name;                       /* database name */
440    char *m_db_user;                       /* database user */
441    char *m_db_address;                    /* host name address */
442    char *m_db_socket;                     /* socket for local access */
443    char *m_db_password;                   /* database password */
444    int m_db_port;                         /* port for host name address */
445    bool m_disabled_batch_insert;          /* explicitly disabled batch insert mode ? */
446
447 public:
448    POOLMEM *errmsg;                       /* nicely edited error message */
449    POOLMEM *cmd;                          /* SQL command string */
450    POOLMEM *cached_path;                  /* cached path name */
451    int cached_path_len;                   /* length of cached path */
452    uint32_t cached_path_id;               /* cached path id */
453    int changes;                           /* changes during transaction */
454    POOLMEM *fname;                        /* Filename only */
455    POOLMEM *path;                         /* Path only */
456    POOLMEM *esc_name;                     /* Escaped file name */
457    POOLMEM *esc_path;                     /* Escaped path name */
458    POOLMEM *esc_obj;                      /* Escaped restore object */
459    int fnl;                               /* file name length */
460    int pnl;                               /* path name length */
461
462    /* methods */
463    B_DB() {};
464    virtual ~B_DB() {};
465    const char *get_db_name(void) { return m_db_name; };
466    const char *get_db_user(void) { return m_db_user; };
467    bool is_connected(void) { return m_connected; };
468    bool batch_insert_available(void) { return m_have_batch_insert; };
469    void increment_refcount(void) { m_ref_count++; };
470
471    /* low level methods */
472    bool db_match_database(const char *db_driver, const char *db_name,
473                           const char *db_address, int db_port);
474    B_DB *db_clone_database_connection(JCR *jcr, bool mult_db_connections);
475    int db_get_type_index(void) { return m_db_type; };
476    const char *db_get_type(void);
477    void _db_lock(const char *file, int line);
478    void _db_unlock(const char *file, int line);
479    bool db_sql_query(const char *query, int flags=0);
480    void print_lock_info(FILE *fp);
481
482    /* Pure virtual low level methods */
483    virtual bool db_open_database(JCR *jcr) = 0;
484    virtual void db_close_database(JCR *jcr) = 0;
485    virtual void db_thread_cleanup(void) = 0;
486    virtual void db_escape_string(JCR *jcr, char *snew, char *old, int len) = 0;
487    virtual char *db_escape_object(JCR *jcr, char *old, int len) = 0;
488    virtual void db_unescape_object(JCR *jcr, char *from, int32_t expected_len,
489                                    POOLMEM **dest, int32_t *len) = 0;
490    virtual void db_start_transaction(JCR *jcr) = 0;
491    virtual void db_end_transaction(JCR *jcr) = 0;
492    virtual bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) = 0;
493
494    /* By default, we use db_sql_query */
495    virtual bool db_big_sql_query(const char *query, 
496                                  DB_RESULT_HANDLER *result_handler, void *ctx) {
497       return db_sql_query(query, result_handler, ctx);
498    };
499 };
500
501 /* sql_query Query Flags */
502 #define QF_STORE_RESULT 0x01
503
504 /* Use for better error location printing */
505 #define UPDATE_DB(jcr, db, cmd) UpdateDB(__FILE__, __LINE__, jcr, db, cmd)
506 #define INSERT_DB(jcr, db, cmd) InsertDB(__FILE__, __LINE__, jcr, db, cmd)
507 #define QUERY_DB(jcr, db, cmd) QueryDB(__FILE__, __LINE__, jcr, db, cmd)
508 #define DELETE_DB(jcr, db, cmd) DeleteDB(__FILE__, __LINE__, jcr, db, cmd)
509
510 #include "protos.h"
511 #include "jcr.h"
512 #include "sql_cmds.h"
513
514 /* Object used in db_list_xxx function */
515 class LIST_CTX {
516 public:
517    char line[256];              /* Used to print last dash line */
518    int32_t num_rows;
519
520    e_list_type type;            /* Vertical/Horizontal */
521    DB_LIST_HANDLER *send;       /* send data back */
522    bool once;                   /* Used to print header one time */
523    void *ctx;                   /* send() user argument */
524    B_DB *mdb;
525    JCR *jcr;
526
527    void empty() {
528       once = false;
529       line[0] = '\0';
530    }
531
532    void send_dashes() {
533       if (*line) {
534          send(ctx, line);
535       }
536    }
537
538    LIST_CTX(JCR *j, B_DB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) {
539       line[0] = '\0';
540       once = false;
541       num_rows = 0;
542       type = t;
543       send = h;
544       ctx = c;
545       jcr = j;
546       mdb = m;
547    }
548 };
549
550 /*
551  * Some functions exported by sql.c for use within the cats directory.
552  */
553 int list_result(void *vctx, int cols, char **row);
554 void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx);
555 int get_sql_record_max(JCR *jcr, B_DB *mdb);
556 bool check_tables_version(JCR *jcr, B_DB *mdb);
557 bool db_check_max_connections(JCR *jcr, B_DB *mdb, uint32_t nb);
558
559 void print_dashes(B_DB *mdb);
560 void print_result(B_DB *mdb);
561 int QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
562 int InsertDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
563 int DeleteDB(const char *file, int line, JCR *jcr, B_DB *db, char *delete_cmd);
564 int UpdateDB(const char *file, int line, JCR *jcr, B_DB *db, char *update_cmd);
565 void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname);
566 #endif /* __CATS_H_ */