2 * Bacula Catalog Database Create record interface routines
4 * Kern Sibbald, March 2000
9 Copyright (C) 2000-2006 Kern Sibbald
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 version 2 as amended with additional clauses defined in the
14 file LICENSE in the main source directory.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 the file LICENSE for additional details.
23 /* The following is necessary so that we do not include
24 * the dummy external definition of DB.
26 #define __SQL_C /* indicate that this is sql.c */
31 static const int dbglevel = 500;
33 #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
35 /* -----------------------------------------------------------------------
37 * Generic Routines (or almost generic)
39 * -----------------------------------------------------------------------
42 /* Forward referenced subroutines */
43 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
44 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
45 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
48 /* Imported subroutines */
49 extern void print_dashes(B_DB *mdb);
50 extern void print_result(B_DB *mdb);
51 extern int QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
52 extern int InsertDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
53 extern int UpdateDB(const char *file, int line, JCR *jcr, B_DB *db, char *update_cmd);
54 extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname);
57 /* Create a new record for the Job
58 * Returns: false on failure
62 db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
64 char dt[MAX_TIME_LENGTH];
73 stime = jr->SchedTime;
76 (void)localtime_r(&stime, &tm);
77 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
78 JobTDate = (utime_t)stime;
82 "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate) VALUES "
83 "('%s','%s','%c','%c','%c','%s',%s)",
84 jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel),
85 (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1));
87 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
88 Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
89 mdb->cmd, sql_strerror(mdb));
93 jr->JobId = sql_insert_id(mdb, NT_("Job"));
101 /* Create a JobMedia record for medium used this job
102 * Returns: false on failure
106 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
110 char ed1[50], ed2[50];
114 /* Now get count for VolIndex */
115 Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
116 edit_int64(jm->JobId, ed1));
117 count = get_sql_record_max(jcr, mdb);
123 /* Note, jm->Strip is not used and is not likely to be used
124 * in the near future, so I have removed it from the insert
125 * to save space in the DB. KES June 2006.
128 "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
129 "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy) "
130 "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u)",
131 edit_int64(jm->JobId, ed1),
132 edit_int64(jm->MediaId, ed2),
133 jm->FirstIndex, jm->LastIndex,
134 jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
137 Dmsg0(300, mdb->cmd);
138 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
139 Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
143 /* Worked, now update the Media record with the EndFile and EndBlock */
145 "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
146 jm->EndFile, jm->EndBlock, jm->MediaId);
147 if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
148 Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
154 Dmsg0(300, "Return from JobMedia\n");
160 /* Create Unique Pool record
161 * Returns: false on failure
165 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
168 char ed1[30], ed2[30], ed3[50];
170 Dmsg0(200, "In create pool\n");
172 Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", pr->Name);
173 Dmsg1(200, "selectpool: %s\n", mdb->cmd);
175 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
176 mdb->num_rows = sql_num_rows(mdb);
177 if (mdb->num_rows > 0) {
178 Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
179 sql_free_result(mdb);
183 sql_free_result(mdb);
188 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
189 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
190 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
191 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
193 pr->NumVols, pr->MaxVols,
194 pr->UseOnce, pr->UseCatalog,
196 pr->AutoPrune, pr->Recycle,
197 edit_uint64(pr->VolRetention, ed1),
198 edit_uint64(pr->VolUseDuration, ed2),
199 pr->MaxVolJobs, pr->MaxVolFiles,
200 edit_uint64(pr->MaxVolBytes, ed3),
201 pr->PoolType, pr->LabelType, pr->LabelFormat);
202 Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
203 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
204 Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
205 mdb->cmd, sql_strerror(mdb));
209 pr->PoolId = sql_insert_id(mdb, NT_("Pool"));
217 * Create Unique Device record
218 * Returns: false on failure
222 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
225 char ed1[30], ed2[30];
227 Dmsg0(200, "In create Device\n");
229 Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
230 Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
232 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
233 mdb->num_rows = sql_num_rows(mdb);
234 if (mdb->num_rows > 0) {
235 Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
236 sql_free_result(mdb);
240 sql_free_result(mdb);
245 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
247 edit_uint64(dr->MediaTypeId, ed1),
248 edit_int64(dr->StorageId, ed2));
249 Dmsg1(200, "Create Device: %s\n", mdb->cmd);
250 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
251 Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
252 mdb->cmd, sql_strerror(mdb));
256 dr->DeviceId = sql_insert_id(mdb, NT_("Device"));
266 * Create a Unique record for Storage -- no duplicates
267 * Returns: false on failure
268 * true on success with id in sr->StorageId
270 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
276 Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
280 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
281 mdb->num_rows = sql_num_rows(mdb);
282 /* If more than one, report error, but return first row */
283 if (mdb->num_rows > 1) {
284 Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), (int)(mdb->num_rows));
285 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
287 if (mdb->num_rows >= 1) {
288 if ((row = sql_fetch_row(mdb)) == NULL) {
289 Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
290 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
291 sql_free_result(mdb);
295 sr->StorageId = str_to_int64(row[0]);
296 sr->AutoChanger = atoi(row[1]); /* bool */
297 sql_free_result(mdb);
301 sql_free_result(mdb);
305 Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
306 " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
308 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
309 Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
310 mdb->cmd, sql_strerror(mdb));
311 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
314 sr->StorageId = sql_insert_id(mdb, NT_("Storage"));
324 * Create Unique MediaType record
325 * Returns: false on failure
329 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
333 Dmsg0(200, "In create mediatype\n");
335 Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
336 Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
338 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
339 mdb->num_rows = sql_num_rows(mdb);
340 if (mdb->num_rows > 0) {
341 Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
342 sql_free_result(mdb);
346 sql_free_result(mdb);
351 "INSERT INTO MediaType (MediaType,ReadOnly) "
355 Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
356 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
357 Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
358 mdb->cmd, sql_strerror(mdb));
362 mr->MediaTypeId = sql_insert_id(mdb, NT_("MediaType"));
371 * Create Media record. VolumeName and non-zero Slot must be unique
373 * Returns: 0 on failure
377 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
380 char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
381 char ed9[50], ed10[50], ed11[50], ed12[50];
385 Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
387 Dmsg1(500, "selectpool: %s\n", mdb->cmd);
389 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
390 mdb->num_rows = sql_num_rows(mdb);
391 if (mdb->num_rows > 0) {
392 Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
393 sql_free_result(mdb);
397 sql_free_result(mdb);
402 "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
403 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
404 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
405 "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId,"
406 "ScratchPoolId,RecyclePoolId,Enabled)"
407 "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,"
410 mr->MediaType, mr->PoolId,
411 edit_uint64(mr->MaxVolBytes,ed1),
412 edit_uint64(mr->VolCapacityBytes, ed2),
414 edit_uint64(mr->VolRetention, ed3),
415 edit_uint64(mr->VolUseDuration, ed4),
420 edit_uint64(mr->VolBytes, ed5),
422 edit_uint64(mr->VolReadTime, ed6),
423 edit_uint64(mr->VolWriteTime, ed7),
426 edit_int64(mr->StorageId, ed8),
427 edit_int64(mr->DeviceId, ed9),
428 edit_int64(mr->LocationId, ed10),
429 edit_int64(mr->ScratchPoolId, ed11),
430 edit_int64(mr->RecyclePoolId, ed12),
435 Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
436 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
437 Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
438 mdb->cmd, sql_strerror(mdb));
441 mr->MediaId = sql_insert_id(mdb, NT_("Media"));
443 if (mr->set_label_date) {
444 char dt[MAX_TIME_LENGTH];
445 if (mr->LabelDate == 0) {
446 mr->LabelDate = time(NULL);
448 (void)localtime_r(&mr->LabelDate, &tm);
449 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
450 Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
451 "WHERE MediaId=%d", dt, mr->MediaId);
452 stat = UPDATE_DB(jcr, mdb, mdb->cmd);
457 * Make sure that if InChanger is non-zero any other identical slot
458 * has InChanger zero.
460 db_make_inchanger_unique(jcr, mdb, mr);
467 * Create a Unique record for the client -- no duplicates
468 * Returns: 0 on failure
469 * 1 on success with id in cr->ClientId
471 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
475 char ed1[50], ed2[50];
478 Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
481 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
482 mdb->num_rows = sql_num_rows(mdb);
483 /* If more than one, report error, but return first row */
484 if (mdb->num_rows > 1) {
485 Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
486 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
488 if (mdb->num_rows >= 1) {
489 if ((row = sql_fetch_row(mdb)) == NULL) {
490 Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
491 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
492 sql_free_result(mdb);
496 cr->ClientId = str_to_int64(row[0]);
498 bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
500 cr->Uname[0] = 0; /* no name */
502 sql_free_result(mdb);
506 sql_free_result(mdb);
510 Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
511 "FileRetention,JobRetention) VALUES "
512 "('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
513 edit_uint64(cr->FileRetention, ed1),
514 edit_uint64(cr->JobRetention, ed2));
516 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
517 Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
518 mdb->cmd, sql_strerror(mdb));
519 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
523 cr->ClientId = sql_insert_id(mdb, NT_("Client"));
535 * Create a Unique record for the counter -- no duplicates
536 * Returns: 0 on failure
537 * 1 on success with counter filled in
539 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
545 memset(&mcr, 0, sizeof(mcr));
546 bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
547 if (db_get_counter_record(jcr, mdb, &mcr)) {
548 memcpy(cr, &mcr, sizeof(COUNTER_DBR));
554 Mmsg(mdb->cmd, "INSERT INTO Counters (Counter,MinValue,MaxValue,CurrentValue,"
555 "WrapCounter) VALUES ('%s','%d','%d','%d','%s')",
556 cr->Counter, cr->MinValue, cr->MaxValue, cr->CurrentValue,
559 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
560 Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
561 mdb->cmd, sql_strerror(mdb));
562 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
573 * Create a FileSet record. This record is unique in the
574 * name and the MD5 signature of the include/exclude sets.
575 * Returns: 0 on failure
576 * 1 on success with FileSetId in record
578 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
585 fsr->created = false;
586 Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
587 "FileSet='%s' AND MD5='%s'", fsr->FileSet, fsr->MD5);
590 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
591 mdb->num_rows = sql_num_rows(mdb);
592 if (mdb->num_rows > 1) {
593 Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
594 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
596 if (mdb->num_rows >= 1) {
597 if ((row = sql_fetch_row(mdb)) == NULL) {
598 Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
599 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
600 sql_free_result(mdb);
604 fsr->FileSetId = str_to_int64(row[0]);
605 if (row[1] == NULL) {
606 fsr->cCreateTime[0] = 0;
608 bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
610 sql_free_result(mdb);
614 sql_free_result(mdb);
617 if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
618 fsr->CreateTime = time(NULL);
620 (void)localtime_r(&fsr->CreateTime, &tm);
621 strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %H:%M:%S", &tm);
624 Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
625 "VALUES ('%s','%s','%s')", fsr->FileSet, fsr->MD5, fsr->cCreateTime);
627 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
628 Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
629 mdb->cmd, sql_strerror(mdb));
630 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
634 fsr->FileSetId = sql_insert_id(mdb, NT_("FileSet"));
647 * dev_t st_dev; * device *
648 * ino_t st_ino; * inode *
649 * mode_t st_mode; * protection *
650 * nlink_t st_nlink; * number of hard links *
651 * uid_t st_uid; * user ID of owner *
652 * gid_t st_gid; * group ID of owner *
653 * dev_t st_rdev; * device type (if inode device) *
654 * off_t st_size; * total size, in bytes *
655 * unsigned long st_blksize; * blocksize for filesystem I/O *
656 * unsigned long st_blocks; * number of blocks allocated *
657 * time_t st_atime; * time of last access *
658 * time_t st_mtime; * time of last modification *
659 * time_t st_ctime; * time of last inode change *
666 * Create File record in B_DB
668 * In order to reduce database size, we store the File attributes,
669 * the FileName, and the Path separately. In principle, there
670 * is a single FileName record and a single Path record, no matter
671 * how many times it occurs. This is this subroutine, we separate
672 * the file and the path and create three database records.
674 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
678 Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
679 Dmsg0(dbglevel, "put_file_into_catalog\n");
681 * Make sure we have an acceptable attributes record.
683 if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
684 ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
685 Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
687 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
692 split_path_and_file(jcr, mdb, ar->fname);
694 if (!db_create_filename_record(jcr, mdb, ar)) {
697 Dmsg1(dbglevel, "db_create_filename_record: %s\n", mdb->esc_name);
700 if (!db_create_path_record(jcr, mdb, ar)) {
703 Dmsg1(dbglevel, "db_create_path_record: %s\n", mdb->esc_name);
705 /* Now create master File record */
706 if (!db_create_file_record(jcr, mdb, ar)) {
709 Dmsg0(dbglevel, "db_create_file_record OK\n");
711 Dmsg3(dbglevel, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
721 * This is the master File entry containing the attributes.
722 * The filename and path records have already been created.
724 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
727 static char *no_digest = "0";
732 ASSERT(ar->FilenameId);
734 if (ar->Digest == NULL || ar->Digest[0] == 0) {
742 "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
743 "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
744 ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
747 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
748 Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
749 mdb->cmd, sql_strerror(mdb));
750 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
754 ar->FileId = sql_insert_id(mdb, NT_("File"));
760 /* Create a Unique record for the Path -- no duplicates */
761 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
766 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
767 db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
769 if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
770 strcmp(mdb->cached_path, mdb->path) == 0) {
771 ar->PathId = mdb->cached_path_id;
775 Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
777 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
778 mdb->num_rows = sql_num_rows(mdb);
779 if (mdb->num_rows > 1) {
781 Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
782 edit_uint64(mdb->num_rows, ed1), mdb->path);
783 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
785 /* Even if there are multiple paths, take the first one */
786 if (mdb->num_rows >= 1) {
787 if ((row = sql_fetch_row(mdb)) == NULL) {
788 Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
789 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
790 sql_free_result(mdb);
795 ar->PathId = str_to_int64(row[0]);
796 sql_free_result(mdb);
798 if (ar->PathId != mdb->cached_path_id) {
799 mdb->cached_path_id = ar->PathId;
800 mdb->cached_path_len = mdb->pnl;
801 pm_strcpy(mdb->cached_path, mdb->path);
806 sql_free_result(mdb);
809 Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
811 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
812 Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
813 mdb->cmd, sql_strerror(mdb));
814 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
818 ar->PathId = sql_insert_id(mdb, NT_("Path"));
823 if (stat && ar->PathId != mdb->cached_path_id) {
824 mdb->cached_path_id = ar->PathId;
825 mdb->cached_path_len = mdb->pnl;
826 pm_strcpy(mdb->cached_path, mdb->path);
831 /* Create a Unique record for the filename -- no duplicates */
832 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
836 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
837 db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
839 Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
841 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
842 mdb->num_rows = sql_num_rows(mdb);
843 if (mdb->num_rows > 1) {
845 Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
846 edit_uint64(mdb->num_rows, ed1), mdb->fname);
847 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
849 if (mdb->num_rows >= 1) {
850 if ((row = sql_fetch_row(mdb)) == NULL) {
851 Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
852 mdb->fname, sql_strerror(mdb));
853 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
856 ar->FilenameId = str_to_int64(row[0]);
858 sql_free_result(mdb);
859 return ar->FilenameId > 0;
861 sql_free_result(mdb);
864 Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
866 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
867 Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
868 mdb->cmd, sql_strerror(mdb));
869 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
872 ar->FilenameId = sql_insert_id(mdb, NT_("Filename"));
874 return ar->FilenameId > 0;
877 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */