Page MenuHomePhabricator

No OneTemporary

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

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

Event Timeline