diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,461 +1,457 @@ #include "mainwindow.h" -#include "updater.h" #include "psettings.h" #include "sqlerrordlg.h" -#include +#include "updater.h" #include #include +#include #ifdef Q_OS_WIN32 #include #endif #include #include #include -#include #include #include -#include +#include +#include #include -#include -#include #include #include #include +#include +#include //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -MainWindow::MainWindow( QWidget* parent, Qt::WindowFlags flags ) - : QDialog( parent, flags ) - , _exitCode( 0 ) - , _actionEventType( QEvent::User ) - , _errorCount( 0 ) - , _updater( new DatabaseUpdater ) +MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags) + : QDialog(parent, flags) + , _exitCode(0) + , _actionEventType(QEvent::User) + , _errorCount(0) + , _updater(new DatabaseUpdater) { - setWindowTitle( QString::fromUtf8( "Создание/обновление базы данных" ) ); - setWindowFlags( windowFlags() & ~Qt::WindowContextHelpButtonHint ); - setSizeGripEnabled( true ); + setWindowTitle(QString::fromUtf8("Создание/обновление базы данных")); + 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 ); + leftLayout->setContentsMargins(0, + 2 * style()->pixelMetric(QStyle::PM_LayoutTopMargin), + style()->pixelMetric(QStyle::PM_LayoutRightMargin), 0); QLabel* picture = new QLabel; - picture->setPixmap( QPixmap( ":/picture.png" ) ); + picture->setPixmap(QPixmap(":/picture.png")); //кнопки, скрытые до завершения процесса - _btnSave = new QPushButton( QString::fromUtf8( "Сохранить" ) ); - _btnClose = new QPushButton( QString::fromUtf8( "Закрыть" ) ); - _btnSave->setVisible( false ); - _btnClose->setVisible( false ); - _btnClose->setDefault( true ); - - leftLayout->addWidget( picture ); + _btnSave = new QPushButton(QString::fromUtf8("Сохранить")); + _btnClose = new QPushButton(QString::fromUtf8("Закрыть")); + _btnSave->setVisible(false); + _btnClose->setVisible(false); + _btnClose->setDefault(true); + + leftLayout->addWidget(picture); leftLayout->addStretch(); - leftLayout->addWidget( _btnSave ); - leftLayout->addWidget( _btnClose ); + leftLayout->addWidget(_btnSave); + leftLayout->addWidget(_btnClose); - QLabel* label = new QLabel( QString::fromUtf8( "Протокол работы" ) ); - rightLayout->addWidget( label ); + QLabel* label = new QLabel(QString::fromUtf8("Протокол работы")); + rightLayout->addWidget(label); _protocol = new QTextEdit(); - _protocol->setReadOnly( true ); - label->setBuddy( _protocol ); - rightLayout->addWidget( _protocol ); + _protocol->setReadOnly(true); + label->setBuddy(_protocol); + rightLayout->addWidget(_protocol); //индикаторы выполнения _progress = new QProgressBar; - _progress->setTextVisible( false ); - _ai = new KActivityIndicator( KActivityIndicator::Gray ); - _ai->setVisible( false ); + _progress->setTextVisible(false); + _ai = new KActivityIndicator(KActivityIndicator::Gray); + _ai->setVisible(false); - bottomRightLayout->addWidget( _progress ); - bottomRightLayout->addWidget( _ai ); - rightLayout->addLayout( bottomRightLayout ); + bottomRightLayout->addWidget(_progress); + bottomRightLayout->addWidget(_ai); + rightLayout->addLayout(bottomRightLayout); - mainLayout->addLayout( leftLayout ); - mainLayout->addLayout( rightLayout ); - setLayout( mainLayout ); + mainLayout->addLayout(leftLayout); + mainLayout->addLayout(rightLayout); + setLayout(mainLayout); //нажатие Esc не соединяется со слотом, чтобы окно не закрывалось - new QShortcut( QKeySequence(Qt::Key_Escape), this ); + new QShortcut(QKeySequence(Qt::Key_Escape), this); //соединить сигналы со слотами - connect( _btnSave, SIGNAL(clicked()), this, SLOT(saveProtocol()) ); - connect( _btnClose, SIGNAL(clicked()), this, SLOT(closeDialog()) ); + connect(_btnSave, SIGNAL(clicked()), this, SLOT(saveProtocol())); + connect(_btnClose, SIGNAL(clicked()), this, SLOT(closeDialog())); //получить незадействованный тип события _actionEventType = QEvent::registerEventType(); } MainWindow::~MainWindow() { delete _updater; } //--------------------------------------------------------------------------- -void MainWindow::showEvent( QShowEvent* a_event ) +void MainWindow::showEvent(QShowEvent* a_event) { - QDialog::showEvent( a_event ); - qApp->postEvent( this, new QEvent( QEvent::Type(_actionEventType) ) ); + QDialog::showEvent(a_event); + qApp->postEvent(this, new QEvent(QEvent::Type(_actionEventType))); } //--------------------------------------------------------------------------- -bool MainWindow::event( QEvent* a_event ) +bool MainWindow::event(QEvent* a_event) { - if ( a_event->type() == _actionEventType ) + if (a_event->type() == _actionEventType) { startExecution(); a_event->accept(); return true; } - return QWidget::event( a_event ); + return QWidget::event(a_event); } //--------------------------------------------------------------------------- -void MainWindow::closeEvent( QCloseEvent* a_event ) +void MainWindow::closeEvent(QCloseEvent* a_event) { - if ( _futureWatcher.isRunning() ) + if (_futureWatcher.isRunning()) a_event->ignore(); else a_event->accept(); } //--------------------------------------------------------------------------- void MainWindow::startExecution() { - if ( _futureWatcher.isRunning() ) + if (_futureWatcher.isRunning()) return; ProgramSettings pset; - processArguments( pset ); - logon( pset ); + processArguments(pset); + 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 ); + 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 rc = QtConcurrent::run( _updater, &DatabaseUpdater::run, pset ); - _futureWatcher.setFuture( rc ); + QFuture rc = QtConcurrent::run(_updater, &DatabaseUpdater::run, pset); + _futureWatcher.setFuture(rc); } //--------------------------------------------------------------------------- void MainWindow::finishExecution() { _ai->stop(); - _ai->setVisible( false ); + _ai->setVisible(false); //проверяем число ошибок, т.к. при выполнении без транзакции run() всегда возвращает 0 - if ( _errorCount == 0 ) + if (_errorCount == 0) { int before = _updater->revisionBefore(); int after = _updater->revisionAfter(); - if ( before == after ) - message( QString::fromUtf8( "База данных в актуальном состоянии." ) ); - else if ( before == 0 ) - message( QString::fromUtf8( "База данных создана и обновлена до версии %1." ).arg( after ) ); + if (before == after) + message(QString::fromUtf8("База данных в актуальном состоянии.")); + else if (before == 0) + message(QString::fromUtf8("База данных создана и обновлена до версии %1.").arg(after)); else - message( QString::fromUtf8( "База данных версии %1 обновлена до версии %2." ). - arg( before ).arg( after ) ); + message(QString::fromUtf8("База данных версии %1 обновлена до версии %2.").arg(before).arg(after)); _exitCode = (before & 0xFFFF) | ((after & 0xFFFF) << 16); closeDialog(); //при успешном завершении, то окно закрывается автоматически } else { _btnClose->show(); _btnSave->show(); _btnClose->setFocus(); - message( QString::fromUtf8( "Выполнение прервано в результате ошибки." - "
База данных не изменилась.") ); + message(QString::fromUtf8("Выполнение прервано в результате ошибки." + "
База данных не изменилась.")); _exitCode = -1; } } //--------------------------------------------------------------------------- int MainWindow::executeAction() { ProgramSettings pset; - processArguments( pset ); - logon( pset ); + processArguments(pset); + 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 ); + 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&))); - //проверяем число ошибок, т.к. при выполнении без транзакции run() всегда возвращает 0 - if ( _errorCount == 0 ) + int rc = updater.run(pset); + + //проверяем число ошибок, т.к. при выполнении без транзакции run() всегда возвращает 0 + if (_errorCount == 0) { int before = updater.revisionBefore(); int after = updater.revisionAfter(); - if ( before == after ) - message( QString::fromUtf8( "База данных в актуальном состоянии." ) ); - else if ( before == 0 ) - message( QString::fromUtf8( "База данных создана и обновлена до версии %1." ).arg( after ) ); + if (before == after) + message(QString::fromUtf8("База данных в актуальном состоянии.")); + else if (before == 0) + message(QString::fromUtf8("База данных создана и обновлена до версии %1.").arg(after)); else - message( QString::fromUtf8( "База данных версии %1 обновлена до версии %2." ). - arg( before ).arg( after ) ); + message(QString::fromUtf8("База данных версии %1 обновлена до версии %2.").arg(before).arg(after)); rc = (before & 0xFFFF) | ((after & 0xFFFF) << 16); } else { _btnClose->show(); _btnSave->show(); _btnClose->setFocus(); - message( QString::fromUtf8( "Выполнение прервано в результате ошибки." - "
База данных не изменилась.") ); + message(QString::fromUtf8("Выполнение прервано в результате ошибки." + "
База данных не изменилась.")); rc = -1; } return rc; } -void MainWindow::processArguments( ProgramSettings& a_pset ) +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" ); + 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 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() ); + 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; QString curArg; - QStringListIterator args( QApplication::arguments() ); - args.next(); //пропускаем первый параметр - имя программы - while ( args.hasNext() ) + QStringListIterator args(QApplication::arguments()); + args.next(); //пропускаем первый параметр - имя программы + while (args.hasNext()) { curArg = args.next(); - - if ( curArg.startsWith( "--" ) ) - {//обработка длинного параметра - curArg.remove( 0, 2 ); - QMutableHashIterator option( params ); - while ( option.hasNext() ) + + if (curArg.startsWith("--")) + { //обработка длинного параметра + curArg.remove(0, 2); + QMutableHashIterator option(params); + while (option.hasNext()) { option.next(); key = option.key(); - if ( curArg.startsWith( key ) && curArg.at( key.size() ) == '=' ) - option.setValue( curArg.right( curArg.size() - key.size() - 1 ) ); + if (curArg.startsWith(key) && curArg.at(key.size()) == '=') + option.setValue(curArg.right(curArg.size() - key.size() - 1)); } key.clear(); } - else if ( curArg.at( 0 ) == QChar('-') ) - {//обработка короткого параметра + else if (curArg.at(0) == QChar('-')) + { //обработка короткого параметра key.clear(); - switch ( curArg.at( 1 ).toLatin1() ) + 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; + 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() ) + { //обработка одиночного параметра + 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(); + 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 ) +void MainWindow::logon(ProgramSettings& a_pset) { - if ( !a_pset.host.isEmpty() || !a_pset.username.isEmpty() ) + if (!a_pset.host.isEmpty() || !a_pset.username.isEmpty()) return; #if defined(Q_OS_WIN) KLogon* logon = KLogon::create(); - if ( !logon ) + if (!logon) return; QString defaultDSN; HKEY k; DWORD cb = 0; - QString valuename( "System Directory" ); - if ( 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 valuename("System Directory"); + if (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 ); + 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(); + KSettings systemini(systemdir + "/system.ini"); + systemini.beginGroup("Database"); + defaultDSN = systemini.value("DefaultDSN").toString(); } - QString username = QString::fromLocal8Bit( qgetenv( "USERNAME" ) ); - logon->setParent( winId() ); - logon->setUsername( username ); - if ( !defaultDSN.isNull() ) - logon->setDSN( defaultDSN ); + QString username = QString::fromLocal8Bit(qgetenv("USERNAME")); + logon->setParent(winId()); + logon->setUsername(username); + if (!defaultDSN.isNull()) + logon->setDSN(defaultDSN); - if ( !logon->execute() ) - emit message( QString::fromUtf8( "Отказ от ввода имени и пароля пользователя" ) ); + if (!logon->execute()) + emit message(QString::fromUtf8("Отказ от ввода имени и пароля пользователя")); else { a_pset.host = logon->host(); a_pset.username = logon->username(); a_pset.password = logon->password(); } delete logon; #else - QString username = QString::fromLocal8Bit( getenv( "USER" ) ); + QString username = QString::fromLocal8Bit(getenv("USER")); #endif } //--------------------------------------------------------------------------- -void MainWindow::logConnectionParameters( const QString& a_host, - const QString& a_database, - const QString& a_username ) +void MainWindow::logConnectionParameters(const QString& a_host, + const QString& a_database, + const QString& a_username) { - message( QString::fromUtf8( "Подключение к базе данных
" - "  Сервер: %1
  База данных: %2
" - "  Пользователь: %3").arg( a_host, a_database, a_username ) ); + message(QString::fromUtf8("Подключение к базе данных
" + "  Сервер: %1
  База данных: %2
" + "  Пользователь: %3") + .arg(a_host, a_database, a_username)); } //--------------------------------------------------------------------------- -void MainWindow::sqlError( const QString& a_dbError, - const QString& a_commandDescription, - const QString& a_command ) +void MainWindow::sqlError(const QString& a_dbError, + const QString& a_commandDescription, + const QString& a_command) { QString errorHtml; - if ( !a_commandDescription.isEmpty() ) - errorHtml.append( QString::fromUtf8( "Операция:
" ) ). - append( a_commandDescription ).append( "
" ); + if (!a_commandDescription.isEmpty()) + errorHtml.append(QString::fromUtf8("Операция:
")).append(a_commandDescription).append("
"); QString dbError = a_dbError; - errorHtml.append( QString::fromUtf8( "Сообщение об ошибке:
" ) ).
-            append( dbError.trimmed().replace( '\n', "
" ) ).append( "
"); + errorHtml.append(QString::fromUtf8("Сообщение об ошибке:
")).append(dbError.trimmed().replace('\n', "
")).append("
"); - if ( !a_command.isEmpty() ) - errorHtml.append( QString::fromUtf8( "Текст команды:
" ) ).
-                append( a_command ).append( "
" ); + if (!a_command.isEmpty()) + errorHtml.append(QString::fromUtf8("Текст команды:
")).append(a_command).append("
"); - errorHtmlToLog( errorHtml ); + errorHtmlToLog(errorHtml); } //--------------------------------------------------------------------------- -void MainWindow::error( const QString& a_error ) +void MainWindow::error(const QString& a_error) { QString errorHtml = a_error; - errorHtmlToLog( errorHtml.replace( '<', "<" ).replace( '>', ">" ).replace( '\n', "
" ) ); + errorHtmlToLog(errorHtml.replace('<', "<").replace('>', ">").replace('\n', "
")); } //--------------------------------------------------------------------------- -void MainWindow::errorHtmlToLog( const QString& a_errorHtml ) +void MainWindow::errorHtmlToLog(const QString& a_errorHtml) { QString errorHtml = a_errorHtml; QTextCursor cursor = _protocol->textCursor(); - cursor.insertHtml( QString::fromUtf8( "Ошибка
" ) ); - cursor.insertHtml( errorHtml ); - cursor.insertHtml( QString::fromUtf8( "
" ) ); - _protocol->moveCursor( QTextCursor::End ); + cursor.insertHtml(QString::fromUtf8("Ошибка
")); + cursor.insertHtml(errorHtml); + cursor.insertHtml(QString::fromUtf8("
")); + _protocol->moveCursor(QTextCursor::End); ++_errorCount; } //--------------------------------------------------------------------------- -void MainWindow::message( const QString& a_message ) +void MainWindow::message(const QString& a_message) { QString message = a_message; - _protocol->textCursor().insertHtml( message.replace( QChar('\n'), "
" ).append( "
" ) ); - _protocol->moveCursor( QTextCursor::End ); + _protocol->textCursor().insertHtml(message.replace(QChar('\n'), "
").append("
")); + _protocol->moveCursor(QTextCursor::End); } //--------------------------------------------------------------------------- void MainWindow::closeDialog() { - QDialog::done( _exitCode ); + QDialog::done(_exitCode); } //--------------------------------------------------------------------------- void MainWindow::saveProtocol() { - QString filename = QFileDialog::getSaveFileName( this, - QString::fromUtf8( "Сохранить протокол в файл…" ), QString(), - QString::fromUtf8( "Текстовые файлы (*.txt);;Все файлы (*.*)" ) ); - if ( !filename.isEmpty() ) + QString filename = QFileDialog::getSaveFileName(this, + QString::fromUtf8("Сохранить протокол в файл…"), QString(), + QString::fromUtf8("Текстовые файлы (*.txt);;Все файлы (*.*)")); + if (!filename.isEmpty()) { - QFile outf( filename ); - if ( outf.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) + QFile outf(filename); + if (outf.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - QTextStream os( &outf ); - os.setGenerateByteOrderMark( true ); - os.setCodec( "UTF-8" ); + 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,65 +1,65 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include 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(QWidget* parent = 0, Qt::WindowFlags flags = 0); virtual ~MainWindow(); 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 ); + 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: - virtual void showEvent( QShowEvent* a_event ); - virtual void closeEvent( QCloseEvent* a_event ); - virtual bool event( QEvent* a_event ); + virtual void showEvent(QShowEvent* a_event); + virtual void closeEvent(QCloseEvent* a_event); + virtual bool event(QEvent* a_event); private: int executeAction(); - void logon( ProgramSettings& a_pset ); - void processArguments( ProgramSettings& a_pset ); + void logon(ProgramSettings& a_pset); + void processArguments(ProgramSettings& a_pset); void errorHtmlToLog(const QString& a_errorHtml); int _exitCode; int _actionEventType; int _errorCount; QTextEdit* _protocol; QLabel* _lblWait; QPushButton* _btnSave; QPushButton* _btnClose; KActivityIndicator* _ai; QProgressBar* _progress; QFutureWatcher _futureWatcher; DatabaseUpdater* _updater; }; //!главное окно приложения #endif //MAINWINDOW_H diff --git a/src/restruct.cpp b/src/restruct.cpp --- a/src/restruct.cpp +++ b/src/restruct.cpp @@ -1,57 +1,57 @@ #include "mainwindow.h" #include #include #include #ifdef Q_OS_WIN32 #include #endif -int main( int argc, char* argv[] ) +int main(int argc, char* argv[]) { //int width = 504; //int height = 262; int width = 679; int height = 420; - QApplication app( argc, argv ); + QApplication app(argc, argv); //загрузка русской локализации библиотеки Qt QTranslator translator; - translator.load( QString("qt_ru") ); + translator.load(QString("qt_ru")); app.installTranslator(&translator); //создание главного окна MainWindow window; #ifdef Q_OS_WIN32 //масштабирование для случая увеличенного шрифта - HWND hwnd = (HWND)app.desktop()->winId(); - int dpi = GetDeviceCaps( GetDC(hwnd), LOGPIXELSY ); - if ( dpi != 96 ) + HWND hwnd = (HWND)app.desktop()->winId(); + int dpi = GetDeviceCaps(GetDC(hwnd), LOGPIXELSY); + if (dpi != 96) { width = (width * dpi) / 96; height = (height * dpi) / 96; } //шрифт окна такой же, как в системе подписи к иконкам LOGFONTW lf; - SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0 ); - int fh = qAbs( (lf.lfHeight * 72) / dpi ); - QString fn( (const QChar*)lf.lfFaceName, wcslen(lf.lfFaceName) ); + SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0); + int fh = qAbs((lf.lfHeight * 72) / dpi); + QString fn((const QChar*)lf.lfFaceName, wcslen(lf.lfFaceName)); window.setStyleSheet( - QString( "*{ font-family: %1; font-size: %2pt; }" ).arg( fn ).arg( fh ) ); + QString("*{ font-family: %1; font-size: %2pt; }").arg(fn).arg(fh)); #endif //перемещение главного окна в центр экрана - window.setMinimumSize( width, height ); + window.setMinimumSize(width, height); QRect wg = window.geometry(); - wg.setSize( window.minimumSize() ); - wg.moveCenter( qApp->desktop()->screenGeometry().center() ); - window.setGeometry( wg ); + wg.setSize(window.minimumSize()); + wg.moveCenter(qApp->desktop()->screenGeometry().center()); + window.setGeometry(wg); int exitCode = window.exec(); return exitCode; } //!приложение restruct diff --git a/src/sqlerrordlg.cpp b/src/sqlerrordlg.cpp --- a/src/sqlerrordlg.cpp +++ b/src/sqlerrordlg.cpp @@ -1,49 +1,48 @@ -#include +#include "sqlerrordlg.h" #include -#include +#include #include #include -#include "sqlerrordlg.h" +#include //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -SqlErrorDialog::SqlErrorDialog( QWidget* parent, Qt::WindowFlags flags ) - : QDialog( parent, flags ) +SqlErrorDialog::SqlErrorDialog(QWidget* parent, Qt::WindowFlags flags) + : QDialog(parent, flags) { - setWindowTitle( QString::fromUtf8( "Список ошибок" ) ); - setWindowFlags( windowFlags() & ~Qt::WindowContextHelpButtonHint ); - setSizeGripEnabled( true ); - setMinimumSize( QSize( 512, 428 ) ); + setWindowTitle(QString::fromUtf8("Список ошибок")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setSizeGripEnabled(true); + setMinimumSize(QSize(512, 428)); - QVBoxLayout* mainLayout = new QVBoxLayout( this ); + QVBoxLayout* mainLayout = new QVBoxLayout(this); QHBoxLayout* layout = new QHBoxLayout; - mainLayout->addLayout( layout ); + mainLayout->addLayout(layout); - QLabel* label = new QLabel( - QString( "Во время выполнения команд произошли\nследующие ошибки:" ) ); - layout->addWidget( label ); + QLabel* label = new QLabel( + QString("Во время выполнения команд произошли\nследующие ошибки:")); + layout->addWidget(label); layout->addStretch(); - _btnClose = new QPushButton( QString( "Закрыть" ) ); - _btnClose->setDefault( true ); - layout->addWidget( _btnClose ); + _btnClose = new QPushButton(QString("Закрыть")); + _btnClose->setDefault(true); + layout->addWidget(_btnClose); _errorLog = new QTextEdit; - _errorLog->setReadOnly( true ); - mainLayout->addWidget( _errorLog ); + _errorLog->setReadOnly(true); + mainLayout->addWidget(_errorLog); - connect( _btnClose, SIGNAL(clicked()), this, SLOT(close()) ); + connect(_btnClose, SIGNAL(clicked()), this, SLOT(close())); } SqlErrorDialog::~SqlErrorDialog() { } -void SqlErrorDialog::setLogText( const QString& a_text ) +void SqlErrorDialog::setLogText(const QString& a_text) { _errorLog->clear(); - _errorLog->setHtml( a_text ); + _errorLog->setHtml(a_text); } - //!главное окно приложения diff --git a/src/sqlerrordlg.h b/src/sqlerrordlg.h --- a/src/sqlerrordlg.h +++ b/src/sqlerrordlg.h @@ -1,24 +1,24 @@ #ifndef SQLERRORDLG_H #define SQLERRORDLG_H #include class QPushButton; class QString; class QTextEdit; class SqlErrorDialog : public QDialog { public: - SqlErrorDialog( QWidget * parent = 0, Qt::WindowFlags flags = 0 ); + SqlErrorDialog(QWidget* parent = 0, Qt::WindowFlags flags = 0); virtual ~SqlErrorDialog(); - void setLogText( const QString& a_text ); + void setLogText(const QString& a_text); private: QPushButton* _btnClose; QTextEdit* _errorLog; }; //!главное окно приложения #endif //SQLERRORDLG_H diff --git a/src/updater.cpp b/src/updater.cpp --- a/src/updater.cpp +++ b/src/updater.cpp @@ -1,885 +1,883 @@ #include "updater.h" #include "psettings.h" -#include -#include -#include #include #include #include #include +#include +#include +#include DatabaseUpdater::DatabaseUpdater() : QObject() , _pset(0) , _revisionBefore(0) , _revisionAfter(0) { } DatabaseUpdater::~DatabaseUpdater() { delete _pset; } -int DatabaseUpdater::run( ProgramSettings& a_pset ) +int DatabaseUpdater::run(ProgramSettings& a_pset) { - _pset = new ProgramSettings( a_pset ); - if ( !checkArguments() ) + _pset = new ProgramSettings(a_pset); + if (!checkArguments()) return -1; - if ( !readConfig() ) + if (!readConfig()) return -1; - if ( !loadScriptsFromResource() ) + if (!loadScriptsFromResource()) return -1; - if ( !runScripts() ) + if (!runScripts()) return -1; return 0; } //--------------------------------------------------------------------------- bool DatabaseUpdater::checkArguments() { - if ( _pset->controlFile.isEmpty() ) + if (_pset->controlFile.isEmpty()) { - emit error( QString::fromUtf8( "Не задан файл конфигурации." ) ); + emit error(QString::fromUtf8("Не задан файл конфигурации.")); return false; } - + //если не задано полное имя файла конфигурации, то искать его в текущем каталоге QString filename = _pset->controlFile; - if ( !QDir::isAbsolutePath( filename ) ) - filename = QString( "%1/%2" ).arg( QDir::currentPath() ).arg( _pset->controlFile ); - + if (!QDir::isAbsolutePath(filename)) + filename = QString("%1/%2").arg(QDir::currentPath()).arg(_pset->controlFile); + //проверить наличие файла - if ( !QFile::exists( filename ) ) + if (!QFile::exists(filename)) { - emit error( QString::fromUtf8( "Не найден файл конфигурации\n" ) + - QDir::toNativeSeparators( filename ) ); + emit error(QString::fromUtf8("Не найден файл конфигурации\n") + QDir::toNativeSeparators(filename)); return false; } _pset->controlFile = filename; return true; } //--------------------------------------------------------------------------- bool DatabaseUpdater::readConfig() { //открываем входной файл - QFile controlFile( _pset->controlFile ); - if ( !controlFile.open( QIODevice::ReadOnly ) ) + QFile controlFile(_pset->controlFile); + if (!controlFile.open(QIODevice::ReadOnly)) { - emit error( QString::fromUtf8( "Сбой при загрузке файла конфигурации:\n" - "Невозможно открыть для чтения файл %1" ).arg( QDir::toNativeSeparators( - _pset->controlFile ) ) ); + emit error(QString::fromUtf8("Сбой при загрузке файла конфигурации:\n" + "Невозможно открыть для чтения файл %1") + .arg(QDir::toNativeSeparators(_pset->controlFile))); return false; } - + //парсим входной файл QXmlStreamReader xml; - xml.setDevice( &controlFile ); + xml.setDevice(&controlFile); - emit message( QString::fromUtf8( "Загрузка конфигурации из файла\n%1" ). - arg( QDir::toNativeSeparators( _pset->controlFile ) ) ); + emit message(QString::fromUtf8("Загрузка конфигурации из файла\n%1").arg(QDir::toNativeSeparators(_pset->controlFile))); //идём по элементам документа - while ( !xml.atEnd() ) + while (!xml.atEnd()) { xml.readNext(); - if ( xml.isStartElement() && xml.name() == "package" ) - if ( !readPackage( xml ) ) + if (xml.isStartElement() && xml.name() == "package") + if (!readPackage(xml)) return false; } - if ( xml.hasError() ) + if (xml.hasError()) { - emit error( QString::fromUtf8( "Сбой при загрузке файла конфигурации:\n" - "Ошибка: %1, строка %2, позиция %3"). - arg( xml.errorString() ).arg( xml.lineNumber() ).arg( xml.columnNumber() ) ); + emit error(QString::fromUtf8("Сбой при загрузке файла конфигурации:\n" + "Ошибка: %1, строка %2, позиция %3") + .arg(xml.errorString()) + .arg(xml.lineNumber()) + .arg(xml.columnNumber())); return false; } controlFile.close(); //найти файл с расширением pkginfo и именем как у входного файла, если такого нет, - //то использовать первый попавшийся файл с расширением pkginfo; - //прочитать из него идентификатор пакета и имя базы данных; + //то использовать первый попавшийся файл с расширением pkginfo; + //прочитать из него идентификатор пакета и имя базы данных; //если файла нет, то и не надо - QFileInfo fi( controlFile ); - QStringList files = QDir( QFileInfo( controlFile ).path(), "*.pkginfo", - QDir::NoSort, QDir::Files ).entryList(); - if ( !files.isEmpty() ) + QFileInfo fi(controlFile); + QStringList files = QDir(QFileInfo(controlFile).path(), "*.pkginfo", + QDir::NoSort, QDir::Files).entryList(); + if (!files.isEmpty()) { - QString pkgfile = QFileInfo( controlFile ).completeBaseName() + ".pkginfo"; + QString pkgfile = QFileInfo(controlFile).completeBaseName() + ".pkginfo"; - if ( !files.contains( pkgfile, Qt::CaseInsensitive ) ) - pkgfile = files.at( 0 ); + if (!files.contains(pkgfile, Qt::CaseInsensitive)) + pkgfile = files.at(0); + + pkgfile = QFileInfo(controlFile).path() + '/' + pkgfile; + emit message(QString::fromUtf8("Загрузка конфигурации из файла\n%1").arg(QDir::toNativeSeparators(pkgfile))); - pkgfile = QFileInfo( controlFile ).path() + '/' + pkgfile; - emit message( QString::fromUtf8( "Загрузка конфигурации из файла\n%1" ). - arg( QDir::toNativeSeparators( pkgfile ) ) ); + KSettings pkginfo(pkgfile); + pkginfo.beginGroup("package"); - KSettings pkginfo( pkgfile ); - pkginfo.beginGroup( "package" ); - - QString s = pkginfo.value( "dbname" ).toString(); - if ( !s.isEmpty() && _pset->database.isEmpty() ) + QString s = pkginfo.value("dbname").toString(); + if (!s.isEmpty() && _pset->database.isEmpty()) _pset->database = s; - QStringList ver = pkginfo.value( "version" ).toString().split( QChar('.') ); - if ( ver.size() > 1 ) + QStringList ver = pkginfo.value("version").toString().split(QChar('.')); + if (ver.size() > 1) { - s = ver.at( 1 ); + s = ver.at(1); bool ok; - int i = s.toInt( &ok ); - if ( ok ) + int i = s.toInt(&ok); + if (ok) _pset->dbVersion = i; } - _pset->packageId = pkginfo.value( "id" ).toString(); + _pset->packageId = pkginfo.value("id").toString(); } //после загрузки конфигурации из файлов должно быть определено имя БД - if ( _pset->database.isEmpty() ) + if (_pset->database.isEmpty()) { - emit error( QString::fromUtf8( "Не задано имя базы данных" ) ); + emit error(QString::fromUtf8("Не задано имя базы данных")); return false; } return true; } //--------------------------------------------------------------------------- -bool DatabaseUpdater::readPackage( QXmlStreamReader& a_xml ) +bool DatabaseUpdater::readPackage(QXmlStreamReader& a_xml) { const QXmlStreamAttributes& packageAttrs = a_xml.attributes(); - QString packageId = packageAttrs.value( "id" ).toString(); - QString uriAttr = packageAttrs.value( "uri" ).toString(); + QString packageId = packageAttrs.value("id").toString(); + QString uriAttr = packageAttrs.value("uri").toString(); bool uri = !((uriAttr == "no") || (uriAttr == "нет")); - Package* package = new Package( packageId, uri ); - _packages.append( package ); + Package* package = new Package(packageId, uri); + _packages.append(package); //собираем информацию о скриптах данного пакета - const QString SCRIPT_NODE( "script" ); - const QString REVISION_ATTR( "revision" ); - const QString TRANSACTION_ATTR( "transaction" ); - const QString COMMENT_ATTR( "comment" ); - const QString SCRIPT_ATTR( "file" ); - const QString URI_DATA_ATTR( "udata" ); - const QString NO_REQUIRED_ATTR = QString::fromUtf8( "Неправильное содержание файла конфигурации:\n" - "Не указан обязательный атрибут «%1» пакета «%2»" ); + const QString SCRIPT_NODE("script"); + const QString REVISION_ATTR("revision"); + const QString TRANSACTION_ATTR("transaction"); + const QString COMMENT_ATTR("comment"); + const QString SCRIPT_ATTR("file"); + const QString URI_DATA_ATTR("udata"); + const QString NO_REQUIRED_ATTR = QString::fromUtf8("Неправильное содержание файла конфигурации:\n" + "Не указан обязательный атрибут «%1» пакета «%2»"); - while ( !a_xml.atEnd() ) + while (!a_xml.atEnd()) { a_xml.readNext(); - if ( a_xml.isStartElement() && a_xml.name() == SCRIPT_NODE ) + if (a_xml.isStartElement() && a_xml.name() == SCRIPT_NODE) { const QXmlStreamAttributes& attrs = a_xml.attributes(); //проверка наличия обязательных атрибутов - if ( !attrs.hasAttribute( REVISION_ATTR ) ) + if (!attrs.hasAttribute(REVISION_ATTR)) { - emit error( NO_REQUIRED_ATTR.arg( REVISION_ATTR ).arg( packageId ) ); + emit error(NO_REQUIRED_ATTR.arg(REVISION_ATTR).arg(packageId)); return false; } - if ( !attrs.hasAttribute( SCRIPT_ATTR ) ) + if (!attrs.hasAttribute(SCRIPT_ATTR)) { - emit error( NO_REQUIRED_ATTR.arg( SCRIPT_ATTR ).arg( packageId ) ); + emit error(NO_REQUIRED_ATTR.arg(SCRIPT_ATTR).arg(packageId)); return false; } //проверка правильности указания атрибутов bool ok; - int revision = attrs.value( REVISION_ATTR ).toString().toInt( &ok ); - if ( !ok ) + int revision = attrs.value(REVISION_ATTR).toString().toInt(&ok); + if (!ok) { - emit error( QString::fromUtf8( - "Атрибут «revision» пакета «%1» должен быть числом" ). - arg( packageId ) ); + emit error(QString::fromUtf8( + "Атрибут «revision» пакета «%1» должен быть числом") + .arg(packageId)); return false; } //заносим информацию о скрипте в список скриптов пакета - QString file = attrs.value( SCRIPT_ATTR ).toString(); - QString uriScript = attrs.value( URI_DATA_ATTR ).toString(); - QString comment = attrs.value( COMMENT_ATTR ).toString(); - QString strans = attrs.value( TRANSACTION_ATTR ).toString(); - bool transaction = !((strans == "0") || - (strans.compare( "no", Qt::CaseInsensitive ) == 0) || - (strans.compare( "нет", Qt::CaseInsensitive ) == 0)); - - DatabaseScript* script = new DatabaseScript( revision, transaction, - file, uriScript, comment ); - package->addScript( script ); + QString file = attrs.value(SCRIPT_ATTR).toString(); + QString uriScript = attrs.value(URI_DATA_ATTR).toString(); + QString comment = attrs.value(COMMENT_ATTR).toString(); + QString strans = attrs.value(TRANSACTION_ATTR).toString(); + bool transaction = !((strans == "0") || (strans.compare("no", Qt::CaseInsensitive) == 0) || (strans.compare("нет", Qt::CaseInsensitive) == 0)); + + DatabaseScript* script = new DatabaseScript(revision, transaction, + file, uriScript, comment); + package->addScript(script); } } //упорядочить скрипты по возрастанию номеров ревизий package->sortScripts(); return true; } //--------------------------------------------------------------------------- bool DatabaseUpdater::runScripts() { //определение пакета, скрипты которого будут выполняться Package* package = 0; - QListIterator it( _packages ); - while ( it.hasNext() ) + QListIterator it(_packages); + while (it.hasNext()) { package = it.next(); - if ( package->id() == _pset->packageId ) + if (package->id() == _pset->packageId) break; else package = 0; } - if ( !package ) + if (!package) { - emit error( QString::fromUtf8( "Для пакета «%1» не задано ни одного " - "сценария создания базы данных" ).arg( _pset->packageId ) ); + emit error(QString::fromUtf8("Для пакета «%1» не задано ни одного " + "сценария создания базы данных") + .arg(_pset->packageId)); return false; } //проверка наличия файлов со скриптами на диске QStringList paths; - QFileInfo fi( _pset->controlFile ); + QFileInfo fi(_pset->controlFile); paths << fi.canonicalPath() << fi.canonicalPath() + "/script" << QDir::currentPath(); DatabaseScript* script = 0; - QListIterator it2( package->scripts() ); - while ( it2.hasNext() ) + QListIterator it2(package->scripts()); + while (it2.hasNext()) { script = it2.next(); - if ( !script->findScript( paths ) ) + if (!script->findScript(paths)) { - emit error( QString::fromUtf8( "Не найден файл сценария создания " - "базы данных %1" ).arg( script->script() ) ); + emit error(QString::fromUtf8("Не найден файл сценария создания " + "базы данных %1") + .arg(script->script())); return false; } - if ( package->uri() && !script->findUriScript( paths ) ) + if (package->uri() && !script->findUriScript(paths)) { - emit error( QString::fromUtf8( "Не найден файл условно-реальной " - "информации %1" ).arg( script->uriScript() ) ); + emit error(QString::fromUtf8("Не найден файл условно-реальной " + "информации %1") + .arg(script->uriScript())); return false; } } - QString curDate = QDate::currentDate().toString( Qt::ISODate ); + QString curDate = QDate::currentDate().toString(Qt::ISODate); SqlProcessor proc; SqlProcessor uriProc; - emit message( QString::fromUtf8( "Подключение к серверу баз данных" ) ); + emit message(QString::fromUtf8("Подключение к серверу баз данных")); //пока идут служебные подключения к БД и запросы, подключаем только сигнал error - connect( &proc, SIGNAL(error(const QString&,const QString&,const QString&)), - this, SIGNAL(sqlError(const QString&,const QString&,const QString&)) ); - connect( &uriProc, SIGNAL(error(const QString&,const QString&,const QString&)), - this, SIGNAL(sqlError(const QString&,const QString&,const QString&)) ); + connect(&proc, SIGNAL(error(const QString&, const QString&, const QString&)), + this, SIGNAL(sqlError(const QString&, const QString&, const QString&))); + connect(&uriProc, SIGNAL(error(const QString&, const QString&, const QString&)), + this, SIGNAL(sqlError(const QString&, const QString&, const QString&))); //---- template1 ---- //попытка подключения к template1 и получение списка таблиц - if ( !proc.connectdb( _pset->host, _pset->port, "template1", _pset->username, - _pset->password ) ) + if (!proc.connectdb(_pset->host, _pset->port, "template1", _pset->username, + _pset->password)) return false; - QStringList template1Tables = databaseTableList( proc ); - int currentDatabaseRevision = 0; //БД нет или пустая + QStringList template1Tables = databaseTableList(proc); + int currentDatabaseRevision = 0; //БД нет или пустая //удаление БД если задано параметром при запуске программы - bool dbExists = databaseExists( proc, _pset->database ); - if ( dbExists && _pset->dropdb ) + bool dbExists = databaseExists(proc, _pset->database); + if (dbExists && _pset->dropdb) { - emit message( QString::fromUtf8( "Удаление базы данных %1" ).arg( _pset->database ) ); + emit message(QString::fromUtf8("Удаление базы данных %1").arg(_pset->database)); - if ( !dropDatabase( proc, _pset ) ) + if (!dropDatabase(proc, _pset)) return false; dbExists = false; } //создание БД если она не существует - if ( !dbExists ) + if (!dbExists) { - emit message( QString::fromUtf8( "Создание базы данных %1" ).arg( _pset->database ) ); + emit message(QString::fromUtf8("Создание базы данных %1").arg(_pset->database)); - if ( !createDatabase( proc, _pset ) ) + if (!createDatabase(proc, _pset)) return false; } QString uriDatabase = _pset->database + "_u"; - if ( package->uri() ) + if (package->uri()) { //удаление учебной БД если задано параметром при запуске программы - bool uriDbExists = databaseExists( proc, uriDatabase ); - if ( uriDbExists && _pset->dropdb ) + bool uriDbExists = databaseExists(proc, uriDatabase); + if (uriDbExists && _pset->dropdb) { - emit message( QString::fromUtf8( "Удаление учебной базы данных %1" ).arg( uriDatabase ) ); + emit message(QString::fromUtf8("Удаление учебной базы данных %1").arg(uriDatabase)); - if ( !dropDatabase( proc, _pset, uriDatabase ) ) + if (!dropDatabase(proc, _pset, uriDatabase)) return false; uriDbExists = false; } //создание учебной БД если она не существует - if ( !uriDbExists ) + if (!uriDbExists) { - emit message( QString::fromUtf8( "Создание учебной базы данных %1" ).arg( uriDatabase ) ); + emit message(QString::fromUtf8("Создание учебной базы данных %1").arg(uriDatabase)); - if ( !createDatabase( proc, _pset, uriDatabase ) ) + if (!createDatabase(proc, _pset, uriDatabase)) return false; } } - connect( &proc, SIGNAL(afterConnect(QString,QString,QString,QString,QString)), - this, SLOT(afterConnect(QString,QString,QString,QString,QString)) ); + connect(&proc, SIGNAL(afterConnect(QString, QString, QString, QString, QString)), + this, SLOT(afterConnect(QString, QString, QString, QString, QString))); //---- database ---- //подключение к созданной/существующей БД и получение списка таблиц - if ( !proc.connectdb( _pset->host, _pset->port, _pset->database, _pset->username, - _pset->password ) ) + if (!proc.connectdb(_pset->host, _pset->port, _pset->database, _pset->username, + _pset->password)) return false; - QStringList databaseTables = databaseTableList( proc ); + QStringList databaseTables = databaseTableList(proc); //подключение к учебной БД и получение списка таблиц QStringList uriDatabaseTables; - if ( package->uri() ) + if (package->uri()) { //---- database_u ---- - if ( !uriProc.connectdb( _pset->host, _pset->port, uriDatabase, - _pset->username, _pset->password ) ) + if (!uriProc.connectdb(_pset->host, _pset->port, uriDatabase, + _pset->username, _pset->password)) return false; - - uriDatabaseTables = databaseTableList( uriProc ); + + uriDatabaseTables = databaseTableList(uriProc); } //считывание данных о версии БД из таблицы dm_version, //эта таблица существует только в основной БД, версия учебной должна совпадать bool legacyDatabase = false; - proc.execSQL( "select relnatts from pg_class " - "where relname='dm_version' and relkind='r'" ); - + proc.execSQL("select relnatts from pg_class " + "where relname='dm_version' and relkind='r'"); PGresult* pgresult = proc.result().pgresult; //если пустой результат запроса, значит таблицы dm_version нет в БД // bool createDmVersion = data.size() == 0; bool createDmVersion = PQntuples(pgresult) == 0; //если таблица есть, то сравнить число её атрибутов с эталоном if (!createDmVersion) { const char* pgvalue = PQgetvalue(pgresult, 0, 0); - if ( QByteArray::fromRawData(pgvalue, qstrlen(pgvalue)).toInt() != DM_VERSION_FIELDS_COUNT ) - { //не та структура, удаляем таблицу - if ( !proc.execSQL( "drop table dm_version" ) ) + if (QByteArray::fromRawData(pgvalue, qstrlen(pgvalue)).toInt() != DM_VERSION_FIELDS_COUNT) + { //не та структура, удаляем таблицу + if (!proc.execSQL("drop table dm_version")) return false; createDmVersion = true; } } - if ( createDmVersion ) - { //БД уже существовала, а таблицы dm_version в ней нет, или не та структура - if ( databaseTables != template1Tables ) + if (createDmVersion) + { //БД уже существовала, а таблицы dm_version в ней нет, или не та структура + if (databaseTables != template1Tables) { legacyDatabase = true; currentDatabaseRevision = 1; } - emit message( QString::fromUtf8( "Создание таблицы изменений БД" ) ); - proc.execSQL( "begin" ); - if ( !proc.execute( _createDmVersionScript ) ) + emit message(QString::fromUtf8("Создание таблицы изменений БД")); + proc.execSQL("begin"); + if (!proc.execute(_createDmVersionScript)) { - emit error( QString::fromUtf8( "Сбой при создании таблицы изменений БД" ) ); + emit error(QString::fromUtf8("Сбой при создании таблицы изменений БД")); return false; } - if ( legacyDatabase ) - { //запись информации о версии №1 в unversioned БД - if ( !proc.execSQL( QString::fromUtf8( "insert into dm_version " - "(revision,package_id,comment,gen_date) values " - "(1,'%1','Изначальная версия','%2')" ).arg( - package->id(), curDate ) ) ) + if (legacyDatabase) + { //запись информации о версии №1 в unversioned БД + if (!proc.execSQL(QString::fromUtf8("insert into dm_version " + "(revision,package_id,comment,gen_date) values " + "(1,'%1','Изначальная версия','%2')") + .arg(package->id(), curDate))) return false; } - proc.execSQL( "commit" ); + proc.execSQL("commit"); } else { - proc.execSQL( QString("select max(revision), count(*) from dm_version " - "where package_id='%1'" ).arg( package->id() ) ); + proc.execSQL(QString("select max(revision), count(*) from dm_version " + "where package_id='%1'") + .arg(package->id())); PGresult* pgresult = proc.result().pgresult; if (PQntuples(pgresult)) { const char* pgvalue = PQgetvalue(pgresult, 0, 1); if (QByteArray::fromRawData(pgvalue, qstrlen(pgvalue)).toInt() > 0) { pgvalue = PQgetvalue(pgresult, 0, 0); currentDatabaseRevision = QByteArray::fromRawData(pgvalue, qstrlen(pgvalue)).toInt(); } } } //создание языка plpgsql - if ( !createLanguagePlpgsql( proc, uriProc, package->uri() ) ) + if (!createLanguagePlpgsql(proc, uriProc, package->uri())) return false; _revisionAfter = _revisionBefore = currentDatabaseRevision; //выполнение необходимых скриптов - connect( &proc, SIGNAL(progress(int)), this, SIGNAL(progress(int)) ); - connect( &uriProc, SIGNAL(progress(int)), this, SIGNAL(progress(int)) ); + connect(&proc, SIGNAL(progress(int)), this, SIGNAL(progress(int))); + connect(&uriProc, SIGNAL(progress(int)), this, SIGNAL(progress(int))); - QListIterator iter( package->scripts() ); - while ( iter.hasNext() ) + QListIterator iter(package->scripts()); + while (iter.hasNext()) { script = iter.next(); int revision = script->revision(); bool transaction = script->transaction(); //если была найдена изначальная БД, то всё уже сделано для 1-й версии - if ( (revision == 1) && legacyDatabase ) - continue; + if ((revision == 1) && legacyDatabase) + continue; //пропускаем уже установленные версии БД - if ( revision <= currentDatabaseRevision ) + if (revision <= currentDatabaseRevision) continue; - if ( revision == 1 ) - emit message( QString::fromUtf8( "Создание базы данных версии %1" ).arg( revision ) ); + if (revision == 1) + emit message(QString::fromUtf8("Создание базы данных версии %1").arg(revision)); else - emit message( QString::fromUtf8( "Обновление базы данных до версии %1" ).arg( revision ) ); + emit message(QString::fromUtf8("Обновление базы данных до версии %1").arg(revision)); //подготовка скрипта к выполнению QList mainScript; QList globalsScript; - prepareScripts( script->script(), mainScript, globalsScript ); + prepareScripts(script->script(), mainScript, globalsScript); //если в скрипте были команды создания глобальных объектов, то выполнить //их в отдельной транзакции - if ( globalsScript.size() > 0 ) + if (globalsScript.size() > 0) { - proc.execSQL( "begin" ); - if ( !proc.execute( globalsScript ) ) + proc.execSQL("begin"); + if (!proc.execute(globalsScript)) return false; - proc.execSQL( "commit" ); + proc.execSQL("commit"); } //выполнение скрипта - if ( transaction ) - proc.execSQL( "begin" ); - - if ( !proc.execute( mainScript ) ) + if (transaction) + proc.execSQL("begin"); + + if (!proc.execute(mainScript)) return false; //выполнение скриптов в учебной БД, если задано её создание - if ( package->uri() ) - { - if ( transaction ) - uriProc.execSQL( "begin" ); - - if ( revision == 1 ) - emit message( QString::fromUtf8( "Создание учебной базы данных версии %1" ).arg( revision ) ); + if (package->uri()) + { + if (transaction) + uriProc.execSQL("begin"); + + if (revision == 1) + emit message(QString::fromUtf8("Создание учебной базы данных версии %1").arg(revision)); else - emit message( QString::fromUtf8( "Обновление учебной базы данных до версии %1" ).arg( revision ) ); + emit message(QString::fromUtf8("Обновление учебной базы данных до версии %1").arg(revision)); - if ( !uriProc.execute( mainScript ) ) + if (!uriProc.execute(mainScript)) { - if ( transaction ) - proc.execSQL( "rollback" ); + if (transaction) + proc.execSQL("rollback"); return false; } - if ( !script->uriScript().isEmpty() ) + if (!script->uriScript().isEmpty()) { - emit message( QString::fromUtf8( "Загрузка условной информации в учебную базу данных" ) ); + emit message(QString::fromUtf8("Загрузка условной информации в учебную базу данных")); - if ( !uriProc.execute( script->uriScript() ) ) + if (!uriProc.execute(script->uriScript())) { - if ( transaction ) - proc.execSQL( "rollback" ); + if (transaction) + proc.execSQL("rollback"); return false; } } - if ( !uriProc.execute( _setSearchPathScript ) ) + if (!uriProc.execute(_setSearchPathScript)) return false; - clearMaclabels( uriProc ); - if ( transaction ) - uriProc.execSQL( "commit" ); + clearMaclabels(uriProc); + if (transaction) + uriProc.execSQL("commit"); } //сброс параметра search_path, он мог быть изменён при выполнении скрипта - if ( !proc.execute( _setSearchPathScript ) ) + if (!proc.execute(_setSearchPathScript)) return false; //запись информации о версии в БД - if ( !proc.execSQL( QString::fromUtf8( "insert into dm_version " - "(revision,package_id,comment,gen_date) values " - "(%1,'%2','%3','%4')" ).arg( revision ). - arg( package->id() ).arg( script->comment() ). - arg( curDate ) ) ) + if (!proc.execSQL(QString::fromUtf8("insert into dm_version " + "(revision,package_id,comment,gen_date) values " + "(%1,'%2','%3','%4')") + .arg(revision) + .arg(package->id()) + .arg(script->comment()) + .arg(curDate))) return false; //сброс мандатных меток, если они есть в БД - clearMaclabels( proc ); + clearMaclabels(proc); - if ( transaction ) - proc.execSQL( "commit" ); - + if (transaction) + proc.execSQL("commit"); + _revisionAfter = revision; } return true; } //--------------------------------------------------------------------------- -bool DatabaseUpdater::databaseExists( SqlProcessor& a_proc, const QString& a_dbname ) +bool DatabaseUpdater::databaseExists(SqlProcessor& a_proc, const QString& a_dbname) { - a_proc.execSQL( QString( "select 1 from pg_database where datname='%1\'" ).arg(a_dbname) ); + a_proc.execSQL(QString("select 1 from pg_database where datname='%1\'").arg(a_dbname)); return PQntuples(a_proc.result().pgresult) == 1; } //--------------------------------------------------------------------------- -bool DatabaseUpdater::createDatabase( SqlProcessor& a_proc, ProgramSettings* a_pset, - const QString& a_dbname ) +bool DatabaseUpdater::createDatabase(SqlProcessor& a_proc, ProgramSettings* a_pset, + const QString& a_dbname) { - if ( a_dbname.isEmpty() && a_pset->database.isEmpty() ) + if (a_dbname.isEmpty() && a_pset->database.isEmpty()) return false; - QString dbname = (a_dbname.isEmpty() ? a_pset->database : a_dbname ); + QString dbname = (a_dbname.isEmpty() ? a_pset->database : a_dbname); //если уже подключены к указанной БД, то отключение - if ( a_proc.database() == dbname ) + if (a_proc.database() == dbname) a_proc.disconnectdb(); //если не подключены, то подключение к template1 - if ( a_proc.database().isNull() ) + if (a_proc.database().isNull()) { - if ( !a_proc.connectdb( a_pset->host, a_pset->port, QString( "template1" ), - a_pset->username, a_pset->password ) ) + if (!a_proc.connectdb(a_pset->host, a_pset->port, QString("template1"), + a_pset->username, a_pset->password)) return false; } //если БД уже существует, то создавать не надо - if ( databaseExists( a_proc, dbname ) ) + if (databaseExists(a_proc, dbname)) return true; - return a_proc.execSQL( QString( "create database \"%1\"" ).arg(dbname) ) - && a_proc.commandStatus() == QString( "CREATE DATABASE" ); + return a_proc.execSQL(QString("create database \"%1\"").arg(dbname)) + && a_proc.commandStatus() == QString("CREATE DATABASE"); } //--------------------------------------------------------------------------- -bool DatabaseUpdater::dropDatabase( SqlProcessor& a_proc, ProgramSettings* a_pset, - const QString& a_dbname ) +bool DatabaseUpdater::dropDatabase(SqlProcessor& a_proc, ProgramSettings* a_pset, + const QString& a_dbname) { - if ( a_pset->database.isEmpty() ) + if (a_pset->database.isEmpty()) return false; - QString dbname = (a_dbname.isEmpty() ? a_pset->database : a_dbname ); + QString dbname = (a_dbname.isEmpty() ? a_pset->database : a_dbname); //если уже подключены к указанной БД, то отключение - if ( a_proc.database() == dbname ) + if (a_proc.database() == dbname) a_proc.disconnectdb(); //если не подключены, то подключение к template1 - if ( a_proc.database().isNull() ) + if (a_proc.database().isNull()) { - if ( !a_proc.connectdb( a_pset->host, a_pset->port, QString( "template1" ), - a_pset->username, a_pset->password ) ) + if (!a_proc.connectdb(a_pset->host, a_pset->port, QString("template1"), + a_pset->username, a_pset->password)) return false; } //если БД не существует, то удалять не надо - if ( !databaseExists( a_proc, dbname ) ) + if (!databaseExists(a_proc, dbname)) return true; - return a_proc.execSQL( QString( "drop database \"%1\"" ).arg(dbname) ) - && a_proc.commandStatus() == QString( "DROP DATABASE" ); + return a_proc.execSQL(QString("drop database \"%1\"").arg(dbname)) + && a_proc.commandStatus() == QString("DROP DATABASE"); } //--------------------------------------------------------------------------- // Получение списка таблиц в БД //--------------------------------------------------------------------------- QStringList DatabaseUpdater::databaseTableList(SqlProcessor& a_proc) { QStringList result; if (!a_proc.execSQL("select tablename from pg_tables order by tablename")) return result; SqlResult sqlresult = a_proc.result(); PGresult* pgresult = sqlresult.pgresult; QTextCodec* codec = sqlresult.codec; int numTuples = PQntuples(pgresult); for (int i = 0; i < numTuples; ++i) { if (PQgetisnull(pgresult, i, 0)) result.append(QString()); else result.append(codec->toUnicode(PQgetvalue(pgresult, i, 0))); } return result; } //--------------------------------------------------------------------------- bool DatabaseUpdater::loadScriptsFromResource() { - QString errmess = QString::fromUtf8( "Сбой при чтении ресурсов программы" ); + QString errmess = QString::fromUtf8("Сбой при чтении ресурсов программы"); SqlProcessor proc; - QFile resFile( ":/dm_version.sql" ); - if ( !(resFile.open( QIODevice::ReadOnly ) ) ) + QFile resFile(":/dm_version.sql"); + if (!(resFile.open(QIODevice::ReadOnly))) { - emit error( errmess ); + emit error(errmess); return false; } - _createDmVersionScript = proc.parse( resFile ); + _createDmVersionScript = proc.parse(resFile); resFile.close(); - resFile.setFileName( ":/create_helper_functions.sql"); - if ( !(resFile.open( QIODevice::ReadOnly ) ) ) + resFile.setFileName(":/create_helper_functions.sql"); + if (!(resFile.open(QIODevice::ReadOnly))) { - emit error( errmess ); + emit error(errmess); return false; } - _createHelperFunctionsScript = proc.parse( resFile ); + _createHelperFunctionsScript = proc.parse(resFile); resFile.close(); - resFile.setFileName( ":/drop_helper_functions.sql"); - if ( !(resFile.open( QIODevice::ReadOnly ) ) ) + resFile.setFileName(":/drop_helper_functions.sql"); + if (!(resFile.open(QIODevice::ReadOnly))) { - emit error( errmess ); + emit error(errmess); return false; } - _dropHelperFunctionsScript = proc.parse( resFile ); + _dropHelperFunctionsScript = proc.parse(resFile); resFile.close(); - resFile.setFileName( ":/set_search_path.sql"); - if ( !(resFile.open( QIODevice::ReadOnly ) ) ) + resFile.setFileName(":/set_search_path.sql"); + if (!(resFile.open(QIODevice::ReadOnly))) { - emit error( errmess ); + emit error(errmess); return false; } - _setSearchPathScript = proc.parse( resFile ); + _setSearchPathScript = proc.parse(resFile); return true; } //--------------------------------------------------------------------------- // Подготавливает скрипт, считанный из файла, к выполнению в БД. // Команды анализируются и разделяются на два скрипта — основной и глобальных // объектов. Обработка заключается в следующем: // 1. Команды создания глобальных объектов // CREATE GROUP // CREATE USER // CREATE ROLE // CREATE TABLESPACE // заменяются вызовами функций-обёрток для их безопасного выполнения. // Эти вызовы вставляются в скрипт глобальных объектов. В этот же скрипт // добавляются команды создания функций-обёрток и их удаления. // 2. Команды установки кодировки клиента // SET CLIENT_ENCODING // SET NAMES // \encoding // добавляются в оба скрипта. // 3. Команда подключения языка plpgsql // CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE plpgsql -// игнорируется и не попадает ни в один скрипт. Создание языка plpgsql +// игнорируется и не попадает ни в один скрипт. Создание языка plpgsql // производится отдельно, перед началом выполнения скриптов. //--------------------------------------------------------------------------- -void DatabaseUpdater::prepareScripts( const QString& a_filename, - QList& oa_mainScript, - QList& oa_globalsScript ) +void DatabaseUpdater::prepareScripts(const QString& a_filename, + QList& oa_mainScript, + QList& oa_globalsScript) { //пропустим файл через парсер, на выходе список команд bool helperInjected = false; SqlProcessor proc; - QList result = proc.parse( a_filename ); + QList result = proc.parse(a_filename); //обход списка и анализ команд - QListIterator it( result ); - while ( it.hasNext() ) - { + QListIterator it(result); + while (it.hasNext()) + { const QByteArray line = it.next(); int i = 0; int end = line.size(); //пропускаем первое слово, перед ним пробелов нет, парсер их убирает - while ( i != end && !QChar(line.at( i )).isSpace() ) + while (i != end && !QChar(line.at(i)).isSpace()) ++i; //анализируем первое слово - QByteArray command1 = line.left( i ).toLower(); - if ( command1 == "\\encoding" ) + QByteArray command1 = line.left(i).toLower(); + if (command1 == "\\encoding") { - oa_mainScript.append( line ); - oa_globalsScript.append( line ); + oa_mainScript.append(line); + oa_globalsScript.append(line); continue; } //переход на начало второго слова - while ( i != end && QChar(line.at( i )).isSpace() ) + while (i != end && QChar(line.at(i)).isSpace()) ++i; int p = i; //пропускаем второе слово - while ( i != end && !QChar(line.at( i )).isSpace() ) + while (i != end && !QChar(line.at(i)).isSpace()) ++i; //анализируем команду - QByteArray command2 = line.mid( p, i - p ).toLower(); - if ( command1 == "set" ) + QByteArray command2 = line.mid(p, i - p).toLower(); + if (command1 == "set") { - oa_mainScript.append( line ); - if ( command2 == "names" || command2.startsWith( "client_encoding" ) ) - oa_globalsScript.append( line ); + oa_mainScript.append(line); + if (command2 == "names" || command2.startsWith("client_encoding")) + oa_globalsScript.append(line); } - else if ( command1 == "create" ) + else if (command1 == "create") { - if ( command2 == "group" || command2 == "user" || - command2 == "role" || command2 == "tablespace" ) + if (command2 == "group" || command2 == "user" || command2 == "role" || command2 == "tablespace") { //добавляем в выходной скрипт globals вызов безопасной функции-обёртки if (!helperInjected) { //но сначала вставляем команды создания функций-обёрток helperInjected = true; QListIterator helperIter(_createHelperFunctionsScript); while (helperIter.hasNext()) oa_globalsScript.append(helperIter.next()); } //переход на начало имени объекта - while ( i != end && QChar(line.at( i )).isSpace() ) + while (i != end && QChar(line.at(i)).isSpace()) ++i; QByteArray name; - if ( i != end ) - { - if ( line.at( i ) == '"' ) - { //если имя объекта начинается с двойной кавычки, то пропуск до следующей + if (i != end) + { + if (line.at(i) == '"') + { //если имя объекта начинается с двойной кавычки, то пропуск до следующей //двойной кавычки - ++i; //пропустить открывающую двойную кавычку + ++i; //пропустить открывающую двойную кавычку p = i; - while ( i != end && line.at( i ) != '"' ) + while (i != end && line.at(i) != '"') ++i; - name = line.mid( p, i - p ); - if ( i != end ) - ++i; //пропустить закрывающую двойную кавычку + name = line.mid(p, i - p); + if (i != end) + ++i; //пропустить закрывающую двойную кавычку } else - { //пропуск до конца слова + { //пропуск до конца слова p = i; - while ( i != end && !QChar(line.at( i )).isSpace() ) + while (i != end && !QChar(line.at(i)).isSpace()) ++i; - name = line.mid( p, i - p ); - if ( name.size() > 0 && name.at( name.size() - 1 ) == ';' ) - name.chop( 1 ); + name = line.mid(p, i - p); + if (name.size() > 0 && name.at(name.size() - 1) == ';') + name.chop(1); } } - QByteArray parameters( line.right( end - i ) ); - if ( parameters.size() > 0 && parameters.at( parameters.size() - 1 ) == ';' ) - parameters.chop( 1 ); + QByteArray parameters(line.right(end - i)); + if (parameters.size() > 0 && parameters.at(parameters.size() - 1) == ';') + parameters.chop(1); - QByteArray safeCall( "select _rct_safe_create_" ); - safeCall.append( command2 ).append( "('" ).append( name ).append( "','" ) - .append( parameters ).append( "');" ); + QByteArray safeCall("select _rct_safe_create_"); + safeCall.append(command2).append("('").append(name).append("','").append(parameters).append("');"); - oa_globalsScript.append( safeCall ); + oa_globalsScript.append(safeCall); } - else if ( command2 == "trusted" || command2 == "procedural" || - command2 == "language" ) - { //create language не нужен + else if (command2 == "trusted" || command2 == "procedural" || command2 == "language") + { //create language не нужен continue; } else - { //create неглобального объекта, в основной скрипт - oa_mainScript.append( line ); + { //create неглобального объекта, в основной скрипт + oa_mainScript.append(line); } } - else - { //все остальные команды в основной скрипт - oa_mainScript.append( line ); + else + { //все остальные команды в основной скрипт + oa_mainScript.append(line); } } //цикл по командам - if ( helperInjected ) - oa_globalsScript.append( _dropHelperFunctionsScript ); + if (helperInjected) + oa_globalsScript.append(_dropHelperFunctionsScript); } //--------------------------------------------------------------------------- -void DatabaseUpdater::clearMaclabels( SqlProcessor& a_proc ) +void DatabaseUpdater::clearMaclabels(SqlProcessor& a_proc) { - a_proc.execSQL( "select distinct 1 from pg_attribute a join pg_class c " - "on (a.attrelid=c.oid) where c.relname='pg_class' and a.attname='relmaclabel'" ); - if ( PQntuples(a_proc.result().pgresult) == 1 ) - a_proc.execSQL( "update pg_class set relmaclabel=null" ); + a_proc.execSQL("select distinct 1 from pg_attribute a join pg_class c " + "on (a.attrelid=c.oid) where c.relname='pg_class' and a.attname='relmaclabel'"); + if (PQntuples(a_proc.result().pgresult) == 1) + a_proc.execSQL("update pg_class set relmaclabel=null"); } //--------------------------------------------------------------------------- -bool DatabaseUpdater::createLanguagePlpgsql( SqlProcessor& a_proc, - SqlProcessor& a_uriProc, - bool a_uri ) +bool DatabaseUpdater::createLanguagePlpgsql(SqlProcessor& a_proc, + SqlProcessor& a_uriProc, + bool a_uri) { static const char* CREATE_SQL = "create language plpgsql"; static const char* CHECK_SQL = "select 1 from pg_language where lanname='plpgsql'"; - a_proc.execSQL( CHECK_SQL ); - if ( PQntuples(a_proc.result().pgresult) == 0 ) + a_proc.execSQL(CHECK_SQL); + if (PQntuples(a_proc.result().pgresult) == 0) { - if ( !a_proc.execSQL( CREATE_SQL ) ) + if (!a_proc.execSQL(CREATE_SQL)) return false; } - if ( a_uri ) + if (a_uri) { - a_uriProc.execSQL( CHECK_SQL ); - if ( PQntuples(a_uriProc.result().pgresult) == 0 ) + a_uriProc.execSQL(CHECK_SQL); + if (PQntuples(a_uriProc.result().pgresult) == 0) { - if ( !a_uriProc.execSQL( CREATE_SQL ) ) + if (!a_uriProc.execSQL(CREATE_SQL)) return false; } } return true; } //--------------------------------------------------------------------------- -void DatabaseUpdater::afterConnect( const QString& a_host, const QString& a_port, - const QString& a_database, const QString& a_username, - const QString& a_password ) +void DatabaseUpdater::afterConnect(const QString& a_host, const QString& a_port, + const QString& a_database, const QString& a_username, + const QString& a_password) { Q_UNUSED(a_port); Q_UNUSED(a_password); - emit logConnectionParameters( a_host, a_database, a_username ); + emit logConnectionParameters(a_host, a_database, a_username); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -bool DatabaseScript::findScript( const QStringList& a_paths ) +bool DatabaseScript::findScript(const QStringList& a_paths) { - _script.replace( QChar('\\'), QChar('/') ); - foreach( QString path, a_paths ) + _script.replace(QChar('\\'), QChar('/')); + foreach (QString path, a_paths) { - QDir dir( path ); - if ( dir.exists( _script ) ) + QDir dir(path); + if (dir.exists(_script)) { - _script = dir.absoluteFilePath( _script ); + _script = dir.absoluteFilePath(_script); return true; } } return false; } //--------------------------------------------------------------------------- -bool DatabaseScript::findUriScript( const QStringList& a_paths ) +bool DatabaseScript::findUriScript(const QStringList& a_paths) { - _uriScript.replace( QChar('\\'), QChar('/') ); - if ( _uriScript.isEmpty() ) + _uriScript.replace(QChar('\\'), QChar('/')); + if (_uriScript.isEmpty()) return true; - foreach( QString path, a_paths ) + foreach (QString path, a_paths) { - QDir dir( path ); - if ( dir.exists( _uriScript ) ) + QDir dir(path); + if (dir.exists(_uriScript)) { - _uriScript = dir.absoluteFilePath( _uriScript ); + _uriScript = dir.absoluteFilePath(_uriScript); return true; } } return false; } - diff --git a/src/updater.h b/src/updater.h --- a/src/updater.h +++ b/src/updater.h @@ -1,115 +1,127 @@ #ifndef UPDATER_H #define UPDATER_H #include #include class DatabaseScript { friend class DatabaseUpdater; + public: - DatabaseScript( int a_revision, bool a_transaction, const QString& a_script, - const QString& a_uriScript, const QString& a_comment ) - : _revision(a_revision), _transaction(a_transaction) - ,_script(a_script), _uriScript(a_uriScript), _comment(a_comment) {} + DatabaseScript(int a_revision, bool a_transaction, const QString& a_script, + const QString& a_uriScript, const QString& a_comment) + : _revision(a_revision) + , _transaction(a_transaction) + , _script(a_script) + , _uriScript(a_uriScript) + , _comment(a_comment) + { + } int revision() const { return _revision; } bool transaction() const { return _transaction; } QString script() const { return _script; } QString uriScript() const { return _uriScript; } QString comment() const { return _comment; } - bool findScript( const QStringList& a_paths ); - bool findUriScript( const QStringList& a_paths ); + bool findScript(const QStringList& a_paths); + bool findUriScript(const QStringList& a_paths); private: int _revision; bool _transaction; QString _script; QString _uriScript; QString _comment; }; class Package { public: - Package( const QString& a_id, bool a_uri = true ) - : _id(a_id), _uri(a_uri) {} - void addScript( DatabaseScript* a_script ) { _scripts.append( a_script ); } + Package(const QString& a_id, bool a_uri = true) + : _id(a_id) + , _uri(a_uri) + { + } + void addScript(DatabaseScript* a_script) { _scripts.append(a_script); } - void sortScripts() { qSort( _scripts.begin(), _scripts.end(), scriptRevisionLessThan ); } - static bool scriptRevisionLessThan( DatabaseScript* a_script1, - DatabaseScript* a_script2 ) { return a_script1->revision() < a_script2->revision(); } + void sortScripts() { qSort(_scripts.begin(), _scripts.end(), scriptRevisionLessThan); } + static bool scriptRevisionLessThan(DatabaseScript* a_script1, + DatabaseScript* a_script2) { return a_script1->revision() < a_script2->revision(); } bool uri() const { return _uri; } QString id() const { return _id; } QList scripts() const { return _scripts; } private: QList _scripts; QString _id; bool _uri; }; class SqlProcessor; class ProgramSettings; class QByteArray; class QByteArrayMatcher; class QXmlStreamReader; class DatabaseUpdater : public QObject { Q_OBJECT public: DatabaseUpdater(); virtual ~DatabaseUpdater(); - int run( ProgramSettings& a_pset ); + int run(ProgramSettings& a_pset); int revisionBefore() const { return _revisionBefore; } int revisionAfter() const { return _revisionAfter; } signals: - void error( const QString& a_message ); - void sqlError( const QString& a_dbError, const QString& a_commandDescription, - const QString& a_command ); - void logConnectionParameters( const QString& a_host, const QString& a_database, - const QString& a_username ); - void progress( int ); - void message( const QString& a_message ); + void error(const QString& a_message); + void sqlError(const QString& a_dbError, const QString& a_commandDescription, + const QString& a_command); + void logConnectionParameters(const QString& a_host, const QString& a_database, + const QString& a_username); + void progress(int); + void message(const QString& a_message); public slots: - void afterConnect( const QString& a_host, const QString& a_port, const QString& a_database, - const QString& a_username, const QString& a_password ); + void afterConnect(const QString& a_host, const QString& a_port, const QString& a_database, + const QString& a_username, const QString& a_password); private: - enum { DM_VERSION_FIELDS_COUNT = 5 }; + enum + { + DM_VERSION_FIELDS_COUNT = 5 + }; ProgramSettings* _pset; QString _logText; QList _packages; QList _createDmVersionScript; QList _createHelperFunctionsScript; QList _dropHelperFunctionsScript; QList _setSearchPathScript; int _revisionBefore; int _revisionAfter; - QStringList databaseTableList( SqlProcessor& a_proc ); + QStringList databaseTableList(SqlProcessor& a_proc); bool checkArguments(); bool readConfig(); - bool readPackage( QXmlStreamReader& a_xml ); + bool readPackage(QXmlStreamReader& a_xml); bool loadScriptsFromResource(); bool runScripts(); - bool databaseExists( SqlProcessor& a_proc, const QString& a_dbname ); - bool createDatabase( SqlProcessor& a_proc, ProgramSettings* a_pset, - const QString& a_dbname = QString() ); - bool dropDatabase( SqlProcessor& a_proc, ProgramSettings* a_pset, - const QString& a_dbname = QString() ); - bool createLanguagePlpgsql( SqlProcessor& a_proc, SqlProcessor& a_uriProc, - bool a_uri ); - void prepareScripts( const QString& a_filename, QList& oa_mainScript, - QList& oa_globalsScript ); - void clearMaclabels( SqlProcessor& a_proc ); + bool databaseExists(SqlProcessor& a_proc, const QString& a_dbname); + bool createDatabase(SqlProcessor& a_proc, ProgramSettings* a_pset, + const QString& a_dbname = QString()); + bool dropDatabase(SqlProcessor& a_proc, ProgramSettings* a_pset, + const QString& a_dbname = QString()); + bool createLanguagePlpgsql(SqlProcessor& a_proc, SqlProcessor& a_uriProc, + bool a_uri); + void prepareScripts(const QString& a_filename, QList& oa_mainScript, + QList& oa_globalsScript); + void clearMaclabels(SqlProcessor& a_proc); }; //!главный класс приложения #endif //UPDATER_H