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 /* Create a new record for the Job
49 * Returns: false on failure
53 db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
55 char dt[MAX_TIME_LENGTH];
64 stime = jr->SchedTime;
67 (void)localtime_r(&stime, &tm);
68 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
69 JobTDate = (utime_t)stime;
73 "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate) VALUES "
74 "('%s','%s','%c','%c','%c','%s',%s)",
75 jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel),
76 (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1));
78 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
79 Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
80 mdb->cmd, sql_strerror(mdb));
84 jr->JobId = sql_insert_id(mdb, NT_("Job"));
92 /* Create a JobMedia record for medium used this job
93 * Returns: false on failure
97 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
101 char ed1[50], ed2[50];
105 /* Now get count for VolIndex */
106 Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
107 edit_int64(jm->JobId, ed1));
108 count = get_sql_record_max(jcr, mdb);
114 /* Note, jm->Strip is not used and is not likely to be used
115 * in the near future, so I have removed it from the insert
116 * to save space in the DB. KES June 2006.
119 "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
120 "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy) "
121 "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u)",
122 edit_int64(jm->JobId, ed1),
123 edit_int64(jm->MediaId, ed2),
124 jm->FirstIndex, jm->LastIndex,
125 jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
128 Dmsg0(300, mdb->cmd);
129 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
130 Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
134 /* Worked, now update the Media record with the EndFile and EndBlock */
136 "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
137 jm->EndFile, jm->EndBlock, jm->MediaId);
138 if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
139 Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
145 Dmsg0(300, "Return from JobMedia\n");
151 /* Create Unique Pool record
152 * Returns: false on failure
156 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
159 char ed1[30], ed2[30], ed3[50];
161 Dmsg0(200, "In create pool\n");
163 Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", pr->Name);
164 Dmsg1(200, "selectpool: %s\n", mdb->cmd);
166 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
167 mdb->num_rows = sql_num_rows(mdb);
168 if (mdb->num_rows > 0) {
169 Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
170 sql_free_result(mdb);
174 sql_free_result(mdb);
179 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
180 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
181 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
182 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
184 pr->NumVols, pr->MaxVols,
185 pr->UseOnce, pr->UseCatalog,
187 pr->AutoPrune, pr->Recycle,
188 edit_uint64(pr->VolRetention, ed1),
189 edit_uint64(pr->VolUseDuration, ed2),
190 pr->MaxVolJobs, pr->MaxVolFiles,
191 edit_uint64(pr->MaxVolBytes, ed3),
192 pr->PoolType, pr->LabelType, pr->LabelFormat);
193 Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
194 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
195 Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
196 mdb->cmd, sql_strerror(mdb));
200 pr->PoolId = sql_insert_id(mdb, NT_("Pool"));
208 * Create Unique Device record
209 * Returns: false on failure
213 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
216 char ed1[30], ed2[30];
218 Dmsg0(200, "In create Device\n");
220 Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
221 Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
223 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
224 mdb->num_rows = sql_num_rows(mdb);
225 if (mdb->num_rows > 0) {
226 Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
227 sql_free_result(mdb);
231 sql_free_result(mdb);
236 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
238 edit_uint64(dr->MediaTypeId, ed1),
239 edit_int64(dr->StorageId, ed2));
240 Dmsg1(200, "Create Device: %s\n", mdb->cmd);
241 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
242 Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
243 mdb->cmd, sql_strerror(mdb));
247 dr->DeviceId = sql_insert_id(mdb, NT_("Device"));
257 * Create a Unique record for Storage -- no duplicates
258 * Returns: false on failure
259 * true on success with id in sr->StorageId
261 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
267 Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
271 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
272 mdb->num_rows = sql_num_rows(mdb);
273 /* If more than one, report error, but return first row */
274 if (mdb->num_rows > 1) {
275 Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), (int)(mdb->num_rows));
276 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
278 if (mdb->num_rows >= 1) {
279 if ((row = sql_fetch_row(mdb)) == NULL) {
280 Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
281 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
282 sql_free_result(mdb);
286 sr->StorageId = str_to_int64(row[0]);
287 sr->AutoChanger = atoi(row[1]); /* bool */
288 sql_free_result(mdb);
292 sql_free_result(mdb);
296 Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
297 " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
299 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
300 Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
301 mdb->cmd, sql_strerror(mdb));
302 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
305 sr->StorageId = sql_insert_id(mdb, NT_("Storage"));
315 * Create Unique MediaType record
316 * Returns: false on failure
320 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
324 Dmsg0(200, "In create mediatype\n");
326 Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
327 Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
329 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
330 mdb->num_rows = sql_num_rows(mdb);
331 if (mdb->num_rows > 0) {
332 Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
333 sql_free_result(mdb);
337 sql_free_result(mdb);
342 "INSERT INTO MediaType (MediaType,ReadOnly) "
346 Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
347 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
348 Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
349 mdb->cmd, sql_strerror(mdb));
353 mr->MediaTypeId = sql_insert_id(mdb, NT_("MediaType"));
362 * Create Media record. VolumeName and non-zero Slot must be unique
364 * Returns: 0 on failure
368 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
371 char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
372 char ed9[50], ed10[50], ed11[50], ed12[50];
376 Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
378 Dmsg1(500, "selectpool: %s\n", mdb->cmd);
380 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
381 mdb->num_rows = sql_num_rows(mdb);
382 if (mdb->num_rows > 0) {
383 Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
384 sql_free_result(mdb);
388 sql_free_result(mdb);
393 "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
394 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
395 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
396 "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId,"
397 "ScratchPoolId,RecyclePoolId,Enabled)"
398 "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,"
401 mr->MediaType, mr->PoolId,
402 edit_uint64(mr->MaxVolBytes,ed1),
403 edit_uint64(mr->VolCapacityBytes, ed2),
405 edit_uint64(mr->VolRetention, ed3),
406 edit_uint64(mr->VolUseDuration, ed4),
411 edit_uint64(mr->VolBytes, ed5),
413 edit_uint64(mr->VolReadTime, ed6),
414 edit_uint64(mr->VolWriteTime, ed7),
417 edit_int64(mr->StorageId, ed8),
418 edit_int64(mr->DeviceId, ed9),
419 edit_int64(mr->LocationId, ed10),
420 edit_int64(mr->ScratchPoolId, ed11),
421 edit_int64(mr->RecyclePoolId, ed12),
426 Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
427 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
428 Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
429 mdb->cmd, sql_strerror(mdb));
432 mr->MediaId = sql_insert_id(mdb, NT_("Media"));
434 if (mr->set_label_date) {
435 char dt[MAX_TIME_LENGTH];
436 if (mr->LabelDate == 0) {
437 mr->LabelDate = time(NULL);
439 (void)localtime_r(&mr->LabelDate, &tm);
440 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
441 Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
442 "WHERE MediaId=%d", dt, mr->MediaId);
443 stat = UPDATE_DB(jcr, mdb, mdb->cmd);
448 * Make sure that if InChanger is non-zero any other identical slot
449 * has InChanger zero.
451 db_make_inchanger_unique(jcr, mdb, mr);
458 * Create a Unique record for the client -- no duplicates
459 * Returns: 0 on failure
460 * 1 on success with id in cr->ClientId
462 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
466 char ed1[50], ed2[50];
469 Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
472 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
473 mdb->num_rows = sql_num_rows(mdb);
474 /* If more than one, report error, but return first row */
475 if (mdb->num_rows > 1) {
476 Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
477 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
479 if (mdb->num_rows >= 1) {
480 if ((row = sql_fetch_row(mdb)) == NULL) {
481 Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
482 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
483 sql_free_result(mdb);
487 cr->ClientId = str_to_int64(row[0]);
489 bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
491 cr->Uname[0] = 0; /* no name */
493 sql_free_result(mdb);
497 sql_free_result(mdb);
501 Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
502 "FileRetention,JobRetention) VALUES "
503 "('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
504 edit_uint64(cr->FileRetention, ed1),
505 edit_uint64(cr->JobRetention, ed2));
507 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
508 Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
509 mdb->cmd, sql_strerror(mdb));
510 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
514 cr->ClientId = sql_insert_id(mdb, NT_("Client"));
526 * Create a Unique record for the counter -- no duplicates
527 * Returns: 0 on failure
528 * 1 on success with counter filled in
530 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
536 memset(&mcr, 0, sizeof(mcr));
537 bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
538 if (db_get_counter_record(jcr, mdb, &mcr)) {
539 memcpy(cr, &mcr, sizeof(COUNTER_DBR));
545 Mmsg(mdb->cmd, "INSERT INTO Counters (Counter,MinValue,MaxValue,CurrentValue,"
546 "WrapCounter) VALUES ('%s','%d','%d','%d','%s')",
547 cr->Counter, cr->MinValue, cr->MaxValue, cr->CurrentValue,
550 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
551 Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
552 mdb->cmd, sql_strerror(mdb));
553 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
564 * Create a FileSet record. This record is unique in the
565 * name and the MD5 signature of the include/exclude sets.
566 * Returns: 0 on failure
567 * 1 on success with FileSetId in record
569 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
576 fsr->created = false;
577 Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
578 "FileSet='%s' AND MD5='%s'", fsr->FileSet, fsr->MD5);
581 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
582 mdb->num_rows = sql_num_rows(mdb);
583 if (mdb->num_rows > 1) {
584 Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
585 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
587 if (mdb->num_rows >= 1) {
588 if ((row = sql_fetch_row(mdb)) == NULL) {
589 Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
590 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
591 sql_free_result(mdb);
595 fsr->FileSetId = str_to_int64(row[0]);
596 if (row[1] == NULL) {
597 fsr->cCreateTime[0] = 0;
599 bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
601 sql_free_result(mdb);
605 sql_free_result(mdb);
608 if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
609 fsr->CreateTime = time(NULL);
611 (void)localtime_r(&fsr->CreateTime, &tm);
612 strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %H:%M:%S", &tm);
615 Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
616 "VALUES ('%s','%s','%s')", fsr->FileSet, fsr->MD5, fsr->cCreateTime);
618 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
619 Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
620 mdb->cmd, sql_strerror(mdb));
621 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
625 fsr->FileSetId = sql_insert_id(mdb, NT_("FileSet"));
638 * dev_t st_dev; * device *
639 * ino_t st_ino; * inode *
640 * mode_t st_mode; * protection *
641 * nlink_t st_nlink; * number of hard links *
642 * uid_t st_uid; * user ID of owner *
643 * gid_t st_gid; * group ID of owner *
644 * dev_t st_rdev; * device type (if inode device) *
645 * off_t st_size; * total size, in bytes *
646 * unsigned long st_blksize; * blocksize for filesystem I/O *
647 * unsigned long st_blocks; * number of blocks allocated *
648 * time_t st_atime; * time of last access *
649 * time_t st_mtime; * time of last modification *
650 * time_t st_ctime; * time of last inode change *
657 * Create File record in B_DB
659 * In order to reduce database size, we store the File attributes,
660 * the FileName, and the Path separately. In principle, there
661 * is a single FileName record and a single Path record, no matter
662 * how many times it occurs. This is this subroutine, we separate
663 * the file and the path and create three database records.
665 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
669 Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
670 Dmsg0(dbglevel, "put_file_into_catalog\n");
672 * Make sure we have an acceptable attributes record.
674 if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
675 ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
676 Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
678 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
683 split_path_and_file(jcr, mdb, ar->fname);
685 if (!db_create_filename_record(jcr, mdb, ar)) {
688 Dmsg1(dbglevel, "db_create_filename_record: %s\n", mdb->esc_name);
691 if (!db_create_path_record(jcr, mdb, ar)) {
694 Dmsg1(dbglevel, "db_create_path_record: %s\n", mdb->esc_name);
696 /* Now create master File record */
697 if (!db_create_file_record(jcr, mdb, ar)) {
700 Dmsg0(dbglevel, "db_create_file_record OK\n");
702 Dmsg3(dbglevel, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
712 * This is the master File entry containing the attributes.
713 * The filename and path records have already been created.
715 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
718 static char *no_digest = "0";
723 ASSERT(ar->FilenameId);
725 if (ar->Digest == NULL || ar->Digest[0] == 0) {
733 "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
734 "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
735 ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
738 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
739 Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
740 mdb->cmd, sql_strerror(mdb));
741 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
745 ar->FileId = sql_insert_id(mdb, NT_("File"));
751 /* Create a Unique record for the Path -- no duplicates */
752 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
757 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
758 db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
760 if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
761 strcmp(mdb->cached_path, mdb->path) == 0) {
762 ar->PathId = mdb->cached_path_id;
766 Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
768 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
769 mdb->num_rows = sql_num_rows(mdb);
770 if (mdb->num_rows > 1) {
772 Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
773 edit_uint64(mdb->num_rows, ed1), mdb->path);
774 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
776 /* Even if there are multiple paths, take the first one */
777 if (mdb->num_rows >= 1) {
778 if ((row = sql_fetch_row(mdb)) == NULL) {
779 Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
780 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
781 sql_free_result(mdb);
786 ar->PathId = str_to_int64(row[0]);
787 sql_free_result(mdb);
789 if (ar->PathId != mdb->cached_path_id) {
790 mdb->cached_path_id = ar->PathId;
791 mdb->cached_path_len = mdb->pnl;
792 pm_strcpy(mdb->cached_path, mdb->path);
797 sql_free_result(mdb);
800 Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
802 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
803 Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
804 mdb->cmd, sql_strerror(mdb));
805 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
809 ar->PathId = sql_insert_id(mdb, NT_("Path"));
814 if (stat && ar->PathId != mdb->cached_path_id) {
815 mdb->cached_path_id = ar->PathId;
816 mdb->cached_path_len = mdb->pnl;
817 pm_strcpy(mdb->cached_path, mdb->path);
822 /* Create a Unique record for the filename -- no duplicates */
823 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
827 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
828 db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
830 Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
832 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
833 mdb->num_rows = sql_num_rows(mdb);
834 if (mdb->num_rows > 1) {
836 Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
837 edit_uint64(mdb->num_rows, ed1), mdb->fname);
838 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
840 if (mdb->num_rows >= 1) {
841 if ((row = sql_fetch_row(mdb)) == NULL) {
842 Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
843 mdb->fname, sql_strerror(mdb));
844 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
847 ar->FilenameId = str_to_int64(row[0]);
849 sql_free_result(mdb);
850 return ar->FilenameId > 0;
852 sql_free_result(mdb);
855 Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
857 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
858 Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
859 mdb->cmd, sql_strerror(mdb));
860 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
863 ar->FilenameId = sql_insert_id(mdb, NT_("Filename"));
865 return ar->FilenameId > 0;
868 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */