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