2 * Bacula Catalog Database Create record interface routines
4 * Kern Sibbald, March 2000
9 Copyright (C) 2000-2005 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 localtime_r(&stime, &tm);
75 strftime(dt, sizeof(dt), "%Y-%m-%d %T", &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, N_("Job"));
98 /* Create a new migration, archive, copy
99 * Returns: false on failure
103 db_create_mac_record(JCR *jcr, B_DB *mdb, MAC_DBR *mr)
105 char schedt[MAX_TIME_LENGTH], sdt[MAX_TIME_LENGTH], edt[MAX_TIME_LENGTH];
110 char ed1[30], ed2[30];
114 stime = mr->SchedTime;
117 localtime_r(&stime, &tm);
118 strftime(schedt, sizeof(schedt), "%Y-%m-%d %T", &tm);
119 JobTDate = (utime_t)stime;
120 localtime_r(&mr->StartTime, &tm);
121 strftime(sdt, sizeof(sdt), "%Y-%m-%d %T", &tm);
122 localtime_r(&mr->EndTime, &tm);
123 strftime(edt, sizeof(edt), "%Y-%m-%d %T", &tm);
127 "INSERT INTO MAC (OriginaJobId,JobType,JobLevel,SchedTime,"
128 "StartTime,EndTime,JobTDate) VALUES "
129 "('%s','%c','%c','%s','%s','%s',%s)",
130 edit_int64(mr->OriginalJobId, ed1),
131 (char)(mr->JobType), (char)(mr->JobLevel),
132 schedt, sdt, edt, edit_uint64(JobTDate, ed2));
134 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
135 Mmsg2(&mdb->errmsg, _("Create DB MAC record %s failed. ERR=%s\n"),
136 mdb->cmd, sql_strerror(mdb));
140 mr->JobId = sql_insert_id(mdb, N_("Job"));
148 /* Create a JobMedia record for medium used this job
149 * Returns: false on failure
153 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
157 char ed1[50], ed2[50];
161 /* Now get count for VolIndex */
162 Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
163 edit_int64(jm->JobId, ed1));
164 count = get_sql_record_max(jcr, mdb);
171 "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
172 "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy,Stripe) "
173 "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u,%u)",
174 edit_int64(jm->JobId, ed1),
175 edit_int64(jm->MediaId, ed2),
176 jm->FirstIndex, jm->LastIndex,
177 jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
178 jm->Copy, jm->Stripe);
180 Dmsg0(300, mdb->cmd);
181 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
182 Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
186 /* Worked, now update the Media record with the EndFile and EndBlock */
188 "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
189 jm->EndFile, jm->EndBlock, jm->MediaId);
190 if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
191 Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
197 Dmsg0(300, "Return from JobMedia\n");
203 /* Create Unique Pool record
204 * Returns: false on failure
208 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
211 char ed1[30], ed2[30], ed3[50];
213 Dmsg0(200, "In create pool\n");
215 Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", pr->Name);
216 Dmsg1(200, "selectpool: %s\n", mdb->cmd);
218 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
219 mdb->num_rows = sql_num_rows(mdb);
220 if (mdb->num_rows > 0) {
221 Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
222 sql_free_result(mdb);
226 sql_free_result(mdb);
231 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
232 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
233 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
234 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
236 pr->NumVols, pr->MaxVols,
237 pr->UseOnce, pr->UseCatalog,
239 pr->AutoPrune, pr->Recycle,
240 edit_uint64(pr->VolRetention, ed1),
241 edit_uint64(pr->VolUseDuration, ed2),
242 pr->MaxVolJobs, pr->MaxVolFiles,
243 edit_uint64(pr->MaxVolBytes, ed3),
244 pr->PoolType, pr->LabelType, pr->LabelFormat);
245 Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
246 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
247 Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
248 mdb->cmd, sql_strerror(mdb));
252 pr->PoolId = sql_insert_id(mdb, N_("Pool"));
260 * Create Unique Device record
261 * Returns: false on failure
265 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
268 char ed1[30], ed2[30];
270 Dmsg0(200, "In create Device\n");
272 Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
273 Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
275 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
276 mdb->num_rows = sql_num_rows(mdb);
277 if (mdb->num_rows > 0) {
278 Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
279 sql_free_result(mdb);
283 sql_free_result(mdb);
288 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
290 edit_uint64(dr->MediaTypeId, ed1),
291 edit_int64(dr->StorageId, ed2));
292 Dmsg1(200, "Create Device: %s\n", mdb->cmd);
293 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
294 Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
295 mdb->cmd, sql_strerror(mdb));
299 dr->DeviceId = sql_insert_id(mdb, N_("Device"));
309 * Create a Unique record for Storage -- no duplicates
310 * Returns: false on failure
311 * true on success with id in sr->StorageId
313 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
319 Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
323 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
324 mdb->num_rows = sql_num_rows(mdb);
325 /* If more than one, report error, but return first row */
326 if (mdb->num_rows > 1) {
327 Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), (int)(mdb->num_rows));
328 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
330 if (mdb->num_rows >= 1) {
331 if ((row = sql_fetch_row(mdb)) == NULL) {
332 Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
333 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
334 sql_free_result(mdb);
338 sr->StorageId = str_to_int64(row[0]);
339 sr->AutoChanger = atoi(row[1]); /* bool */
340 sql_free_result(mdb);
344 sql_free_result(mdb);
348 Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
349 " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
351 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
352 Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
353 mdb->cmd, sql_strerror(mdb));
354 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
357 sr->StorageId = sql_insert_id(mdb, N_("Storage"));
367 * Create Unique MediaType record
368 * Returns: false on failure
372 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
376 Dmsg0(200, "In create mediatype\n");
378 Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
379 Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
381 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
382 mdb->num_rows = sql_num_rows(mdb);
383 if (mdb->num_rows > 0) {
384 Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
385 sql_free_result(mdb);
389 sql_free_result(mdb);
394 "INSERT INTO MediaType (MediaType,ReadOnly) "
398 Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
399 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
400 Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
401 mdb->cmd, sql_strerror(mdb));
405 mr->MediaTypeId = sql_insert_id(mdb, N_("MediaType"));
414 * Create Media record. VolumeName and non-zero Slot must be unique
416 * Returns: 0 on failure
420 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
423 char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
427 Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
429 Dmsg1(500, "selectpool: %s\n", mdb->cmd);
431 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
432 mdb->num_rows = sql_num_rows(mdb);
433 if (mdb->num_rows > 0) {
434 Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
435 sql_free_result(mdb);
439 sql_free_result(mdb);
444 "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
445 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
446 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
447 "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId) "
448 "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,0,0)",
450 mr->MediaType, mr->PoolId,
451 edit_uint64(mr->MaxVolBytes,ed1),
452 edit_uint64(mr->VolCapacityBytes, ed2),
454 edit_uint64(mr->VolRetention, ed3),
455 edit_uint64(mr->VolUseDuration, ed4),
460 edit_uint64(mr->VolBytes, ed5),
462 edit_uint64(mr->VolReadTime, ed6),
463 edit_uint64(mr->VolWriteTime, ed7),
466 edit_int64(mr->StorageId, ed8)
470 Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
471 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
472 Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
473 mdb->cmd, sql_strerror(mdb));
476 mr->MediaId = sql_insert_id(mdb, N_("Media"));
478 if (mr->set_label_date) {
479 char dt[MAX_TIME_LENGTH];
480 if (mr->LabelDate == 0) {
481 mr->LabelDate = time(NULL);
483 localtime_r(&mr->LabelDate, &tm);
484 strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
485 Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
486 "WHERE MediaId=%d", dt, mr->MediaId);
487 stat = UPDATE_DB(jcr, mdb, mdb->cmd);
492 * Make sure that if InChanger is non-zero any other identical slot
493 * has InChanger zero.
495 db_make_inchanger_unique(jcr, mdb, mr);
502 * Create a Unique record for the client -- no duplicates
503 * Returns: 0 on failure
504 * 1 on success with id in cr->ClientId
506 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
510 char ed1[50], ed2[50];
513 Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
516 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
517 mdb->num_rows = sql_num_rows(mdb);
518 /* If more than one, report error, but return first row */
519 if (mdb->num_rows > 1) {
520 Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
521 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
523 if (mdb->num_rows >= 1) {
524 if ((row = sql_fetch_row(mdb)) == NULL) {
525 Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
526 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
527 sql_free_result(mdb);
531 cr->ClientId = str_to_int64(row[0]);
533 bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
535 cr->Uname[0] = 0; /* no name */
537 sql_free_result(mdb);
541 sql_free_result(mdb);
545 Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
546 "FileRetention,JobRetention) VALUES "
547 "('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
548 edit_uint64(cr->FileRetention, ed1),
549 edit_uint64(cr->JobRetention, ed2));
551 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
552 Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
553 mdb->cmd, sql_strerror(mdb));
554 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
558 cr->ClientId = sql_insert_id(mdb, N_("Client"));
570 * Create a Unique record for the counter -- no duplicates
571 * Returns: 0 on failure
572 * 1 on success with counter filled in
574 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
580 memset(&mcr, 0, sizeof(mcr));
581 bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
582 if (db_get_counter_record(jcr, mdb, &mcr)) {
583 memcpy(cr, &mcr, sizeof(COUNTER_DBR));
589 Mmsg(mdb->cmd, "INSERT INTO Counters (Counter,MinValue,MaxValue,CurrentValue,"
590 "WrapCounter) VALUES ('%s','%d','%d','%d','%s')",
591 cr->Counter, cr->MinValue, cr->MaxValue, cr->CurrentValue,
594 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
595 Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
596 mdb->cmd, sql_strerror(mdb));
597 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
608 * Create a FileSet record. This record is unique in the
609 * name and the MD5 signature of the include/exclude sets.
610 * Returns: 0 on failure
611 * 1 on success with FileSetId in record
613 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
620 fsr->created = false;
621 Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
622 "FileSet='%s' AND MD5='%s'", fsr->FileSet, fsr->MD5);
625 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
626 mdb->num_rows = sql_num_rows(mdb);
627 if (mdb->num_rows > 1) {
628 Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
629 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
631 if (mdb->num_rows >= 1) {
632 if ((row = sql_fetch_row(mdb)) == NULL) {
633 Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
634 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
635 sql_free_result(mdb);
639 fsr->FileSetId = str_to_int64(row[0]);
640 if (row[1] == NULL) {
641 fsr->cCreateTime[0] = 0;
643 bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
645 sql_free_result(mdb);
649 sql_free_result(mdb);
652 if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
653 fsr->CreateTime = time(NULL);
655 localtime_r(&fsr->CreateTime, &tm);
656 strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %T", &tm);
659 Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
660 "VALUES ('%s','%s','%s')", fsr->FileSet, fsr->MD5, fsr->cCreateTime);
662 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
663 Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
664 mdb->cmd, sql_strerror(mdb));
665 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
669 fsr->FileSetId = sql_insert_id(mdb, N_("FileSet"));
682 * dev_t st_dev; * device *
683 * ino_t st_ino; * inode *
684 * mode_t st_mode; * protection *
685 * nlink_t st_nlink; * number of hard links *
686 * uid_t st_uid; * user ID of owner *
687 * gid_t st_gid; * group ID of owner *
688 * dev_t st_rdev; * device type (if inode device) *
689 * off_t st_size; * total size, in bytes *
690 * unsigned long st_blksize; * blocksize for filesystem I/O *
691 * unsigned long st_blocks; * number of blocks allocated *
692 * time_t st_atime; * time of last access *
693 * time_t st_mtime; * time of last modification *
694 * time_t st_ctime; * time of last inode change *
701 * Create File record in B_DB
703 * In order to reduce database size, we store the File attributes,
704 * the FileName, and the Path separately. In principle, there
705 * is a single FileName record and a single Path record, no matter
706 * how many times it occurs. This is this subroutine, we separate
707 * the file and the path and create three database records.
709 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
713 Dmsg1(300, "Fname=%s\n", ar->fname);
714 Dmsg0(500, "put_file_into_catalog\n");
716 * Make sure we have an acceptable attributes record.
718 if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
719 ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
720 Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
722 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
727 split_path_and_file(jcr, mdb, ar->fname);
729 if (!db_create_filename_record(jcr, mdb, ar)) {
732 Dmsg1(500, "db_create_filename_record: %s\n", mdb->esc_name);
735 if (!db_create_path_record(jcr, mdb, ar)) {
738 Dmsg1(500, "db_create_path_record: %s\n", mdb->esc_name);
740 /* Now create master File record */
741 if (!db_create_file_record(jcr, mdb, ar)) {
744 Dmsg0(500, "db_create_file_record OK\n");
746 Dmsg3(300, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
756 * This is the master File entry containing the attributes.
757 * The filename and path records have already been created.
759 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
762 static char *no_digest = "0";
767 ASSERT(ar->FilenameId);
769 if (ar->Digest == NULL) {
777 "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
778 "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
779 ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
782 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
783 Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
784 mdb->cmd, sql_strerror(mdb));
785 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
789 ar->FileId = sql_insert_id(mdb, N_("File"));
795 /* Create a Unique record for the Path -- no duplicates */
796 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
801 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
802 db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
804 if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
805 strcmp(mdb->cached_path, mdb->path) == 0) {
806 ar->PathId = mdb->cached_path_id;
810 Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
812 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
813 mdb->num_rows = sql_num_rows(mdb);
814 if (mdb->num_rows > 1) {
816 Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
817 edit_uint64(mdb->num_rows, ed1), mdb->path);
818 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
820 /* Even if there are multiple paths, take the first one */
821 if (mdb->num_rows >= 1) {
822 if ((row = sql_fetch_row(mdb)) == NULL) {
823 Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
824 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
825 sql_free_result(mdb);
830 ar->PathId = str_to_int64(row[0]);
831 sql_free_result(mdb);
833 if (ar->PathId != mdb->cached_path_id) {
834 mdb->cached_path_id = ar->PathId;
835 mdb->cached_path_len = mdb->pnl;
836 pm_strcpy(mdb->cached_path, mdb->path);
841 sql_free_result(mdb);
844 Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
846 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
847 Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
848 mdb->cmd, sql_strerror(mdb));
849 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
853 ar->PathId = sql_insert_id(mdb, N_("Path"));
858 if (stat && ar->PathId != mdb->cached_path_id) {
859 mdb->cached_path_id = ar->PathId;
860 mdb->cached_path_len = mdb->pnl;
861 pm_strcpy(mdb->cached_path, mdb->path);
866 /* Create a Unique record for the filename -- no duplicates */
867 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
871 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
872 db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
874 Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
876 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
877 mdb->num_rows = sql_num_rows(mdb);
878 if (mdb->num_rows > 1) {
880 Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
881 edit_uint64(mdb->num_rows, ed1), mdb->fname);
882 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
884 if (mdb->num_rows >= 1) {
885 if ((row = sql_fetch_row(mdb)) == NULL) {
886 Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
887 mdb->fname, sql_strerror(mdb));
888 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
891 ar->FilenameId = str_to_int64(row[0]);
893 sql_free_result(mdb);
894 return ar->FilenameId > 0;
896 sql_free_result(mdb);
899 Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
901 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
902 Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
903 mdb->cmd, sql_strerror(mdb));
904 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
907 ar->FilenameId = sql_insert_id(mdb, N_("Filename"));
909 return ar->FilenameId > 0;
912 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */