diff --git a/core/BackupFormatModel.cpp b/core/BackupFormatModel.cpp index e6dc2e0..dc265c8 100644 --- a/core/BackupFormatModel.cpp +++ b/core/BackupFormatModel.cpp @@ -21,10 +21,10 @@ namespace { t_BackupFormatItemVector g_BackupFormats = { - BackupFormatItem{ "p", "plain", "Output a plaintext SQL script, restore with psql" }, - BackupFormatItem{ "c", "custom", "Postgresql's own format most flexible and compressed, restore with pg_restore" }, - BackupFormatItem{ "d", "directory", "Generates a directory with a file for each table or blob" }, - BackupFormatItem{ "t", "tar", "Similar to directory if untarred it results in a valid directory backup" } + BackupFormatItem{ "p", "plain (-Fp)", "Output a plaintext SQL script, restore with psql" }, + BackupFormatItem{ "c", "custom (-Fc)", "Postgresql's own format most flexible and compressed, restore with pg_restore" }, + BackupFormatItem{ "d", "directory (-Fd)", "Generates a directory with a file for each table or blob" }, + BackupFormatItem{ "t", "tar (-Ft)", "Similar to directory if untarred it results in a valid directory backup" } }; } // end of unnamed namespace diff --git a/pglab/BackupDialog.cpp b/pglab/BackupDialog.cpp index 7c1fa9e..c00317d 100644 --- a/pglab/BackupDialog.cpp +++ b/pglab/BackupDialog.cpp @@ -1,5 +1,4 @@ #include "BackupDialog.h" -#include "ui_BackupDialog.h" #include "BackupFormatModel.h" @@ -9,25 +8,238 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #ifdef WIN32 # include // for CreateProcess flags #endif -BackupDialog::BackupDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::BackupDialog) +QPlainTextEdit* createStdOutput(QWidget *parent) { - ui->setupUi(this); + auto stdOutput = new QPlainTextEdit(parent); + stdOutput->setObjectName(QString::fromUtf8("stdOutput")); + QPalette palette; + QBrush brush(QColor(255, 255, 255, 255)); + brush.setStyle(Qt::SolidPattern); + palette.setBrush(QPalette::Active, QPalette::Text, brush); + QBrush brush1(QColor(0, 0, 0, 255)); + brush1.setStyle(Qt::SolidPattern); + palette.setBrush(QPalette::Active, QPalette::Base, brush1); + palette.setBrush(QPalette::Inactive, QPalette::Text, brush); + palette.setBrush(QPalette::Inactive, QPalette::Base, brush1); + QBrush brush2(QColor(120, 120, 120, 255)); + brush2.setStyle(Qt::SolidPattern); + palette.setBrush(QPalette::Disabled, QPalette::Text, brush2); + QBrush brush3(QColor(240, 240, 240, 255)); + brush3.setStyle(Qt::SolidPattern); + palette.setBrush(QPalette::Disabled, QPalette::Base, brush3); + stdOutput->setPalette(palette); + QFont font; + font.setFamily(QString::fromUtf8("Source Code Pro")); + font.setPointSize(10); + stdOutput->setFont(font); + stdOutput->setLineWrapMode(QPlainTextEdit::NoWrap); + stdOutput->setReadOnly(true); + return stdOutput; +} + +BackupDialog::BackupDialog(QWidget *parent) + : QDialog(parent) +{ + + btnStart = new QPushButton(this); + btnStart->setObjectName(QString::fromUtf8("btnStart")); + btnStart->setGeometry(QRect(270, 630, 75, 23)); + + tabWidget = new QTabWidget(this); + tabWidget->setObjectName(QString::fromUtf8("tabWidget")); + tabWidget->setGeometry(QRect(30, 90, 601, 501)); + + tab = new QWidget(); + tab->setObjectName(QString::fromUtf8("tab")); + + verticalLayout = new QVBoxLayout(tab); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + + formLayout = new QFormLayout(); + formLayout->setObjectName(QString::fromUtf8("formLayout")); + + label = new QLabel(tab); + label->setObjectName(QString::fromUtf8("label")); + + formLayout->setWidget(0, QFormLayout::LabelRole, label); + + widget = new QWidget(tab); + widget->setObjectName(QString::fromUtf8("widget")); + horizontalLayout = new QHBoxLayout(widget); + horizontalLayout->setSpacing(0); + horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + editFilename = new QLineEdit(widget); + editFilename->setObjectName(QString::fromUtf8("editFilename")); + + horizontalLayout->addWidget(editFilename); + + selectDestination = new QPushButton(widget); + selectDestination->setObjectName(QString::fromUtf8("selectDestination")); + + horizontalLayout->addWidget(selectDestination); + + + formLayout->setWidget(0, QFormLayout::FieldRole, widget); + + label_2 = new QLabel(tab); + label_2->setObjectName(QString::fromUtf8("label_2")); + + formLayout->setWidget(1, QFormLayout::LabelRole, label_2); + + backupFormat = new QComboBox(tab); + backupFormat->setObjectName(QString::fromUtf8("backupFormat")); + backupFormat->setModelColumn(0); + + formLayout->setWidget(1, QFormLayout::FieldRole, backupFormat); + + label_3 = new QLabel(tab); + label_3->setObjectName(QString::fromUtf8("label_3")); + + formLayout->setWidget(2, QFormLayout::LabelRole, label_3); + + jobs = new QSpinBox(tab); + jobs->setObjectName(QString::fromUtf8("jobs")); + + formLayout->setWidget(2, QFormLayout::FieldRole, jobs); + + chkbxVerbose = new QCheckBox(tab); + chkbxVerbose->setObjectName(QString::fromUtf8("chkbxVerbose")); + + formLayout->setWidget(3, QFormLayout::FieldRole, chkbxVerbose); + + label_5 = new QLabel(tab); + label_5->setObjectName(QString::fromUtf8("label_5")); + + formLayout->setWidget(4, QFormLayout::LabelRole, label_5); + + compression = new QSpinBox(tab); + compression->setObjectName(QString::fromUtf8("compression")); + compression->setMinimum(-1); + compression->setMaximum(9); + compression->setValue(-1); + + formLayout->setWidget(4, QFormLayout::FieldRole, compression); + + chkbxIncludeBlobs = new QCheckBox(tab); + chkbxIncludeBlobs->setObjectName(QString::fromUtf8("chkbxIncludeBlobs")); + + formLayout->setWidget(6, QFormLayout::FieldRole, chkbxIncludeBlobs); + + chkbxClean = new QCheckBox(tab); + chkbxClean->setObjectName(QString::fromUtf8("chkbxClean")); + + formLayout->setWidget(7, QFormLayout::FieldRole, chkbxClean); + + chkbxCreate = new QCheckBox(tab); + chkbxCreate->setObjectName(QString::fromUtf8("chkbxCreate")); + + formLayout->setWidget(8, QFormLayout::FieldRole, chkbxCreate); + + noOwner = new QCheckBox(tab); + noOwner->setObjectName(QString::fromUtf8("noOwner")); + + formLayout->setWidget(9, QFormLayout::FieldRole, noOwner); + + oids = new QCheckBox(tab); + oids->setObjectName(QString::fromUtf8("oids")); + + formLayout->setWidget(10, QFormLayout::FieldRole, oids); + + what = new QComboBox(tab); + what->addItem(QString()); + what->addItem(QString()); + what->addItem(QString()); + what->setObjectName(QString::fromUtf8("what")); + + formLayout->setWidget(5, QFormLayout::FieldRole, what); + + label_4 = new QLabel(tab); + label_4->setObjectName(QString::fromUtf8("label_4")); + + formLayout->setWidget(5, QFormLayout::LabelRole, label_4); + + noAcl = new QCheckBox(tab); + noAcl->setObjectName(QString::fromUtf8("noAcl")); + + formLayout->setWidget(11, QFormLayout::FieldRole, noAcl); + + verticalLayout->addLayout(formLayout); + + tabWidget->addTab(tab, QString()); + tab_2 = new QWidget(); + tab_2->setObjectName(QString::fromUtf8("tab_2")); + verticalLayout_2 = new QVBoxLayout(tab_2); + verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + + stdOutput = createStdOutput(this); + verticalLayout_2->addWidget(stdOutput); + tabWidget->addTab(tab_2, QString()); + + tabWidget->setCurrentIndex(0); + + QMetaObject::connectSlotsByName(this); auto format_model = new BackupFormatModel(this); - ui->backupFormat->setModel(format_model); + backupFormat->setModel(format_model); + + retranslateUi(); } BackupDialog::~BackupDialog() { - delete ui; } + +void BackupDialog::retranslateUi() +{ + setWindowTitle(QApplication::translate("BackupDialog", "Dialog", nullptr)); + label->setText(QApplication::translate("BackupDialog", "Filename", nullptr)); + selectDestination->setText(QApplication::translate("BackupDialog", "...", nullptr)); + label_2->setText(QApplication::translate("BackupDialog", "Format", nullptr)); + label_3->setText(QApplication::translate("BackupDialog", "Jobs:", nullptr)); + chkbxVerbose->setText(QApplication::translate("BackupDialog", "Verbose (-v)", nullptr)); + label_5->setText(QApplication::translate("BackupDialog", "Compression (-Z)", nullptr)); +#ifndef QT_NO_TOOLTIP + compression->setToolTip(QApplication::translate("BackupDialog", "-1 means default, 0-9 is no compression to max compression", nullptr)); +#endif // QT_NO_TOOLTIP + label_4->setText(QApplication::translate("BackupDialog", "What", nullptr)); + what->setItemText(0, QApplication::translate("BackupDialog", "data + schema", nullptr)); + what->setItemText(1, QApplication::translate("BackupDialog", "data only (-a)", nullptr)); + what->setItemText(2, QApplication::translate("BackupDialog", "schema-only (-s)", nullptr)); + + chkbxIncludeBlobs->setText(QApplication::translate("BackupDialog", "Include blobs (-b)", nullptr)); + chkbxClean->setText(QApplication::translate("BackupDialog", "Clean (-c)", nullptr)); + chkbxCreate->setText(QApplication::translate("BackupDialog", "Create (-C)", nullptr)); + noOwner->setText(QApplication::translate("BackupDialog", "No owner (-O)", nullptr)); + oids->setText(QApplication::translate("BackupDialog", "Oids (-o)", nullptr)); + noAcl->setText(QApplication::translate("BackupDialog", "No privileges/acl (-x)", nullptr)); + btnStart->setText(QApplication::translate("BackupDialog", "START", nullptr)); + tabWidget->setTabText(tabWidget->indexOf(tab), QApplication::translate("BackupDialog", "Tab 1", nullptr)); + stdOutput->setPlainText(QApplication::translate("BackupDialog", "Test text.", nullptr)); + tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("BackupDialog", "Tab 2", nullptr)); +} // retranslateUi + void BackupDialog::setConfig(const ConnectionConfig &cfg) { m_config = cfg; @@ -66,8 +278,8 @@ void BackupDialog::disconnectCurrentProcess() void BackupDialog::writeOutput(const QString &s) { - ui->stdOutput->appendPlainText(s); - QScrollBar *bar = ui->stdOutput->verticalScrollBar(); + stdOutput->appendPlainText(s); + QScrollBar *bar = stdOutput->verticalScrollBar(); bar->setValue(bar->maximum()); } @@ -119,15 +331,15 @@ void BackupDialog::on_process_finished(int exitCode, QProcess::ExitStatus ) void BackupDialog::setParams(QStringList &args) { QString short_args("-"); - if (ui->chkbxVerbose->checkState() == Qt::Checked) + if (chkbxVerbose->checkState() == Qt::Checked) short_args += "v"; - if (ui->chkbxClean->checkState() == Qt::Checked) + if (chkbxClean->checkState() == Qt::Checked) short_args += "c"; - if (ui->chkbxCreate->checkState() == Qt::Checked) + if (chkbxCreate->checkState() == Qt::Checked) short_args += "C"; - if (ui->chkbxIncludeBlobs->checkState() == Qt::Checked) + if (chkbxIncludeBlobs->checkState() == Qt::Checked) short_args += "b"; - switch (ui->what->currentIndex()) { + switch (what->currentIndex()) { case 1: short_args += "a"; break; @@ -135,24 +347,24 @@ void BackupDialog::setParams(QStringList &args) short_args += "s"; break; } - if (ui->oids->checkState() == Qt::Checked) + if (oids->checkState() == Qt::Checked) short_args += "o"; - if (ui->noAcl->checkState() == Qt::Checked) + if (noAcl->checkState() == Qt::Checked) short_args += "x"; if (short_args.length() > 1) // larger then one because always includes '-' args << short_args; // Todo check path exists and name is valid? - QFileInfo fi(QDir::fromNativeSeparators(ui->editFilename->text())); + QFileInfo fi(QDir::fromNativeSeparators(editFilename->text())); QDir dir(fi.absolutePath()); if (!dir.exists()) dir.mkdir(fi.absolutePath()); - args << "-f" << ui->editFilename->text(); // R"-(c:\temp\backup.sql)-"; + args << "-f" << editFilename->text(); // R"-(c:\temp\backup.sql)-"; - int format_index = ui->backupFormat->currentIndex(); - auto format_model_base = ui->backupFormat->model(); + int format_index = backupFormat->currentIndex(); + auto format_model_base = backupFormat->model(); auto *bfm = dynamic_cast(format_model_base); if (bfm) { QVariant v = bfm->data(bfm->index(format_index, 1)); @@ -161,73 +373,24 @@ void BackupDialog::setParams(QStringList &args) args << format; } - int jobs = ui->jobs->value(); - if (jobs > 0) - args << "-j" << QString::number(jobs); + int j = jobs->value(); + if (j > 0) + args << "-j" << QString::number(j); - int compression = ui->compression->value(); - if (compression >= 0) - args << "-Z" << QString::number(compression); + int comp = compression->value(); + if (comp >= 0) + args << "-Z" << QString::number(comp); } void BackupDialog::on_btnStart_clicked() { - ui->stdOutput->clear(); + stdOutput->clear(); //QString program = R"-(C:\Prog\bigsql\pg96\bin\pg_dump.exe)-"; - QString program = "/usr/bin/pg_dump"; + QString program = "C:/Prog/bigsql/pg11/bin/pg_dump.exe"; QStringList arguments; setParams(arguments); - -// BOOL res = AllocConsole(); -// if (!res) { -// DWORD error = GetLastError(); -// QMessageBox::critical(this, "pglab", tr("AllocConsole failed %1").arg(error), QMessageBox::Close); -// } -// HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); -// DWORD written; -// res = WriteConsoleOutputCharacter(out, L"Hello, world!\n", 14, {0, 0}, &written); - -// PROCESS_INFORMATION proc_info; -// STARTUPINFO startup_info; -// memset(&startup_info, 0, sizeof(startup_info)); -// startup_info.cb = sizeof(startup_info); -// startup_info.lpReserved; -// startup_info.lpDesktop; -// startup_info.lpTitle; -// startup_info.dwX; -// startup_info.dwY; -// startup_info.dwXSize; -// startup_info.dwYSize; -// startup_info.dwXCountChars; -// startup_info.dwYCountChars; -// startup_info.dwFillAttribute; -// startup_info.dwFlags = STARTF_USESTDHANDLES; -// startup_info.wShowWindow; -// startup_info.cbReserved2; -// startup_info.lpReserved2; -// startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); -// startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); -// startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); -// res = CreateProcess( -// LR"_(C:\Prog\build-conoutputtest-Desktop_Qt_5_8_0_MSVC2015_32bit2-Debug\debug\conoutputtest.exe)_", -// NULL, // _Inout_opt_ LPTSTR lpCommandLine, -// NULL, // _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, -// NULL, // _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, -// TRUE, -// 0, // _In_ DWORD dwCreationFlags, -// NULL, // _In_opt_ LPVOID lpEnvironment, -// NULL, // _In_opt_ LPCTSTR lpCurrentDirectory, -// &startup_info, // _In_ LPSTARTUPINFO lpStartupInfo, -// &proc_info // _Out_ LPPROCESS_INFORMATION lpProcessInformation -// ); - - -// QString program = R"_(C:\prog\build-conoutputtest-Desktop_Qt_5_8_0_MSVC2015_32bit2-Debug\debug\conoutputtest.exe)_"; -// QStringList arguments; -// arguments << "/C" << "DIR /S c:\\"; - // Database connection paramters are passed through the environment as this is far less visible to others. Commandline // parameters can often be viewed even if the user is not the owner of the process. // We use the systemEnvironment as a sane default. Then we let the connection overwrite all PG variables in it. @@ -238,34 +401,34 @@ void BackupDialog::on_btnStart_clicked() ConnectTo(p); p->setProcessEnvironment(env); #ifdef WIN32 - p->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args) - { - args->flags |= CREATE_NEW_CONSOLE; - args->flags &= ~DETACHED_PROCESS; - args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES; - }); +// p->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args) +// { +// args->flags |= CREATE_NEW_CONSOLE; +// args->flags &= ~DETACHED_PROCESS; +// args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES; +// }); #endif p->start(program, arguments); } void BackupDialog::on_backupFormat_currentIndexChanged(int /*index*/) { - int format_index = ui->backupFormat->currentIndex(); - auto format_model_base = ui->backupFormat->model(); + int format_index = backupFormat->currentIndex(); + auto format_model_base = backupFormat->model(); auto *bfm = dynamic_cast(format_model_base); if (bfm) { QVariant v = bfm->data(bfm->index(format_index, 1)); QString format = v.toString(); bool comp_enable = (format == "c" || format == "d"); - ui->compression->setEnabled(comp_enable); + compression->setEnabled(comp_enable); if (!comp_enable) - ui->compression->setValue(-1); + compression->setValue(-1); bool jobs_enable = (format == "d"); - ui->jobs->setEnabled(jobs_enable); + jobs->setEnabled(jobs_enable); if (!jobs_enable) - ui->jobs->setValue(0); + jobs->setValue(0); } } @@ -275,7 +438,7 @@ void BackupDialog::on_selectDestination_clicked() QString fn = QFileDialog::getSaveFileName(this, tr("Save backup"), home_dir, tr("Backup file (*.backup)")); if (!fn.isEmpty()) { - ui->editFilename->setText(QDir::toNativeSeparators(fn)); + editFilename->setText(QDir::toNativeSeparators(fn)); } } diff --git a/pglab/BackupDialog.h b/pglab/BackupDialog.h index 6ed5afa..c0ccc9b 100644 --- a/pglab/BackupDialog.h +++ b/pglab/BackupDialog.h @@ -5,12 +5,21 @@ #include "ConnectionConfig.h" #include -namespace Ui { - class BackupDialog; -} - class QStringList; +class QLabel; +class QPushButton; +class QTabWidget; +class QVBoxLayout; +class QHBoxLayout; +class QComboBox; +class QSpinBox; +class QCheckBox; +class QPlainTextEdit; +class QLineEdit; +class QFormLayout; + + class BackupDialog : public QDialog { Q_OBJECT @@ -23,11 +32,42 @@ public: void disconnectCurrentProcess(); void setConfig(const ConnectionConfig &cfg); + void retranslateUi(); private: - Ui::BackupDialog *ui; + QProcess *m_process = nullptr; ConnectionConfig m_config; + QPushButton *btnStart; + QTabWidget *tabWidget; + QWidget *tab; + QVBoxLayout *verticalLayout; + QFormLayout *formLayout; + QWidget *widget; + QHBoxLayout *horizontalLayout; + QLineEdit *editFilename; + QPushButton *selectDestination; + QComboBox *backupFormat; + QSpinBox *jobs; + QCheckBox *chkbxVerbose; + QSpinBox *compression; + QCheckBox *chkbxIncludeBlobs; + QCheckBox *chkbxClean; + QCheckBox *chkbxCreate; + QCheckBox *noOwner; + QCheckBox *oids; + QComboBox *what; + QCheckBox *noAcl; + QWidget *tab_2; + QVBoxLayout *verticalLayout_2; + QPlainTextEdit *stdOutput; + QLabel *label; + QLabel *label_2; + QLabel *label_3; + QLabel *label_4; + QLabel *label_5; + + void writeOutput(const QString &s); void setParams(QStringList &args); diff --git a/pglab/BackupDialog.ui b/pglab/BackupDialog.ui deleted file mode 100644 index 3138428..0000000 --- a/pglab/BackupDialog.ui +++ /dev/null @@ -1,306 +0,0 @@ - - - BackupDialog - - - - 0 - 0 - 650 - 745 - - - - Dialog - - - - - 270 - 630 - 75 - 23 - - - - START - - - - - - 30 - 90 - 601 - 501 - - - - 0 - - - - Tab 1 - - - - - - - - Filename - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - ... - - - - - - - - - - Format - - - - - - - 0 - - - - - - - Jobs: - - - - - - - - - - Verbose - - - - - - - Compression - - - - - - - -1 means default, 0-9 is no compression to max compression - - - -1 - - - 9 - - - -1 - - - - - - - Include blobs - - - - - - - Clean - - - - - - - Create - - - - - - - No owner - - - - - - - Oids - - - - - - - - data + schema - - - - - data only (-a) - - - - - schema-only (-s) - - - - - - - - What - - - - - - - No privileges/acl - - - - - - - - - - Tab 2 - - - - - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - - - 120 - 120 - 120 - - - - - - - 240 - 240 - 240 - - - - - - - - - Source Code Pro - 10 - - - - QPlainTextEdit::NoWrap - - - true - - - Test text. - - - - - - - - - - diff --git a/pglab/pglab.pro b/pglab/pglab.pro index 4317378..5c2e24b 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -173,7 +173,6 @@ FORMS += \ CreateDatabaseDialog.ui \ TuplesResultWidget.ui \ QueryTab.ui \ - BackupDialog.ui \ ServerWindow.ui \ ProcessStdioWidget.ui \ NamespaceFilterWidget.ui \ diff --git a/pgsql/ArrayParser.h b/pgsql/ArrayParser.h index 93ae1cd..e20e284 100644 --- a/pgsql/ArrayParser.h +++ b/pgsql/ArrayParser.h @@ -1,4 +1,10 @@ -#ifndef ARRAYPARSER_H +/* + * Copyright (C) 2017-2019 Eelke Klein + * Contact: eelke.klein@gmail.com + * + * This file is part of the Pgsql module of the pgLab program. + */ +#ifndef ARRAYPARSER_H #define ARRAYPARSER_H #include