]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/sql_create.c
Fix verify
[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  *    Version $Id$
7  */
8
9 /*
10    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of
15    the License, or (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20    General Public License for more details.
21
22    You should have received a copy of the GNU General Public
23    License along with this program; if not, write to the Free
24    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25    MA 02111-1307, USA.
26
27  */
28
29 /* *****FIXME**** fix fixed length of select_cmd[] and insert_cmd[] */
30
31 /* The following is necessary so that we do not include
32  * the dummy external definition of DB.
33  */
34 #define __SQL_C                       /* indicate that this is sql.c */
35
36 #include "bacula.h"
37 #include "cats.h"
38
39 #if    HAVE_MYSQL || HAVE_SQLITE
40
41 /* -----------------------------------------------------------------------
42  *
43  *   Generic Routines (or almost generic)
44  *
45  * -----------------------------------------------------------------------
46  */
47
48 /* Forward referenced subroutines */
49 static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar);
50 static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar, char *fname);
51 static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path);
52
53
54 /* Imported subroutines */
55 extern void print_dashes(B_DB *mdb);
56 extern void print_result(B_DB *mdb);
57 extern int QueryDB(char *file, int line, B_DB *db, char *select_cmd);
58 extern int InsertDB(char *file, int line, B_DB *db, char *select_cmd);
59
60
61 /* Create a new record for the Job
62  * Returns: 0 on failure
63  *          1 on success
64  */
65 int
66 db_create_job_record(B_DB *mdb, JOB_DBR *jr)
67 {
68    char dt[MAX_TIME_LENGTH];
69    time_t stime;
70    struct tm tm;
71    int stat;
72    char *JobId;
73    btime_t JobTDate;
74    char ed1[30];
75
76    stime = jr->SchedTime;
77
78    localtime_r(&stime, &tm); 
79    strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
80    JobTDate = (btime_t)stime;
81
82    db_lock(mdb);
83    JobId = db_next_index(mdb, "Job");
84    if (!JobId) {
85       jr->JobId = 0;
86       db_unlock(mdb);
87       return 0;
88    }
89    /* Must create it */
90    Mmsg(&mdb->cmd,
91 "INSERT INTO Job (JobId, Job, Name, Type, Level, SchedTime, JobTDate) VALUES \
92 (%s, \"%s\", \"%s\", \"%c\", \"%c\", \"%s\", %s)", 
93            JobId, jr->Job, jr->Name, (char)(jr->Type), (char)(jr->Level), dt,
94            edit_uint64(JobTDate, ed1));
95
96    if (!INSERT_DB(mdb, mdb->cmd)) {
97       Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"), 
98             mdb->cmd, sql_strerror(mdb));
99       jr->JobId = 0;
100       stat = 0;
101    } else {
102       jr->JobId = sql_insert_id(mdb);
103       stat = 1;
104    }
105    db_unlock(mdb);
106    return stat;
107 }
108
109 /* Create a JobMedia record for medium used this job   
110  * Returns: 0 on failure
111  *          1 on success
112  */
113 int
114 db_create_jobmedia_record(B_DB *mdb, JOBMEDIA_DBR *jm)
115 {
116    int stat;
117
118    db_lock(mdb);
119    Mmsg(&mdb->cmd, "SELECT JobId, MediaId FROM JobMedia WHERE \
120 JobId=%d AND MediaId=%d", jm->JobId, jm->MediaId);
121
122    Dmsg0(30, mdb->cmd);
123    if (QUERY_DB(mdb, mdb->cmd)) {
124       mdb->num_rows = sql_num_rows(mdb);
125       if (mdb->num_rows > 0) {
126          Mmsg0(&mdb->errmsg, _("Create JobMedia failed. Record already exists.\n"));
127          sql_free_result(mdb);
128          db_unlock(mdb);
129          Dmsg0(0, "Already have JobMedia record\n");
130          return 0;
131       }
132       sql_free_result(mdb);
133    }
134
135    /* Must create it */
136    Mmsg(&mdb->cmd, 
137 "INSERT INTO JobMedia (JobId, MediaId, FirstIndex, LastIndex) \
138 VALUES (%d, %d, %u, %u)", 
139        jm->JobId, jm->MediaId, jm->FirstIndex, jm->LastIndex);
140
141    Dmsg0(30, mdb->cmd);
142    if (!INSERT_DB(mdb, mdb->cmd)) {
143       Mmsg2(&mdb->errmsg, _("Create db JobMedia record %s failed. ERR=%s\n"), mdb->cmd, 
144          sql_strerror(mdb));
145       stat = 0;
146    } else {
147       stat = 1;
148    }
149    db_unlock(mdb);
150    Dmsg0(30, "Return from JobMedia\n");
151    return stat;
152 }
153
154
155
156 /* Create Unique Pool record
157  * Returns: 0 on failure
158  *          1 on success
159  */
160 int
161 db_create_pool_record(B_DB *mdb, POOL_DBR *pr)
162 {
163    int stat;
164    char ed1[30];
165
166    db_lock(mdb);
167    Mmsg(&mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name=\"%s\"", pr->Name);
168    Dmsg1(20, "selectpool: %s\n", mdb->cmd);
169
170    if (QUERY_DB(mdb, mdb->cmd)) {
171
172       mdb->num_rows = sql_num_rows(mdb);
173    
174       if (mdb->num_rows > 0) {
175          Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
176          sql_free_result(mdb);
177          db_unlock(mdb);
178          return 0;
179       }
180       sql_free_result(mdb);
181    }
182
183    /* Must create it */
184    Mmsg(&mdb->cmd, 
185 "INSERT INTO Pool (Name, NumVols, MaxVols, UseOnce, UseCatalog, \
186 AcceptAnyVolume, AutoPrune, Recycle, VolRetention, PoolType, LabelFormat) \
187 VALUES (\"%s\", %d, %d, %d, %d, %d, %d, %d, %s, \"%s\", \"%s\")", 
188                   pr->Name,
189                   pr->NumVols, pr->MaxVols,
190                   pr->UseOnce, pr->UseCatalog,
191                   pr->AcceptAnyVolume,
192                   pr->AutoPrune, pr->Recycle,
193                   edit_uint64(pr->VolRetention, ed1),
194                   pr->PoolType, pr->LabelFormat);
195    Dmsg1(500, "Create Pool: %s\n", mdb->cmd);
196    if (!INSERT_DB(mdb, mdb->cmd)) {
197       Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"), 
198             mdb->cmd, sql_strerror(mdb));
199       pr->PoolId = 0;
200       stat = 0;
201    } else {
202       pr->PoolId = sql_insert_id(mdb);
203       stat = 1;
204    }
205    db_unlock(mdb);
206    
207    return stat;
208 }
209
210
211 /* 
212  * Create Unique Media record   
213  * Returns: 0 on failure
214  *          1 on success
215  */ 
216 int
217 db_create_media_record(B_DB *mdb, MEDIA_DBR *mr)
218 {
219    int stat;
220    char ed1[30], ed2[30], ed3[30];
221
222    db_lock(mdb);
223    Mmsg(&mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName=\"%s\"", 
224            mr->VolumeName);
225    Dmsg1(110, "selectpool: %s\n", mdb->cmd);
226
227    if (QUERY_DB(mdb, mdb->cmd)) {
228       mdb->num_rows = sql_num_rows(mdb);
229       if (mdb->num_rows > 0) {
230          Mmsg1(&mdb->errmsg, _("Media record %s already exists\n"), mr->VolumeName);
231          sql_free_result(mdb);
232          db_unlock(mdb);
233          return 0;
234       }
235       sql_free_result(mdb);
236    }
237
238    /* Must create it */
239    Mmsg(&mdb->cmd, 
240 "INSERT INTO Media (VolumeName, MediaType, PoolId, VolMaxBytes, VolCapacityBytes, \
241 Recycle, VolRetention, VolStatus) VALUES (\"%s\", \"%s\", %d, %s, %s, %d, %s, \"%s\")", 
242                   mr->VolumeName,
243                   mr->MediaType, mr->PoolId, 
244                   edit_uint64(mr->VolMaxBytes,ed1),
245                   edit_uint64(mr->VolCapacityBytes, ed2),
246                   mr->Recycle,
247                   edit_uint64(mr->VolRetention, ed3),
248                   mr->VolStatus);
249
250    Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
251    if (!INSERT_DB(mdb, mdb->cmd)) {
252       Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
253             mdb->cmd, sql_strerror(mdb));
254       stat = 0;
255    } else {
256       mr->MediaId = sql_insert_id(mdb);
257       stat = 1;
258    }
259    db_unlock(mdb);
260    return stat;
261 }
262
263
264
265 /* 
266  * Create a Unique record for the client -- no duplicates 
267  * Returns: 0 on failure
268  *          1 on success with id in cr->ClientId
269  */
270 int db_create_client_record(B_DB *mdb, CLIENT_DBR *cr)
271 {
272    SQL_ROW row;
273    int stat;
274    char ed1[30], ed2[30];
275
276    db_lock(mdb);
277    Mmsg(&mdb->cmd, "SELECT ClientId FROM Client WHERE Name=\"%s\"", cr->Name);
278
279    cr->ClientId = 0;
280    if (QUERY_DB(mdb, mdb->cmd)) {
281
282       mdb->num_rows = sql_num_rows(mdb);
283       
284       /* If more than one, report error, but return first row */
285       if (mdb->num_rows > 1) {
286          Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
287          Emsg0(M_ERROR, 0, mdb->errmsg);
288       }
289       if (mdb->num_rows >= 1) {
290          if ((row = sql_fetch_row(mdb)) == NULL) {
291             Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
292             sql_free_result(mdb);
293             db_unlock(mdb);
294             return 0;
295          }
296          sql_free_result(mdb);
297          cr->ClientId = atoi(row[0]);
298          db_unlock(mdb);
299          return 1;
300       }
301       sql_free_result(mdb);
302    }
303
304    /* Must create it */
305    Mmsg(&mdb->cmd, "INSERT INTO Client (Name, Uname, AutoPrune, \
306 FileRetention, JobRetention) VALUES \
307 (\"%s\", \"%s\", %d, %s, %s)", cr->Name, cr->Uname, cr->AutoPrune,
308       edit_uint64(cr->FileRetention, ed1),
309       edit_uint64(cr->JobRetention, ed2));
310
311    if (!INSERT_DB(mdb, mdb->cmd)) {
312       Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
313             mdb->cmd, sql_strerror(mdb));
314       cr->ClientId = 0;
315       stat = 0;
316    } else {
317       cr->ClientId = sql_insert_id(mdb);
318       stat = 1;
319    }
320    db_unlock(mdb);
321    return stat;
322 }
323
324
325 /* 
326  * Create a FileSet record. This record is unique in the
327  *  name and the MD5 signature of the include/exclude sets.
328  *  Returns: 0 on failure
329  *           1 on success with FileSetId in record
330  */
331 int db_create_fileset_record(B_DB *mdb, FILESET_DBR *fsr)
332 {
333    SQL_ROW row;
334    int stat;
335
336    db_lock(mdb);
337    Mmsg(&mdb->cmd, "SELECT FileSetId FROM FileSet WHERE \
338 FileSet=\"%s\" and MD5=\"%s\"", fsr->FileSet, fsr->MD5);
339
340    fsr->FileSetId = 0;
341    if (QUERY_DB(mdb, mdb->cmd)) {
342
343       mdb->num_rows = sql_num_rows(mdb);
344       
345       if (mdb->num_rows > 1) {
346          Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
347          Emsg0(M_ERROR, 0, mdb->errmsg);
348       }
349       if (mdb->num_rows >= 1) {
350          if ((row = sql_fetch_row(mdb)) == NULL) {
351             Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
352             sql_free_result(mdb);
353             db_unlock(mdb);
354             return 0;
355          }
356          sql_free_result(mdb);
357          fsr->FileSetId = atoi(row[0]);
358          db_unlock(mdb);
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    db_unlock(mdb);
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    ASSERT(ar->JobId);
514    ASSERT(ar->PathId);
515    ASSERT(ar->FilenameId);
516
517    db_lock(mdb);
518    /* Must create it */
519    Mmsg(&mdb->cmd,
520 "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, \
521 LStat, MD5) VALUES (%d, %d, %d, %d, \"%s\", \"0\")", 
522      (int)ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId, 
523       ar->attr);
524
525    if (!INSERT_DB(mdb, mdb->cmd)) {
526       Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),       
527          mdb->cmd, sql_strerror(mdb));
528       ar->FileId = 0;
529       stat = 0;
530    } else {
531       ar->FileId = sql_insert_id(mdb);
532       stat = 1;
533    }
534    db_unlock(mdb);
535    return stat;
536 }
537
538 /* Create a Unique record for the Path -- no duplicates */
539 static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path)
540 {
541    SQL_ROW row;
542    int stat;
543
544    if (*path == 0) {
545       Mmsg0(&mdb->errmsg, _("Null path given to db_create_path_record\n"));
546       ar->PathId = 0;
547       return 0;
548    }
549
550    db_lock(mdb);
551
552    if (mdb->cached_path_id != 0 && strcmp(mdb->cached_path, path) == 0) {
553       ar->PathId = mdb->cached_path_id;
554       db_unlock(mdb);
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             db_unlock(mdb);
574             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
575             sql_free_result(mdb);
576             ar->PathId = 0;
577             return 0;
578          }
579          sql_free_result(mdb);
580          ar->PathId = atoi(row[0]);
581          /* Cache path */
582          if (ar->PathId != mdb->cached_path_id) {
583             mdb->cached_path_id = ar->PathId;
584             mdb->cached_path = check_pool_memory_size(mdb->cached_path,
585                strlen(path)+1);
586             strcpy(mdb->cached_path, path);
587          }
588          db_unlock(mdb);
589          return 1;
590       }
591
592       sql_free_result(mdb);
593    }
594
595    Mmsg(&mdb->cmd, "INSERT INTO Path (Path)  VALUES (\"%s\")", path);
596
597    if (!INSERT_DB(mdb, mdb->cmd)) {
598       Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"), 
599          mdb->cmd, sql_strerror(mdb));
600       ar->PathId = 0;
601       stat = 0;
602    } else {
603       ar->PathId = sql_insert_id(mdb);
604       stat = 1;
605    }
606
607    /* Cache path */
608    if (ar->PathId != mdb->cached_path_id) {
609       mdb->cached_path_id = ar->PathId;
610       mdb->cached_path = check_pool_memory_size(mdb->cached_path,
611          strlen(path)+1);
612       strcpy(mdb->cached_path, path);
613    }
614    db_unlock(mdb);
615    return stat;
616 }
617
618 /* Create a Unique record for the filename -- no duplicates */
619 static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar, char *fname) 
620 {
621    SQL_ROW row;
622
623    db_lock(mdb);
624    Mmsg(&mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name=\"%s\"", fname);
625
626    if (QUERY_DB(mdb, mdb->cmd)) {
627       mdb->num_rows = sql_num_rows(mdb);
628       if (mdb->num_rows > 1) {
629          Mmsg2(&mdb->errmsg, _("More than one Filename!: %d File=%s\n"), 
630             (int)(mdb->num_rows), fname);
631          Emsg1(M_ERROR, 0, "%s", mdb->errmsg);
632          Emsg1(M_ERROR, 0, "%s\n", mdb->cmd);
633       }
634       if (mdb->num_rows >= 1) {
635          if ((row = sql_fetch_row(mdb)) == NULL) {
636             Mmsg2(&mdb->errmsg, _("error fetching row for file=%s: ERR=%s\n"), 
637                 fname, sql_strerror(mdb));
638             ar->FilenameId = 0;
639          } else {
640             ar->FilenameId = atoi(row[0]);
641          }
642          sql_free_result(mdb);
643          db_unlock(mdb);
644          return ar->FilenameId > 0;
645       }
646       sql_free_result(mdb);
647    }
648
649    Mmsg(&mdb->cmd, "INSERT INTO Filename (Name) \
650 VALUES (\"%s\")", fname);
651
652    if (!INSERT_DB(mdb, mdb->cmd)) {
653       Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"), 
654             mdb->cmd, sql_strerror(mdb));
655       ar->FilenameId = 0;
656    } else {
657       ar->FilenameId = sql_insert_id(mdb);
658    }
659
660    db_unlock(mdb);
661    return ar->FilenameId > 0;
662 }
663
664 #endif /* HAVE_MYSQL || HAVE_SQLITE */