int DigestType;
};
+struct ROBJECT_DBR {
+ char *full_fname;
+ char *fname;
+ char *path;
+ char *plugin_name;
+ char *object;
+ uint32_t object_len;
+ uint32_t ObjectIndex;
+ uint32_t FileIndex;
+ uint32_t Stream;
+ uint32_t FileType;
+ JobId_t JobId;
+ DBId_t RestoreObjectId;
+};
+
/* File record -- same format as database */
struct FILE_DBR {
INDEX (JobId, PathId, FilenameId)
);
+CREATE TABLE RestoreObject (
+ RestoreObjectId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT;
+ Fname BLOB NOT NULL,
+ Path BLOB NOT NULL,
+ RestoreObject BLOB NOT NULL,
+ PluginName TINYBLOB NOT NULL,
+ ObjectIndex INTEGER DEFAULT 0,
+ ObjectType INTEGER DEFAULT 0,
+ FileIndex INTEGER UNSIGNED DEFAULT 0,
+ JobId INTEGER UNSIGNED NOT NULL REFERENCES Job,
+ PRIMARY KEY(RestoreObjectId),
+ INDEX (JobId)
+ );
+
+
#
# Possibly add one or more of the following indexes
# to the above File table if your Verifies are
'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL,
Enabled TINYINT DEFAULT 1,
Recycle TINYINT DEFAULT 0,
- ActionOnPurge TINYINT DEFAULT 0,
+ ActionOnPurge TINYINT DEFAULT 0,
VolRetention BIGINT UNSIGNED DEFAULT 0,
VolUseDuration BIGINT UNSIGNED DEFAULT 0,
MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
AutoPrune TINYINT DEFAULT 0,
Recycle TINYINT DEFAULT 0,
- ActionOnPurge TINYINT DEFAULT 0,
+ ActionOnPurge TINYINT DEFAULT 0,
PoolType ENUM('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch') NOT NULL,
LabelType TINYINT DEFAULT 0,
LabelFormat TINYBLOB,
);
CREATE INDEX pathhierarchy_ppathid
- ON PathHierarchy (PPathId);
+ ON PathHierarchy (PPathId);
CREATE TABLE PathVisibility
(
CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId)
);
CREATE INDEX pathvisibility_jobid
- ON PathVisibility (JobId);
+ ON PathVisibility (JobId);
CREATE TABLE Version (
VersionId INTEGER UNSIGNED NOT NULL
bool my_batch_end(JCR *jcr, B_DB *mdb, const char *error);
bool my_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
bool db_create_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
+bool db_create_restore_object_record(JCR *jcr, B_DB *mdb, ROBJECT_DBR *ar);
bool db_create_base_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
bool db_commit_base_file_attributes_record(JCR *jcr, B_DB *mdb);
bool db_create_base_file_list(JCR *jcr, B_DB *mdb, char *jobids);
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
*
* Kern Sibbald, March 2000
*
- * Version $Id: sql_create.c 8407 2009-01-28 10:47:21Z ricozz $
*/
/* The following is necessary so that we do not include
return ret;
}
+
+/*
+ * Create Restore Object record in B_DB
+ *
+ */
+bool db_create_restore_object_record(JCR *jcr, B_DB *mdb, ROBJECT_DBR *ro)
+{
+ bool stat;
+ POOLMEM *esc_obj = get_pool_memory(PM_MESSAGE);
+ db_lock(mdb);
+
+ Dmsg1(dbglevel, "Fname=%s\n", ro->fname);
+ Dmsg0(dbglevel, "put_object_into_catalog\n");
+
+ split_path_and_file(jcr, mdb, ro->fname);
+
+ mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1);
+ db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl);
+
+ mdb->esc_path = check_pool_memory_size(mdb->esc_path, mdb->pnl*2+1);
+ db_escape_string(jcr, mdb, mdb->esc_path, mdb->path, mdb->pnl);
+
+ esc_obj = check_pool_memory_size(esc_obj, ro->object_len*2+1);
+ db_escape_string(jcr, mdb, esc_obj, ro->object, ro->object_len);
+
+ Mmsg(mdb->cmd,
+ "INSERT INTO RestoreObject (Fname,Path,PluginName,RestoreObject"
+ "ObjectIndex,ObjectType,FileIndex,JobId) VALUES"
+ "('%s','%s','%s','%s',%d,%d,%d,%u)",
+ ro->fname, ro->path, ro->plugin_name, esc_obj, ro->object_len,
+ ro->ObjectIndex, FT_RESTORE_FIRST, ro->FileIndex, ro->JobId);
+
+ ro->RestoreObjectId = sql_insert_id(mdb, mdb->cmd, NT_("RestoreObject"));
+ if (ro->RestoreObjectId == 0) {
+ Mmsg2(&mdb->errmsg, _("Create db Object record %s failed. ERR=%s"),
+ mdb->cmd, sql_strerror(mdb));
+ Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+ stat = false;
+ } else {
+ stat = true;
+ }
+ db_unlock(mdb);
+ free_pool_memory(esc_obj);
+ return stat;
+}
+
+
#endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */
if (!db_create_attributes_record(jcr, jcr->db, ar)) {
Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db));
}
+ jcr->cached_attribute = false;
}
/* Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */
jcr->attr = check_pool_memory_size(jcr->attr, msglen);
} else {
ar->JobId = jcr->JobId;
}
- ar->Digest = NULL;
- ar->DigestType = CRYPTO_DIGEST_NONE;
- jcr->cached_attribute = true;
+ /*
+ * Restore object */
+ if (ar->FileType == FT_RESTORE_FIRST) {
+ ROBJECT_DBR ro;
+ POOLMEM *attrEx = get_pool_memory(PM_MESSAGE);
+ char *p;
+ ro.full_fname = fname;
+ ro.Stream = Stream;
+ ro.FileType = ar->FileType;
+ ro.FileIndex = FileIndex;
+ ro.JobId = ar->JobId;
+ p = ar->attr; /* point to attributes */
+ while (*p++ != 0) /* skip attributes */
+ { }
+ while (*p++ != 0) /* skip link */
+ { }
+ /* We have an object, so do a binary copy */
+ ro.object_len = msglen + ar->attr - p;
+ attrEx = check_pool_memory_size(attrEx, ro.object_len + 1);
+ memcpy(attrEx, p, ro.object_len);
+ ro.object = attrEx;
+ /* Add a EOS for those who attempt to print the object */
+ p = attrEx + ro.object_len;
+ *p = 0;
+ /* Send it */
+ if (!db_create_restore_object_record(jcr, jcr->db, &ro)) {
+ Jmsg1(jcr, M_FATAL, 0, _("Restore object create error. %s"), db_strerror(jcr->db));
+ }
+ free_pool_memory(attrEx);
+ } else {
+ ar->Digest = NULL;
+ ar->DigestType = CRYPTO_DIGEST_NONE;
+ jcr->cached_attribute = true;
+ }
Dmsg2(400, "dird<filed: stream=%d %s\n", Stream, fname);
Dmsg1(400, "dird<filed: attr=%s\n", attr);