mirror of
				https://github.com/arcan1s/queued.git
				synced 2025-10-31 14:13:40 +00:00 
			
		
		
		
	add database manager
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -41,8 +41,6 @@ build | |||||||
| # archives | # archives | ||||||
| *src.tar.[gx]z | *src.tar.[gx]z | ||||||
| *pkg.tar.[gx]z | *pkg.tar.[gx]z | ||||||
| src |  | ||||||
| pkg |  | ||||||
| *.deb | *.deb | ||||||
|  |  | ||||||
| # clion settings | # clion settings | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ if (POLICY CMP0063) | |||||||
|     cmake_policy(SET CMP0063 OLD) |     cmake_policy(SET CMP0063 OLD) | ||||||
| endif () | endif () | ||||||
|  |  | ||||||
| project(awesomewidgets) | project(queued) | ||||||
| set(PROJECT_AUTHOR "Evgeniy Alekseev") | set(PROJECT_AUTHOR "Evgeniy Alekseev") | ||||||
| set(PROJECT_CONTACT "esalexeev@gmail.com") | set(PROJECT_CONTACT "esalexeev@gmail.com") | ||||||
| set(PROJECT_LICENSE "MIT") | set(PROJECT_LICENSE "MIT") | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| # main qt libraries | # main qt libraries | ||||||
| find_package(Qt5 5.6.0 REQUIRED COMPONENTS Core DBus Test) | find_package(Qt5 5.6.0 REQUIRED COMPONENTS Core DBus Sql Test) | ||||||
| add_definitions( | add_definitions( | ||||||
|         ${Qt5Core_DEFINITIONS} ${Qt5DBus_DEFINITIONS} |         ${Qt5Core_DEFINITIONS} ${Qt5DBus_DEFINITIONS} ${Qt5Sql_DEFINITIONS} | ||||||
| ) | ) | ||||||
| set(Qt_INCLUDE | set(Qt_INCLUDE | ||||||
|         ${Qt5Core_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} |         ${Qt5Core_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS} ${Qt5Sql_INCLUDE_DIRS} | ||||||
| ) | ) | ||||||
| set(Qt_LIBRARIES | set(Qt_LIBRARIES | ||||||
|         ${Qt5Core_LIBRARIES} ${Qt5DBus_LIBRARIES} |         ${Qt5Core_LIBRARIES} ${Qt5DBus_LIBRARIES} ${Qt5Sql_LIBRARIES} | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ | |||||||
| #ifndef QUEUED_H | #ifndef QUEUED_H | ||||||
| #define QUEUED_H | #define QUEUED_H | ||||||
|  |  | ||||||
|  | #include "QueuedDatabase.h" | ||||||
| #include "QueuedDebug.h" | #include "QueuedDebug.h" | ||||||
| #include "QueuedProcess.h" | #include "QueuedProcess.h" | ||||||
| #include "QueuedProcessManager.h" | #include "QueuedProcessManager.h" | ||||||
|  | |||||||
							
								
								
									
										103
									
								
								sources/queued/include/queued/QueuedDatabase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								sources/queued/include/queued/QueuedDatabase.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2016 Evgeniy Alekseev | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in | ||||||
|  |  * all copies or substantial portions of the Software. | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * @file QueuedDatabase.h | ||||||
|  |  * Header of Queued library | ||||||
|  |  * @author Evgeniy Alekseev | ||||||
|  |  * @copyright MIT | ||||||
|  |  * @bug https://github.com/arcan1s/queued/issues | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifndef QUEUEDDATABASE_H | ||||||
|  | #define QUEUEDDATABASE_H | ||||||
|  |  | ||||||
|  | #include <QHash> | ||||||
|  | #include <QObject> | ||||||
|  | #include <QSqlDatabase> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef QHash<QString, QStringList> QueuedDBSchema; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief queued adaptor to databases | ||||||
|  |  */ | ||||||
|  | class QueuedDatabase : public QObject | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |     Q_PROPERTY(QString path READ path) | ||||||
|  |  | ||||||
|  |     // TODO add fields SQL parameters (type whatever), Qt specific types | ||||||
|  |     const QueuedDBSchema DBSchema = { | ||||||
|  |         {"users", | ||||||
|  |          {"_id", "name", "uid", "gid", "password_sha512", "email", "cpu", "gpu", | ||||||
|  |           "memory", "gpumemory", "storage"}}, | ||||||
|  |         {"tasks", {"_id", "userId", "command", "arguments", "workDirectory"}}}; | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     /** | ||||||
|  |      * @brief QueuedDatabase class constructor | ||||||
|  |      * @param parent         pointer to parent item | ||||||
|  |      * @param path           path to database | ||||||
|  |      * @param driver         database driver | ||||||
|  |      */ | ||||||
|  |     explicit QueuedDatabase(QObject *parent, const QString path, | ||||||
|  |                             const QString driver); | ||||||
|  |     /** | ||||||
|  |      * @brief QueuedDatabase class destructor | ||||||
|  |      */ | ||||||
|  |     virtual ~QueuedDatabase(); | ||||||
|  |     /** | ||||||
|  |      * @brief check and create database | ||||||
|  |      */ | ||||||
|  |     void checkDatabase(); | ||||||
|  |     /** | ||||||
|  |      * @brief open database | ||||||
|  |      * @param _hostname      hostname to connect, may be empty | ||||||
|  |      * @param _port          port to connect, may be 0 | ||||||
|  |      * @param _username      username to connect, may be empty | ||||||
|  |      * @param _password      password to connect, will be ignored if _username | ||||||
|  |      * is empty | ||||||
|  |      */ | ||||||
|  |     void open(const QString _hostname, const int _port, const QString _username, | ||||||
|  |               const QString _password); | ||||||
|  |     /** | ||||||
|  |      * @brief path to database | ||||||
|  |      * @return path to used database | ||||||
|  |      */ | ||||||
|  |     QString path() const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     /** | ||||||
|  |      * @brief database | ||||||
|  |      */ | ||||||
|  |     QSqlDatabase m_database; | ||||||
|  |     /** | ||||||
|  |      * @brief database path | ||||||
|  |      */ | ||||||
|  |     QString m_path; | ||||||
|  |     /** | ||||||
|  |      * @brief create or update actual schema in table | ||||||
|  |      * @param _table         table name | ||||||
|  |      */ | ||||||
|  |     void createSchema(const QString _table); | ||||||
|  |     /** | ||||||
|  |      * @brief create given table | ||||||
|  |      * @param _table         table name | ||||||
|  |      */ | ||||||
|  |     void createTable(const QString _table); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif /* QUEUEDDATABASE_H */ | ||||||
| @ -31,6 +31,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| typedef QHash<long long, QueuedProcess *> QueuedProcessMap; | typedef QHash<long long, QueuedProcess *> QueuedProcessMap; | ||||||
|  | typedef QHash<long long, QMetaObject::Connection> QueuedProcessConnectionMap; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief implementation over QProcess to run processes |  * @brief implementation over QProcess to run processes | ||||||
| @ -103,6 +104,10 @@ private slots: | |||||||
|                       const long long _index); |                       const long long _index); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  |     /** | ||||||
|  |      * @brief connection map | ||||||
|  |      */ | ||||||
|  |     QueuedProcessConnectionMap m_connections; | ||||||
|     /** |     /** | ||||||
|      * @brief action on exit |      * @brief action on exit | ||||||
|      */ |      */ | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								sources/queued/src/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								sources/queued/src/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | # set files | ||||||
|  | file (GLOB_RECURSE SUBPROJECT_SOURCES "*.cpp") | ||||||
|  | file (GLOB_RECURSE SUBPROJECT_HEADERS "*.h" "${PROJECT_LIBRARY_DIR}/*h") | ||||||
|  |  | ||||||
|  | # include_path | ||||||
|  | include_directories ("${PROJECT_LIBRARY_DIR}/include" | ||||||
|  |                      "${CMAKE_CURRENT_BINARY_DIR}" | ||||||
|  |                      "${CMAKE_BINARY_DIR}" | ||||||
|  |                      "${Qt_INCLUDE}") | ||||||
|  |  | ||||||
|  | qt5_wrap_cpp (SUBPROJECT_MOC_SOURCES "${SUBPROJECT_HEADERS}") | ||||||
|  |  | ||||||
|  | add_library ("${SUBPROJECT}" SHARED "${SUBPROJECT_SOURCES}" "${SUBPROJECT_HEADERS}" | ||||||
|  |         "${SUBPROJECT_MOC_SOURCES}") | ||||||
|  | set_target_properties ("${SUBPROJECT}" PROPERTIES | ||||||
|  |         SOVERSION "${PROJECT_VERSION_MAJOR}" | ||||||
|  |         VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") | ||||||
|  | target_link_libraries ("${SUBPROJECT}" "${Qt_LIBRARIES}") | ||||||
|  | # install properties | ||||||
|  | install (TARGETS "${SUBPROJECT}" DESTINATION "${LIB_INSTALL_DIR}") | ||||||
							
								
								
									
										146
									
								
								sources/queued/src/QueuedDatabase.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								sources/queued/src/QueuedDatabase.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,146 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2016 Evgeniy Alekseev | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in | ||||||
|  |  * all copies or substantial portions of the Software. | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * @file QueuedDatabase.cpp | ||||||
|  |  * Source code of queued library | ||||||
|  |  * @author Evgeniy Alekseev | ||||||
|  |  * @copyright GPLv3 | ||||||
|  |  * @bug https://github.com/arcan1s/queued/issues | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "queued/Queued.h" | ||||||
|  |  | ||||||
|  | #include <QSqlError> | ||||||
|  | #include <QSqlQuery> | ||||||
|  | #include <QSqlRecord> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn QueuedDatabase | ||||||
|  |  */ | ||||||
|  | QueuedDatabase::QueuedDatabase(QObject *parent, const QString path, | ||||||
|  |                                const QString driver) | ||||||
|  |     : QObject(parent) | ||||||
|  |     , m_path(path) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; | ||||||
|  |  | ||||||
|  |     m_database = QSqlDatabase::addDatabase(driver); | ||||||
|  |     m_database.setDatabaseName(path); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn ~QueuedDatabase | ||||||
|  |  */ | ||||||
|  | QueuedDatabase::~QueuedDatabase() | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn open | ||||||
|  |  */ | ||||||
|  | void QueuedDatabase::open(const QString _hostname, const int _port, | ||||||
|  |                           const QString _username, const QString _password) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Open database at" << _hostname << _port << "as user" | ||||||
|  |                      << _username; | ||||||
|  |  | ||||||
|  |     if (!_hostname.isEmpty()) | ||||||
|  |         m_database.setHostName(_hostname); | ||||||
|  |     if (_port > 0) | ||||||
|  |         m_database.setPort(_port); | ||||||
|  |     bool status = _username.isEmpty() ? m_database.open() | ||||||
|  |                                       : m_database.open(_username, _password); | ||||||
|  |  | ||||||
|  |     qCDebug(LOG_LIB) << "Open database status" << status; | ||||||
|  |     if (status) | ||||||
|  |         return checkDatabase(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn checkDatabase | ||||||
|  |  */ | ||||||
|  | void QueuedDatabase::checkDatabase() | ||||||
|  | { | ||||||
|  |     QStringList tables = m_database.tables(); | ||||||
|  |     for (auto table : DBSchema.keys()) { | ||||||
|  |         // create table if does not exist | ||||||
|  |         if (!tables.contains(table)) | ||||||
|  |             createTable(table); | ||||||
|  |         // update schema | ||||||
|  |         createSchema(table); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn path | ||||||
|  |  */ | ||||||
|  | QString QueuedDatabase::path() const | ||||||
|  | { | ||||||
|  |     return m_path; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn createSchema | ||||||
|  |  */ | ||||||
|  | void QueuedDatabase::createSchema(const QString _table) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Create schema for" << _table; | ||||||
|  |  | ||||||
|  |     QSqlRecord record = m_database.record(_table); | ||||||
|  |     // get column names | ||||||
|  |     QStringList columns; | ||||||
|  |     for (int i = 0; i < record.count(); i++) | ||||||
|  |         columns.append(record.fieldName(i)); | ||||||
|  |  | ||||||
|  |     // check and append if any | ||||||
|  |     for (auto column : DBSchema[_table]) { | ||||||
|  |         if (columns.contains(column)) | ||||||
|  |             continue; | ||||||
|  |         QSqlQuery query | ||||||
|  |             = m_database.exec(QString("ALTER TABLE '%1' add column `%2`") | ||||||
|  |                                   .arg(_table) | ||||||
|  |                                   .arg(column)); | ||||||
|  |         QSqlError error = query.lastError(); | ||||||
|  |         if (error.isValid()) | ||||||
|  |             qCCritical(LOG_LIB) << "Could not insert column" << column | ||||||
|  |                                 << "to table" << _table | ||||||
|  |                                 << "error:" << error.text(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn createTable | ||||||
|  |  */ | ||||||
|  | void QueuedDatabase::createTable(const QString _table) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Create table" << _table; | ||||||
|  |  | ||||||
|  |     QSqlQuery query = m_database.exec( | ||||||
|  |         QString("CREATE TABLE '%1' (`_id` INTEGER PRIMARY KEY AUTOINCREMENT)") | ||||||
|  |             .arg(_table)); | ||||||
|  |     QSqlError error = query.lastError(); | ||||||
|  |     if (error.isValid()) | ||||||
|  |         qCCritical(LOG_LIB) << "Could not create table" << _table | ||||||
|  |                             << "error:" << error.text(); | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								sources/queued/src/QueuedDebug.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								sources/queued/src/QueuedDebug.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2016 Evgeniy Alekseev | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in | ||||||
|  |  * all copies or substantial portions of the Software. | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * @file QueuedDebug.cpp | ||||||
|  |  * Source code of queued library | ||||||
|  |  * @author Evgeniy Alekseev | ||||||
|  |  * @copyright GPLv3 | ||||||
|  |  * @bug https://github.com/arcan1s/queued/issues | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "queued/Queued.h" | ||||||
|  |  | ||||||
|  | #include "version.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Q_LOGGING_CATEGORY(LOG_CTL, "org.queued.control", QtMsgType::QtWarningMsg) | ||||||
|  | Q_LOGGING_CATEGORY(LOG_DBUS, "org.queued.dbus", QtMsgType::QtWarningMsg) | ||||||
|  | Q_LOGGING_CATEGORY(LOG_LIB, "org.queued.library", QtMsgType::QtWarningMsg) | ||||||
|  | Q_LOGGING_CATEGORY(LOG_PL, "org.queued.plugin", QtMsgType::QtWarningMsg) | ||||||
|  | Q_LOGGING_CATEGORY(LOG_SERV, "org.queued.server", QtMsgType::QtWarningMsg) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn getBuildData | ||||||
|  |  */ | ||||||
|  | QStringList QueuedDebug::getBuildData() | ||||||
|  | { | ||||||
|  |     QStringList metadata; | ||||||
|  |  | ||||||
|  |     return metadata; | ||||||
|  | } | ||||||
							
								
								
									
										161
									
								
								sources/queued/src/QueuedProcess.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								sources/queued/src/QueuedProcess.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,161 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2016 Evgeniy Alekseev | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in | ||||||
|  |  * all copies or substantial portions of the Software. | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * @file QueuedProcess.cpp | ||||||
|  |  * Source code of queued library | ||||||
|  |  * @author Evgeniy Alekseev | ||||||
|  |  * @copyright GPLv3 | ||||||
|  |  * @bug https://github.com/arcan1s/queued/issues | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "queued/Queued.h" | ||||||
|  |  | ||||||
|  | #include <unistd.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @class QueuedProcess | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * @fn QueuedProcess | ||||||
|  |  */ | ||||||
|  | QueuedProcess::QueuedProcess(QObject *parent, | ||||||
|  |                              const QueuedProcessDefinitions definitions, | ||||||
|  |                              const long long index) | ||||||
|  |     : QProcess(parent) | ||||||
|  |     , m_definitions(definitions) | ||||||
|  |     , m_index(index) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; | ||||||
|  |  | ||||||
|  |     setArguments(m_definitions.args); | ||||||
|  |     setProgram(m_definitions.cmd); | ||||||
|  |     setWorkingDirectory(m_definitions.workingDirectory); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn ~QueuedProcess | ||||||
|  |  */ | ||||||
|  | QueuedProcess::~QueuedProcess() | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn index | ||||||
|  |  */ | ||||||
|  | long long QueuedProcess::index() const | ||||||
|  | { | ||||||
|  |     return m_index; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn name | ||||||
|  |  */ | ||||||
|  | QString QueuedProcess::name() const | ||||||
|  | { | ||||||
|  |     return QString("queued-%1").arg(index()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn removeLimit | ||||||
|  |  */ | ||||||
|  | void QueuedProcess::removeLimit(const LimitType _limitType) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Remove limit" << static_cast<int>(_limitType); | ||||||
|  |  | ||||||
|  |     m_limits.remove(_limitType); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn setLimit | ||||||
|  |  */ | ||||||
|  | void QueuedProcess::setLimit(const LimitType _limitType, const QVariant _value) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Set limit" << static_cast<int>(_limitType) << "to" | ||||||
|  |                      << _value; | ||||||
|  |  | ||||||
|  |     if (!_value.isValid()) | ||||||
|  |         return removeLimit(_limitType); | ||||||
|  |  | ||||||
|  |     bool status = false; | ||||||
|  |     long long intValue = _value.type() == QVariant::String | ||||||
|  |                              ? convertMemory(_value.toString(), status) | ||||||
|  |                              : _value.toLongLong(&status); | ||||||
|  |  | ||||||
|  |     if (!status) | ||||||
|  |         removeLimit(_limitType); | ||||||
|  |     else | ||||||
|  |         m_limits[_limitType] = intValue; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn operator== | ||||||
|  |  */ | ||||||
|  | bool QueuedProcess::operator==(const QueuedProcess _other) | ||||||
|  | { | ||||||
|  |     return name() == _other.name(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn setupChildProcess | ||||||
|  |  */ | ||||||
|  | void QueuedProcess::setupChildProcess() | ||||||
|  | { | ||||||
|  |     ::setgid(m_definitions.gid); | ||||||
|  |     ::setuid(m_definitions.uid); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn run | ||||||
|  |  */ | ||||||
|  | void QueuedProcess::run() | ||||||
|  | { | ||||||
|  |     // TODO set limits to child process and etc | ||||||
|  |     return start(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn convertMemory | ||||||
|  |  */ | ||||||
|  | long long QueuedProcess::convertMemory(QString _value, bool &_status) const | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Convert memory value" << _value; | ||||||
|  |  | ||||||
|  |     long long intValue; | ||||||
|  |     if (_value.endsWith(QString("K"))) | ||||||
|  |         intValue = _value.remove(QString("K")).toLongLong(&_status) * 1024; | ||||||
|  |     else if (_value.endsWith(QString("M"))) | ||||||
|  |         intValue | ||||||
|  |             = _value.remove(QString("M")).toLongLong(&_status) * 1024 * 1024; | ||||||
|  |     else if (_value.endsWith(QString("G"))) | ||||||
|  |         intValue = _value.remove(QString("G")).toLongLong(&_status) * 1024 | ||||||
|  |                    * 1024 * 1024; | ||||||
|  |     else | ||||||
|  |         intValue = _value.toInt(&_status); | ||||||
|  |  | ||||||
|  |     qCInfo(LOG_LIB) << "Converted value" << intValue; | ||||||
|  |     return intValue; | ||||||
|  | } | ||||||
							
								
								
									
										146
									
								
								sources/queued/src/QueuedProcessManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								sources/queued/src/QueuedProcessManager.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,146 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2016 Evgeniy Alekseev | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |  * of this software and associated documentation files (the "Software"), to deal | ||||||
|  |  * | ||||||
|  |  * in the Software without restriction, including without limitation the rights | ||||||
|  |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |  * copies of the Software, and to permit persons to whom the Software is | ||||||
|  |  * furnished to do so, subject to the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice shall be included in | ||||||
|  |  * all copies or substantial portions of the Software. | ||||||
|  |  */ | ||||||
|  | /** | ||||||
|  |  * @file QueuedProcessManager.cpp | ||||||
|  |  * Source code of queued library | ||||||
|  |  * @author Evgeniy Alekseev | ||||||
|  |  * @copyright GPLv3 | ||||||
|  |  * @bug https://github.com/arcan1s/queued/issues | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "queued/Queued.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn QueuedProcessManager | ||||||
|  |  */ | ||||||
|  | QueuedProcessManager::QueuedProcessManager(QObject *parent, | ||||||
|  |                                            const OnExitAction onExit) | ||||||
|  |     : QObject(parent) | ||||||
|  |     , m_onExit(onExit) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn ~QueuedProcessManager | ||||||
|  |  */ | ||||||
|  | QueuedProcessManager::~QueuedProcessManager() | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; | ||||||
|  |  | ||||||
|  |     QList<long long> indices = m_processes.keys(); | ||||||
|  |     for (auto index : indices) | ||||||
|  |         remove(index); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn add | ||||||
|  |  */ | ||||||
|  | QueuedProcess * | ||||||
|  | QueuedProcessManager::add(const long long _index, | ||||||
|  |                           const QueuedProcessDefinitions _definitions) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Add new process" << _definitions.cmd << "with index" | ||||||
|  |                      << _index; | ||||||
|  |  | ||||||
|  |     if (m_processes.contains(_index)) | ||||||
|  |         return m_processes[_index]; | ||||||
|  |  | ||||||
|  |     QueuedProcess *process = new QueuedProcess(this, _definitions, _index); | ||||||
|  |     m_processes[_index] = process; | ||||||
|  |     // connect to signal | ||||||
|  |     m_connections[_index] = connect( | ||||||
|  |         process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>( | ||||||
|  |                      &QProcess::finished), | ||||||
|  |         [=](const int exitCode, const QProcess::ExitStatus exitStatus) { | ||||||
|  |             return taskFinished(exitCode, exitStatus, _index); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |     return process; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn onExit | ||||||
|  |  */ | ||||||
|  | QueuedProcessManager::OnExitAction QueuedProcessManager::onExit() const | ||||||
|  | { | ||||||
|  |     return m_onExit; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn process | ||||||
|  |  */ | ||||||
|  | QueuedProcess *QueuedProcessManager::process(const long long _index) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Get process by index" << _index; | ||||||
|  |  | ||||||
|  |     return m_processes.contains(_index) ? m_processes[_index] : nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn processes | ||||||
|  |  */ | ||||||
|  | QueuedProcessMap QueuedProcessManager::processes() | ||||||
|  | { | ||||||
|  |     return m_processes; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn remove | ||||||
|  |  */ | ||||||
|  | void QueuedProcessManager::remove(const long long _index) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Remove process by index" << _index; | ||||||
|  |  | ||||||
|  |     if (!m_processes.contains(_index)) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     QueuedProcess *process = m_processes.take(_index); | ||||||
|  |     auto connection = m_connections.take(_index); | ||||||
|  |     disconnect(connection); | ||||||
|  |  | ||||||
|  |     switch (m_onExit) { | ||||||
|  |     case OnExitAction::Kill: | ||||||
|  |         process->kill(); | ||||||
|  |         break; | ||||||
|  |     case OnExitAction::Terminate: | ||||||
|  |         process->terminate(); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     process->deleteLater(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @fn taskFinished | ||||||
|  |  */ | ||||||
|  | void QueuedProcessManager::taskFinished(const int _exitCode, | ||||||
|  |                                         const QProcess::ExitStatus _exitStatus, | ||||||
|  |                                         const long long _index) | ||||||
|  | { | ||||||
|  |     qCDebug(LOG_LIB) << "Process" << _index << "finished with code" << _exitCode | ||||||
|  |                      << "and status" << _exitStatus; | ||||||
|  |  | ||||||
|  |     // TODO implementation | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user