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 #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
33 /* -----------------------------------------------------------------------
35 * Generic Routines (or almost generic)
37 * -----------------------------------------------------------------------
40 /* Forward referenced subroutines */
41 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
42 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
43 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
46 /* Imported subroutines */
47 extern void print_dashes(B_DB *mdb);
48 extern void print_result(B_DB *mdb);
49 extern int QueryDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
50 extern int InsertDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd);
51 extern int UpdateDB(const char *file, int line, JCR *jcr, B_DB *db, char *update_cmd);
52 extern void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname);
55 /* Create a new record for the Job
56 * Returns: false on failure
60 db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
62 char dt[MAX_TIME_LENGTH];
71 stime = jr->SchedTime;
74 (void)localtime_r(&stime, &tm);
75 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
76 JobTDate = (utime_t)stime;
80 "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate) VALUES "
81 "('%s','%s','%c','%c','%c','%s',%s)",
82 jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel),
83 (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1));
85 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
86 Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
87 mdb->cmd, sql_strerror(mdb));
91 jr->JobId = sql_insert_id(mdb, NT_("Job"));
99 /* Create a JobMedia record for medium used this job
100 * Returns: false on failure
104 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
108 char ed1[50], ed2[50];
112 /* Now get count for VolIndex */
113 Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
114 edit_int64(jm->JobId, ed1));
115 count = get_sql_record_max(jcr, mdb);
121 /* Note, jm->Strip is not used and is not likely to be used
122 * in the near future, so I have removed it from the insert
123 * to save space in the DB. KES June 2006.
126 "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
127 "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy) "
128 "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u)",
129 edit_int64(jm->JobId, ed1),
130 edit_int64(jm->MediaId, ed2),
131 jm->FirstIndex, jm->LastIndex,
132 jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
135 Dmsg0(300, mdb->cmd);
136 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
137 Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
141 /* Worked, now update the Media record with the EndFile and EndBlock */
143 "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
144 jm->EndFile, jm->EndBlock, jm->MediaId);
145 if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
146 Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
152 Dmsg0(300, "Return from JobMedia\n");
158 /* Create Unique Pool record
159 * Returns: false on failure
163 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
166 char ed1[30], ed2[30], ed3[50];
168 Dmsg0(200, "In create pool\n");
170 Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", pr->Name);
171 Dmsg1(200, "selectpool: %s\n", mdb->cmd);
173 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
174 mdb->num_rows = sql_num_rows(mdb);
175 if (mdb->num_rows > 0) {
176 Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
177 sql_free_result(mdb);
181 sql_free_result(mdb);
186 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
187 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
188 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
189 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
191 pr->NumVols, pr->MaxVols,
192 pr->UseOnce, pr->UseCatalog,
194 pr->AutoPrune, pr->Recycle,
195 edit_uint64(pr->VolRetention, ed1),
196 edit_uint64(pr->VolUseDuration, ed2),
197 pr->MaxVolJobs, pr->MaxVolFiles,
198 edit_uint64(pr->MaxVolBytes, ed3),
199 pr->PoolType, pr->LabelType, pr->LabelFormat);
200 Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
201 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
202 Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
203 mdb->cmd, sql_strerror(mdb));
207 pr->PoolId = sql_insert_id(mdb, NT_("Pool"));
215 * Create Unique Device record
216 * Returns: false on failure
220 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
223 char ed1[30], ed2[30];
225 Dmsg0(200, "In create Device\n");
227 Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
228 Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
230 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
231 mdb->num_rows = sql_num_rows(mdb);
232 if (mdb->num_rows > 0) {
233 Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
234 sql_free_result(mdb);
238 sql_free_result(mdb);
243 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
245 edit_uint64(dr->MediaTypeId, ed1),
246 edit_int64(dr->StorageId, ed2));
247 Dmsg1(200, "Create Device: %s\n", mdb->cmd);
248 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
249 Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
250 mdb->cmd, sql_strerror(mdb));
254 dr->DeviceId = sql_insert_id(mdb, NT_("Device"));
264 * Create a Unique record for Storage -- no duplicates
265 * Returns: false on failure
266 * true on success with id in sr->StorageId
268 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
274 Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
278 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
279 mdb->num_rows = sql_num_rows(mdb);
280 /* If more than one, report error, but return first row */
281 if (mdb->num_rows > 1) {
282 Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), (int)(mdb->num_rows));
283 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
285 if (mdb->num_rows >= 1) {
286 if ((row = sql_fetch_row(mdb)) == NULL) {
287 Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
288 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
289 sql_free_result(mdb);
293 sr->StorageId = str_to_int64(row[0]);
294 sr->AutoChanger = atoi(row[1]); /* bool */
295 sql_free_result(mdb);
299 sql_free_result(mdb);
303 Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
304 " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
306 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
307 Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
308 mdb->cmd, sql_strerror(mdb));
309 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
312 sr->StorageId = sql_insert_id(mdb, NT_("Storage"));
322 * Create Unique MediaType record
323 * Returns: false on failure
327 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
331 Dmsg0(200, "In create mediatype\n");
333 Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
334 Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
336 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
337 mdb->num_rows = sql_num_rows(mdb);
338 if (mdb->num_rows > 0) {
339 Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
340 sql_free_result(mdb);
344 sql_free_result(mdb);
349 "INSERT INTO MediaType (MediaType,ReadOnly) "
353 Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
354 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
355 Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
356 mdb->cmd, sql_strerror(mdb));
360 mr->MediaTypeId = sql_insert_id(mdb, NT_("MediaType"));
369 * Create Media record. VolumeName and non-zero Slot must be unique
371 * Returns: 0 on failure
375 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
378 char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
379 char ed9[50], ed10[50], ed11[50], ed12[50];
383 Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
385 Dmsg1(500, "selectpool: %s\n", mdb->cmd);
387 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
388 mdb->num_rows = sql_num_rows(mdb);
389 if (mdb->num_rows > 0) {
390 Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
391 sql_free_result(mdb);
395 sql_free_result(mdb);
400 "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
401 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
402 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
403 "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId,"
404 "ScratchPoolId,RecyclePoolId,Enabled)"
405 "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,"
408 mr->MediaType, mr->PoolId,
409 edit_uint64(mr->MaxVolBytes,ed1),
410 edit_uint64(mr->VolCapacityBytes, ed2),
412 edit_uint64(mr->VolRetention, ed3),
413 edit_uint64(mr->VolUseDuration, ed4),
418 edit_uint64(mr->VolBytes, ed5),
420 edit_uint64(mr->VolReadTime, ed6),
421 edit_uint64(mr->VolWriteTime, ed7),
424 edit_int64(mr->StorageId, ed8),
425 edit_int64(mr->DeviceId, ed9),
426 edit_int64(mr->LocationId, ed10),
427 edit_int64(mr->ScratchPoolId, ed11),
428 edit_int64(mr->RecyclePoolId, ed12),
433 Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
434 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
435 Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
436 mdb->cmd, sql_strerror(mdb));
439 mr->MediaId = sql_insert_id(mdb, NT_("Media"));
441 if (mr->set_label_date) {
442 char dt[MAX_TIME_LENGTH];
443 if (mr->LabelDate == 0) {
444 mr->LabelDate = time(NULL);
446 (void)localtime_r(&mr->LabelDate, &tm);
447 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
448 Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
449 "WHERE MediaId=%d", dt, mr->MediaId);
450 stat = UPDATE_DB(jcr, mdb, mdb->cmd);
455 * Make sure that if InChanger is non-zero any other identical slot
456 * has InChanger zero.
458 db_make_inchanger_unique(jcr, mdb, mr);
465 * Create a Unique record for the client -- no duplicates
466 * Returns: 0 on failure
467 * 1 on success with id in cr->ClientId
469 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
473 char ed1[50], ed2[50];
476 Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
479 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
480 mdb->num_rows = sql_num_rows(mdb);
481 /* If more than one, report error, but return first row */
482 if (mdb->num_rows > 1) {
483 Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
484 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
486 if (mdb->num_rows >= 1) {
487 if ((row = sql_fetch_row(mdb)) == NULL) {
488 Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
489 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
490 sql_free_result(mdb);
494 cr->ClientId = str_to_int64(row[0]);
496 bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
498 cr->Uname[0] = 0; /* no name */
500 sql_free_result(mdb);
504 sql_free_result(mdb);
508 Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
509 "FileRetention,JobRetention) VALUES "
510 "('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
511 edit_uint64(cr->FileRetention, ed1),
512 edit_uint64(cr->JobRetention, ed2));
514 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
515 Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
516 mdb->cmd, sql_strerror(mdb));
517 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
521 cr->ClientId = sql_insert_id(mdb, NT_("Client"));
533 * Create a Unique record for the counter -- no duplicates
534 * Returns: 0 on failure
535 * 1 on success with counter filled in
537 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
543 memset(&mcr, 0, sizeof(mcr));
544 bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
545 if (db_get_counter_record(jcr, mdb, &mcr)) {
546 memcpy(cr, &mcr, sizeof(COUNTER_DBR));
552 Mmsg(mdb->cmd, "INSERT INTO Counters (Counter,MinValue,MaxValue,CurrentValue,"
553 "WrapCounter) VALUES ('%s','%d','%d','%d','%s')",
554 cr->Counter, cr->MinValue, cr->MaxValue, cr->CurrentValue,
557 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
558 Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
559 mdb->cmd, sql_strerror(mdb));
560 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
571 * Create a FileSet record. This record is unique in the
572 * name and the MD5 signature of the include/exclude sets.
573 * Returns: 0 on failure
574 * 1 on success with FileSetId in record
576 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
583 fsr->created = false;
584 Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
585 "FileSet='%s' AND MD5='%s'", fsr->FileSet, fsr->MD5);
588 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
589 mdb->num_rows = sql_num_rows(mdb);
590 if (mdb->num_rows > 1) {
591 Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
592 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
594 if (mdb->num_rows >= 1) {
595 if ((row = sql_fetch_row(mdb)) == NULL) {
596 Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
597 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
598 sql_free_result(mdb);
602 fsr->FileSetId = str_to_int64(row[0]);
603 if (row[1] == NULL) {
604 fsr->cCreateTime[0] = 0;
606 bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
608 sql_free_result(mdb);
612 sql_free_result(mdb);
615 if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
616 fsr->CreateTime = time(NULL);
618 (void)localtime_r(&fsr->CreateTime, &tm);
619 strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %H:%M:%S", &tm);
622 Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
623 "VALUES ('%s','%s','%s')", fsr->FileSet, fsr->MD5, fsr->cCreateTime);
625 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
626 Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
627 mdb->cmd, sql_strerror(mdb));
628 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
632 fsr->FileSetId = sql_insert_id(mdb, NT_("FileSet"));
645 * dev_t st_dev; * device *
646 * ino_t st_ino; * inode *
647 * mode_t st_mode; * protection *
648 * nlink_t st_nlink; * number of hard links *
649 * uid_t st_uid; * user ID of owner *
650 * gid_t st_gid; * group ID of owner *
651 * dev_t st_rdev; * device type (if inode device) *
652 * off_t st_size; * total size, in bytes *
653 * unsigned long st_blksize; * blocksize for filesystem I/O *
654 * unsigned long st_blocks; * number of blocks allocated *
655 * time_t st_atime; * time of last access *
656 * time_t st_mtime; * time of last modification *
657 * time_t st_ctime; * time of last inode change *
664 * Create File record in B_DB
666 * In order to reduce database size, we store the File attributes,
667 * the FileName, and the Path separately. In principle, there
668 * is a single FileName record and a single Path record, no matter
669 * how many times it occurs. This is this subroutine, we separate
670 * the file and the path and create three database records.
672 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
676 Dmsg1(300, "Fname=%s\n", ar->fname);
677 Dmsg0(500, "put_file_into_catalog\n");
679 * Make sure we have an acceptable attributes record.
681 if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
682 ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
683 Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
685 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
690 split_path_and_file(jcr, mdb, ar->fname);
692 if (!db_create_filename_record(jcr, mdb, ar)) {
695 Dmsg1(500, "db_create_filename_record: %s\n", mdb->esc_name);
698 if (!db_create_path_record(jcr, mdb, ar)) {
701 Dmsg1(500, "db_create_path_record: %s\n", mdb->esc_name);
703 /* Now create master File record */
704 if (!db_create_file_record(jcr, mdb, ar)) {
707 Dmsg0(500, "db_create_file_record OK\n");
709 Dmsg3(300, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
719 * This is the master File entry containing the attributes.
720 * The filename and path records have already been created.
722 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
725 static char *no_digest = "0";
730 ASSERT(ar->FilenameId);
732 if (ar->Digest == NULL || ar->Digest[0] == 0) {
740 "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
741 "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
742 ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
745 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
746 Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
747 mdb->cmd, sql_strerror(mdb));
748 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
752 ar->FileId = sql_insert_id(mdb, NT_("File"));
758 /* Create a Unique record for the Path -- no duplicates */
759 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
764 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
765 db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
767 if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
768 strcmp(mdb->cached_path, mdb->path) == 0) {
769 ar->PathId = mdb->cached_path_id;
773 Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
775 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
776 mdb->num_rows = sql_num_rows(mdb);
777 if (mdb->num_rows > 1) {
779 Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
780 edit_uint64(mdb->num_rows, ed1), mdb->path);
781 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
783 /* Even if there are multiple paths, take the first one */
784 if (mdb->num_rows >= 1) {
785 if ((row = sql_fetch_row(mdb)) == NULL) {
786 Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
787 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
788 sql_free_result(mdb);
793 ar->PathId = str_to_int64(row[0]);
794 sql_free_result(mdb);
796 if (ar->PathId != mdb->cached_path_id) {
797 mdb->cached_path_id = ar->PathId;
798 mdb->cached_path_len = mdb->pnl;
799 pm_strcpy(mdb->cached_path, mdb->path);
804 sql_free_result(mdb);
807 Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
809 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
810 Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
811 mdb->cmd, sql_strerror(mdb));
812 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
816 ar->PathId = sql_insert_id(mdb, NT_("Path"));
821 if (stat && ar->PathId != mdb->cached_path_id) {
822 mdb->cached_path_id = ar->PathId;
823 mdb->cached_path_len = mdb->pnl;
824 pm_strcpy(mdb->cached_path, mdb->path);
829 /* Create a Unique record for the filename -- no duplicates */
830 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
834 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
835 db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
837 Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
839 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
840 mdb->num_rows = sql_num_rows(mdb);
841 if (mdb->num_rows > 1) {
843 Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
844 edit_uint64(mdb->num_rows, ed1), mdb->fname);
845 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
847 if (mdb->num_rows >= 1) {
848 if ((row = sql_fetch_row(mdb)) == NULL) {
849 Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
850 mdb->fname, sql_strerror(mdb));
851 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
854 ar->FilenameId = str_to_int64(row[0]);
856 sql_free_result(mdb);
857 return ar->FilenameId > 0;
859 sql_free_result(mdb);
862 Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
864 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
865 Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
866 mdb->cmd, sql_strerror(mdb));
867 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
870 ar->FilenameId = sql_insert_id(mdb, NT_("Filename"));
872 return ar->FilenameId > 0;
875 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */