Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F193423
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Subscribers
None
View Options
diff --git a/src/mainconsole.cpp b/src/mainconsole.cpp
--- a/src/mainconsole.cpp
+++ b/src/mainconsole.cpp
@@ -1,191 +1,218 @@
#include "exitcode.h"
#include "mainconsole.h"
#include "psettings.h"
#include "updater.h"
#include <QDebug>
#include <QCommandLineParser>
#include <QTimer>
#include <QtConcurrentRun>
MainConsole::MainConsole(QObject* a_parent)
: QObject(a_parent)
, _exitCode(0)
, _errorCount(0)
, _os(stdout)
, _updater(new DatabaseUpdater)
{
}
MainConsole::~MainConsole()
{
delete _updater;
}
void MainConsole::run()
{
ProgramSettings pset = processArguments();
if (!pset.helpText.isEmpty())
{
_os << pset.helpText;
QTimer::singleShot(0, this, &MainConsole::quit);
return;
}
-// connect(_updater, SIGNAL(progress(int)), _progress, SLOT(setValue(int)));
+ connect(_updater, SIGNAL(progress(int)), this, SLOT(progress(int)));
connect(_updater, SIGNAL(error(const QString&)), SLOT(error(const QString&)));
connect(_updater, SIGNAL(message(const QString&)), SLOT(message(const QString&)));
connect(_updater, SIGNAL(sqlError(const QString&, const QString&, const QString&)),
SLOT(sqlError(const QString&, const QString&, const QString&)));
connect(_updater, SIGNAL(logConnectionParameters(const QString&, const QString&, const QString&)),
SLOT(logConnectionParameters(const QString&, const QString&, const QString&)));
connect(&_futureWatcher, SIGNAL(finished()), SLOT(finishExecution()));
QFuture<int> rc = QtConcurrent::run(_updater, &DatabaseUpdater::run, pset);
_futureWatcher.setFuture(rc);
}
void MainConsole::quit()
{
emit finished();
}
void MainConsole::finishExecution()
{
//проверяем число ошибок, т.к. при выполнении без транзакции run() всегда возвращает 0
if (_errorCount == 0)
{
ExitCode rc(_updater->revisionBefore(), _updater->revisionAfter());
message(rc.message());
_exitCode = 0;
}
else
{
message(QStringLiteral("Выполнение прервано в результате ошибки.\nБаза данных не изменилась."));
_exitCode = 1;
}
emit finished();
}
ProgramSettings MainConsole::processArguments()
{
ProgramSettings result;
QString USERNAME_VALUE = QStringLiteral("пользователь");
QString PASSWORD_VALUE = QStringLiteral("пароль");
QString DATABASE_VALUE = QStringLiteral("база_данных");
QString HOST_VALUE = QStringLiteral("адрес_сервера");
QString PORT_VALUE = QStringLiteral("номер_порта");
QString FILE_VALUE = QStringLiteral("file.dmv");
QString USERNAME_OPTION = QStringLiteral("U");
QString PASSWORD_OPTION = QStringLiteral("W");
QString DATABASE_OPTION = QStringLiteral("d");
QString DROPDB_OPTION = QStringLiteral("0");
QString HOST_OPTION = QStringLiteral("h");
QString PORT_OPTION = QStringLiteral("p");
QString FILE_OPTION = QStringLiteral("f");
QString HELP_OPTION = QStringLiteral("help");
//обработать аргументы командной строки
QCommandLineParser parser;
QCommandLineOption helpOption(HELP_OPTION, QStringLiteral("Показать справку") );
parser.addOption(helpOption);
QCommandLineOption usernameOption(USERNAME_OPTION, QStringLiteral("Имя пользователя"), USERNAME_VALUE);
parser.addOption(usernameOption);
QCommandLineOption databaseOption(DATABASE_OPTION, QStringLiteral("Имя базы данных"), DATABASE_VALUE);
parser.addOption(databaseOption);
QCommandLineOption filenameOption(FILE_OPTION, QStringLiteral("Управляющий файл"), FILE_VALUE);
parser.addOption(filenameOption);
QCommandLineOption hostOption(HOST_OPTION, QStringLiteral("Адрес сервера"), HOST_VALUE);
parser.addOption(hostOption);
QCommandLineOption portOption(PORT_OPTION, QStringLiteral("Порт сервера"), PORT_VALUE);
parser.addOption(portOption);
QCommandLineOption passwordOption(PASSWORD_OPTION, QStringLiteral("Пароль"), PASSWORD_VALUE);
parser.addOption(passwordOption);
QCommandLineOption dropdbOption(DROPDB_OPTION, QStringLiteral("Сначала удалить базу данных") );
parser.addOption(dropdbOption);
parser.addPositionalArgument(FILE_VALUE, QStringLiteral("Управляющий файл"), FILE_VALUE);
parser.process(*qApp);
//записать прочитанные значения в структуру ProgramSettings
result.username = parser.value(usernameOption);
result.password = parser.value(passwordOption);
result.database = parser.value(databaseOption);
result.host = parser.value(hostOption);
result.port = parser.value(portOption);
result.dropdb = parser.isSet(dropdbOption);
if (parser.isSet(filenameOption))
result.controlFile = parser.value(filenameOption);
else if (parser.positionalArguments().size() > 0)
result.controlFile = parser.positionalArguments().at(0);
if (parser.isSet(helpOption))
result.helpText = parser.helpText();
return result;
}
void MainConsole::error(const QString& a_error)
{
- static const auto CONSOLE_RED_BEGIN = QByteArray("\x1B[1m\x1B[31m");
- static const auto CONSOLE_RESET = QByteArray("\x1B(B\x1B[m");
+ static const char* CONSOLE_RED_BEGIN = "\x1B[1m\x1B[31m";
+ static const char* CONSOLE_RESET = "\x1B(B\x1B[m";
+ hideProgress();
_os << CONSOLE_RED_BEGIN << QStringLiteral("ОШИБКА") << CONSOLE_RESET << endl;
message(a_error);
_os << CONSOLE_RESET << endl;
++_errorCount;
}
void MainConsole::message(const QString& a_message)
{
+ hideProgress();
_os << toConsoleText(a_message) << endl;
}
+void MainConsole::progress(int a_value)
+{
+ char bytes[50 + 2 + 1];
+ auto begin = std::begin(bytes);
+ auto end = std::end(bytes) - 1;
+ *begin++ = '[';
+ *end-- = '\0';
+ *end = ']';
+ std::fill(begin, end, '.');
+ int done = a_value / 2;
+ std::fill(begin, begin + done, 'O');
+ if (a_value & 1)
+ bytes[done + 1] = 'o';
+ _os << '\r' << bytes << flush;
+}
+
+void MainConsole::hideProgress()
+{
+ static const char* CONSOLE_ERASE_LINE = "\r\x1B[K";
+ _os << CONSOLE_ERASE_LINE << flush;
+}
+
QString MainConsole::toConsoleText(const QString& a_text)
{
QString result = a_text;
static const QString BOLD = QStringLiteral("**");
static const QString CONSOLE_BOLD_BEGIN = QStringLiteral("\x1B[1m");
static const QString CONSOLE_RESET = QStringLiteral("\x1B(B\x1B[m");
static const QString CONSOLE_TAB = QStringLiteral(" ");
static const QChar TAB('\t');
bool begin = true;
int pos = result.indexOf(BOLD);
while (pos >= 0)
{
result.replace(pos, BOLD.size(), begin ? CONSOLE_BOLD_BEGIN : CONSOLE_RESET);
begin = !begin;
pos = result.indexOf(BOLD, pos + 1);
}
if (result.contains(TAB))
result.replace(TAB, CONSOLE_TAB);
+ if (result.endsWith(QChar('\n')))
+ result.chop(1);
+
return result;
}
void MainConsole::logConnectionParameters(const QString& a_host, const QString& a_database, const QString& a_username)
{
message(QStringLiteral("Подключение к базе данных\n"
"\tСервер: **%1**\n\tБаза данных: **%2**\n"
"\tПользователь: **%3**")
.arg(a_host, a_database, a_username));
}
void MainConsole::sqlError(const QString& a_dbError, const QString& a_commandDescription, const QString& a_command)
{
QString errorText;
if (!a_commandDescription.isEmpty())
errorText.append(QStringLiteral("**Операция:**\n")).append(a_commandDescription).append("\n\n");
QString dbError = a_dbError;
errorText.append(QStringLiteral("**Сообщение об ошибке:**\n")).append(dbError.trimmed()).append("\n\n");
if (!a_command.isEmpty())
errorText.append(QStringLiteral("**Текст команды:**\n")).append(a_command);
error(errorText);
}
diff --git a/src/mainconsole.h b/src/mainconsole.h
--- a/src/mainconsole.h
+++ b/src/mainconsole.h
@@ -1,43 +1,45 @@
#ifndef MAINCLASS_H
#define MAINCLASS_H
#include <QFutureWatcher>
#include <QObject>
#include <QTextStream>
class ProgramSettings;
class DatabaseUpdater;
class QStringList;
class MainConsole : public QObject
{
Q_OBJECT
public:
MainConsole(QObject* a_parent = nullptr);
~MainConsole() override;
int exitCode() const { return _exitCode; }
signals:
void finished();
public slots:
void run();
void quit();
void finishExecution();
void error(const QString& a_error);
void message(const QString& a_message);
+ void progress(int a_value);
void logConnectionParameters(const QString& a_host, const QString& a_database,
const QString& a_username);
void sqlError(const QString& a_dbError, const QString& a_commandDescription,
const QString& a_command);
private:
int _exitCode;
int _errorCount;
QTextStream _os;
DatabaseUpdater* _updater;
QFutureWatcher<int> _futureWatcher;
ProgramSettings processArguments();
QString toConsoleText(const QString& a_text);
+ void hideProgress();
};
#endif // MAINCLASS_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jun 11, 8:15 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
127140
Attached To
rRCT Программа создания/обновления структуры БД
Event Timeline
Log In to Comment