]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sql_create.c
add Prune command -- not yet tested
[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 StartDay;
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    StartDay = (btime_t)(date_encode(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday) -
79        date_encode(2000, 1, 1));
80
81    P(mdb->mutex);
82    JobId = db_next_index(mdb, "Job");
83    if (!JobId) {
84       jr->JobId = 0;
85       V(mdb->mutex);
86       return 0;
87    }
88    /* Must create it */
89    Mmsg(&mdb->cmd,
90 "INSERT INTO Job (JobId, Job, Name, Type, Level, SchedTime, StartDay) VALUES \
91 (%s, \"%s\", \"%s\", \"%c\", \"%c\", \"%s\", %s)", 
92            JobId, jr->Job, jr->Name, (char)(jr->Type), (char)(jr->Level), dt,
93            edit_uint64(StartDay, ed1));
94
95    if (!INSERT_DB(mdb, mdb->cmd)) {
96       Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"), 
97             mdb->cmd, sql_strerror(mdb));
98       jr->JobId = 0;
99       stat = 0;
100    } else {
101       jr->JobId = sql_insert_id(mdb);
102       stat = 1;
103    }
104    V(mdb->mutex);
105    return stat;
106 }
107
108 /* Create a JobMedia record for medium used this job   
109  * Returns: 0 on failure
110  *          1 on success
111  */
112 int
113 db_create_jobmedia_record(B_DB *mdb, JOBMEDIA_DBR *jm)
114 {
115    int stat;
116
117    P(mdb->mutex);
118    Mmsg(&mdb->cmd, "SELECT JobId, MediaId FROM JobMedia WHERE \
119 JobId=%d AND MediaId=%d", jm->JobId, jm->MediaId);
120
121    Dmsg0(30, mdb->cmd);
122    if (QUERY_DB(mdb, mdb->cmd)) {
123       mdb->num_rows = sql_num_rows(mdb);
124       if (mdb->num_rows > 0) {
125          Mmsg0(&mdb->errmsg, _("Create JobMedia failed. Record already exists.\n"));
126          sql_free_result(mdb);
127          V(mdb->mutex);
128          Dmsg0(0, "Already have JobMedia record\n");
129          return 0;
130       }
131       sql_free_result(mdb);
132    }
133
134    /* Must create it */
135    Mmsg(&mdb->cmd, 
136 "INSERT INTO JobMedia (JobId, MediaId, FirstIndex, LastIndex) \
137 VALUES (%d, %d, %u, %u)", 
138        jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex);
139
140    Dmsg0(30, mdb->cmd);
141    if (!INSERT_DB(mdb, mdb->cmd)) {
142       Mmsg2(&mdb->errmsg, _("Create db JobMedia record %s failed. ERR=%s\n"), mdb->cmd, 
143          sql_strerror(mdb));
144       stat = 0;
145    } else {
146       stat = 1;
147    }
148    V(mdb->mutex);
149    Dmsg0(30, "Return from JobMedia\n");
150    return stat;
151 }
152
153
154
155 /* Create Unique Pool record
156  * Returns: 0 on failure
157  *          1 on success
158  */
159 int
160 db_create_pool_record(B_DB *mdb, POOL_DBR *pool_dbr)
161 {
162    int stat;
163
164    P(mdb->mutex);
165    Mmsg(&mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name=\"%s\"", pool_dbr->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"), pool_dbr->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, PoolType, LabelFormat) \
185 VALUES (\"%s\", %d, %d, %d, %d, %d, \"%s\", \"%s\")", 
186                   pool_dbr->Name,
187                   pool_dbr->NumVols, pool_dbr->MaxVols,
188                   pool_dbr->UseOnce, pool_dbr->UseCatalog,
189                   pool_dbr->AcceptAnyVolume,
190                   pool_dbr->PoolType, pool_dbr->LabelFormat);
191
192    if (!INSERT_DB(mdb, mdb->cmd)) {
193       Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"), 
194             mdb->cmd, sql_strerror(mdb));
195       pool_dbr->PoolId = 0;
196       stat = 0;
197    } else {
198       pool_dbr->PoolId = sql_insert_id(mdb);
199       stat = 1;
200    }
201    V(mdb->mutex);
202    
203    return stat;
204 }
205
206
207 /* 
208  * Create Unique Media record   
209  * Returns: 0 on failure
210  *          1 on success
211  */ 
212 int
213 db_create_media_record(B_DB *mdb, MEDIA_DBR *mr)
214 {
215    int stat;
216    char ed1[30], ed2[30];
217
218    P(mdb->mutex);
219    Mmsg(&mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName=\"%s\"", 
220            mr->VolumeName);
221    Dmsg1(110, "selectpool: %s\n", mdb->cmd);
222
223    if (QUERY_DB(mdb, mdb->cmd)) {
224       mdb->num_rows = sql_num_rows(mdb);
225       if (mdb->num_rows > 0) {
226          Mmsg1(&mdb->errmsg, _("Media record %s already exists\n"), mr->VolumeName);
227          sql_free_result(mdb);
228          V(mdb->mutex);
229          return 0;
230       }
231       sql_free_result(mdb);
232    }
233
234    /* Must create it */
235    Mmsg(&mdb->cmd, 
236 "INSERT INTO Media (VolumeName, MediaType, PoolId, VolMaxBytes, VolCapacityBytes, \
237 VolStatus, Recycle) VALUES (\"%s\", \"%s\", %d, %s, %s, \"%s\", \"%s\")", 
238                   mr->VolumeName,
239                   mr->MediaType, mr->PoolId, 
240                   edit_uint64(mr->VolMaxBytes,ed1),
241                   edit_uint64(mr->VolCapacityBytes, ed2),
242                   mr->VolStatus, mr->Recycle);
243
244    if (!INSERT_DB(mdb, mdb->cmd)) {
245       Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
246             mdb->cmd, sql_strerror(mdb));
247       stat = 0;
248    } else {
249       mr->MediaId = sql_insert_id(mdb);
250       stat = 1;
251    }
252    V(mdb->mutex);
253    return stat;
254 }
255
256
257
258 /* 
259  * Create a Unique record for the client -- no duplicates 
260  * Returns: 0 on failure
261  *          1 on success with id in cr->ClientId
262  */
263 int db_create_client_record(B_DB *mdb, CLIENT_DBR *cr)
264 {
265    SQL_ROW row;
266    int stat;
267
268    P(mdb->mutex);
269    Mmsg(&mdb->cmd, "SELECT ClientId FROM Client WHERE Name=\"%s\"", cr->Name);
270
271    cr->ClientId = 0;
272    if (QUERY_DB(mdb, mdb->cmd)) {
273
274       mdb->num_rows = sql_num_rows(mdb);
275       
276       /* If more than one, report error, but return first row */
277       if (mdb->num_rows > 1) {
278          Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
279          Emsg0(M_ERROR, 0, mdb->errmsg);
280       }
281       if (mdb->num_rows >= 1) {
282          if ((row = sql_fetch_row(mdb)) == NULL) {
283             Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
284             Emsg0(M_ERROR, 0, mdb->errmsg);
285             sql_free_result(mdb);
286             V(mdb->mutex);
287             return 0;
288          }
289          sql_free_result(mdb);
290          cr->ClientId = atoi(row[0]);
291          V(mdb->mutex);
292          return 1;
293       }
294       sql_free_result(mdb);
295    }
296
297    /* Must create it */
298    Mmsg(&mdb->cmd, "INSERT INTO Client (Name, Uname) VALUES \
299 (\"%s\", \"%s\")", cr->Name, cr->Uname);
300
301    if (!INSERT_DB(mdb, mdb->cmd)) {
302       Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
303             mdb->cmd, sql_strerror(mdb));
304       cr->ClientId = 0;
305       stat = 0;
306    } else {
307       cr->ClientId = sql_insert_id(mdb);
308       stat = 1;
309    }
310    V(mdb->mutex);
311    return stat;
312 }
313
314
315 /* 
316  * Create a FileSet record. This record is unique in the
317  *  name and the MD5 signature of the include/exclude sets.
318  *  Returns: 0 on failure
319  *           1 on success with FileSetId in record
320  */
321 int db_create_fileset_record(B_DB *mdb, FILESET_DBR *fsr)
322 {
323    SQL_ROW row;
324    int stat;
325
326    P(mdb->mutex);
327    Mmsg(&mdb->cmd, "SELECT FileSetId FROM FileSet WHERE \
328 FileSet=\"%s\" and MD5=\"%s\"", fsr->FileSet, fsr->MD5);
329
330    fsr->FileSetId = 0;
331    if (QUERY_DB(mdb, mdb->cmd)) {
332
333       mdb->num_rows = sql_num_rows(mdb);
334       
335       if (mdb->num_rows > 1) {
336          Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
337          Emsg0(M_ERROR, 0, mdb->errmsg);
338       }
339       if (mdb->num_rows >= 1) {
340          if ((row = sql_fetch_row(mdb)) == NULL) {
341             Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
342             Emsg0(M_ERROR, 0, mdb->errmsg);
343             sql_free_result(mdb);
344             V(mdb->mutex);
345             return 0;
346          }
347          sql_free_result(mdb);
348          fsr->FileSetId = atoi(row[0]);
349          V(mdb->mutex);
350          return 1;
351       }
352       sql_free_result(mdb);
353    }
354
355    /* Must create it */
356    Mmsg(&mdb->cmd, "INSERT INTO FileSet (FileSet, MD5) VALUES \
357 (\"%s\", \"%s\")", fsr->FileSet, fsr->MD5);
358
359    if (!INSERT_DB(mdb, mdb->cmd)) {
360       Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
361             mdb->cmd, sql_strerror(mdb));
362       fsr->FileSetId = 0;
363       stat = 0;
364    } else {
365       fsr->FileSetId = sql_insert_id(mdb);
366       stat = 1;
367    }
368
369    V(mdb->mutex);
370    return stat;
371 }
372
373
374 /*
375  *  struct stat
376  *  {
377  *      dev_t         st_dev;       * device *
378  *      ino_t         st_ino;       * inode *
379  *      mode_t        st_mode;      * protection *
380  *      nlink_t       st_nlink;     * number of hard links *
381  *      uid_t         st_uid;       * user ID of owner *
382  *      gid_t         st_gid;       * group ID of owner *
383  *      dev_t         st_rdev;      * device type (if inode device) *
384  *      off_t         st_size;      * total size, in bytes *
385  *      unsigned long st_blksize;   * blocksize for filesystem I/O *
386  *      unsigned long st_blocks;    * number of blocks allocated *
387  *      time_t        st_atime;     * time of last access *
388  *      time_t        st_mtime;     * time of last modification *
389  *      time_t        st_ctime;     * time of last inode change *            
390  *  };
391  */
392
393
394
395 /* 
396  * Create File record in B_DB   
397  *
398  *  In order to reduce database size, we store the File attributes,
399  *  the FileName, and the Path separately.  In principle, there   
400  *  is a single FileName record and a single Path record, no matter
401  *  how many times it occurs.  This is this subroutine, we separate
402  *  the file and the path and create three database records.
403  */
404 int db_create_file_attributes_record(B_DB *mdb, ATTR_DBR *ar)
405 {
406    int fnl, pnl;
407    char *l, *p;
408    /* ****FIXME***** malloc these */
409    char file[MAXSTRING];
410    char spath[MAXSTRING];
411    char buf[MAXSTRING];
412
413    Dmsg1(100, "Fname=%s\n", ar->fname);
414    Dmsg0(50, "put_file_into_catalog\n");
415    /* For the moment, we only handle Unix attributes.  Note, we are
416     * also getting any MD5 signature that was computed.
417     */
418    if (ar->Stream != STREAM_UNIX_ATTRIBUTES) {
419       Mmsg0(&mdb->errmsg, _("Attempt to put non-attributes into catalog\n"));
420       return 0;
421    }
422
423    /* Find path without the filename.  
424     * I.e. everything after the last / is a "filename".
425     * OK, maybe it is a directory name, but we treat it like
426     * a filename. If we don't find a / then the whole name
427     * must be a path name (e.g. c:).
428     */
429    for (p=l=ar->fname; *p; p++) {
430       if (*p == '/') {
431          l = p;                       /* set pos of last slash */
432       }
433    }
434    if (*l == '/') {                   /* did we find a slash? */
435       l++;                            /* yes, point to filename */
436    } else {                           /* no, whole thing must be path name */
437       l = p;
438    }
439
440    /* If filename doesn't exist (i.e. root directory), we
441     * simply create a blank name consisting of a single 
442     * space. This makes handling zero length filenames
443     * easier.
444     */
445    fnl = p - l;
446    if (fnl > 255) {
447       Emsg1(M_WARNING, 0, _("Filename truncated to 255 chars: %s\n"), l);
448       fnl = 255;
449    }
450    if (fnl > 0) {
451       strncpy(file, l, fnl);          /* copy filename */
452       file[fnl] = 0;
453    } else {
454       file[0] = ' ';                  /* blank filename */
455       file[1] = 0;
456    }
457
458    pnl = l - ar->fname;    
459    if (pnl > 255) {
460       Emsg1(M_WARNING, 0, _("Path name truncated to 255 chars: %s\n"), ar->fname);
461       pnl = 255;
462    }
463    strncpy(spath, ar->fname, pnl);
464    spath[pnl] = 0;
465
466    if (pnl == 0) {
467       Mmsg1(&mdb->errmsg, _("Path length is zero. File=%s\n"), ar->fname);
468       Emsg0(M_ERROR, 0, mdb->errmsg);
469       spath[0] = ' ';
470       spath[1] = 0;
471    }
472
473    Dmsg1(100, "spath=%s\n", spath);
474    Dmsg1(100, "file=%s\n", file);
475
476    db_escape_string(buf, file, fnl);
477
478    if (!db_create_filename_record(mdb, ar, buf)) {
479       return 0;
480    }
481    Dmsg1(100, "db_create_filename_record: %s\n", buf);
482
483    db_escape_string(buf, spath, pnl);
484
485    if (!db_create_path_record(mdb, ar, buf)) {
486       return 0;
487    }
488    Dmsg1(100, "db_create_path_record\n", buf);
489
490    if (!db_create_file_record(mdb, ar)) {
491       return 0;
492    }
493    Dmsg0(50, "db_create_file_record\n");
494
495    Dmsg3(100, "Path=%s File=%s FilenameId=%d\n", spath, file, ar->FilenameId);
496
497    return 1;
498 }
499
500 static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar)
501 {
502    int stat;
503
504    P(mdb->mutex);
505    /* Must create it */
506    Mmsg(&mdb->cmd,
507 "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, \
508 LStat, MD5) VALUES (%d, %d, %d, %d, \"%s\", \"0\")", 
509      (int)ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId, 
510       ar->attr);
511
512    if (!INSERT_DB(mdb, mdb->cmd)) {
513       Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),       
514          mdb->cmd, sql_strerror(mdb));
515       Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
516       ar->FileId = 0;
517       stat = 0;
518    } else {
519       ar->FileId = sql_insert_id(mdb);
520       stat = 1;
521    }
522    V(mdb->mutex);
523    return stat;
524 }
525
526 /* Create a Unique record for the Path -- no duplicates */
527 static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path)
528 {
529    SQL_ROW row;
530    static uint32_t cached_id = 0;
531    static char cached_path[MAXSTRING];
532    int stat;
533
534    if (*path == 0) {
535       Mmsg0(&mdb->errmsg, _("Null path given to db_create_path_record\n"));
536       Emsg0(M_ERROR, 0, mdb->errmsg);
537       ar->PathId = 0;
538       return 0;
539    }
540
541    P(mdb->mutex);
542
543    if (cached_id != 0 && strcmp(cached_path, path) == 0) {
544       ar->PathId = cached_id;
545       V(mdb->mutex);
546       return 1;
547    }
548
549    Mmsg(&mdb->cmd, "SELECT PathId FROM Path WHERE Path=\"%s\"", path);
550
551    if (QUERY_DB(mdb, mdb->cmd)) {
552
553       mdb->num_rows = sql_num_rows(mdb);
554
555       if (mdb->num_rows > 1) {
556          char ed1[30];
557          Mmsg2(&mdb->errmsg, _("More than one Path!: %s for Path=%s\n"), 
558             edit_uint64(mdb->num_rows, ed1), path);
559          Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
560          Emsg1(M_ERROR, 0, "%s\n", mdb->cmd);
561       }
562       if (mdb->num_rows >= 1) {
563          if ((row = sql_fetch_row(mdb)) == NULL) {
564             V(mdb->mutex);
565             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
566             Emsg0(M_ERROR, 0, mdb->errmsg);
567             sql_free_result(mdb);
568             ar->PathId = 0;
569             return 0;
570          }
571          sql_free_result(mdb);
572          ar->PathId = atoi(row[0]);
573          if (ar->PathId != cached_id) {
574             cached_id = ar->PathId;
575             strncpy(cached_path, path, sizeof(cached_path));
576             cached_path[sizeof(cached_path)-1] = 0;
577          }
578          V(mdb->mutex);
579          return 1;
580       }
581
582       sql_free_result(mdb);
583    }
584
585    Mmsg(&mdb->cmd, "INSERT INTO Path (Path)  VALUES (\"%s\")", path);
586
587    if (!INSERT_DB(mdb, mdb->cmd)) {
588       Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"), 
589          mdb->cmd, sql_strerror(mdb));
590       Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
591       ar->PathId = 0;
592       stat = 0;
593    } else {
594       ar->PathId = sql_insert_id(mdb);
595       stat = 1;
596    }
597
598    if (ar->PathId != cached_id) {
599       cached_id = ar->PathId;
600       strncpy(cached_path, path, sizeof(cached_path));
601       cached_path[sizeof(cached_path)-1] = 0;
602    }
603    V(mdb->mutex);
604    return stat;
605 }
606
607 /* Create a Unique record for the filename -- no duplicates */
608 static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar, char *fname) 
609 {
610    SQL_ROW row;
611    int stat;
612
613    P(mdb->mutex);
614    Mmsg(&mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name=\"%s\"", fname);
615
616    if (QUERY_DB(mdb, mdb->cmd)) {
617       mdb->num_rows = sql_num_rows(mdb);
618       if (mdb->num_rows > 1) {
619          Mmsg2(&mdb->errmsg, _("More than one Filename!: %d File=%s\n"), 
620             (int)(mdb->num_rows), fname);
621          Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
622          Emsg1(M_ERROR, 0, "%s\n", mdb->cmd);
623       }
624       if (mdb->num_rows >= 1) {
625          if ((row = sql_fetch_row(mdb)) == NULL) {
626             Mmsg2(&mdb->errmsg, _("error fetching row for file=%s: ERR=%s\n"), 
627                 fname, sql_strerror(mdb));
628             sql_free_result(mdb);
629             V(mdb->mutex);
630             Emsg0(M_ERROR, 0, mdb->errmsg);
631             ar->FilenameId = 0;
632             return 0;
633          }
634          sql_free_result(mdb);
635          ar->FilenameId = atoi(row[0]);
636          V(mdb->mutex);
637          return 1;
638       }
639       sql_free_result(mdb);
640    }
641
642    Mmsg(&mdb->cmd, "INSERT INTO Filename (Name) \
643 VALUES (\"%s\")", fname);
644
645    if (!INSERT_DB(mdb, mdb->cmd)) {
646       Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"), 
647             mdb->cmd, sql_strerror(mdb));
648       Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
649       ar->FilenameId = 0;
650       stat = 0;
651    } else {
652       ar->FilenameId = sql_insert_id(mdb);
653       stat = 1;
654    }
655
656    V(mdb->mutex);
657    return stat;
658 }
659
660 #endif /* HAVE_MYSQL || HAVE_SQLITE */