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,ClientId) "
87 "VALUES ('%s','%s','%c','%c','%c','%s',%s,%s)",
88 jr->Job, jr->Name, (char)(jr->JobType), (char)(jr->JobLevel),
89 (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1),
90 edit_int64(jr->ClientId, ed2));
92 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
93 Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
94 mdb->cmd, sql_strerror(mdb));
98 jr->JobId = sql_insert_id(mdb, NT_("Job"));
106 /* Create a JobMedia record for medium used this job
107 * Returns: false on failure
111 db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
115 char ed1[50], ed2[50];
119 /* Now get count for VolIndex */
120 Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
121 edit_int64(jm->JobId, ed1));
122 count = get_sql_record_max(jcr, mdb);
128 /* Note, jm->Strip is not used and is not likely to be used
129 * in the near future, so I have removed it from the insert
130 * to save space in the DB. KES June 2006.
133 "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
134 "StartFile,EndFile,StartBlock,EndBlock,VolIndex,Copy) "
135 "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u,%u)",
136 edit_int64(jm->JobId, ed1),
137 edit_int64(jm->MediaId, ed2),
138 jm->FirstIndex, jm->LastIndex,
139 jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count,
142 Dmsg0(300, mdb->cmd);
143 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
144 Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
148 /* Worked, now update the Media record with the EndFile and EndBlock */
150 "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
151 jm->EndFile, jm->EndBlock, jm->MediaId);
152 if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
153 Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
159 Dmsg0(300, "Return from JobMedia\n");
165 /* Create Unique Pool record
166 * Returns: false on failure
170 db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
173 char ed1[30], ed2[30], ed3[50];
175 Dmsg0(200, "In create pool\n");
177 Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", pr->Name);
178 Dmsg1(200, "selectpool: %s\n", mdb->cmd);
180 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
181 mdb->num_rows = sql_num_rows(mdb);
182 if (mdb->num_rows > 0) {
183 Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
184 sql_free_result(mdb);
188 sql_free_result(mdb);
193 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
194 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
195 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat) "
196 "VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s',%d,'%s')",
198 pr->NumVols, pr->MaxVols,
199 pr->UseOnce, pr->UseCatalog,
201 pr->AutoPrune, pr->Recycle,
202 edit_uint64(pr->VolRetention, ed1),
203 edit_uint64(pr->VolUseDuration, ed2),
204 pr->MaxVolJobs, pr->MaxVolFiles,
205 edit_uint64(pr->MaxVolBytes, ed3),
206 pr->PoolType, pr->LabelType, pr->LabelFormat);
207 Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
208 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
209 Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
210 mdb->cmd, sql_strerror(mdb));
214 pr->PoolId = sql_insert_id(mdb, NT_("Pool"));
222 * Create Unique Device record
223 * Returns: false on failure
227 db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
230 char ed1[30], ed2[30];
232 Dmsg0(200, "In create Device\n");
234 Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", dr->Name);
235 Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
237 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
238 mdb->num_rows = sql_num_rows(mdb);
239 if (mdb->num_rows > 0) {
240 Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
241 sql_free_result(mdb);
245 sql_free_result(mdb);
250 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
252 edit_uint64(dr->MediaTypeId, ed1),
253 edit_int64(dr->StorageId, ed2));
254 Dmsg1(200, "Create Device: %s\n", mdb->cmd);
255 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
256 Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
257 mdb->cmd, sql_strerror(mdb));
261 dr->DeviceId = sql_insert_id(mdb, NT_("Device"));
271 * Create a Unique record for Storage -- no duplicates
272 * Returns: false on failure
273 * true on success with id in sr->StorageId
275 bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
281 Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
285 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
286 mdb->num_rows = sql_num_rows(mdb);
287 /* If more than one, report error, but return first row */
288 if (mdb->num_rows > 1) {
289 Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), (int)(mdb->num_rows));
290 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
292 if (mdb->num_rows >= 1) {
293 if ((row = sql_fetch_row(mdb)) == NULL) {
294 Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
295 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
296 sql_free_result(mdb);
300 sr->StorageId = str_to_int64(row[0]);
301 sr->AutoChanger = atoi(row[1]); /* bool */
302 sql_free_result(mdb);
306 sql_free_result(mdb);
310 Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
311 " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
313 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
314 Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
315 mdb->cmd, sql_strerror(mdb));
316 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
319 sr->StorageId = sql_insert_id(mdb, NT_("Storage"));
329 * Create Unique MediaType record
330 * Returns: false on failure
334 db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
338 Dmsg0(200, "In create mediatype\n");
340 Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", mr->MediaType);
341 Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
343 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
344 mdb->num_rows = sql_num_rows(mdb);
345 if (mdb->num_rows > 0) {
346 Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
347 sql_free_result(mdb);
351 sql_free_result(mdb);
356 "INSERT INTO MediaType (MediaType,ReadOnly) "
360 Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
361 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
362 Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
363 mdb->cmd, sql_strerror(mdb));
367 mr->MediaTypeId = sql_insert_id(mdb, NT_("MediaType"));
376 * Create Media record. VolumeName and non-zero Slot must be unique
378 * Returns: 0 on failure
382 db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
385 char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
386 char ed9[50], ed10[50], ed11[50], ed12[50];
390 Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'",
392 Dmsg1(500, "selectpool: %s\n", mdb->cmd);
394 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
395 mdb->num_rows = sql_num_rows(mdb);
396 if (mdb->num_rows > 0) {
397 Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
398 sql_free_result(mdb);
402 sql_free_result(mdb);
407 "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
408 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
409 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
410 "EndFile,EndBlock,LabelType,StorageId,DeviceId,LocationId,"
411 "ScratchPoolId,RecyclePoolId,Enabled)"
412 "VALUES ('%s','%s',0,%u,%s,%s,%d,%s,%s,%u,%u,'%s',%d,%s,%d,%s,%s,%d,0,0,%d,%s,"
415 mr->MediaType, mr->PoolId,
416 edit_uint64(mr->MaxVolBytes,ed1),
417 edit_uint64(mr->VolCapacityBytes, ed2),
419 edit_uint64(mr->VolRetention, ed3),
420 edit_uint64(mr->VolUseDuration, ed4),
425 edit_uint64(mr->VolBytes, ed5),
427 edit_uint64(mr->VolReadTime, ed6),
428 edit_uint64(mr->VolWriteTime, ed7),
431 edit_int64(mr->StorageId, ed8),
432 edit_int64(mr->DeviceId, ed9),
433 edit_int64(mr->LocationId, ed10),
434 edit_int64(mr->ScratchPoolId, ed11),
435 edit_int64(mr->RecyclePoolId, ed12),
440 Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
441 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
442 Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
443 mdb->cmd, sql_strerror(mdb));
446 mr->MediaId = sql_insert_id(mdb, NT_("Media"));
448 if (mr->set_label_date) {
449 char dt[MAX_TIME_LENGTH];
450 if (mr->LabelDate == 0) {
451 mr->LabelDate = time(NULL);
453 (void)localtime_r(&mr->LabelDate, &tm);
454 strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
455 Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
456 "WHERE MediaId=%d", dt, mr->MediaId);
457 stat = UPDATE_DB(jcr, mdb, mdb->cmd);
462 * Make sure that if InChanger is non-zero any other identical slot
463 * has InChanger zero.
465 db_make_inchanger_unique(jcr, mdb, mr);
472 * Create a Unique record for the client -- no duplicates
473 * Returns: 0 on failure
474 * 1 on success with id in cr->ClientId
476 int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
480 char ed1[50], ed2[50];
483 Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'", cr->Name);
486 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
487 mdb->num_rows = sql_num_rows(mdb);
488 /* If more than one, report error, but return first row */
489 if (mdb->num_rows > 1) {
490 Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), (int)(mdb->num_rows));
491 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
493 if (mdb->num_rows >= 1) {
494 if ((row = sql_fetch_row(mdb)) == NULL) {
495 Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
496 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
497 sql_free_result(mdb);
501 cr->ClientId = str_to_int64(row[0]);
503 bstrncpy(cr->Uname, row[1], sizeof(cr->Uname));
505 cr->Uname[0] = 0; /* no name */
507 sql_free_result(mdb);
511 sql_free_result(mdb);
515 Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
516 "FileRetention,JobRetention) VALUES "
517 "('%s','%s',%d,%s,%s)", cr->Name, cr->Uname, cr->AutoPrune,
518 edit_uint64(cr->FileRetention, ed1),
519 edit_uint64(cr->JobRetention, ed2));
521 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
522 Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
523 mdb->cmd, sql_strerror(mdb));
524 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
528 cr->ClientId = sql_insert_id(mdb, NT_("Client"));
540 * Create a Unique record for the counter -- no duplicates
541 * Returns: 0 on failure
542 * 1 on success with counter filled in
544 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
550 memset(&mcr, 0, sizeof(mcr));
551 bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
552 if (db_get_counter_record(jcr, mdb, &mcr)) {
553 memcpy(cr, &mcr, sizeof(COUNTER_DBR));
559 Mmsg(mdb->cmd, "INSERT INTO Counters (Counter,MinValue,MaxValue,CurrentValue,"
560 "WrapCounter) VALUES ('%s','%d','%d','%d','%s')",
561 cr->Counter, cr->MinValue, cr->MaxValue, cr->CurrentValue,
564 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
565 Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
566 mdb->cmd, sql_strerror(mdb));
567 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
578 * Create a FileSet record. This record is unique in the
579 * name and the MD5 signature of the include/exclude sets.
580 * Returns: 0 on failure
581 * 1 on success with FileSetId in record
583 bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
590 fsr->created = false;
591 Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
592 "FileSet='%s' AND MD5='%s'", fsr->FileSet, fsr->MD5);
595 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
596 mdb->num_rows = sql_num_rows(mdb);
597 if (mdb->num_rows > 1) {
598 Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), (int)(mdb->num_rows));
599 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
601 if (mdb->num_rows >= 1) {
602 if ((row = sql_fetch_row(mdb)) == NULL) {
603 Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
604 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
605 sql_free_result(mdb);
609 fsr->FileSetId = str_to_int64(row[0]);
610 if (row[1] == NULL) {
611 fsr->cCreateTime[0] = 0;
613 bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
615 sql_free_result(mdb);
619 sql_free_result(mdb);
622 if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
623 fsr->CreateTime = time(NULL);
625 (void)localtime_r(&fsr->CreateTime, &tm);
626 strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %H:%M:%S", &tm);
629 Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
630 "VALUES ('%s','%s','%s')", fsr->FileSet, fsr->MD5, fsr->cCreateTime);
632 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
633 Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
634 mdb->cmd, sql_strerror(mdb));
635 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
639 fsr->FileSetId = sql_insert_id(mdb, NT_("FileSet"));
652 * dev_t st_dev; * device *
653 * ino_t st_ino; * inode *
654 * mode_t st_mode; * protection *
655 * nlink_t st_nlink; * number of hard links *
656 * uid_t st_uid; * user ID of owner *
657 * gid_t st_gid; * group ID of owner *
658 * dev_t st_rdev; * device type (if inode device) *
659 * off_t st_size; * total size, in bytes *
660 * unsigned long st_blksize; * blocksize for filesystem I/O *
661 * unsigned long st_blocks; * number of blocks allocated *
662 * time_t st_atime; * time of last access *
663 * time_t st_mtime; * time of last modification *
664 * time_t st_ctime; * time of last inode change *
671 * Create File record in B_DB
673 * In order to reduce database size, we store the File attributes,
674 * the FileName, and the Path separately. In principle, there
675 * is a single FileName record and a single Path record, no matter
676 * how many times it occurs. This is this subroutine, we separate
677 * the file and the path and create three database records.
679 int db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
683 Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
684 Dmsg0(dbglevel, "put_file_into_catalog\n");
686 * Make sure we have an acceptable attributes record.
688 if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
689 ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
690 Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
692 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
697 split_path_and_file(jcr, mdb, ar->fname);
699 if (!db_create_filename_record(jcr, mdb, ar)) {
702 Dmsg1(dbglevel, "db_create_filename_record: %s\n", mdb->esc_name);
705 if (!db_create_path_record(jcr, mdb, ar)) {
708 Dmsg1(dbglevel, "db_create_path_record: %s\n", mdb->esc_name);
710 /* Now create master File record */
711 if (!db_create_file_record(jcr, mdb, ar)) {
714 Dmsg0(dbglevel, "db_create_file_record OK\n");
716 Dmsg3(dbglevel, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
726 * This is the master File entry containing the attributes.
727 * The filename and path records have already been created.
729 static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
732 static char *no_digest = "0";
737 ASSERT(ar->FilenameId);
739 if (ar->Digest == NULL || ar->Digest[0] == 0) {
747 "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
748 "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
749 ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
752 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
753 Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
754 mdb->cmd, sql_strerror(mdb));
755 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
759 ar->FileId = sql_insert_id(mdb, NT_("File"));
765 /* Create a Unique record for the Path -- no duplicates */
766 static int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
771 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
772 db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
774 if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
775 strcmp(mdb->cached_path, mdb->path) == 0) {
776 ar->PathId = mdb->cached_path_id;
780 Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
782 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
783 mdb->num_rows = sql_num_rows(mdb);
784 if (mdb->num_rows > 1) {
786 Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
787 edit_uint64(mdb->num_rows, ed1), mdb->path);
788 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
790 /* Even if there are multiple paths, take the first one */
791 if (mdb->num_rows >= 1) {
792 if ((row = sql_fetch_row(mdb)) == NULL) {
793 Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
794 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
795 sql_free_result(mdb);
800 ar->PathId = str_to_int64(row[0]);
801 sql_free_result(mdb);
803 if (ar->PathId != mdb->cached_path_id) {
804 mdb->cached_path_id = ar->PathId;
805 mdb->cached_path_len = mdb->pnl;
806 pm_strcpy(mdb->cached_path, mdb->path);
811 sql_free_result(mdb);
814 Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
816 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
817 Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
818 mdb->cmd, sql_strerror(mdb));
819 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
823 ar->PathId = sql_insert_id(mdb, NT_("Path"));
828 if (stat && ar->PathId != mdb->cached_path_id) {
829 mdb->cached_path_id = ar->PathId;
830 mdb->cached_path_len = mdb->pnl;
831 pm_strcpy(mdb->cached_path, mdb->path);
836 /* Create a Unique record for the filename -- no duplicates */
837 static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
841 mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
842 db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
844 Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
846 if (QUERY_DB(jcr, mdb, mdb->cmd)) {
847 mdb->num_rows = sql_num_rows(mdb);
848 if (mdb->num_rows > 1) {
850 Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
851 edit_uint64(mdb->num_rows, ed1), mdb->fname);
852 Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
854 if (mdb->num_rows >= 1) {
855 if ((row = sql_fetch_row(mdb)) == NULL) {
856 Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
857 mdb->fname, sql_strerror(mdb));
858 Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
861 ar->FilenameId = str_to_int64(row[0]);
863 sql_free_result(mdb);
864 return ar->FilenameId > 0;
866 sql_free_result(mdb);
869 Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
871 if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
872 Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
873 mdb->cmd, sql_strerror(mdb));
874 Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
877 ar->FilenameId = sql_insert_id(mdb, NT_("Filename"));
879 return ar->FilenameId > 0;
882 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL */