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: 0 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 JobMedia record for medium used this job
99 * Returns: false on failure
103 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
107 char ed1[50], ed2[50];
111 /* Now get count for VolIndex */
112 Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
113 edit_int64(jm->JobId, ed1));
114 count = get_sql_record_max(jcr, mdb);
121 "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
122 "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy,Stripe) "
123 "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u,%u)",
124 edit_int64(jm->JobId, ed1),
125 edit_int64(jm->MediaId, ed2),
126 jm->FirstIndex, jm->LastIndex,
127 jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
128 jm->Copy, jm->Stripe);
130 Dmsg0(300, mdb->cmd);
131 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
132 Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
136 /* Worked, now update the Media record with the EndFile and EndBlock */
138 "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
139 jm->EndFile, jm->EndBlock, jm->MediaId);
140 if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
141 Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
147 Dmsg0(300, "Return from JobMedia\n");
153 /* Create Unique Pool record
154 * Returns: false on failure
158 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
161 char ed1[30], ed2[30], ed3[50];
163 Dmsg0(200, "In create pool\n");
165 Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", pr->Name);
166 Dmsg1(200, "selectpool: %s\n", mdb->cmd);
168 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
169 mdb->num_rows = sql_num_rows(mdb);
170 if (mdb->num_rows > 0) {
171 Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
172 sql_free_result(mdb);
176 sql_free_result(mdb);
181 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
182 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
183 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
184 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
186 pr->NumVols, pr->MaxVols,
187 pr->UseOnce, pr->UseCatalog,
189 pr->AutoPrune, pr->Recycle,
190 edit_uint64(pr->VolRetention, ed1),
191 edit_uint64(pr->VolUseDuration, ed2),
192 pr->MaxVolJobs, pr->MaxVolFiles,
193 edit_uint64(pr->MaxVolBytes, ed3),
194 pr->PoolType, pr->LabelType, pr->LabelFormat);
195 Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
196 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
197 Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
198 mdb->cmd, sql_strerror(mdb));
202 pr->PoolId = sql_insert_id(mdb, N_("Pool"));
210 * Create Unique Device record
211 * Returns: false on failure
215 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
218 char ed1[30], ed2[30];
220 Dmsg0(200, "In create Device\n");
222 Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
223 Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
225 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
226 mdb->num_rows = sql_num_rows(mdb);
227 if (mdb->num_rows > 0) {
228 Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
229 sql_free_result(mdb);
233 sql_free_result(mdb);
238 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
240 edit_uint64(dr->MediaTypeId, ed1),
241 edit_int64(dr->StorageId, ed2));
242 Dmsg1(200, "Create Device: %s\n", mdb->cmd);
243 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
244 Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
245 mdb->cmd, sql_strerror(mdb));
249 dr->DeviceId = sql_insert_id(mdb, N_("Device"));
259 * Create a Unique record for Storage -- no duplicates
260 * Returns: false on failure
261 * true on success with id in sr->StorageId
263 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
269 Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
273 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
274 mdb->num_rows = sql_num_rows(mdb);
275 /* If more than one, report error, but return first row */
276 if (mdb->num_rows > 1) {
277 Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), (int)(mdb->num_rows));
278 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
280 if (mdb->num_rows >= 1) {
281 if ((row = sql_fetch_row(mdb)) == NULL) {
282 Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
283 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
284 sql_free_result(mdb);
288 sr->StorageId = str_to_int64(row[0]);
289 sr->AutoChanger = atoi(row[1]); /* bool */
290 sql_free_result(mdb);
294 sql_free_result(mdb);
298 Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
299 " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
301 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
302 Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
303 mdb->cmd, sql_strerror(mdb));
304 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
307 sr->StorageId = sql_insert_id(mdb, N_("Storage"));
317 * Create Unique MediaType record
318 * Returns: false on failure
322 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
326 Dmsg0(200, "In create mediatype\n");
328 Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
329 Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
331 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
332 mdb->num_rows = sql_num_rows(mdb);
333 if (mdb->num_rows > 0) {
334 Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
335 sql_free_result(mdb);
339 sql_free_result(mdb);
344 "INSERT INTO MediaType (MediaType,ReadOnly) "
348 Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
349 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
350 Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
351 mdb->cmd, sql_strerror(mdb));
355 mr->MediaTypeId = sql_insert_id(mdb, N_("MediaType"));
364 * Create Media record. VolumeName and non-zero Slot must be unique
366 * Returns: 0 on failure
370 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
373 char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
377 Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
379 Dmsg1(500, "selectpool: %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, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
385 sql_free_result(mdb);
389 sql_free_result(mdb);
394 "INSERT INTO Media (VolumeName,MediaType,PoolId,MaxVolBytes,VolCapacityBytes,"
395 "Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
396 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
397 "EndFile,EndBlock,LabelType,StorageId) "
398 "VALUES ('%s','%s',%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s)",
400 mr->MediaType, mr->PoolId,
401 edit_uint64(mr->MaxVolBytes,ed1),
402 edit_uint64(mr->VolCapacityBytes, ed2),
404 edit_uint64(mr->VolRetention, ed3),
405 edit_uint64(mr->VolUseDuration, ed4),
410 edit_uint64(mr->VolBytes, ed5),
412 edit_uint64(mr->VolReadTime, ed6),
413 edit_uint64(mr->VolWriteTime, ed7),
416 edit_int64(mr->StorageId, ed8)
420 Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
421 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
422 Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
423 mdb->cmd, sql_strerror(mdb));
426 mr->MediaId = sql_insert_id(mdb, N_("Media"));
428 if (mr->set_label_date) {
429 char dt[MAX_TIME_LENGTH];
430 if (mr->LabelDate == 0) {
431 mr->LabelDate = time(NULL);
433 localtime_r(&mr->LabelDate, &tm);
434 strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
435 Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
436 "WHERE MediaId=%d", dt, mr->MediaId);
437 stat = UPDATE_DB(jcr, mdb, mdb->cmd);
442 * Make sure that if InChanger is non-zero any other identical slot
443 * has InChanger zero.
445 db_make_inchanger_unique(jcr, mdb, mr);
452 * Create a Unique record for the client -- no duplicates
453 * Returns: 0 on failure
454 * 1 on success with id in cr->ClientId
456 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
460 char ed1[50], ed2[50];
463 Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
466 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
467 mdb->num_rows = sql_num_rows(mdb);
468 /* If more than one, report error, but return first row */
469 if (mdb->num_rows > 1) {
470 Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
471 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
473 if (mdb->num_rows >= 1) {
474 if ((row = sql_fetch_row(mdb)) == NULL) {
475 Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
476 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
477 sql_free_result(mdb);
481 cr->ClientId = str_to_int64(row[0]);
483 bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
485 cr->Uname[0] = 0; /* no name */
487 sql_free_result(mdb);
491 sql_free_result(mdb);
495 Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
496 "FileRetention,JobRetention) VALUES "
497 "('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
498 edit_uint64(cr->FileRetention, ed1),
499 edit_uint64(cr->JobRetention, ed2));
501 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
502 Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
503 mdb->cmd, sql_strerror(mdb));
504 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
508 cr->ClientId = sql_insert_id(mdb, N_("Client"));
520 * Create a Unique record for the counter -- no duplicates
521 * Returns: 0 on failure
522 * 1 on success with counter filled in
524 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
530 memset(&mcr, 0, sizeof(mcr));
531 bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
532 if (db_get_counter_record(jcr, mdb, &mcr)) {
533 memcpy(cr, &mcr, sizeof(COUNTER_DBR));
539 Mmsg(mdb->cmd, "INSERT INTO Counters (Counter,MinValue,MaxValue,CurrentValue,"
540 "WrapCounter) VALUES ('%s','%d','%d','%d','%s')",
541 cr->Counter, cr->MinValue, cr->MaxValue, cr->CurrentValue,
544 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
545 Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
546 mdb->cmd, sql_strerror(mdb));
547 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
558 * Create a FileSet record. This record is unique in the
559 * name and the MD5 signature of the include/exclude sets.
560 * Returns: 0 on failure
561 * 1 on success with FileSetId in record
563 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
570 fsr->created = false;
571 Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
572 "FileSet='%s' AND MD5='%s'", fsr->FileSet, fsr->MD5);
575 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
576 mdb->num_rows = sql_num_rows(mdb);
577 if (mdb->num_rows > 1) {
578 Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
579 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
581 if (mdb->num_rows >= 1) {
582 if ((row = sql_fetch_row(mdb)) == NULL) {
583 Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
584 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
585 sql_free_result(mdb);
589 fsr->FileSetId = str_to_int64(row[0]);
590 if (row[1] == NULL) {
591 fsr->cCreateTime[0] = 0;
593 bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
595 sql_free_result(mdb);
599 sql_free_result(mdb);
602 if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
603 fsr->CreateTime = time(NULL);
605 localtime_r(&fsr->CreateTime, &tm);
606 strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %T", &tm);
609 Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
610 "VALUES ('%s','%s','%s')", fsr->FileSet, fsr->MD5, fsr->cCreateTime);
612 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
613 Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
614 mdb->cmd, sql_strerror(mdb));
615 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
619 fsr->FileSetId = sql_insert_id(mdb, N_("FileSet"));
632 * dev_t st_dev; * device *
633 * ino_t st_ino; * inode *
634 * mode_t st_mode; * protection *
635 * nlink_t st_nlink; * number of hard links *
636 * uid_t st_uid; * user ID of owner *
637 * gid_t st_gid; * group ID of owner *
638 * dev_t st_rdev; * device type (if inode device) *
639 * off_t st_size; * total size, in bytes *
640 * unsigned long st_blksize; * blocksize for filesystem I/O *
641 * unsigned long st_blocks; * number of blocks allocated *
642 * time_t st_atime; * time of last access *
643 * time_t st_mtime; * time of last modification *
644 * time_t st_ctime; * time of last inode change *
651 * Create File record in B_DB
653 * In order to reduce database size, we store the File attributes,
654 * the FileName, and the Path separately. In principle, there
655 * is a single FileName record and a single Path record, no matter
656 * how many times it occurs. This is this subroutine, we separate
657 * the file and the path and create three database records.
659 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
663 Dmsg1(300, "Fname=%s\n", ar->fname);
664 Dmsg0(500, "put_file_into_catalog\n");
666 * Make sure we have an acceptable attributes record.
668 if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
669 ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
670 Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
672 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
677 split_path_and_file(jcr, mdb, ar->fname);
679 if (!db_create_filename_record(jcr, mdb, ar)) {
682 Dmsg1(500, "db_create_filename_record: %s\n", mdb->esc_name);
685 if (!db_create_path_record(jcr, mdb, ar)) {
688 Dmsg1(500, "db_create_path_record: %s\n", mdb->esc_name);
690 /* Now create master File record */
691 if (!db_create_file_record(jcr, mdb, ar)) {
694 Dmsg0(500, "db_create_file_record OK\n");
696 Dmsg3(300, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
706 * This is the master File entry containing the attributes.
707 * The filename and path records have already been created.
709 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
712 static char *no_sig = "0";
717 ASSERT(ar->FilenameId);
719 if (ar->Sig == NULL) {
727 "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
728 "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
729 ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
732 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
733 Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
734 mdb->cmd, sql_strerror(mdb));
735 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
739 ar->FileId = sql_insert_id(mdb, N_("File"));
745 /* Create a Unique record for the Path -- no duplicates */
746 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
751 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
752 db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
754 if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
755 strcmp(mdb->cached_path, mdb->path) == 0) {
756 ar->PathId = mdb->cached_path_id;
760 Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
762 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
763 mdb->num_rows = sql_num_rows(mdb);
764 if (mdb->num_rows > 1) {
766 Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
767 edit_uint64(mdb->num_rows, ed1), mdb->path);
768 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
770 /* Even if there are multiple paths, take the first one */
771 if (mdb->num_rows >= 1) {
772 if ((row = sql_fetch_row(mdb)) == NULL) {
773 Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
774 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
775 sql_free_result(mdb);
780 ar->PathId = str_to_int64(row[0]);
781 sql_free_result(mdb);
783 if (ar->PathId != mdb->cached_path_id) {
784 mdb->cached_path_id = ar->PathId;
785 mdb->cached_path_len = mdb->pnl;
786 pm_strcpy(mdb->cached_path, mdb->path);
791 sql_free_result(mdb);
794 Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
796 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
797 Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
798 mdb->cmd, sql_strerror(mdb));
799 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
803 ar->PathId = sql_insert_id(mdb, N_("Path"));
808 if (stat && ar->PathId != mdb->cached_path_id) {
809 mdb->cached_path_id = ar->PathId;
810 mdb->cached_path_len = mdb->pnl;
811 pm_strcpy(mdb->cached_path, mdb->path);
816 /* Create a Unique record for the filename -- no duplicates */
817 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
821 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
822 db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
824 Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
826 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
827 mdb->num_rows = sql_num_rows(mdb);
828 if (mdb->num_rows > 1) {
830 Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
831 edit_uint64(mdb->num_rows, ed1), mdb->fname);
832 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
834 if (mdb->num_rows >= 1) {
835 if ((row = sql_fetch_row(mdb)) == NULL) {
836 Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
837 mdb->fname, sql_strerror(mdb));
838 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
841 ar->FilenameId = str_to_int64(row[0]);
843 sql_free_result(mdb);
844 return ar->FilenameId > 0;
846 sql_free_result(mdb);
849 Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
851 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
852 Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
853 mdb->cmd, sql_strerror(mdb));
854 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
857 ar->FilenameId = sql_insert_id(mdb, N_("Filename"));
859 return ar->FilenameId > 0;
862 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */