jcr = j;
jcr->inc_use_count();
db = mdb; /* need to inc ref count */
+ jobids = get_pool_memory(PM_NAME);
prev_dir = get_pool_memory(PM_NAME);
pattern = get_pool_memory(PM_NAME);
- *prev_dir = *pattern = 0;
+ *jobids = *prev_dir = *pattern = 0;
dir_filenameid = pwd_id = offset = 0;
see_copies = see_all_version = false;
limit = 1000;
}
Bvfs::~Bvfs() {
+ free_pool_memory(jobids);
free_pool_memory(pattern);
free_pool_memory(prev_dir);
free_attr(attr);
void bvfs_update_cache(JCR *jcr, B_DB *mdb)
{
uint32_t nb=0;
- db_list_ctx jobids;
+ db_list_ctx jobids_list;
db_lock(mdb);
db_start_transaction(jcr, mdb);
"AND Type IN ('B') AND JobStatus IN ('T', 'f', 'A') "
"ORDER BY JobId");
- db_sql_query(mdb, mdb->cmd, db_list_handler, &jobids);
+ db_sql_query(mdb, mdb->cmd, db_list_handler, &jobids_list);
- bvfs_update_path_hierarchy_cache(jcr, mdb, &jobids);
+ bvfs_update_path_hierarchy_cache(jcr, mdb, jobids_list.list);
db_end_transaction(jcr, mdb);
db_start_transaction(jcr, mdb);
* Update the bvfs cache for given jobids (1,2,3,4)
*/
void
-bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, db_list_ctx *jobids)
+bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, char *jobids)
{
pathid_cache ppathid_cache;
JobId_t JobId;
char *p;
- for (p=jobids->list; ; ) {
+ for (p=jobids; ; ) {
int stat = get_next_jobid_from_list(&p, &JobId);
- Dmsg1(dbglevel, "Updating cache for %lld\n", (uint64_t)JobId);
if (stat < 0) {
return;
}
*/
void Bvfs::update_cache()
{
- bvfs_update_path_hierarchy_cache(jcr, db, &jobids);
+ bvfs_update_path_hierarchy_cache(jcr, db, jobids);
}
/* Change the current directory, returns true if the path exists */
POOL_MEM query;
- Mmsg(query,//0 1 2 3
-"SELECT File.FileId, File.Md5, File.JobId, File.LStat, "
-// 4 5
+ Mmsg(query,// 1 2 3 4
+"SELECT 'V', File.FileId, File.Md5, File.JobId, File.LStat, "
+// 5 6
"Media.VolumeName, Media.InChanger "
"FROM File, Job, Client, JobMedia, Media "
"WHERE File.FilenameId = %s "
int Bvfs::_handle_path(void *ctx, int fields, char **row)
{
- if (fields == BVFS_DIR_RECORD) {
+ if (bvfs_is_dir(row)) {
/* can have the same path 2 times */
if (strcmp(row[BVFS_Name], prev_dir)) {
pm_strcpy(prev_dir, row[BVFS_Name]);
{
Dmsg1(dbglevel, "ls_special_dirs(%lld)\n", (uint64_t)pwd_id);
char ed1[50], ed2[50];
- if (jobids.count == 0) {
+ if (*jobids == 0) {
return;
}
if (!dir_filenameid) {
edit_uint64(pwd_id, ed1), ed1);
POOL_MEM query2;
- Mmsg(query2,
-"SELECT tmp.PathId, tmp.Path, JobId, LStat "
+ Mmsg(query2,// 1 2 3 4 5 6
+"SELECT 'D', tmp.PathId, 0, tmp.Path, JobId, LStat, FileId "
"FROM %s AS tmp LEFT JOIN ( " // get attributes if any
"SELECT File1.PathId AS PathId, File1.JobId AS JobId, "
- "File1.LStat AS LStat FROM File AS File1 "
+ "File1.LStat AS LStat, File1.FileId AS FileId FROM File AS File1 "
"WHERE File1.FilenameId = %s "
"AND File1.JobId IN (%s)) AS listfile1 "
"ON (tmp.PathId = listfile1.PathId) "
"ORDER BY tmp.Path, JobId DESC ",
- query.c_str(), edit_uint64(dir_filenameid, ed2), jobids.list);
+ query.c_str(), edit_uint64(dir_filenameid, ed2), jobids);
Dmsg1(dbglevel_sql, "q=%s\n", query2.c_str());
db_sql_query(db, query2.c_str(), path_handler, this);
{
Dmsg1(dbglevel, "ls_dirs(%lld)\n", (uint64_t)pwd_id);
char ed1[50], ed2[50];
- if (jobids.count == 0) {
+ if (*jobids == 0) {
return false;
}
/* Then we get all the dir entries from File ... */
POOL_MEM query;
Mmsg(query,
-// 0 1 2 3
-"SELECT PathId, Path, JobId, LStat FROM ( "
+// 0 1 2 3 4 5 6
+"SELECT 'D', PathId, 0, Path, JobId, LStat, FileId FROM ( "
"SELECT Path1.PathId AS PathId, Path1.Path AS Path, "
"lower(Path1.Path) AS lpath, "
- "listfile1.JobId AS JobId, listfile1.LStat AS LStat "
+ "listfile1.JobId AS JobId, listfile1.LStat AS LStat, "
+ "listfile1.FileId AS FileId "
"FROM ( "
"SELECT DISTINCT brestore_pathhierarchy1.PathId AS PathId "
"FROM brestore_pathhierarchy AS brestore_pathhierarchy1 "
"LEFT JOIN ( " /* get attributes if any */
"SELECT File1.PathId AS PathId, File1.JobId AS JobId, "
- "File1.LStat AS LStat FROM File AS File1 "
+ "File1.LStat AS LStat, File1.FileId AS FileId FROM File AS File1 "
"WHERE File1.FilenameId = %s "
"AND File1.JobId IN (%s)) AS listfile1 "
"ON (listpath1.PathId = listfile1.PathId) "
") AS A ORDER BY 2,3 DESC LIMIT %d OFFSET %d",
edit_uint64(pwd_id, ed1),
- jobids.list,
+ jobids,
filter.c_str(),
edit_uint64(dir_filenameid, ed2),
- jobids.list,
+ jobids,
limit, offset);
Dmsg1(dbglevel_sql, "q=%s\n", query.c_str());
{
Dmsg1(dbglevel, "ls_files(%lld)\n", (uint64_t)pwd_id);
char ed1[50];
- if (jobids.count == 0) {
+ if (*jobids == 0) {
return false;
}
}
POOL_MEM query;
- Mmsg(query, // 0 1 2 3 4
-"SELECT File.FilenameId, listfiles.Name, File.JobId, File.LStat, listfiles.id "
+ Mmsg(query, // 1 2 3 4
+"SELECT 'F', File.PathId, File.FilenameId, listfiles.Name, File.JobId, "
+ "File.LStat, listfiles.id "
"FROM File, ( "
"SELECT Filename.Name as Name, max(File.FileId) as id "
"FROM File, Filename "
") AS listfiles "
"WHERE File.FileId = listfiles.id",
edit_uint64(pwd_id, ed1),
- jobids.list,
+ jobids,
filter.c_str(),
limit,
offset);
/* Helper for result handler */
typedef enum {
- BVFS_FILE_RECORD = 5,
- BVFS_DIR_RECORD = 4,
- BVFS_FILE_VERSION = 6
+ BVFS_FILE_RECORD = 'F',
+ BVFS_DIR_RECORD = 'D',
+ BVFS_FILE_VERSION = 'V'
} bvfs_handler_type;
typedef enum {
- BVFS_Id = 0, /* Could be PathId or FilenameId */
- BVFS_Name = 1,
- BVFS_JobId = 2,
- BVFS_LStat = 3,
+ BVFS_Type = 0, /* Could be D, F, V */
+ BVFS_PathId = 1,
+ BVFS_FilenameId = 2,
- /* Only if File record */
- BVFS_FileId = 4,
+ BVFS_Name = 3,
+ BVFS_JobId = 4,
+
+ BVFS_LStat = 5, /* Can be empty for missing directories */
+ BVFS_FileId = 6, /* Can be empty for missing directories */
/* Only if File Version record */
- BVFS_Md5 = 1,
+ BVFS_Md5 = 3,
BVFS_VolName = 4,
BVFS_VolInchanger = 5
} bvfs_row_index;
virtual ~Bvfs();
void set_jobid(JobId_t id) {
- Mmsg(jobids.list, "%lld", (uint64_t)id);
+ Mmsg(jobids, "%lld", (uint64_t)id);
}
void set_jobids(char *ids) {
- pm_strcpy(jobids.list, ids);
+ pm_strcpy(jobids, ids);
}
void set_limit(uint32_t max) {
JCR *jcr;
B_DB *db;
- db_list_ctx jobids;
+ POOLMEM *jobids;
uint32_t limit;
uint32_t offset;
uint32_t nb_record; /* number of records of the last query */
void *user_data;
};
-void bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, db_list_ctx *jobids);
+#define bvfs_is_dir(row) ((row)[BVFS_Type][0] == BVFS_DIR_RECORD)
+#define bvfs_is_file(row) ((row)[BVFS_Type][0] == BVFS_FILE_RECORD)
+
+void bvfs_update_path_hierarchy_cache(JCR *jcr, B_DB *mdb, char *jobids);
void bvfs_update_cache(JCR *jcr, B_DB *mdb);
char *bvfs_parent_dir(char *path);
int pos = find_arg_with_value(ua, "jobid");
if (pos != -1 && is_a_number_list(ua->argv[pos])) {
- db_list_ctx jobids;
- pm_strcpy(jobids.list, ua->argv[pos]);
- bvfs_update_path_hierarchy_cache(ua->jcr, ua->db, &jobids);
+ POOL_MEM jobids;
+ pm_strcpy(jobids, ua->argv[pos]);
+ bvfs_update_path_hierarchy_cache(ua->jcr, ua->db, jobids.c_str());
} else {
/* update cache for all jobids */
bvfs_update_cache(ua->jcr, ua->db);
UAContext *ua = (UAContext *)ctx;
struct stat statp;
int32_t LinkFI;
+ const char *fileid;
+ char *lstat;
char empty[] = "A A A A A A A A A A A A A A";
+ lstat = (row[BVFS_LStat] && row[BVFS_LStat][0])?row[BVFS_LStat]:empty;
+ fileid = (row[BVFS_FileId] && row[BVFS_FileId][0])?row[BVFS_FileId]:"0";
+
memset(&statp, 0, sizeof(struct stat));
- decode_stat((row[BVFS_LStat] && row[BVFS_LStat][0])?row[BVFS_LStat]:empty,
- &statp, &LinkFI);
+ decode_stat(lstat, &statp, &LinkFI);
- if (fields == BVFS_DIR_RECORD) {
+ Dmsg1(0, "type=%s\n", row[0]);
+ if (bvfs_is_dir(row)) {
char *path = bvfs_basename_dir(row[BVFS_Name]);
- ua->send_msg("%s\t%s\t\%s\n", row[BVFS_Id], row[BVFS_JobId], path);
- } else if (fields == BVFS_FILE_RECORD) {
- ua->send_msg("%s\t%s\t\%s\n", row[BVFS_Id], row[BVFS_JobId], row[BVFS_Name]);
+ ua->send_msg("%s\t0\t%s\t%s\t%s\t%s\n", row[BVFS_PathId], fileid,
+ row[BVFS_JobId], row[BVFS_LStat], path);
+
+ } else if (bvfs_is_file(row)) {
+ ua->send_msg("%s\t%s\t%s\t%s\t%s\t%s\n", row[BVFS_PathId],
+ row[BVFS_FilenameId], fileid, row[BVFS_JobId],
+ row[BVFS_LStat], row[BVFS_Name]);
}
return 0;
}
}
- if (!((pathid || path) && jobid)) {
+ if (!((*pathid || *path) && *jobid)) {
return false;
}