2 * Bacula Catalog Database Create record interface routines
4 * Kern Sibbald, March 2000
9 Bacula® - The Network Backup Solution
11 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
13 The main author of Bacula is Kern Sibbald, with contributions from
14 many others, a complete list can be found in the file AUTHORS.
15 This program is Free Software; you can redistribute it and/or
16 modify it under the terms of version two of the GNU General Public
17 License as published by the Free Software Foundation plus additions
18 that are listed in the file LICENSE.
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 Bacula® is a registered trademark of John Walker.
31 The licensor of Bacula is the Free Software Foundation Europe
32 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
33 Switzerland, email:ftf@fsfeurope.org.
36 /* The following is necessary so that we do not include
37 * the dummy external definition of DB.
39 #define __SQL_C /* indicate that this is sql.c */
44 static const int dbglevel = 500;
46 #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL
48 /* -----------------------------------------------------------------------
50 * Generic Routines (or almost generic)
52 * -----------------------------------------------------------------------
55 /* Forward referenced subroutines */
56 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
57 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
58 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
61 /* Create a new record for the Job
62 * Returns: false on failure
66 db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
68 char dt[MAX_TIME_LENGTH];
77 stime = jr->SchedTime;
80 (void)localtime_r(&stime, &tm);
81 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
82 JobTDate = (utime_t)stime;
86 "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate) VALUES "
87 "('%s','%s','%c','%c','%c','%s',%s)",
88 jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel),
89 (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1));
91 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
92 Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
93 mdb->cmd, sql_strerror(mdb));
97 jr->JobId = sql_insert_id(mdb, NT_("Job"));
105 /* Create a JobMedia record for medium used this job
106 * Returns: false on failure
110 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
114 char ed1[50], ed2[50];
118 /* Now get count for VolIndex */
119 Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
120 edit_int64(jm->JobId, ed1));
121 count = get_sql_record_max(jcr, mdb);
127 /* Note, jm->Strip is not used and is not likely to be used
128 * in the near future, so I have removed it from the insert
129 * to save space in the DB. KES June 2006.
132 "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
133 "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy) "
134 "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u)",
135 edit_int64(jm->JobId, ed1),
136 edit_int64(jm->MediaId, ed2),
137 jm->FirstIndex, jm->LastIndex,
138 jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
141 Dmsg0(300, mdb->cmd);
142 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
143 Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
147 /* Worked, now update the Media record with the EndFile and EndBlock */
149 "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
150 jm->EndFile, jm->EndBlock, jm->MediaId);
151 if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
152 Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
158 Dmsg0(300, "Return from JobMedia\n");
164 /* Create Unique Pool record
165 * Returns: false on failure
169 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
172 char ed1[30], ed2[30], ed3[50];
174 Dmsg0(200, "In create pool\n");
176 Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", pr->Name);
177 Dmsg1(200, "selectpool: %s\n", mdb->cmd);
179 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
180 mdb->num_rows = sql_num_rows(mdb);
181 if (mdb->num_rows > 0) {
182 Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
183 sql_free_result(mdb);
187 sql_free_result(mdb);
192 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
193 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
194 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
195 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
197 pr->NumVols, pr->MaxVols,
198 pr->UseOnce, pr->UseCatalog,
200 pr->AutoPrune, pr->Recycle,
201 edit_uint64(pr->VolRetention, ed1),
202 edit_uint64(pr->VolUseDuration, ed2),
203 pr->MaxVolJobs, pr->MaxVolFiles,
204 edit_uint64(pr->MaxVolBytes, ed3),
205 pr->PoolType, pr->LabelType, pr->LabelFormat);
206 Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
207 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
208 Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
209 mdb->cmd, sql_strerror(mdb));
213 pr->PoolId = sql_insert_id(mdb, NT_("Pool"));
221 * Create Unique Device record
222 * Returns: false on failure
226 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
229 char ed1[30], ed2[30];
231 Dmsg0(200, "In create Device\n");
233 Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
234 Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
236 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
237 mdb->num_rows = sql_num_rows(mdb);
238 if (mdb->num_rows > 0) {
239 Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
240 sql_free_result(mdb);
244 sql_free_result(mdb);
249 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
251 edit_uint64(dr->MediaTypeId, ed1),
252 edit_int64(dr->StorageId, ed2));
253 Dmsg1(200, "Create Device: %s\n", mdb->cmd);
254 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
255 Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
256 mdb->cmd, sql_strerror(mdb));
260 dr->DeviceId = sql_insert_id(mdb, NT_("Device"));
270 * Create a Unique record for Storage -- no duplicates
271 * Returns: false on failure
272 * true on success with id in sr->StorageId
274 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
280 Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
284 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
285 mdb->num_rows = sql_num_rows(mdb);
286 /* If more than one, report error, but return first row */
287 if (mdb->num_rows > 1) {
288 Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), (int)(mdb->num_rows));
289 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
291 if (mdb->num_rows >= 1) {
292 if ((row = sql_fetch_row(mdb)) == NULL) {
293 Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
294 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
295 sql_free_result(mdb);
299 sr->StorageId = str_to_int64(row[0]);
300 sr->AutoChanger = atoi(row[1]); /* bool */
301 sql_free_result(mdb);
305 sql_free_result(mdb);
309 Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
310 " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
312 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
313 Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
314 mdb->cmd, sql_strerror(mdb));
315 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
318 sr->StorageId = sql_insert_id(mdb, NT_("Storage"));
328 * Create Unique MediaType record
329 * Returns: false on failure
333 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
337 Dmsg0(200, "In create mediatype\n");
339 Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
340 Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
342 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
343 mdb->num_rows = sql_num_rows(mdb);
344 if (mdb->num_rows > 0) {
345 Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
346 sql_free_result(mdb);
350 sql_free_result(mdb);
355 "INSERT INTO MediaType (MediaType,ReadOnly) "
359 Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
360 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
361 Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
362 mdb->cmd, sql_strerror(mdb));
366 mr->MediaTypeId = sql_insert_id(mdb, NT_("MediaType"));
375 * Create Media record. VolumeName and non-zero Slot must be unique
377 * Returns: 0 on failure
381 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
384 char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
385 char ed9[50], ed10[50], ed11[50], ed12[50];
389 Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
391 Dmsg1(500, "selectpool: %s\n", mdb->cmd);
393 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
394 mdb->num_rows = sql_num_rows(mdb);
395 if (mdb->num_rows > 0) {
396 Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
397 sql_free_result(mdb);
401 sql_free_result(mdb);
406 "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
407 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
408 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
409 "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId,"
410 "ScratchPoolId,RecyclePoolId,Enabled)"
411 "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,"
414 mr->MediaType, mr->PoolId,
415 edit_uint64(mr->MaxVolBytes,ed1),
416 edit_uint64(mr->VolCapacityBytes, ed2),
418 edit_uint64(mr->VolRetention, ed3),
419 edit_uint64(mr->VolUseDuration, ed4),
424 edit_uint64(mr->VolBytes, ed5),
426 edit_uint64(mr->VolReadTime, ed6),
427 edit_uint64(mr->VolWriteTime, ed7),
430 edit_int64(mr->StorageId, ed8),
431 edit_int64(mr->DeviceId, ed9),
432 edit_int64(mr->LocationId, ed10),
433 edit_int64(mr->ScratchPoolId, ed11),
434 edit_int64(mr->RecyclePoolId, ed12),
439 Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
440 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
441 Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
442 mdb->cmd, sql_strerror(mdb));
445 mr->MediaId = sql_insert_id(mdb, NT_("Media"));
447 if (mr->set_label_date) {
448 char dt[MAX_TIME_LENGTH];
449 if (mr->LabelDate == 0) {
450 mr->LabelDate = time(NULL);
452 (void)localtime_r(&mr->LabelDate, &tm);
453 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
454 Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
455 "WHERE MediaId=%d", dt, mr->MediaId);
456 stat = UPDATE_DB(jcr, mdb, mdb->cmd);
461 * Make sure that if InChanger is non-zero any other identical slot
462 * has InChanger zero.
464 db_make_inchanger_unique(jcr, mdb, mr);
471 * Create a Unique record for the client -- no duplicates
472 * Returns: 0 on failure
473 * 1 on success with id in cr->ClientId
475 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
479 char ed1[50], ed2[50];
482 Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
485 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
486 mdb->num_rows = sql_num_rows(mdb);
487 /* If more than one, report error, but return first row */
488 if (mdb->num_rows > 1) {
489 Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
490 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
492 if (mdb->num_rows >= 1) {
493 if ((row = sql_fetch_row(mdb)) == NULL) {
494 Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
495 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
496 sql_free_result(mdb);
500 cr->ClientId = str_to_int64(row[0]);
502 bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
504 cr->Uname[0] = 0; /* no name */
506 sql_free_result(mdb);
510 sql_free_result(mdb);
514 Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
515 "FileRetention,JobRetention) VALUES "
516 "('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
517 edit_uint64(cr->FileRetention, ed1),
518 edit_uint64(cr->JobRetention, ed2));
520 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
521 Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
522 mdb->cmd, sql_strerror(mdb));
523 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
527 cr->ClientId = sql_insert_id(mdb, NT_("Client"));
539 * Create a Unique record for the counter -- no duplicates
540 * Returns: 0 on failure
541 * 1 on success with counter filled in
543 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
549 memset(&mcr, 0, sizeof(mcr));
550 bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
551 if (db_get_counter_record(jcr, mdb, &mcr)) {
552 memcpy(cr, &mcr, sizeof(COUNTER_DBR));
558 Mmsg(mdb->cmd, "INSERT INTO Counters (Counter,MinValue,MaxValue,CurrentValue,"
559 "WrapCounter) VALUES ('%s','%d','%d','%d','%s')",
560 cr->Counter, cr->MinValue, cr->MaxValue, cr->CurrentValue,
563 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
564 Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
565 mdb->cmd, sql_strerror(mdb));
566 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
577 * Create a FileSet record. This record is unique in the
578 * name and the MD5 signature of the include/exclude sets.
579 * Returns: 0 on failure
580 * 1 on success with FileSetId in record
582 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
589 fsr->created = false;
590 Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
591 "FileSet='%s' AND MD5='%s'", fsr->FileSet, fsr->MD5);
594 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
595 mdb->num_rows = sql_num_rows(mdb);
596 if (mdb->num_rows > 1) {
597 Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
598 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
600 if (mdb->num_rows >= 1) {
601 if ((row = sql_fetch_row(mdb)) == NULL) {
602 Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
603 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
604 sql_free_result(mdb);
608 fsr->FileSetId = str_to_int64(row[0]);
609 if (row[1] == NULL) {
610 fsr->cCreateTime[0] = 0;
612 bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
614 sql_free_result(mdb);
618 sql_free_result(mdb);
621 if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
622 fsr->CreateTime = time(NULL);
624 (void)localtime_r(&fsr->CreateTime, &tm);
625 strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %H:%M:%S", &tm);
628 Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
629 "VALUES ('%s','%s','%s')", fsr->FileSet, fsr->MD5, fsr->cCreateTime);
631 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
632 Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
633 mdb->cmd, sql_strerror(mdb));
634 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
638 fsr->FileSetId = sql_insert_id(mdb, NT_("FileSet"));
651 * dev_t st_dev; * device *
652 * ino_t st_ino; * inode *
653 * mode_t st_mode; * protection *
654 * nlink_t st_nlink; * number of hard links *
655 * uid_t st_uid; * user ID of owner *
656 * gid_t st_gid; * group ID of owner *
657 * dev_t st_rdev; * device type (if inode device) *
658 * off_t st_size; * total size, in bytes *
659 * unsigned long st_blksize; * blocksize for filesystem I/O *
660 * unsigned long st_blocks; * number of blocks allocated *
661 * time_t st_atime; * time of last access *
662 * time_t st_mtime; * time of last modification *
663 * time_t st_ctime; * time of last inode change *
670 * Create File record in B_DB
672 * In order to reduce database size, we store the File attributes,
673 * the FileName, and the Path separately. In principle, there
674 * is a single FileName record and a single Path record, no matter
675 * how many times it occurs. This is this subroutine, we separate
676 * the file and the path and create three database records.
678 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
682 Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
683 Dmsg0(dbglevel, "put_file_into_catalog\n");
685 * Make sure we have an acceptable attributes record.
687 if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
688 ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
689 Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
691 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
696 split_path_and_file(jcr, mdb, ar->fname);
698 if (!db_create_filename_record(jcr, mdb, ar)) {
701 Dmsg1(dbglevel, "db_create_filename_record: %s\n", mdb->esc_name);
704 if (!db_create_path_record(jcr, mdb, ar)) {
707 Dmsg1(dbglevel, "db_create_path_record: %s\n", mdb->esc_name);
709 /* Now create master File record */
710 if (!db_create_file_record(jcr, mdb, ar)) {
713 Dmsg0(dbglevel, "db_create_file_record OK\n");
715 Dmsg3(dbglevel, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
725 * This is the master File entry containing the attributes.
726 * The filename and path records have already been created.
728 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
731 static char *no_digest = "0";
736 ASSERT(ar->FilenameId);
738 if (ar->Digest == NULL || ar->Digest[0] == 0) {
746 "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
747 "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
748 ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
751 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
752 Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
753 mdb->cmd, sql_strerror(mdb));
754 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
758 ar->FileId = sql_insert_id(mdb, NT_("File"));
764 /* Create a Unique record for the Path -- no duplicates */
765 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
770 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
771 db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
773 if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
774 strcmp(mdb->cached_path, mdb->path) == 0) {
775 ar->PathId = mdb->cached_path_id;
779 Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
781 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
782 mdb->num_rows = sql_num_rows(mdb);
783 if (mdb->num_rows > 1) {
785 Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
786 edit_uint64(mdb->num_rows, ed1), mdb->path);
787 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
789 /* Even if there are multiple paths, take the first one */
790 if (mdb->num_rows >= 1) {
791 if ((row = sql_fetch_row(mdb)) == NULL) {
792 Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
793 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
794 sql_free_result(mdb);
799 ar->PathId = str_to_int64(row[0]);
800 sql_free_result(mdb);
802 if (ar->PathId != mdb->cached_path_id) {
803 mdb->cached_path_id = ar->PathId;
804 mdb->cached_path_len = mdb->pnl;
805 pm_strcpy(mdb->cached_path, mdb->path);
810 sql_free_result(mdb);
813 Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
815 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
816 Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
817 mdb->cmd, sql_strerror(mdb));
818 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
822 ar->PathId = sql_insert_id(mdb, NT_("Path"));
827 if (stat && ar->PathId != mdb->cached_path_id) {
828 mdb->cached_path_id = ar->PathId;
829 mdb->cached_path_len = mdb->pnl;
830 pm_strcpy(mdb->cached_path, mdb->path);
835 /* Create a Unique record for the filename -- no duplicates */
836 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
840 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
841 db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
843 Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
845 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
846 mdb->num_rows = sql_num_rows(mdb);
847 if (mdb->num_rows > 1) {
849 Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
850 edit_uint64(mdb->num_rows, ed1), mdb->fname);
851 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
853 if (mdb->num_rows >= 1) {
854 if ((row = sql_fetch_row(mdb)) == NULL) {
855 Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
856 mdb->fname, sql_strerror(mdb));
857 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
860 ar->FilenameId = str_to_int64(row[0]);
862 sql_free_result(mdb);
863 return ar->FilenameId > 0;
865 sql_free_result(mdb);
868 Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
870 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
871 Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
872 mdb->cmd, sql_strerror(mdb));
873 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
876 ar->FilenameId = sql_insert_id(mdb, NT_("Filename"));
878 return ar->FilenameId > 0;
881 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */