Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F193408
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
35 KB
Subscribers
None
View Options
diff --git a/restruct.pro b/restruct.pro
--- a/restruct.pro
+++ b/restruct.pro
@@ -1,48 +1,49 @@
######################################################################
# Project started 11.01.2008 at 13:10
######################################################################
QT += core concurrent
TEMPLATE = app
TARGET = restruct
CONFIG += c++14
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
isEmpty(INCLUDEPATH): INCLUDEPATH = $$(HOME)/src/include
isEmpty(LIBS): LIBS = -L$$(HOME)/src/lib
INCLUDEPATH += src
unix:INCLUDEPATH += /usr/include/postgresql
LIBS += -lktools -lsqlproc -lpq
SOURCES += src/updater.cpp \
- src/exitcode.cpp
+ src/exitcode.cpp \
+ src/psettings.cpp
HEADERS += \
src/updater.h \
src/psettings.h \
src/exitcode.h
RESOURCES += resource/project.qrc
win32 {
QT += gui widgets
SOURCES += src/main_win.cpp src/mainwindow.cpp
HEADERS += src/mainwindow.h
RC_FILE = resource/project.rc
contains(DEFINES,SQLPROC_STATIC):LIBS += -luuid -loleaut32
}
unix {
CONFIG += console
SOURCES += src/main_lin.cpp src/mainconsole.cpp
HEADERS += src/mainconsole.h
}
target.path = /bin # install location
INSTALLS += target
diff --git a/src/mainconsole.cpp b/src/mainconsole.cpp
--- a/src/mainconsole.cpp
+++ b/src/mainconsole.cpp
@@ -1,229 +1,159 @@
#include "exitcode.h"
#include "mainconsole.h"
#include "psettings.h"
#include "updater.h"
-#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)), 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 LOGFILE_VALUE = QStringLiteral("файл_журнала");
- 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 LOGFILE_OPTION = QStringLiteral("L");
- QString URIDB_OPTION = QStringLiteral("u");
- 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 logfileOption(LOGFILE_OPTION, QStringLiteral("Сохранить протокол работы в файл"), LOGFILE_VALUE);
- parser.addOption(logfileOption);
- QCommandLineOption dropdbOption(DROPDB_OPTION, QStringLiteral("Сначала удалить базу данных"));
- parser.addOption(dropdbOption);
- QCommandLineOption uridbOption(URIDB_OPTION, QStringLiteral("Не создавать учебную базу данных"));
- parser.addOption(uridbOption);
- 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.logfile = parser.value(logfileOption);
- result.dropdb = parser.isSet(dropdbOption);
- result.uridb = !parser.isSet(uridbOption);
-
- 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 char* CONSOLE_BRIGHT_RED_BEGIN = "\x1B[1m\x1B[31m";
static const char* CONSOLE_RESET = "\x1B(B\x1B[m";
hideProgress();
_os << CONSOLE_BRIGHT_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)
{
static const char* CONSOLE_GREEN_BEGIN = "\x1B[0m\x1B[32m";
static const char* CONSOLE_RESET = "\x1B(B\x1B[m";
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' << CONSOLE_GREEN_BEGIN << bytes << CONSOLE_RESET << 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,45 +1,44 @@
#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
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1,473 +1,393 @@
#include "exitcode.h"
#include "mainwindow.h"
#include "psettings.h"
#include "updater.h"
#include <kactivityindicator.h>
#include <ksettings.h>
#include <sqlproc.h>
#include <klogon_win.h>
#include <QApplication>
#include <QCloseEvent>
#include <QEvent>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QLabel>
#include <QProgressBar>
#include <QPushButton>
#include <QShortcut>
#include <QStandardPaths>
#include <QStyle>
#include <QTextCodec>
#include <QTextEdit>
#include <QTimer>
#include <QVBoxLayout>
#include <QtConcurrentRun>
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags)
: QDialog(parent, flags)
, _exitCode(0)
, _errorCount(0)
, _updater(new DatabaseUpdater)
{
setWindowTitle(QStringLiteral("Создание/обновление базы данных"));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setSizeGripEnabled(true);
QHBoxLayout* mainLayout = new QHBoxLayout;
QVBoxLayout* leftLayout = new QVBoxLayout;
QVBoxLayout* rightLayout = new QVBoxLayout;
QHBoxLayout* bottomRightLayout = new QHBoxLayout;
leftLayout->setContentsMargins(0,
2 * style()->pixelMetric(QStyle::PM_LayoutTopMargin),
style()->pixelMetric(QStyle::PM_LayoutRightMargin), 0);
QLabel* picture = new QLabel;
picture->setPixmap(QPixmap(":/picture.png"));
//кнопки, скрытые до завершения процесса
_btnSave = new QPushButton(QStringLiteral("Сохранить"));
_btnClose = new QPushButton(QStringLiteral("Закрыть"));
_btnSave->setVisible(false);
_btnClose->setVisible(false);
_btnClose->setDefault(true);
leftLayout->addWidget(picture);
leftLayout->addStretch();
leftLayout->addWidget(_btnSave);
leftLayout->addWidget(_btnClose);
QLabel* label = new QLabel(QStringLiteral("Протокол работы"));
rightLayout->addWidget(label);
_protocol = new QTextEdit();
_protocol->setReadOnly(true);
label->setBuddy(_protocol);
rightLayout->addWidget(_protocol);
//индикаторы выполнения
_progress = new QProgressBar;
_progress->setTextVisible(false);
_ai = new KActivityIndicator;
_ai->setVisible(false);
bottomRightLayout->addWidget(_progress);
bottomRightLayout->addWidget(_ai);
rightLayout->addLayout(bottomRightLayout);
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
setLayout(mainLayout);
//нажатие Esc не соединяется со слотом, чтобы окно не закрывалось
new QShortcut(QKeySequence(Qt::Key_Escape), this);
//соединить сигналы со слотами
connect(_btnSave, SIGNAL(clicked()), this, SLOT(saveProtocol()));
connect(_btnClose, SIGNAL(clicked()), this, SLOT(closeDialog()));
QTimer::singleShot(0, this, SLOT(startExecution()));
}
MainWindow::~MainWindow()
{
delete _updater;
}
//---------------------------------------------------------------------------
void MainWindow::closeEvent(QCloseEvent* a_event)
{
if (_futureWatcher.isRunning())
a_event->ignore();
else
a_event->accept();
}
//---------------------------------------------------------------------------
void MainWindow::startExecution()
{
if (_futureWatcher.isRunning())
return;
- ProgramSettings pset;
-
- processArguments(pset);
+ ProgramSettings pset = processArguments();
logon(pset);
connect(_updater, SIGNAL(progress(int)), _progress, SLOT(setValue(int)));
connect(_updater, SIGNAL(error(const QString&)), this, SLOT(error(const QString&)));
connect(_updater, SIGNAL(message(const QString&)), this, SLOT(message(const QString&)));
connect(_updater, SIGNAL(sqlError(const QString&, const QString&, const QString&)),
this, SLOT(sqlError(const QString&, const QString&, const QString&)));
connect(_updater, SIGNAL(logConnectionParameters(const QString&, const QString&, const QString&)),
this, SLOT(logConnectionParameters(const QString&, const QString&, const QString&)));
connect(&_futureWatcher, SIGNAL(finished()), this, SLOT(finishExecution()));
_ai->setVisible(true);
_ai->start();
//int rc = _updater.run( pset );
QFuture<int> rc = QtConcurrent::run(_updater, &DatabaseUpdater::run, pset);
_futureWatcher.setFuture(rc);
}
//---------------------------------------------------------------------------
void MainWindow::finishExecution()
{
_ai->stop();
_ai->setVisible(false);
//проверяем число ошибок, т.к. при выполнении без транзакции run() всегда возвращает 0
if (_errorCount == 0)
{
ExitCode rc(_updater->revisionBefore(), _updater->revisionAfter());
message(rc.message());
_exitCode = rc.exitCode();
closeDialog(); //при успешном завершении, то окно закрывается автоматически
}
else
{
_btnClose->show();
_btnSave->show();
_btnClose->setFocus();
message(QStringLiteral("Выполнение прервано в результате ошибки.\nБаза данных не изменилась."));
_exitCode = -1;
}
}
//---------------------------------------------------------------------------
int MainWindow::executeAction()
{
- ProgramSettings pset;
-
- processArguments(pset);
+ ProgramSettings pset = processArguments();
logon(pset);
_ai->start();
DatabaseUpdater updater;
connect(&updater, SIGNAL(progress(int)), _progress, SLOT(setValue(int)));
connect(&updater, SIGNAL(error(const QString&)), this, SLOT(error(const QString&)));
connect(&updater, SIGNAL(message(const QString&)), this, SLOT(message(const QString&)));
connect(&updater, SIGNAL(sqlError(const QString&, const QString&, const QString&)),
this, SLOT(sqlError(const QString&, const QString&, const QString&)));
connect(&updater, SIGNAL(logConnectionParameters(const QString&, const QString&, const QString&)),
this, SLOT(logConnectionParameters(const QString&, const QString&, const QString&)));
int rc = updater.run(pset);
//проверяем число ошибок, т.к. при выполнении без транзакции run() всегда возвращает 0
if (_errorCount == 0)
{
int before = updater.revisionBefore();
int after = updater.revisionAfter();
if (before == after)
message(QStringLiteral("База данных в актуальном состоянии."));
else if (before == 0)
message(QStringLiteral("База данных создана и обновлена до версии %1.").arg(after));
else
message(QStringLiteral("База данных версии %1 обновлена до версии %2.").arg(before).arg(after));
rc = (before & 0xFFFF) | ((after & 0xFFFF) << 16);
}
else
{
_btnClose->show();
_btnSave->show();
_btnClose->setFocus();
message(QStringLiteral("Выполнение прервано в результате ошибки."
"<br>База данных не изменилась."));
rc = -1;
}
return rc;
}
-void MainWindow::processArguments(ProgramSettings& a_pset)
-{
- QString USERNAME_PARAM("username");
- QString PASSWORD_PARAM("password");
- QString DATABASE_PARAM("database");
- QString DROPDB_PARAM("dropdb");
- QString HOST_PARAM("host");
- QString PORT_PARAM("port");
- QString FILE_PARAM("file");
-
- //заполнить параметры default значениями
- QHash<QString, QString> params;
- params.insert(USERNAME_PARAM, QString());
- params.insert(PASSWORD_PARAM, QString());
- params.insert(DATABASE_PARAM, QString());
- params.insert(DROPDB_PARAM, QString());
- params.insert(HOST_PARAM, QString());
- params.insert(PORT_PARAM, QString());
- params.insert(FILE_PARAM, QString());
-
- //чтение аргументов
- QString key;
- QStringList arguments = QApplication::arguments();
- auto end = arguments.cend();
- auto begin = arguments.cbegin();
- for (auto it = begin + 1; it != end; ++it) //пропускаем первый параметр - имя программы
- {
- QString curArg = *it;
-
- if (curArg.at(0) == QChar('-'))
- { //обработка короткого параметра
- key.clear();
- switch (curArg.at(1).toLatin1())
- {
- case 'U':
- key = USERNAME_PARAM;
- break;
- case 'd':
- key = DATABASE_PARAM;
- break;
- case 'f':
- key = FILE_PARAM;
- break;
- case 'h':
- key = HOST_PARAM;
- break;
- case 'p':
- key = PORT_PARAM;
- break;
- case 'W':
- key = PASSWORD_PARAM;
- break;
- case '0':
- params[ DROPDB_PARAM ] = '1';
- break;
- }
- }
- else
- { //обработка одиночного параметра
- if (key.isEmpty())
- key = FILE_PARAM;
- params[ key ] = curArg;
- key.clear();
- }
- }
-
- //записать прочитанные значения в структуру ProgramSettings
- a_pset.username = params.value(USERNAME_PARAM);
- a_pset.password = params.value(PASSWORD_PARAM);
- a_pset.database = params.value(DATABASE_PARAM);
- a_pset.host = params.value(HOST_PARAM);
- a_pset.port = params.value(PORT_PARAM);
- a_pset.controlFile = params.value(FILE_PARAM);
- a_pset.dropdb = !params.value(DROPDB_PARAM).isEmpty();
-}
-
//---------------------------------------------------------------------------
void MainWindow::logon(ProgramSettings& a_pset)
{
if (!a_pset.host.isEmpty() || !a_pset.username.isEmpty())
return;
KLogon* logon = KLogon::create();
if (!logon)
return;
QString defaultDSN;
QString ospoName;
HKEY k;
DWORD cb = 0;
QString valuename("System Directory");
if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\irs\\b04"), 0, KEY_QUERY_VALUE, &k) == ERROR_SUCCESS
|| RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\irs\\b03"), 0, KEY_QUERY_VALUE, &k) == ERROR_SUCCESS)
&& RegQueryValueEx(k, LPCTSTR(valuename.constData()), 0, 0, 0, &cb) == ERROR_SUCCESS
&& cb > 0)
{
QString systemdir;
systemdir.resize((cb / sizeof(QChar)) - 1);
RegQueryValueEx(k, LPCTSTR(valuename.constData()), 0, 0, LPBYTE(systemdir.data()), &cb);
RegCloseKey(k);
KSettings systemini(systemdir + "/system.ini");
systemini.beginGroup("Database");
defaultDSN = systemini.value("DefaultDSN").toString();
systemini.endGroup();
systemini.beginGroup("Common");
ospoName = systemini.value("SystemName").toString().replace(QLatin1Char('B'),QStringLiteral("ОСПО Б-"));
}
QString username = QString::fromLocal8Bit(qgetenv("USERNAME"));
QHash<QString, QString> aliases = loadAliases(ospoName);
if (aliases.contains(username))
username = aliases[username];
logon->setParent(winId());
logon->setUsername(username);
if (!defaultDSN.isNull())
logon->setDSN(defaultDSN);
if (!logon->execute())
emit message(QStringLiteral("Отказ от ввода имени и пароля пользователя"));
else
{
a_pset.host = logon->host();
a_pset.username = logon->username();
a_pset.password = logon->password();
}
delete logon;
}
//---------------------------------------------------------------------------
QHash<QString, QString> MainWindow::loadAliases(const QString& a_ospoName)
{
QHash<QString, QString> result;
QApplication::setOrganizationName(a_ospoName);
QString filename = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).at(1);
filename.replace(QApplication::applicationName(), QStringLiteral("aliases.conf"));
QFile inf(filename);
if (inf.open(QIODevice::ReadOnly))
{
QTextStream is(&inf);
is.setCodec(QTextCodec::codecForName("UTF-8"));
while ( !is.atEnd() )
{
QStringList chunks = is.readLine().split(QLatin1Char(':'));
if (chunks.size() == 2)
result[chunks.at(0).trimmed()] = chunks.at(1).trimmed();
}
}
return result;
}
//---------------------------------------------------------------------------
void MainWindow::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 MainWindow::sqlError(const QString& a_dbError,
const QString& a_commandDescription,
const QString& a_command)
{
QString errorHtml;
if (!a_commandDescription.isEmpty())
errorHtml.append(QStringLiteral("<font color=\"#0000FF\">Операция:</font><br>")).append(a_commandDescription).append("<br>");
QString dbError = a_dbError;
errorHtml.append(QStringLiteral("<font color=\"#0000FF\">Сообщение об ошибке:</font><pre>")).append(dbError.trimmed().replace('\n', "<br>")).append("</pre>");
if (!a_command.isEmpty())
errorHtml.append(QStringLiteral("<font color=\"#0000FF\">Текст команды:</font><pre>")).append(a_command).append("</pre>");
errorHtmlToLog(errorHtml);
}
//---------------------------------------------------------------------------
void MainWindow::error(const QString& a_error)
{
QString errorHtml = a_error;
errorHtmlToLog(errorHtml.replace('<', "<").replace('>', ">").replace('\n', "<br>"));
}
//---------------------------------------------------------------------------
void MainWindow::errorHtmlToLog(const QString& a_errorHtml)
{
QString errorHtml = a_errorHtml;
QTextCursor cursor = _protocol->textCursor();
cursor.insertHtml(QStringLiteral("<font color=\"#0000FF\">Ошибка</font><br>"));
cursor.insertHtml(errorHtml);
cursor.insertHtml(QStringLiteral("<hr>"));
_protocol->moveCursor(QTextCursor::End);
++_errorCount;
}
QString MainWindow::toHtml(const QString& a_text)
{
QString result = a_text;
static const QString BOLD = QStringLiteral("**");
static const QString HTML_BOLD_BEGIN = QStringLiteral("<b>");
static const QString HTML_BOLD_END = QStringLiteral("</b>");
static const QString HTML_BR = QStringLiteral("<br>");
static const QString HTML_NBSP = QStringLiteral(" ");
static const QChar NL('\n');
static const QChar TAB('\t');
bool begin = true;
int pos = result.indexOf(BOLD);
while (pos >= 0)
{
result.replace(pos, BOLD.size(), begin ? HTML_BOLD_BEGIN : HTML_BOLD_END);
begin = !begin;
pos = result.indexOf(BOLD, pos + 1);
}
if (result.contains(NL))
result.replace(NL, HTML_BR);
if (result.contains(TAB))
result.replace(TAB, HTML_NBSP);
return result;
}
//---------------------------------------------------------------------------
void MainWindow::message(const QString& a_message)
{
QString message = a_message;
_protocol->textCursor().insertHtml(toHtml(message).append(QStringLiteral("<br>")));
_protocol->moveCursor(QTextCursor::End);
}
//---------------------------------------------------------------------------
void MainWindow::closeDialog()
{
QDialog::done(_exitCode);
}
//---------------------------------------------------------------------------
void MainWindow::saveProtocol()
{
QString filename = QFileDialog::getSaveFileName(this,
QStringLiteral("Сохранить протокол в файл…"), QString(),
QStringLiteral("Текстовые файлы (*.txt);;Все файлы (*.*)"));
if (!filename.isEmpty())
{
QFile outf(filename);
if (outf.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
QTextStream os(&outf);
os.setGenerateByteOrderMark(true);
os.setCodec("UTF-8");
os << _protocol->toPlainText();
}
}
}
//!главное окно приложения
diff --git a/src/mainwindow.h b/src/mainwindow.h
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -1,64 +1,63 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QDialog>
#include <QFutureWatcher>
#include <QString>
class QLabel;
class QListWidget;
class QPushButton;
class QProgressBar;
class QTextEdit;
class ProgramSettings;
class SqlErrorDialog;
class SqlProcessor;
class DatabaseUpdater;
class ProgramSettings;
class KActivityIndicator;
class MainWindow : public QDialog
{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0, Qt::WindowFlags flags = 0);
~MainWindow() override;
private slots:
void saveProtocol();
void closeDialog();
void startExecution();
void finishExecution();
void error(const QString& a_error);
void message(const QString& a_message);
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);
protected:
void closeEvent(QCloseEvent* a_event) override;
private:
int executeAction();
void logon(ProgramSettings& a_pset);
- void processArguments(ProgramSettings& a_pset);
void errorHtmlToLog(const QString& a_errorHtml);
static QString toHtml(const QString& a_text);
static QHash<QString, QString> loadAliases(const QString &a_ospoName);
int _exitCode;
int _errorCount;
QTextEdit* _protocol;
QLabel* _lblWait;
QPushButton* _btnSave;
QPushButton* _btnClose;
KActivityIndicator* _ai;
QProgressBar* _progress;
QFutureWatcher<int> _futureWatcher;
DatabaseUpdater* _updater;
};
//!главное окно приложения
#endif //MAINWINDOW_H
diff --git a/src/psettings.cpp b/src/psettings.cpp
new file mode 100644
--- /dev/null
+++ b/src/psettings.cpp
@@ -0,0 +1,71 @@
+#include "psettings.h"
+#include <QCommandLineParser>
+
+ProgramSettings 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 LOGFILE_VALUE = QStringLiteral("файл_журнала");
+ 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 LOGFILE_OPTION = QStringLiteral("L");
+ QString URIDB_OPTION = QStringLiteral("u");
+ 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 logfileOption(LOGFILE_OPTION, QStringLiteral("Сохранить протокол работы в файл"), LOGFILE_VALUE);
+ parser.addOption(logfileOption);
+ QCommandLineOption dropdbOption(DROPDB_OPTION, QStringLiteral("Сначала удалить базу данных"));
+ parser.addOption(dropdbOption);
+ QCommandLineOption uridbOption(URIDB_OPTION, QStringLiteral("Не создавать учебную базу данных"));
+ parser.addOption(uridbOption);
+ 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.logfile = parser.value(logfileOption);
+ result.dropdb = parser.isSet(dropdbOption);
+ result.uridb = !parser.isSet(uridbOption);
+
+ 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;
+}
diff --git a/src/psettings.h b/src/psettings.h
--- a/src/psettings.h
+++ b/src/psettings.h
@@ -1,24 +1,26 @@
#if !defined PSETTINGS_H
#define PSETTINGS_H
#include <QString>
class ProgramSettings
{
public:
ProgramSettings() : dbVersion(0), dropdb(false), uridb(true) {}
QString username;
QString password;
QString database;
QString host;
QString port;
QString controlFile;
QString logfile;
QString packageId;
QString helpText;
int dbVersion;
bool dropdb;
bool uridb;
};
+ProgramSettings processArguments();
+
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jun 11, 8:11 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
127129
Attached To
rRCT Программа создания/обновления структуры БД
Event Timeline
Log In to Comment