impl paratemers to requests, impl support of task modifications

This commit is contained in:
Evgenii Alekseev 2018-03-26 00:13:20 +03:00
parent 9f57f9db88
commit 57fdb62a5c
41 changed files with 214 additions and 194 deletions

View File

@ -86,7 +86,7 @@ static const QHash<int, QByteArray> HTTPCodeMap = {{100, "Continue"},
QVariantHash getData(const Request &_request, const QVariantHash &_data, const QString &_token);
Request parsePath(const QString &_path);
RequestPath pathToEnum(const QString &_path);
};
}; // namespace QueuedTcpServerResponseHelper
#endif /* QUEUEDTCPSERVERRESPONSEHELPER_H */

View File

@ -27,7 +27,7 @@ namespace QueuedTcpServerResponseHelperApi1
QVariantHash getData(const QueuedTcpServerResponseHelper::RequestPath _request, const QString &_arg,
const QString &_type, const QVariantHash &_data, const QString &_token);
QVariantHash getStatus();
};
}; // namespace QueuedTcpServerResponseHelperApi1
#endif /* QUEUEDTCPSERVERRESPONSEHELPERAPI1_H */

View File

@ -24,7 +24,7 @@ namespace QueuedTcpServerResponseHelperAuth
{
QVariantHash auth(const QVariantHash &_payload);
bool tryAuth(const QString &_token);
};
}; // namespace QueuedTcpServerResponseHelperAuth
#endif /* QUEUEDTCPSERVERRESPONSEHELPERAUTH_H */

View File

@ -24,7 +24,7 @@ namespace QueuedTcpServerResponseHelperOption
{
QVariantHash getOption(const QString &_option, const QString &_token);
QVariantHash setOption(const QString &_option, const QVariantHash &_value, const QString &_token);
};
}; // namespace QueuedTcpServerResponseHelperOption
#endif /* QUEUEDTCPSERVERRESPONSEHELPEROPTION_H */

View File

@ -25,7 +25,7 @@ namespace QueuedTcpServerResponseHelperPermissions
QVariantHash addPermission(const long long _id, const QVariantHash &_value, const QString &_token);
QVariantHash removePermission(const long long _id, const QVariantHash &_value,
const QString &_token);
};
}; // namespace QueuedTcpServerResponseHelperPermissions
#endif /* QUEUEDTCPSERVERRESPONSEHELPERPERMISSIONS_H */

View File

@ -26,7 +26,7 @@ QVariantHash addPlugin(const QString &_name, const QString &_token);
QVariantHash getPlugin(const QString &_name, const QString &_token);
QVariantHash listPlugins();
QVariantHash removePlugin(const QString &_name, const QString &_token);
};
}; // namespace QueuedTcpServerResponseHelperPlugins
#endif /* QUEUEDTCPSERVERRESPONSEHELPLUGINS_H */

View File

@ -100,7 +100,7 @@ QVariantHash QueuedTcpServerResponseHelperTask::getTask(const long long _id,
output = {{"code", 500}, {"message", err.message().c_str()}};
});
} else {
auto res = QueuedCoreAdaptor::getTask(_id, property);
auto res = QueuedCoreAdaptor::getTask(_id, property, _token);
res.match(
[&output, &property](const QVariant &val) {
output["properties"] = {{property, val}};

View File

@ -31,7 +31,7 @@ QVariantHash getTasks(const QVariantHash &_data, const QString &_token);
QVariantHash startOrStopTask(const long long _id, const QString &_token);
QVariantHash startTask(const long long _id, const QString &_token);
QVariantHash stopTask(const long long _id, const QString &_token);
};
}; // namespace QueuedTcpServerResponseHelperTask
#endif /* QUEUEDTCPSERVERRESPONSEHELTASK_H */

View File

@ -134,7 +134,7 @@ QVariantHash QueuedTcpServerResponseHelperUser::getUser(const QString &_user,
output = {{"code", 500}, {"message", err.message().c_str()}};
});
} else {
auto res = QueuedCoreAdaptor::getUser(userId, property);
auto res = QueuedCoreAdaptor::getUser(userId, property, _token);
res.match(
[&output, &property](const QVariant &val) {
output["properties"] = {{property, val}};

View File

@ -29,7 +29,7 @@ QueuedUser::QueuedUserDefinitions getDefinitions(const QVariantHash &_data);
QVariantHash getReport(const QVariantHash &_data, const QString &_token);
QVariantHash getUser(const QString &_user, const QVariantHash &_data, const QString &_token);
QVariantHash getUsers(const QVariantHash &_data, const QString &_token);
};
}; // namespace QueuedTcpServerResponseHelperUser
#endif /* QUEUEDTCPSERVERRESPONSEHELUSER_H */

View File

@ -119,7 +119,7 @@ static const char CG_FS_PATH[] = "/sys/fs/cgroup";
* @brief plugin interface name
*/
static const char PLUGIN_INTERFACE[] = PLUGIN_INTERFACE_NAME;
}
} // namespace QueuedConfig
#endif /* QUEUEDCONFIG_H */

View File

@ -381,7 +381,7 @@ QueuedResult<T> sendRequest(const QString &_service, const QString &_path,
return QueuedError(dbusResponse.error().message().toStdString());
}
};
}
} // namespace QueuedCoreAdaptor
#endif /* QUEUEDCOREADAPTOR_H */

