Skip to content

Commit

Permalink
dird: cats: changes to reduce duplication
Browse files Browse the repository at this point in the history
pruning code uses the same function as the `list jobs`to select jobtypes.
Previous commit made them separate, but they still had common code,
so made sense to refactor all.
  • Loading branch information
alaaeddineelamri committed Apr 5, 2022
1 parent 0fe32d8 commit 2a7416d
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 79 deletions.
2 changes: 1 addition & 1 deletion core/src/cats/cats.h
Expand Up @@ -791,7 +791,7 @@ class BareosDb : public BareosDbQueryEnum {
const char* clientname,
int jobstatus,
int joblevel,
std::string jobtype,
std::vector<char> jobtypes,
const char* volumename,
const char* poolname,
utime_t since_time,
Expand Down
8 changes: 5 additions & 3 deletions core/src/cats/sql_list.cc
Expand Up @@ -32,6 +32,7 @@

# include "cats.h"
# include "lib/edit.h"
# include "lib/util.h"

/* -----------------------------------------------------------------------
*
Expand Down Expand Up @@ -508,7 +509,7 @@ void BareosDb::ListJobRecords(JobControlRecord* jcr,
const char* clientname,
int jobstatus,
int joblevel,
std::string jobtype,
std::vector<char> jobtypes,
const char* volumename,
const char* poolname,
utime_t since_time,
Expand Down Expand Up @@ -548,8 +549,9 @@ void BareosDb::ListJobRecords(JobControlRecord* jcr,
PmStrcat(selection, temp.c_str());
}

if (!jobtype.empty()) {
temp.bsprintf("AND Job.Type in (%s) ", jobtype.c_str());
if (!jobtypes.empty()) {
std::string types = CreateDelimitedStringForSqlQueries(jobtypes, ',');
temp.bsprintf("AND Job.Type in (%s) ", types.c_str());
PmStrcat(selection, temp.c_str());
}

Expand Down
6 changes: 4 additions & 2 deletions core/src/dird/autoprune.cc
Expand Up @@ -3,7 +3,7 @@
Copyright (C) 2002-2012 Free Software Foundation Europe e.V.
Copyright (C) 2011-2016 Planets Communications B.V.
Copyright (C) 2013-2019 Bareos GmbH & Co. KG
Copyright (C) 2013-2022 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -58,8 +58,10 @@ void DoAutoprune(JobControlRecord* jcr)
client = jcr->impl->res.client;
pool = jcr->impl->res.pool;

std::vector<char> jobtypes;
jobtypes.push_back(jcr->getJobType());
if (job->PruneJobs || client->AutoPrune) {
PruneJobs(ua, client, pool, jcr->getJobType());
PruneJobs(ua, client, pool, jobtypes);
pruned = true;
} else {
pruned = false;
Expand Down
10 changes: 5 additions & 5 deletions core/src/dird/ua_output.cc
Expand Up @@ -3,7 +3,7 @@
Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
Copyright (C) 2011-2016 Planets Communications B.V.
Copyright (C) 2013-2021 Bareos GmbH & Co. KG
Copyright (C) 2013-2022 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -691,8 +691,8 @@ static bool DoListCmd(UaContext* ua, const char* cmd, e_list_type llist)
}

// jobtype=X
std::string jobtype{};
if (!GetUserJobTypeListSelection(ua, jobtype, false)) {
std::vector<char> jobtypes{};
if (!GetUserJobTypeListSelection(ua, jobtypes, false)) {
ua->ErrorMsg(_("invalid jobtype parameter\n"));
return false;
}
Expand Down Expand Up @@ -756,7 +756,7 @@ static bool DoListCmd(UaContext* ua, const char* cmd, e_list_type llist)
SetQueryRange(query_range, ua, &jr);

ua->db->ListJobRecords(ua->jcr, &jr, query_range.c_str(), clientname,
jobstatus, joblevel, jobtype, volumename, poolname,
jobstatus, joblevel, jobtypes, volumename, poolname,
schedtime, optionslist.last, optionslist.count,
ua->send, llist);
} else if (Bstrcasecmp(ua->argk[1], NT_("jobtotals"))) {
Expand Down Expand Up @@ -807,7 +807,7 @@ static bool DoListCmd(UaContext* ua, const char* cmd, e_list_type llist)
SetQueryRange(query_range, ua, &jr);

ua->db->ListJobRecords(ua->jcr, &jr, query_range.c_str(), clientname,
jobstatus, joblevel, jobtype, volumename,
jobstatus, joblevel, jobtypes, volumename,
poolname, schedtime, optionslist.last,
optionslist.count, ua->send, llist);
}
Expand Down
19 changes: 8 additions & 11 deletions core/src/dird/ua_prune.cc
Expand Up @@ -3,7 +3,7 @@
Copyright (C) 2002-2009 Free Software Foundation Europe e.V.
Copyright (C) 2011-2016 Planets Communications B.V.
Copyright (C) 2013-2021 Bareos GmbH & Co. KG
Copyright (C) 2013-2022 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -199,8 +199,6 @@ bool PruneCmd(UaContext* ua, const char* cmd)

return true;
case 1: { /* prune jobs */
int jobtype = -1;

if (!(client = get_client_resource(ua))) { return false; }

if ((FindArgWithValue(ua, NT_("pool")) >= 0)
Expand All @@ -211,10 +209,11 @@ bool PruneCmd(UaContext* ua, const char* cmd)
}

// Ask what jobtype to prune.
if (!GetUserSingleJobTypeSelection(ua, jobtype, true)) { return false; }
std::vector<char> jobtype{};
if (!GetUserJobTypeListSelection(ua, jobtype, true)) { return false; }

// Verify that result jobtype is valid (this should always be the case).
if (jobtype < 0) { return false; }
if (jobtype.empty()) { return false; }

// Pool Job Retention takes precedence over client Job Retention
if (pool && pool->JobRetention > 0) {
Expand Down Expand Up @@ -830,14 +829,12 @@ static bool PruneBackupJobs(UaContext* ua,
bool PruneJobs(UaContext* ua,
ClientResource* client,
PoolResource* pool,
int JobType)
std::vector<char> JobTypes)
{
switch (JobType) {
case JT_BACKUP:
return PruneBackupJobs(ua, client, pool);
default:
return true;
for (const auto& type : JobTypes) {
if (type == JT_BACKUP) return PruneBackupJobs(ua, client, pool);
}
return true;
}

// Prune a given Volume
Expand Down
4 changes: 2 additions & 2 deletions core/src/dird/ua_prune.h
@@ -1,7 +1,7 @@
/*
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2018-2019 Bareos GmbH & Co. KG
Copyright (C) 2018-2022 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -32,7 +32,7 @@ bool PruneFiles(UaContext* ua, ClientResource* client, PoolResource* pool);
bool PruneJobs(UaContext* ua,
ClientResource* client,
PoolResource* pool,
int JobType);
std::vector<char> JobTypes);
bool PruneVolume(UaContext* ua, MediaDbRecord* mr);
int JobDeleteHandler(void* ctx, int num_fields, char** row);
int DelCountHandler(void* ctx, int num_fields, char** row);
Expand Down
58 changes: 12 additions & 46 deletions core/src/dird/ua_select.cc
Expand Up @@ -994,8 +994,8 @@ PoolResource* get_pool_resource(UaContext* ua)
// List all jobs and ask user to select one
int SelectJobDbr(UaContext* ua, JobDbRecord* jr)
{
ua->db->ListJobRecords(ua->jcr, jr, "", NULL, 0, 0, 0, NULL, NULL, 0, 0, 0,
ua->send, HORZ_LIST);
ua->db->ListJobRecords(ua->jcr, jr, "", NULL, 0, 0, std::vector<char>{}, NULL,
NULL, 0, 0, 0, ua->send, HORZ_LIST);
if (!GetPint(ua, _("Enter the JobId to select: "))) { return 0; }

jr->JobId = ua->int64_val;
Expand Down Expand Up @@ -1908,51 +1908,18 @@ static int GetParsedJobType(std::string jobtype_argument)
return return_jobtype;
}

bool GetUserSingleJobTypeSelection(UaContext* ua, int& jobtype, bool ask_user)
{
int i;
char jobtype_argument[MAX_NAME_LENGTH];

if ((i = FindArgWithValue(ua, NT_("jobtype"))) >= 0) {
bstrncpy(jobtype_argument, ua->argv[i], sizeof(jobtype_argument));
} else if (ask_user) {
StartPrompt(ua, _("Jobtype:\n"));
for (i = 0; jobtypes[i].type_name; i++) {
AddPrompt(ua, jobtypes[i].type_name);
}

if (DoPrompt(ua, _("JobType"), _("Select Job Type"), jobtype_argument,
sizeof(jobtype_argument))
< 0) {
return false;
}
} else {
return true;
}

int parsed_jobtype = GetParsedJobType(jobtype_argument);

if (parsed_jobtype == -1) {
ua->WarningMsg(_("Illegal jobtype %s.\n"), jobtype_argument);
return false;
}

jobtype = parsed_jobtype;
return true;
}

bool GetUserJobTypeListSelection(UaContext* ua,
std::string& jobtype,
std::vector<char>& passed_jobtypes,
bool ask_user)
{
int i;
char jobtype_argument[MAX_NAME_LENGTH];
int argument;

if ((i = FindArgWithValue(ua, NT_("jobtype"))) >= 0) {
bstrncpy(jobtype_argument, ua->argv[i], sizeof(jobtype_argument));
if ((argument = FindArgWithValue(ua, NT_("jobtype"))) >= 0) {
bstrncpy(jobtype_argument, ua->argv[argument], sizeof(jobtype_argument));
} else if (ask_user) {
StartPrompt(ua, _("Jobtype:\n"));
for (i = 0; jobtypes[i].type_name; i++) {
for (int i = 0; jobtypes[i].type_name; i++) {
AddPrompt(ua, jobtypes[i].type_name);
}

Expand All @@ -1967,22 +1934,21 @@ bool GetUserJobTypeListSelection(UaContext* ua,

char delimiter = ',';
std::vector<std::string> split_jobtypes;
if (strchr(jobtype_argument, delimiter) != NULL) {
if (strchr(jobtype_argument, delimiter) != nullptr) {
split_jobtypes = split_string(jobtype_argument, delimiter);
} else {
split_jobtypes.push_back(jobtype_argument);
}

for (auto& split_jobtype : split_jobtypes) {
int type = GetParsedJobType(split_jobtype);
for (auto& jobtype : split_jobtypes) {
int type = GetParsedJobType(jobtype);
if (type == -1) {
ua->WarningMsg(_("Illegal jobtype %s.\n"), split_jobtype.c_str());
ua->WarningMsg(_("Illegal jobtype %s\n"), jobtype.c_str());
return false;
}
split_jobtype = type;
passed_jobtypes.push_back(type);
}

jobtype = CreateDelimitedStringForSqlQueries(split_jobtypes, delimiter);
return true;
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/dird/ua_select.h
Expand Up @@ -89,8 +89,9 @@ bool GetUserSlotList(UaContext* ua,
char* slot_list,
const char* argument,
int num_slots);
bool GetUserSingleJobTypeSelection(UaContext* ua, int &jobtype, bool ask_user);
bool GetUserJobTypeListSelection(UaContext* ua, std::string &jobtype, bool ask_user);
bool GetUserJobTypeListSelection(UaContext* ua,
std::vector<char>& passed_jobtypes,
bool ask_user);
bool GetUserJobStatusSelection(UaContext* ua, int* jobstatus);
bool GetUserJobLevelSelection(UaContext* ua, int* joblevel);

Expand Down
18 changes: 13 additions & 5 deletions core/src/lib/util.cc
Expand Up @@ -1138,13 +1138,21 @@ std::vector<std::string> split_string(const std::string& str, char delim)
return parts;
}


std::string CreateDelimitedStringForSqlQueries(
const std::vector<std::string>& elements,
const std::vector<char>& elements,
char delim)
{
std::string empty_list{"''"};
std::string result{};
for (const auto& element : elements) { result += "'" + element + "',"; }
result.pop_back();
return result;
if (!elements.empty()) {
for (const auto& element : elements) {
result += "'";
result += element;
result += "'";
result += delim;
}
result.pop_back();
return result;
}
return empty_list;
}
5 changes: 4 additions & 1 deletion core/src/lib/util.h
Expand Up @@ -77,6 +77,9 @@ void StringToLowerCase(std::string& s);
void StringToLowerCase(std::string& out, const std::string& in);
bool pm_append(void* pm_string, const char* fmt, ...);
std::vector<std::string> split_string(const std::string& str, char delim);
std::string CreateDelimitedStringForSqlQueries(const std::vector<std::string>& elements, char delim);

std::string CreateDelimitedStringForSqlQueries(
const std::vector<char>& elements,
char delim);

#endif // BAREOS_LIB_UTIL_H_
30 changes: 29 additions & 1 deletion core/src/tests/lib_tests.cc
@@ -1,7 +1,7 @@
/**
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2018-2021 Bareos GmbH & Co. KG
Copyright (C) 2018-2022 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -307,3 +307,31 @@ TEST(Filedaemon, evaluate_jobcommand_wrong_format_test)
EXPECT_EQ(eval.protocol_version_,
filedaemon::JobCommand::ProtocolVersion::kVersionUndefinded);
}

TEST(StringManipulation,
DelimitedSting_PrintsEmptySingleElementWhenNoElementIsGiven)
{
std::vector<char> jobtypes{};

std::string result = CreateDelimitedStringForSqlQueries(jobtypes, ',');

EXPECT_STREQ(result.c_str(), "''");
}

TEST(StringManipulation, DelimitedSting_PrintsCorrectSingleCharacter)
{
std::vector<char> jobtypes{65};

std::string result = CreateDelimitedStringForSqlQueries(jobtypes, ',');

EXPECT_STREQ(result.c_str(), "'A'");
}

TEST(StringManipulation, DelimitedString_PrintsCorrectMultipleCharacters)
{
std::vector<char> jobtypes{65, 66, 67, 68, 69, 70};

std::string result = CreateDelimitedStringForSqlQueries(jobtypes, ',');

EXPECT_STREQ(result.c_str(), "'A','B','C','D','E','F'");
}

0 comments on commit 2a7416d

Please sign in to comment.