]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sql_create.c
DB changes for Retention Periods
[bacula/bacula] / bacula / src / cats / sql_create.c
1 /*
2  * Bacula Catalog Database Create record interface routines
3  * 
4  *    Kern Sibbald, March 2000
5  */
6
7 /*
8    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2 of
13    the License, or (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public
21    License along with this program; if not, write to the Free
22    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23    MA 02111-1307, USA.
24
25  */
26
27 /* *****FIXME**** fix fixed length of select_cmd[] and insert_cmd[] */
28
29 /* The following is necessary so that we do not include
30  * the dummy external definition of DB.
31  */
32 #define __SQL_C                       /* indicate that this is sql.c */
33
34 #include "bacula.h"
35 #include "cats.h"
36
37 #if    HAVE_MYSQL || HAVE_SQLITE
38
39 /* -----------------------------------------------------------------------
40  *
41  *   Generic Routines (or almost generic)
42  *
43  * -----------------------------------------------------------------------
44  */
45
46 /* Forward referenced subroutines */
47 static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar);
48 static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar, char *fname);
49 static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path);
50
51
52 /* Imported subroutines */
53 extern void print_dashes(B_DB *mdb);
54 extern void print_result(B_DB *mdb);
55 extern int QueryDB(char *file, int line, B_DB *db, char *select_cmd);
56 extern int InsertDB(char *file, int line, B_DB *db, char *select_cmd);
57
58
59 /* Create a new record for the Job
60  * Returns: 0 on failure
61  *          1 on success
62  */
63 int
64 db_create_job_record(B_DB *mdb, JOB_DBR *jr)
65 {
66    char dt[MAX_TIME_LENGTH];
67    time_t stime;
68    struct tm tm;
69    int stat;
70    char *JobId;
71    btime_t JobTDate;
72    char ed1[30];
73
74    stime = jr->SchedTime;
75
76    localtime_r(&stime, &tm); 
77    strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
78    JobTDate = (btime_t)stime;
79
80    P(mdb->mutex);
81    JobId = db_next_index(mdb, "Job");
82    if (!JobId) {
83       jr->JobId = 0;
84       V(mdb->mutex);
85       return 0;
86    }
87    /* Must create it */
88    Mmsg(&mdb->cmd,
89 "INSERT INTO Job (JobId, Job, Name, Type, Level, SchedTime, JobTDate) VALUES \
90 (%s, \"%s\", \"%s\", \"%c\", \"%c\", \"%s\", %s)", 
91            JobId, jr->Job, jr->Name, (char)(jr->Type), (char)(jr->Level), dt,
92            edit_uint64(JobTDate, ed1));
93
94    if (!INSERT_DB(mdb, mdb->cmd)) {
95       Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"), 
96             mdb->cmd, sql_strerror(mdb));
97       jr->JobId = 0;
98       stat = 0;
99    } else {
100       jr->JobId = sql_insert_id(mdb);
101       stat = 1;
102    }
103    V(mdb->mutex);
104    return stat;
105 }
106
107 /* Create a JobMedia record for medium used this job   
108  * Returns: 0 on failure
109  *          1 on success
110  */
111 int
112 db_create_jobmedia_record(B_DB *mdb, JOBMEDIA_DBR *jm)
113 {
114    int stat;
115
116    P(mdb->mutex);
117    Mmsg(&mdb->cmd, "SELECT JobId, MediaId FROM JobMedia WHERE \
118 JobId=%d AND MediaId=%d", jm->JobId, jm->MediaId);
119
120    Dmsg0(30, mdb->cmd);
121    if (QUERY_DB(mdb, mdb->cmd)) {
122       mdb->num_rows = sql_num_rows(mdb);
123       if (mdb->num_rows > 0) {
124          Mmsg0(&mdb->errmsg, _("Create JobMedia failed. Record already exists.\n"));
125          sql_free_result(mdb);
126          V(mdb->mutex);
127          Dmsg0(0, "Already have JobMedia record\n");
128          return 0;
129       }
130       sql_free_result(mdb);
131    }
132
133    /* Must create it */
134    Mmsg(&mdb->cmd, 
135 "INSERT INTO JobMedia (JobId, MediaId, FirstIndex, LastIndex) \
136 VALUES (%d, %d, %u, %u)", 
137        jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex);
138
139    Dmsg0(30, mdb->cmd);
140    if (!INSERT_DB(mdb, mdb->cmd)) {
141       Mmsg2(&mdb->errmsg, _("Create db JobMedia record %s failed. ERR=%s\n"), mdb->cmd, 
142          sql_strerror(mdb));
143       stat = 0;
144    } else {
145       stat = 1;
146    }
147    V(mdb->mutex);
148    Dmsg0(30, "Return from JobMedia\n");
149    return stat;
150 }
151
152
153
154 /* Create Unique Pool record
155  * Returns: 0 on failure
156  *          1 on success
157  */
158 int
159 db_create_pool_record(B_DB *mdb, POOL_DBR *pr)
160 {
161    int stat;
162    char ed1[30];
163
164    P(mdb->mutex);
165    Mmsg(&mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name=\"%s\"", pr->Name);
166    Dmsg1(20, "selectpool: %s\n", mdb->cmd);
167
168    if (QUERY_DB(mdb, mdb->cmd)) {
169
170       mdb->num_rows = sql_num_rows(mdb);
171    
172       if (mdb->num_rows > 0) {
173          Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
174          sql_free_result(mdb);
175          V(mdb->mutex);
176          return 0;
177       }
178       sql_free_result(mdb);
179    }
180
181    /* Must create it */
182    Mmsg(&mdb->cmd, 
183 "INSERT INTO Pool (Name, NumVols, MaxVols, UseOnce, UseCatalog, \
184 AcceptAnyVolume, AutoPrune, Recycle, VolRetention, PoolType, LabelFormat) \
185 VALUES (\"%s\", %d, %d, %d, %d, %d, %d, %d, %s, \"%s\", \"%s\")", 
186                   pr->Name,
187                   pr->NumVols, pr->MaxVols,
188                   pr->UseOnce, pr->UseCatalog,
189                   pr->AcceptAnyVolume,
190                   pr->AutoPrune, pr->Recycle,
191                   edit_uint64(pr->VolRetention, ed1),
192                   pr->PoolType, pr->LabelFormat);
193    Dmsg1(500, "Create Pool: %s\n", mdb->cmd);
194    if (!INSERT_DB(mdb, mdb->cmd)) {
195       Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"), 
196             mdb->cmd, sql_strerror(mdb));
197       pr->PoolId = 0;
198       stat = 0;
199    } else {
200       pr->PoolId = sql_insert_id(mdb);
201       stat = 1;
202    }
203    V(mdb->mutex);
204    
205    return stat;
206 }
207
208
209 /* 
210  * Create Unique Media record   
211  * Returns: 0 on failure
212  *          1 on success
213  */ 
214 int
215 db_create_media_record(B_DB *mdb, MEDIA_DBR *mr)
216 {
217    int stat;
218    char ed1[30], ed2[30], ed3[30];
219
220    P(mdb->mutex);
221    Mmsg(&mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName=\"%s\"", 
222            mr->VolumeName);
223    Dmsg1(110, "selectpool: %s\n", mdb->cmd);
224
225    if (QUERY_DB(mdb, mdb->cmd)) {
226       mdb->num_rows = sql_num_rows(mdb);
227       if (mdb->num_rows > 0) {
228          Mmsg1(&mdb->errmsg, _("Media record %s already exists\n"), mr->VolumeName);
229          sql_free_result(mdb);
230          V(mdb->mutex);
231          return 0;
232       }
233       sql_free_result(mdb);
234    }
235
236    /* Must create it */
237    Mmsg(&mdb->cmd, 
238 "INSERT INTO Media (VolumeName, MediaType, PoolId, VolMaxBytes, VolCapacityBytes, \
239 Recycle, VolRetention, VolStatus) VALUES (\"%s\", \"%s\", %d, %s, %s, %d, %s, \"%s\")", 
240                   mr->VolumeName,
241                   mr->MediaType, mr->PoolId, 
242                   edit_uint64(mr->VolMaxBytes,ed1),
243                   edit_uint64(mr->VolCapacityBytes, ed2),
244                   mr->Recycle,
245                   edit_uint64(mr->VolRetention, ed3),
246                   mr->VolStatus);
247
248    Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
249    if (!INSERT_DB(mdb, mdb->cmd)) {
250       Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
251             mdb->cmd, sql_strerror(mdb));
252       stat = 0;
253    } else {
254       mr->MediaId = sql_insert_id(mdb);
255       stat = 1;
256    }
257    V(mdb->mutex);
258    return stat;
259 }
260
261
262
263 /* 
264  * Create a Unique record for the client -- no duplicates 
265  * Returns: 0 on failure
266  *          1 on success with id in cr->ClientId
267  */
268 int db_create_client_record(B_DB *mdb, CLIENT_DBR *cr)
269 {
270    SQL_ROW row;
271    int stat;
272    char ed1[30], ed2[30];
273
274    P(mdb->mutex);
275    Mmsg(&mdb->cmd, "SELECT ClientId FROM Client WHERE Name=\"%s\"", cr->Name);
276
277    cr->ClientId = 0;
278    if (QUERY_DB(mdb, mdb->cmd)) {
279
280       mdb->num_rows = sql_num_rows(mdb);
281       
282       /* If more than one, report error, but return first row */
283       if (mdb->num_rows > 1) {
284          Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
285          Emsg0(M_ERROR, 0, mdb->errmsg);
286       }
287       if (mdb->num_rows >= 1) {
288          if ((row = sql_fetch_row(mdb)) == NULL) {
289             Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
290             Emsg0(M_ERROR, 0, mdb->errmsg);
291             sql_free_result(mdb);
292             V(mdb->mutex);
293             return 0;
294          }
295          sql_free_result(mdb);
296          cr->ClientId = atoi(row[0]);
297          V(mdb->mutex);
298          return 1;
299       }
300       sql_free_result(mdb);
301    }
302
303    /* Must create it */
304    Mmsg(&mdb->cmd, "INSERT INTO Client (Name, Uname, AutoPrune, \
305 FileRetention, JobRetention) VALUES \
306 (\"%s\", \"%s\", %d, %s, %s)", cr->Name, cr->Uname, cr->AutoPrune,
307       edit_uint64(cr->FileRetention, ed1),
308       edit_uint64(cr->JobRetention, ed2));
309
310    if (!INSERT_DB(mdb, mdb->cmd)) {
311       Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
312             mdb->cmd, sql_strerror(mdb));
313       cr->ClientId = 0;
314       stat = 0;
315    } else {
316       cr->ClientId = sql_insert_id(mdb);
317       stat = 1;
318    }
319    V(mdb->mutex);
320    return stat;
321 }
322
323
324 /* 
325  * Create a FileSet record. This record is unique in the
326  *  name and the MD5 signature of the include/exclude sets.
327  *  Returns: 0 on failure
328  *           1 on success with FileSetId in record
329  */
330 int db_create_fileset_record(B_DB *mdb, FILESET_DBR *fsr)
331 {
332    SQL_ROW row;
333    int stat;
334
335    P(mdb->mutex);
336    Mmsg(&mdb->cmd, "SELECT FileSetId FROM FileSet WHERE \
337 FileSet=\"%s\" and MD5=\"%s\"", fsr->FileSet, fsr->MD5);
338
339    fsr->FileSetId = 0;
340    if (QUERY_DB(mdb, mdb->cmd)) {
341
342       mdb->num_rows = sql_num_rows(mdb);
343       
344       if (mdb->num_rows > 1) {
345          Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
346          Emsg0(M_ERROR, 0, mdb->errmsg);
347       }
348       if (mdb->num_rows >= 1) {
349          if ((row = sql_fetch_row(mdb)) == NULL) {
350             Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
351             Emsg0(M_ERROR, 0, mdb->errmsg);
352             sql_free_result(mdb);
353             V(mdb->mutex);
354             return 0;
355          }
356          sql_free_result(mdb);
357          fsr->FileSetId = atoi(row[0]);
358          V(mdb->mutex);
359          return 1;
360       }
361       sql_free_result(mdb);
362    }
363
364    /* Must create it */
365    Mmsg(&mdb->cmd, "INSERT INTO FileSet (FileSet, MD5) VALUES \
366 (\"%s\", \"%s\")", fsr->FileSet, fsr->MD5);
367
368    if (!INSERT_DB(mdb, mdb->cmd)) {
369       Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
370             mdb->cmd, sql_strerror(mdb));
371       fsr->FileSetId = 0;
372       stat = 0;
373    } else {
374       fsr->FileSetId = sql_insert_id(mdb);
375       stat = 1;
376    }
377
378    V(mdb->mutex);
379    return stat;
380 }
381
382
383 /*
384  *  struct stat
385  *  {
386  *      dev_t         st_dev;       * device *
387  *      ino_t         st_ino;       * inode *
388  *      mode_t        st_mode;      * protection *
389  *      nlink_t       st_nlink;     * number of hard links *
390  *      uid_t         st_uid;       * user ID of owner *
391  *      gid_t         st_gid;       * group ID of owner *
392  *      dev_t         st_rdev;      * device type (if inode device) *
393  *      off_t         st_size;      * total size, in bytes *
394  *      unsigned long st_blksize;   * blocksize for filesystem I/O *
395  *      unsigned long st_blocks;    * number of blocks allocated *
396  *      time_t        st_atime;     * time of last access *
397  *      time_t        st_mtime;     * time of last modification *
398  *      time_t        st_ctime;     * time of last inode change *            
399  *  };
400  */
401
402
403
404 /* 
405  * Create File record in B_DB   
406  *
407  *  In order to reduce database size, we store the File attributes,
408  *  the FileName, and the Path separately.  In principle, there   
409  *  is a single FileName record and a single Path record, no matter
410  *  how many times it occurs.  This is this subroutine, we separate
411  *  the file and the path and create three database records.
412  */
413 int db_create_file_attributes_record(B_DB *mdb, ATTR_DBR *ar)
414 {
415    int fnl, pnl;
416    char *l, *p;
417    /* ****FIXME***** malloc these */
418    char file[MAXSTRING];
419    char spath[MAXSTRING];
420    char buf[MAXSTRING];
421
422    Dmsg1(100, "Fname=%s\n", ar->fname);
423    Dmsg0(50, "put_file_into_catalog\n");
424    /* For the moment, we only handle Unix attributes.  Note, we are
425     * also getting any MD5 signature that was computed.
426     */
427    if (ar->Stream != STREAM_UNIX_ATTRIBUTES) {
428       Mmsg0(&mdb->errmsg, _("Attempt to put non-attributes into catalog\n"));
429       return 0;
430    }
431
432    /* Find path without the filename.  
433     * I.e. everything after the last / is a "filename".
434     * OK, maybe it is a directory name, but we treat it like
435     * a filename. If we don't find a / then the whole name
436     * must be a path name (e.g. c:).
437     */
438    for (p=l=ar->fname; *p; p++) {
439       if (*p == '/') {
440          l = p;                       /* set pos of last slash */
441       }
442    }
443    if (*l == '/') {                   /* did we find a slash? */
444       l++;                            /* yes, point to filename */
445    } else {                           /* no, whole thing must be path name */
446       l = p;
447    }
448
449    /* If filename doesn't exist (i.e. root directory), we
450     * simply create a blank name consisting of a single 
451     * space. This makes handling zero length filenames
452     * easier.
453     */
454    fnl = p - l;
455    if (fnl > 255) {
456       Emsg1(M_WARNING, 0, _("Filename truncated to 255 chars: %s\n"), l);
457       fnl = 255;
458    }
459    if (fnl > 0) {
460       strncpy(file, l, fnl);          /* copy filename */
461       file[fnl] = 0;
462    } else {
463       file[0] = ' ';                  /* blank filename */
464       file[1] = 0;
465    }
466
467    pnl = l - ar->fname;    
468    if (pnl > 255) {
469       Emsg1(M_WARNING, 0, _("Path name truncated to 255 chars: %s\n"), ar->fname);
470       pnl = 255;
471    }
472    strncpy(spath, ar->fname, pnl);
473    spath[pnl] = 0;
474
475    if (pnl == 0) {
476       Mmsg1(&mdb->errmsg, _("Path length is zero. File=%s\n"), ar->fname);
477       Emsg0(M_ERROR, 0, mdb->errmsg);
478       spath[0] = ' ';
479       spath[1] = 0;
480    }
481
482    Dmsg1(100, "spath=%s\n", spath);
483    Dmsg1(100, "file=%s\n", file);
484
485    db_escape_string(buf, file, fnl);
486
487    if (!db_create_filename_record(mdb, ar, buf)) {
488       return 0;
489    }
490    Dmsg1(100, "db_create_filename_record: %s\n", buf);
491
492    db_escape_string(buf, spath, pnl);
493
494    if (!db_create_path_record(mdb, ar, buf)) {
495       return 0;
496    }
497    Dmsg1(100, "db_create_path_record\n", buf);
498
499    if (!db_create_file_record(mdb, ar)) {
500       return 0;
501    }
502    Dmsg0(50, "db_create_file_record\n");
503
504    Dmsg3(100, "Path=%s File=%s FilenameId=%d\n", spath, file, ar->FilenameId);
505
506    return 1;
507 }
508
509 static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar)
510 {
511    int stat;
512
513    P(mdb->mutex);
514    /* Must create it */
515    Mmsg(&mdb->cmd,
516 "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, \
517 LStat, MD5) VALUES (%d, %d, %d, %d, \"%s\", \"0\")", 
518      (int)ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId, 
519       ar->attr);
520
521    if (!INSERT_DB(mdb, mdb->cmd)) {
522       Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),       
523          mdb->cmd, sql_strerror(mdb));
524       Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
525       ar->FileId = 0;
526       stat = 0;
527    } else {
528       ar->FileId = sql_insert_id(mdb);
529       stat = 1;
530    }
531    V(mdb->mutex);
532    return stat;
533 }
534
535 /* Create a Unique record for the Path -- no duplicates */
536 static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path)
537 {
538    SQL_ROW row;
539    static uint32_t cached_id = 0;
540    static char cached_path[MAXSTRING];
541    int stat;
542
543    if (*path == 0) {
544       Mmsg0(&mdb->errmsg, _("Null path given to db_create_path_record\n"));
545       Emsg0(M_ERROR, 0, mdb->errmsg);
546       ar->PathId = 0;
547       return 0;
548    }
549
550    P(mdb->mutex);
551
552    if (cached_id != 0 && strcmp(cached_path, path) == 0) {
553       ar->PathId = cached_id;
554       V(mdb->mutex);
555       return 1;
556    }
557
558    Mmsg(&mdb->cmd, "SELECT PathId FROM Path WHERE Path=\"%s\"", path);
559
560    if (QUERY_DB(mdb, mdb->cmd)) {
561
562       mdb->num_rows = sql_num_rows(mdb);
563
564       if (mdb->num_rows > 1) {
565          char ed1[30];
566          Mmsg2(&mdb->errmsg, _("More than one Path!: %s for Path=%s\n"), 
567             edit_uint64(mdb->num_rows, ed1), path);
568          Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
569          Emsg1(M_ERROR, 0, "%s\n", mdb->cmd);
570       }
571       if (mdb->num_rows >= 1) {
572          if ((row = sql_fetch_row(mdb)) == NULL) {
573             V(mdb->mutex);
574             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
575             Emsg0(M_ERROR, 0, mdb->errmsg);
576             sql_free_result(mdb);
577             ar->PathId = 0;
578             return 0;
579          }
580          sql_free_result(mdb);
581          ar->PathId = atoi(row[0]);
582          if (ar->PathId != cached_id) {
583             cached_id = ar->PathId;
584             strncpy(cached_path, path, sizeof(cached_path));
585             cached_path[sizeof(cached_path)-1] = 0;
586          }
587          V(mdb->mutex);
588          return 1;
589       }
590
591       sql_free_result(mdb);
592    }
593
594    Mmsg(&mdb->cmd, "INSERT INTO Path (Path)  VALUES (\"%s\")", path);
595
596    if (!INSERT_DB(mdb, mdb->cmd)) {
597       Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"), 
598          mdb->cmd, sql_strerror(mdb));
599       Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
600       ar->PathId = 0;
601       stat = 0;
602    } else {
603       ar->PathId = sql_insert_id(mdb);
604       stat = 1;
605    }
606
607    if (ar->PathId != cached_id) {
608       cached_id = ar->PathId;
609       strncpy(cached_path, path, sizeof(cached_path));
610       cached_path[sizeof(cached_path)-1] = 0;
611    }
612    V(mdb->mutex);
613    return stat;
614 }
615
616 /* Create a Unique record for the filename -- no duplicates */
617 static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar, char *fname) 
618 {
619    SQL_ROW row;
620    int stat;
621
622    P(mdb->mutex);
623    Mmsg(&mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name=\"%s\"", fname);
624
625    if (QUERY_DB(mdb, mdb->cmd)) {
626       mdb->num_rows = sql_num_rows(mdb);
627       if (mdb->num_rows > 1) {
628          Mmsg2(&mdb->errmsg, _("More than one Filename!: %d File=%s\n"), 
629             (int)(mdb->num_rows), fname);
630          Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
631          Emsg1(M_ERROR, 0, "%s\n", mdb->cmd);
632       }
633       if (mdb->num_rows >= 1) {
634          if ((row = sql_fetch_row(mdb)) == NULL) {
635             Mmsg2(&mdb->errmsg, _("error fetching row for file=%s: ERR=%s\n"), 
636                 fname, sql_strerror(mdb));
637             sql_free_result(mdb);
638             V(mdb->mutex);
639             Emsg0(M_ERROR, 0, mdb->errmsg);
640             ar->FilenameId = 0;
641             return 0;
642          }
643          sql_free_result(mdb);
644          ar->FilenameId = atoi(row[0]);
645          V(mdb->mutex);
646          return 1;
647       }
648       sql_free_result(mdb);
649    }
650
651    Mmsg(&mdb->cmd, "INSERT INTO Filename (Name) \
652 VALUES (\"%s\")", fname);
653
654    if (!INSERT_DB(mdb, mdb->cmd)) {
655       Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"), 
656             mdb->cmd, sql_strerror(mdb));
657       Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
658       ar->FilenameId = 0;
659       stat = 0;
660    } else {
661       ar->FilenameId = sql_insert_id(mdb);
662       stat = 1;
663    }
664
665    V(mdb->mutex);
666    return stat;
667 }
668
669 #endif /* HAVE_MYSQL || HAVE_SQLITE */