View File

@ -27,6 +27,7 @@
#include <QHash>
#include <QObject>
#include <QSqlDatabase>
#include <QVariant>
/**
@ -38,22 +39,6 @@ class QueuedDatabase : public QObject
Q_PROPERTY(QString path READ path)
public:
/**
* @struct QueuedDatabaseCondition
* @brief structure to define database condition payload
* @var key
* payload key
* @var value
* payload value
* @var operation
* comparison operation
*/
struct QueuedDatabaseCondition {
QString key;
QVariant value;
QString operation;
};
/**
* @brief QueuedDatabase class constructor
* @param parent
@ -102,10 +87,12 @@ public:
* table name
* @param _condition
* optional condition string
* @param _params
* optional condition parameters
* @return list of records from table
*/
QList<QVariantHash> get(const QString &_table, const QList<QueuedDatabaseCondition> &_condition
= QList<QueuedDatabaseCondition>());
QList<QVariantHash> get(const QString &_table, const QString &_condition = "",
const QVariantHash &_params = QVariantHash());
/**
* @brief get record from table with given id
* @param _table
@ -198,13 +185,6 @@ private:
* @return list of columns in table
*/
QStringList getColumnsInRecord(const QSqlRecord &_record) const;
/**
* @brief parse condition map to sql query
* @param _condition
* condition map
* @return sql query string part
*/
QString getCondition(const QList<QueuedDatabaseCondition> &_condition) const;
/**
* @brief last insertion ID
* @param _table

View File

@ -38,6 +38,10 @@ namespace QueuedDB
* @brief settings table name
*/
static const char SETTINGS_TABLE[] = "settings";
/**
* @brief tasks modifications table name
*/
static const char TASKS_MODS_TABLE[] = "tasks_modifications";
/**
* @brief tasks table name
*/
@ -78,11 +82,17 @@ typedef QHash<QString, QHash<QString, QueuedDBField>> QueuedDBSchema;
*/
static const QueuedDBSchema DBSchema
= {{SETTINGS_TABLE,
{{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{{"_id", {"_id", "INT PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{"key", {"key", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}},
{"value", {"value", "TEXT", QVariant::String, true}}}},
{TASKS_MODS_TABLE,
{{"_id", {"_id", "INT PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{"task", {"task", "INT NOT NULL DEFAULT 0", QVariant::LongLong, true}},
{"time", {"time", "TEXT", QVariant::String, true}},
{"user", {"user", "INT NOT NULL DEFAULT 0", QVariant::LongLong, true}},
{"value", {"value", "TEXT", QVariant::String, true}}}},
{TASKS_TABLE,
{{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{{"_id", {"_id", "INT PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{"user", {"user", "INT NOT NULL DEFAULT 0", QVariant::LongLong, true}},
{"command", {"command", "TEXT", QVariant::String, false}},
{"commandArguments", {"commandArguments", "TEXT", QVariant::String, false}},
@ -91,15 +101,15 @@ static const QueuedDBSchema DBSchema
{"uid", {"uid", "INT", QVariant::UInt, true}},
{"gid", {"gid", "INT", QVariant::UInt, true}},
{"limits", {"limits", "TEXT", QVariant::String, false}},
{"startTime", {"startTime", "INT", QVariant::LongLong, true}},
{"endTime", {"endTime", "INT", QVariant::LongLong, true}}}},
{"startTime", {"startTime", "TEXT", QVariant::String, true}},
{"endTime", {"endTime", "TEXT", QVariant::String, true}}}},
{TOKENS_TABLE,
{{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{{"_id", {"_id", "INT PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{"token", {"token", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}},
{"user", {"user", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}},
{"validUntil", {"validUntil", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}}}},
{USERS_TABLE,
{{"_id", {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{{"_id", {"_id", "INT PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, true}},
{"name", {"name", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}},
{"password", {"password", "TEXT", QVariant::String, false}},
{"email", {"email", "TEXT", QVariant::String, false}},
@ -107,6 +117,6 @@ static const QueuedDBSchema DBSchema
{"limits", {"limits", "TEXT", QVariant::String, true}},
{"permissions", {"permissions", "INT", QVariant::UInt, true}},
{"priotiry", {"priority", "INT", QVariant::UInt, true}}}}};
};
}; // namespace QueuedDB
#endif /* QUEUEDDATABASESCHEMA_H */

View File

@ -83,7 +83,7 @@ QStringList getBuildData();
* @brief additional method to get build details declared in version.h
*/
QHash<QString, QHash<QString, QString>> getBuildMetaData();
}
} // namespace QueuedDebug
#endif /* QUEUEDDEBUG_H */

View File

@ -100,7 +100,7 @@ enum class ReturnStatus {
InvalidToken = 1 << 4,
InvalidPassword = 1 << 5
};
};
}; // namespace QueuedEnums
#endif /* QUEUEDENUMS_H */

View File

@ -164,7 +164,7 @@ bool limitCompare(const long long _first, const long long _second);
* @return minimal limits from given
*/
Limits minimalLimits(const Limits &_task, const Limits &_user, const Limits &_default);
};
}; // namespace QueuedLimits
#endif /* QUEUEDLIMITS_H */

View File

@ -175,7 +175,7 @@ Plugin readSpecification(const QString &_path);
* @return initialized object
*/
Plugin readSpecification(const QVariantHash &_map);
};
}; // namespace QueuedPluginSpecification
#endif /* QUEUEDPLUGINSPECIFICATION_H */

View File

@ -26,6 +26,7 @@
#include <QDateTime>
#include <QProcess>
#include <QVariant>
class QueuedControlGroupsAdaptor;
@ -56,6 +57,27 @@ class QueuedProcess : public QProcess
Q_PROPERTY(QString workDirectory READ workDirectory WRITE setWorkDirectory)
public:
/**
* @struct QueuedProcessModDefinitions
* @brief structure to define process modifications
* @var QueuedProcessModDefinitions::field
* field name
* @var QueuedProcessModDefinitions::value
* new field value
* @var QueuedProcessModDefinitions::task
* task ID
* @var QueuedProcessModDefinitions::time
* modification time
* @var QueuedProcessModDefinitions::user
* user ID, who modified the task
*/
struct QueuedProcessModDefinitions {
QString field;
QVariant value;
long long task = 0;
QDateTime time;
long long user = 0;
};
/**
* @struct QueuedProcessDefinition
* @brief structure to define process
@ -91,6 +113,7 @@ public:
QDateTime endTime;
long long user = 0;
QString limits;
QList<QueuedProcessModDefinitions> modifications;
};
/**
@ -112,10 +135,6 @@ public:
* @brief force kill ald children
*/
void killChildren();
/**
* @brief update cgroup limits
*/
void updateLimits();
// properties
/**
* @brief children processes

View File

@ -71,19 +71,24 @@ public:
* @brief parse task definitions from table data
* @param _properties
* map of task properties
* @param _modifications
* list of task modifications
* @return data mapped to internal format
*/
static QueuedProcess::QueuedProcessDefinitions
parseDefinitions(const QVariantHash &_properties);
parseDefinitions(const QVariantHash &_properties, const QList<QVariantHash> &_modifications);
/**
* @brief add task
* @param _properties
* task properties from database
* @param _modifications
* list of task modifications
* @param _index
* task index
* @return pointer to created task
*/
QueuedProcess *add(const QVariantHash &_properties, const long long _index);
QueuedProcess *add(const QVariantHash &_properties, const QList<QVariantHash> &_modifications,
const long long _index);
/**
* @brief add task
* @param _definitions
@ -94,12 +99,6 @@ public:
*/
QueuedProcess *add(const QueuedProcess::QueuedProcessDefinitions &_definitions,
const long long _index);
/**
* @brief add tasks from database
* @param _processes
* database stored tasks
*/
void loadProcesses(const QList<QVariantHash> &_processes);
/**
* @brief task
* @param _index

View File

@ -157,6 +157,6 @@ static const QueuedSettingsDefaultMap QueuedSettingsDefaults = {
{"ServerTimeout", {QueuedSettings::ServerTimeout, -1, false}},
{"TokenExpiration", {QueuedSettings::TokenExpiration, 30, false}},
};
};
}; // namespace QueuedConfig
#endif /* QUEUEDCONFIGURATION_H */

View File

@ -55,7 +55,7 @@ long long memoryCount();
* @return weight as proportion
*/
double memoryWeight(const long long _memory);
}
} // namespace QueuedSystemInfo
#endif /* QUEUEDSYSTEMINFO_H */

View File

@ -180,11 +180,14 @@ private:
* task object
* @param _taskData
* task data to edit
* @param _userId
* user id who send request to modify
* @remark _taskData should contain only fields defined in schema, any other
* fields will be ignored. No need to pass all properties here
* @return true on successful task edition
*/
QueuedResult<bool> editTaskPrivate(QueuedProcess *_process, const QVariantHash &_taskData);
QueuedResult<bool> editTaskPrivate(QueuedProcess *_process, const QVariantHash &_taskData,
const int _userId);
/**
* @brief edit user
* @param _id

View File

@ -38,7 +38,6 @@ QueuedControlGroupsAdaptor::QueuedControlGroupsAdaptor(QObject *_parent, QString
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
m_name = std::move(_name);
createGroup();
}

View File

@ -349,8 +349,11 @@ QueuedResult<QVariantHash> QueuedCoreAdaptor::getTask(const long long _id, const
auto res = getTask(_id, "", _token);
QueuedResult<QVariantHash> output;
res.match([&output](const QVariant &val) { output = toResult<QVariantHash>(val); },
[&output](const QueuedError &err) { output = err; });
res.match(
[&output](const QVariant &val) {
output = qdbus_cast<QVariantHash>(val.value<QDBusArgument>());
},
[&output](const QueuedError &err) { output = err; });
return output;
}
@ -398,8 +401,11 @@ QueuedResult<QVariantHash> QueuedCoreAdaptor::getUser(const long long _id, const
auto res = getUser(_id, "", _token);
QueuedResult<QVariantHash> output;
res.match([&output](const QVariant &val) { output = toResult<QVariantHash>(val); },
[&output](const QueuedError &err) { output = err; });
res.match(
[&output](const QVariant &val) {
output = qdbus_cast<QVariantHash>(val.value<QDBusArgument>());
},
[&output](const QueuedError &err) { output = err; });
return output;
}

View File

@ -224,7 +224,7 @@ QueuedResult<bool> QueuedCorePrivate::editTask(const long long _id, const QVaria
if (payload.contains("nice"))
payload["nice"] = std::min(payload["nice"].toUInt(), authUser->priority());
return m_helper->editTaskPrivate(task, payload);
return m_helper->editTaskPrivate(task, payload, userAuthId);
}
@ -369,8 +369,9 @@ QueuedResult<QVariantHash> QueuedCorePrivate::pluginSettings(const QString &_plu
if (!isAdmin)
return QueuedError("Not allowed", QueuedEnums::ReturnStatus::InsufficientPermissions);
auto dbSettings = m_database->get(QueuedDB::SETTINGS_TABLE,
{{"key", QString("Plugin.%1.%").arg(_plugin), "LIKE"}});
auto optionName = QString("Plugin.%1.%").arg(_plugin);
auto dbSettings
= m_database->get(QueuedDB::SETTINGS_TABLE, "WHERE key LIKE :key", {{"key", optionName}});
QVariantHash settings;
std::for_each(dbSettings.cbegin(), dbSettings.cend(),
[&settings, &_plugin](const QVariantHash &value) {

View File

@ -155,7 +155,7 @@ QueuedCorePrivateHelper::addTaskPrivate(const QString &_command, const QStringLi
}
// add to child object
processes()->add(properties, id);
processes()->add(properties, QList<QVariantHash>(), id);
// notify plugins
if (plugins())
emit(plugins()->interface()->onAddTask(id));
@ -282,9 +282,10 @@ QueuedResult<bool> QueuedCorePrivateHelper::editPluginPrivate(const QString &_pl
* @fn editTaskPrivate
*/
QueuedResult<bool> QueuedCorePrivateHelper::editTaskPrivate(QueuedProcess *_process,
const QVariantHash &_taskData)
const QVariantHash &_taskData,
const int _userId)
{
qCDebug(LOG_LIB) << "Edit task with ID" << _process->index();
qCDebug(LOG_LIB) << "Edit task with ID" << _process->index() << "from" << _userId;
// modify record in database first
bool status = database()->modify(QueuedDB::TASKS_TABLE, _process->index(), _taskData);
@ -293,6 +294,14 @@ QueuedResult<bool> QueuedCorePrivateHelper::editTaskPrivate(QueuedProcess *_proc
<< "in database, do not edit it in memory";
return QueuedError("", QueuedEnums::ReturnStatus::Error);
}
// store modification
for (auto &field : _taskData.keys())
database()->add(QueuedDB::TASKS_MODS_TABLE,
{{"task", _process->index()},
{"time", QDateTime::currentDateTimeUtc().toString(Qt::ISODateWithMs)},
{"user", _userId},
{"field", field},
{"value", _taskData[field]}});
// modify values stored in memory
for (auto &property : _taskData.keys())
@ -386,8 +395,11 @@ QueuedProcess *QueuedCorePrivateHelper::tryGetTask(const long long _id)
qCWarning(LOG_LIB) << "Could not find task with ID" << _id;
return nullptr;
}
qCInfo(LOG_LIB) << "Try to get task" << _id << "modifications from database";
auto mods
= database()->get(QueuedDB::TASKS_MODS_TABLE, "WHERE task=:task", {{"task", _id}});
auto defs = QueuedProcessManager::parseDefinitions(data);
auto defs = QueuedProcessManager::parseDefinitions(data, mods);
task = new QueuedProcess(this, defs, _id);
}

View File

@ -131,8 +131,13 @@ void QueuedCorePrivate::initProcesses()
m_processes = m_helper->initObject(m_processes);
m_processes->setExitAction(onExitAction);
auto dbProcesses = m_database->get(QueuedDB::TASKS_TABLE, {{"endTime", "NULL", "IS"}});
m_processes->loadProcesses(dbProcesses);
auto dbProcesses = m_database->get(QueuedDB::TASKS_TABLE, "WHERE endTime IS NULL");
for (auto &proc : dbProcesses) {
auto _id = proc["_id"].toLongLong();
auto mods
= m_database->get(QueuedDB::TASKS_MODS_TABLE, "WHERE task=:task", {{"task", _id}});
m_processes->add(proc, mods, _id);
}
m_connections += connect(m_processes, &QueuedProcessManager::taskStartTimeReceived,
[this](const long long _index, const QDateTime &_time) {
@ -207,7 +212,8 @@ void QueuedCorePrivate::initUsers()
m_users->setSalt(m_settings->admin().salt);
m_users->setTokenExpiration(expiry);
QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODateWithMs);
auto dbTokens = m_database->get(QueuedDB::TOKENS_TABLE, {{"validUntil", now, ">"}});
auto dbTokens = m_database->get(
QueuedDB::TOKENS_TABLE, "WHERE datetime(validUntil) > datetime(:time)", {{"time", now}});
m_users->loadTokens(dbTokens);
auto dbUsers = m_database->get(QueuedDB::USERS_TABLE);
m_users->loadUsers(dbUsers);

View File

@ -64,8 +64,10 @@ void QueuedDatabase::checkDatabase()
QStringList schemaTables = QueuedDB::DBSchema.keys();
for (auto &table : schemaTables) {
// create table if does not exist
if (!tables.contains(table))
if (!tables.contains(table)) {
qDebug() << table;
createTable(table);
}
// update schema
createSchema(table);
}
@ -89,8 +91,7 @@ void QueuedDatabase::createAdministrator(const QString &_user, const QString &_p
qCDebug(LOG_LIB) << "Check for user" << _user;
QSqlQuery query(m_database);
query.prepare("SELECT * FROM :table WHERE name=:username");
query.bindValue(":table", QueuedDB::USERS_TABLE);
query.prepare(QString("SELECT * FROM %1 WHERE name=:username").arg(QueuedDB::USERS_TABLE));
query.bindValue(":username", _user);
query.exec();
@ -131,9 +132,10 @@ void QueuedDatabase::createSchema(const QString &_table)
continue;
QueuedDB::QueuedDBField field = QueuedDB::DBSchema[_table][column];
QSqlQuery query(m_database);
query.prepare(
QString("ALTER TABLE :table ADD `%1` %2").arg(column).arg(field.sqlDescription));
query.bindValue(":table", _table);
query.prepare(QString("ALTER TABLE %1 ADD `%2` %3")
.arg(_table)
.arg(column)
.arg(field.sqlDescription));
query.exec();
QSqlError error = query.lastError();
@ -152,8 +154,7 @@ void QueuedDatabase::createTable(const QString &_table)
qCDebug(LOG_LIB) << "Create table" << _table;
QSqlQuery query(m_database);
query.prepare("CREATE TABLE :table (`_id` INTEGER PRIMARY KEY AUTOINCREMENT)");
query.bindValue(":table", _table);
query.prepare(QString("CREATE TABLE %1 (`_id` INTEGER PRIMARY KEY AUTOINCREMENT)").arg(_table));
query.exec();
QSqlError error = query.lastError();
@ -165,17 +166,16 @@ void QueuedDatabase::createTable(const QString &_table)
/**
* @fn get
*/
QList<QVariantHash> QueuedDatabase::get(const QString &_table,
const QList<QueuedDatabaseCondition> &_condition)
QList<QVariantHash> QueuedDatabase::get(const QString &_table, const QString &_condition,
const QVariantHash &_params)
{
qCDebug(LOG_LIB) << "Get records in table" << _table;
QList<QVariantHash> output;
QSqlQuery query(m_database);
query.prepare("SELECT * FROM :table " + getCondition(_condition) + " ORDER BY _id ASC");
query.bindValue(":table", _table);
for (auto &cond : _condition)
query.bindValue(QString(":%1").arg(cond.key), cond.value);
query.prepare(QString("SELECT * FROM %1 %2 ORDER BY _id ASC").arg(_table).arg(_condition));
for (auto &key : _params.keys())
query.bindValue(QString(":%1").arg(key), _params[key]);
query.exec();
QSqlError error = query.lastError();
@ -204,7 +204,7 @@ QVariantHash QueuedDatabase::get(const QString &_table, const long long _id)
{
qCDebug(LOG_LIB) << "Get record" << _id << "in table" << _table;
auto output = get(_table, {{"_id", _id, "="}});
auto output = get(_table, "WHERE _id=:_id", {{"_id", _id}});
if (output.count() == 0) {
qCWarning(LOG_LIB) << "Could not find records for" << _id;
return QVariantHash();
@ -257,10 +257,10 @@ long long QueuedDatabase::add(const QString &_table, const QVariantHash &_value)
auto payload = getQueryPayload(_table, _value);
// build query
QSqlQuery query(m_database);
query.prepare(QString("INSERT INTO :table (%1) VALUES (%2)")
query.prepare(QString("INSERT INTO %1 (%2) VALUES (%3)")
.arg(_table)
.arg(payload.keys().join(','))
.arg(payload.values().join(',')));
query.bindValue(":table", _table);
for (auto &key : _value.keys())
query.bindValue(QString(":%1").arg(key), _value[key]);
query.exec();
@ -289,8 +289,8 @@ bool QueuedDatabase::modify(const QString &_table, const long long _id, const QV
stringPayload.append(QString("%1=:%1").arg(key));
// build query
QSqlQuery query(m_database);
query.prepare(QString("UPDATE :table SET %1 WHERE _id=:_id").arg(stringPayload.join(',')));
query.bindValue(":table", _table);
query.prepare(
QString("UPDATE %1 SET %2 WHERE _id=:_id").arg(_table).arg(stringPayload.join(',')));
query.bindValue(":_id", _id);
for (auto &key : _value.keys())
query.bindValue(QString(":%1").arg(key), _value[key]);
@ -315,8 +315,7 @@ bool QueuedDatabase::remove(const QString &_table, const long long _id)
qCDebug(LOG_LIB) << "Remove row" << _id << "from" << _table;
QSqlQuery query(m_database);
query.prepare("DELETE FROM :table WHERE _id=:_id");
query.bindValue(":table", _table);
query.prepare(QString("DELETE FROM %1 WHERE _id=:_id").arg(_table));
query.bindValue(":_id", _id);
query.exec();
@ -339,8 +338,8 @@ void QueuedDatabase::removeTasks(const QDateTime &_endTime)
qCDebug(LOG_LIB) << "Remove all tasks which are older than" << _endTime;
QSqlQuery query(m_database);
query.prepare("DELETE FROM :table WHERE datetime(endTime) < datetime(:time)");
query.bindValue(":table", QueuedDB::TASKS_TABLE);
query.prepare(QString("DELETE FROM %1 WHERE datetime(endTime) < datetime(:time)")
.arg(QueuedDB::TASKS_TABLE));
query.bindValue(":time", _endTime.toString(Qt::ISODateWithMs));
query.exec();
@ -358,8 +357,8 @@ void QueuedDatabase::removeTokens()
{
QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODateWithMs);
QSqlQuery query(m_database);
query.prepare("DELETE FROM :table WHERE datetime(validUntil) < datetime(:time)");
query.bindValue(":table", QueuedDB::TOKENS_TABLE);
query.prepare(QString("DELETE FROM %1 WHERE datetime(validUntil) < datetime(:time)")
.arg(QueuedDB::TOKENS_TABLE));
query.bindValue(":time", now);
query.exec();
@ -378,8 +377,8 @@ void QueuedDatabase::removeUsers(const QDateTime &_lastLogin)
qCDebug(LOG_LIB) << "Remove all users which logged older than" << _lastLogin;
QSqlQuery query(m_database);
query.prepare("DELETE FROM :table WHERE datetime(lastLogin) < datetime(:time)");
query.bindValue(":table", QueuedDB::USERS_TABLE);
query.prepare(QString("DELETE FROM %1 WHERE datetime(lastLogin) < datetime(:time)")
.arg(QueuedDB::USERS_TABLE));
query.bindValue(":time", _lastLogin.toString(Qt::ISODateWithMs));
query.exec();
@ -405,22 +404,6 @@ QStringList QueuedDatabase::getColumnsInRecord(const QSqlRecord &_record) const
}
/**
* @fn getCondition
*/
QString QueuedDatabase::getCondition(const QList<QueuedDatabaseCondition> &_condition) const
{
if (_condition.isEmpty())
return "";
QStringList query;
for (auto &cond : _condition)
query += QString("%1 %2 :%1").arg(cond.key).arg(cond.operation);
return "WHERE " + query.join(',');
}
/**
* @fn lastInsertionId
*/
@ -429,8 +412,7 @@ long long QueuedDatabase::lastInsertionId(const QString &_table) const
qCDebug(LOG_LIB) << "Get last row ID from" << _table;
QSqlQuery query(m_database);
query.prepare("SELECT max(_id) FROM :table");
query.bindValue(":table", _table);
query.prepare(QString("SELECT max(_id) FROM %1").arg(_table));
query.exec();
QSqlError error = query.lastError();

View File

@ -58,8 +58,6 @@ QueuedProcess::QueuedProcess(QObject *_parent, const QueuedProcessDefinitions &d
setArguments(m_definitions.arguments);
setWorkDirectory(m_definitions.workingDirectory);
updateLimits();
connect(this, SIGNAL(started()), this, SLOT(applyCGroup()));
}
@ -90,19 +88,6 @@ void QueuedProcess::killChildren()
}
/**
* @fn updateLimits
*/
void QueuedProcess::updateLimits()
{
auto nl = nativeLimits();
m_cgroup->setCpuLimit(std::llround(QueuedSystemInfo::cpuWeight(nl.cpu) * 100.0));
m_cgroup->setMemoryLimit(
std::llround(QueuedSystemInfo::memoryWeight(nl.memory) * QueuedSystemInfo::memoryCount()));
}
/**
* @fn childrenPids
*/
@ -281,7 +266,6 @@ void QueuedProcess::setLimits(const QString &_limits)
qCDebug(LOG_LIB) << "Set process limits" << _limits;
m_definitions.limits = _limits;
updateLimits();
}
@ -372,6 +356,7 @@ bool QueuedProcess::operator==(const QueuedProcess &_other)
return name() == _other.name();
}
/**
* applyCGroup
*/
@ -386,6 +371,14 @@ void QueuedProcess::applyCGroup()
*/
void QueuedProcess::setupChildProcess()
{
// configure cgroup here and apply limits
m_cgroup->createGroup();
auto nl = nativeLimits();
m_cgroup->setCpuLimit(std::llround(QueuedSystemInfo::cpuWeight(nl.cpu) * 100.0));
m_cgroup->setMemoryLimit(
std::llround(QueuedSystemInfo::memoryWeight(nl.memory) * QueuedSystemInfo::memoryCount()));
// setup child properties
::setuid(m_definitions.uid);
::setgid(m_definitions.gid);

View File

@ -62,9 +62,11 @@ QueuedProcessManager::~QueuedProcessManager()
* @fn parseDefinitions
*/
QueuedProcess::QueuedProcessDefinitions
QueuedProcessManager::parseDefinitions(const QVariantHash &_properties)
QueuedProcessManager::parseDefinitions(const QVariantHash &_properties,
const QList<QVariantHash> &_modifications)
{
qCDebug(LOG_LIB) << "Parse definitions from" << _properties;
qCDebug(LOG_LIB) << "Parse definitions from" << _properties << "with modifications"
<< _modifications;
QueuedProcess::QueuedProcessDefinitions defs;
// parameters
@ -81,6 +83,17 @@ QueuedProcessManager::parseDefinitions(const QVariantHash &_properties)
defs.startTime = QDateTime::fromString(_properties["startTime"].toString(), Qt::ISODateWithMs);
defs.endTime = QDateTime::fromString(_properties["endTime"].toString(), Qt::ISODateWithMs);
// modifications
for (auto &mod : _modifications) {
QueuedProcess::QueuedProcessModDefinitions mods;
mods.field = mod["field"].toString();
mods.value = mod["value"];
mods.task = mod["task"].toLongLong();
mods.time = QDateTime::fromString(mod["time"].toString(), Qt::ISODateWithMs);
mods.user = mod["user"].toLongLong();
defs.modifications.append(mods);
}
return defs;
}
@ -88,11 +101,14 @@ QueuedProcessManager::parseDefinitions(const QVariantHash &_properties)
/**
* @fn add
*/
QueuedProcess *QueuedProcessManager::add(const QVariantHash &_properties, const long long _index)
QueuedProcess *QueuedProcessManager::add(const QVariantHash &_properties,
const QList<QVariantHash> &_modifications,
const long long _index)
{
qCDebug(LOG_LIB) << "Add new process" << _properties << "with index" << _index;
qCDebug(LOG_LIB) << "Add new process" << _properties << "with modifications" << _modifications
<< "with index" << _index;
return add(parseDefinitions(_properties), _index);
return add(parseDefinitions(_properties, _modifications), _index);
}
@ -123,18 +139,6 @@ QueuedProcessManager::add(const QueuedProcess::QueuedProcessDefinitions &_defini
}
/**
* @fn loadProcesses
*/
void QueuedProcessManager::loadProcesses(const QList<QVariantHash> &_processes)
{
qCDebug(LOG_LIB) << "Add tasks from" << _processes;
for (auto &processData : _processes)
add(processData, processData["_id"].toLongLong());
}
/**
* @fn process
*/

View File

@ -60,20 +60,21 @@ QList<QVariantHash> QueuedReportManager::performance(const QueuedCore *_core,
{
qCDebug(LOG_LIB) << "Build performance report from" << _from << "to" << _to;
QList<QueuedDatabaseCondition> conditions;
if (_from.isValid())
conditions += QString("((datetime(startTime) > datetime('%1')) OR "
"(startTime IS NULL))")
.arg(_from.toString(Qt::ISODateWithMs));
if (_to.isValid())
conditions += QString("((datetime(endTime) < datetime('%1')) AND "
"(endTime NOT NULL))")
.arg(_to.toString(Qt::ISODateWithMs));
QVariantHash params;
QStringList conditions;
if (_from.isValid()) {
conditions += "((datetime(startTime) > datetime(:startTime)) OR (startTime IS NULL))";
params["startTime"] = _from.toString(Qt::ISODateWithMs);
}
if (_to.isValid()) {
conditions += "((datetime(endTime) < datetime(:endTime)) AND (endTime NOT NULL))";
params["endTime"] = _to.toString(Qt::ISODateWithMs);
}
QString condition
= conditions.isEmpty() ? "" : QString("WHERE (%1)").arg(conditions.join(" AND "));
qCInfo(LOG_LIB) << "Task condition select" << condition;
auto tasks = m_database->get(QueuedDB::TASKS_TABLE, condition);
auto tasks = m_database->get(QueuedDB::TASKS_TABLE, condition, params);
// build hash first
QHash<long long, QVariantHash> hashOutput;
@ -131,23 +132,26 @@ QList<QVariantHash> QueuedReportManager::tasks(const long long _user, const QDat
{
qCDebug(LOG_LIB) << "Search for tasks in" << _user << _from << _to;
QVariantHash params;
QStringList conditions;
if (_user > 0)
conditions += QString("(user = %1)").arg(_user);
if (_from.isValid())
conditions += QString("((datetime(startTime) > datetime('%1')) OR "
"(startTime IS NULL))")
.arg(_from.toString(Qt::ISODateWithMs));
if (_to.isValid())
conditions += QString("((datetime(endTime) < datetime('%1')) AND "
"(endTime NOT NULL))")
.arg(_to.toString(Qt::ISODateWithMs));
if (_user > 0) {
conditions += "(user = :user)";
params["user"] = _user;
}
if (_from.isValid()) {
conditions += "((datetime(startTime) > datetime(:startTime)) OR (startTime IS NULL))";
params["startTime"] = _from.toString(Qt::ISODateWithMs);
}
if (_to.isValid()) {
conditions += "((datetime(endTime) < datetime(:endTime)) AND (endTime NOT NULL))";
params["endTime"] = _to.toString(Qt::ISODateWithMs);
}
QString condition
= conditions.isEmpty() ? "" : QString("WHERE (%1)").arg(conditions.join(" AND "));
qCInfo(LOG_LIB) << "Task condition select" << condition;
return m_database->get(QueuedDB::TASKS_TABLE, condition);
return m_database->get(QueuedDB::TASKS_TABLE, condition, params);
}
@ -159,18 +163,20 @@ QList<QVariantHash> QueuedReportManager::users(const QDateTime &_lastLogged,
{
qCDebug(LOG_LIB) << "Search for users in" << _lastLogged << static_cast<uint>(_permission);
QVariantHash params;
QStringList conditions;
if (_lastLogged.isValid())
conditions += QString("((datetime(lastLogin) > datetime('%1')) AND "
"(lastLogin NOT NULL))")
.arg(_lastLogged.toString(Qt::ISODateWithMs));
if (_permission != QueuedEnums::Permission::Invalid)
conditions
+= QString("((permissions & ~%1) != permissions)").arg(static_cast<uint>(_permission));
if (_lastLogged.isValid()) {
conditions += "((datetime(lastLogin) > datetime(:lastLogin)) AND (lastLogin NOT NULL))";
params["lastLogin"] = _lastLogged.toString(Qt::ISODateWithMs);
}
if (_permission != QueuedEnums::Permission::Invalid) {
conditions += "((permissions & ~:permission) != permissions)";
params["permission"] = static_cast<uint>(_permission);
}
QString condition
= conditions.isEmpty() ? "" : QString("WHERE (%1)").arg(conditions.join(" AND "));
qCInfo(LOG_LIB) << "User condition select" << condition;
return m_database->get(QueuedDB::USERS_TABLE, condition);
return m_database->get(QueuedDB::USERS_TABLE, condition, params);
}

View File

@ -30,7 +30,7 @@ void parser(QCommandLineParser &_parser);
void setToken(const QString &_token, const QString &_user, const QString &_cache);
QString token(const QString &_user, const QString &_cache);
bool tryAuth(const QString &_token);
};
}; // namespace QueuedctlAuth
#endif /* QUEUEDCTLAUTH_H */

View File

@ -89,7 +89,7 @@ QString hashListToString(const QList<QVariantHash> &_list);
void preprocess(const QStringList &_args, QCommandLineParser &_parser);
void print(const QueuedctlResult &_result);
QueuedctlResult process(QCommandLineParser &_parser, const QString &_cache, const QString &_user);
};
}; // namespace QueuedctlCommon
#endif /* QUEUEDCTLCOMMON_H */

View File

@ -29,7 +29,7 @@ QueuedctlCommon::QueuedctlResult editOption(const QString &_option, const QVaria
QueuedctlCommon::QueuedctlResult getOption(const QString &_option, const QString &_token);
void parserGet(QCommandLineParser &_parser);
void parserSet(QCommandLineParser &_parser);
};
}; // namespace QueuedctlOption
#endif /* QUEUEDCTLOPTION_H */

View File

@ -29,7 +29,7 @@ QueuedctlCommon::QueuedctlResult addPermission(const long long _id, const QStrin
QueuedctlCommon::QueuedctlResult removePermission(const long long _id, const QString &_permission,
const QString &_token);
void parser(QCommandLineParser &_parser);
};
}; // namespace QueuedctlPermissions
#endif /* QUEUEDCTLPERMISSIONS_H */

View File

@ -30,7 +30,7 @@ QueuedctlCommon::QueuedctlResult getPluginOptions(const QString &_plugin, const
QueuedctlCommon::QueuedctlResult listPlugins();
QueuedctlCommon::QueuedctlResult removePlugin(const QString &_plugin, const QString &_token);
void parser(QCommandLineParser &_parser);
};
}; // namespace QueuedctlPlugins
#endif /* QUEUEDCTLPLUGINS_H */

View File

@ -109,7 +109,7 @@ QueuedctlTask::getTask(const long long _id, const QString &_property, const QStr
},
[&output](const QueuedError &err) { output.output = err.message().c_str(); });
} else {
auto res = QueuedCoreAdaptor::getTask(_id, _property);
auto res = QueuedCoreAdaptor::getTask(_id, _property, _token);
res.match(
[&output](const QVariant &val) {
output.status = val.isValid();

View File

@ -43,7 +43,7 @@ setTask(const long long _id, const QueuedProcess::QueuedProcessDefinitions &_def
const QString &_token);
QueuedctlCommon::QueuedctlResult startTask(const long long _id, const QString &_token);
QueuedctlCommon::QueuedctlResult stopTask(const long long _id, const QString &_token);
};
}; // namespace QueuedctlTask
#endif /* QUEUEDCTLTASK_H */

View File

@ -139,7 +139,7 @@ QueuedctlUser::getUser(const long long _id, const QString &_property, const QStr
},
[&output](const QueuedError &err) { output.output = err.message().c_str(); });
} else {
auto res = QueuedCoreAdaptor::getUser(_id, _property);
auto res = QueuedCoreAdaptor::getUser(_id, _property, _token);
res.match(
[&output](const QVariant &val) {
output.status = val.isValid();

View File

@ -44,7 +44,7 @@ void parserSet(QCommandLineParser &_parser);
QueuedctlCommon::QueuedctlResult setUser(const long long _id,
const QueuedUser::QueuedUserDefinitions &_definitions,
const QString &_token);
};
}; // namespace QueuedctlUser
#endif /* QUEUEDCTLUSER_H */