Backup functionality working, the UI still needs work.
This commit is contained in:
parent
d0ea9dfa0c
commit
73528ca965
12 changed files with 606 additions and 194 deletions
|
|
@ -30,13 +30,15 @@ SOURCES += Core.cpp \
|
||||||
my_boost_assert_handler.cpp \
|
my_boost_assert_handler.cpp \
|
||||||
SqlLexer.cpp \
|
SqlLexer.cpp \
|
||||||
PasswordManager.cpp \
|
PasswordManager.cpp \
|
||||||
CsvWriter.cpp
|
CsvWriter.cpp \
|
||||||
|
BackupFormatModel.cpp
|
||||||
|
|
||||||
HEADERS += Core.h \
|
HEADERS += Core.h \
|
||||||
PasswordManager.h \
|
PasswordManager.h \
|
||||||
SqlLexer.h \
|
SqlLexer.h \
|
||||||
ScopeGuard.h \
|
ScopeGuard.h \
|
||||||
CsvWriter.h
|
CsvWriter.h \
|
||||||
|
BackupFormatModel.h
|
||||||
unix {
|
unix {
|
||||||
target.path = /usr/lib
|
target.path = /usr/lib
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,223 @@
|
||||||
#include "backupdialog.h"
|
#include "backupdialog.h"
|
||||||
#include "ui_backupdialog.h"
|
#include "ui_backupdialog.h"
|
||||||
|
|
||||||
|
#include "BackupFormatModel.h"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
BackupDialog::BackupDialog(QWidget *parent) :
|
BackupDialog::BackupDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::BackupDialog)
|
ui(new Ui::BackupDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
auto format_model = new BackupFormatModel(this);
|
||||||
|
ui->backupFormat->setModel(format_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackupDialog::~BackupDialog()
|
BackupDialog::~BackupDialog()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BackupDialog::setConfig(const ConnectionConfig &cfg)
|
||||||
|
{
|
||||||
|
m_config = cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BackupDialog::ConnectTo(QProcess *process)
|
||||||
|
{
|
||||||
|
disconnectCurrentProcess();
|
||||||
|
m_process = process;
|
||||||
|
if (process) {
|
||||||
|
process->setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
process->setReadChannel(QProcess::StandardOutput);
|
||||||
|
|
||||||
|
connect(process, SIGNAL(readyRead()), this, SLOT(on_process_readyRead()));
|
||||||
|
connect(process, SIGNAL(errorOccurred(QProcess::ProcessError)), this,
|
||||||
|
SLOT(on_process_errorOccurred(QProcess::ProcessError)));
|
||||||
|
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this,
|
||||||
|
SLOT(on_process_finished(int, QProcess::ExitStatus)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::disconnectCurrentProcess()
|
||||||
|
{
|
||||||
|
if (m_process) {
|
||||||
|
disconnect(m_process, SIGNAL(readyRead()), this, SLOT(on_process_readyRead()));
|
||||||
|
disconnect(m_process, SIGNAL(errorOccurred(QProcess::ProcessError)), this,
|
||||||
|
SLOT(on_process_errorOccurred(QProcess::ProcessError)));
|
||||||
|
disconnect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this,
|
||||||
|
SLOT(on_process_finished(int, QProcess::ExitStatus)));
|
||||||
|
m_process = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BackupDialog::writeOutput(QString s)
|
||||||
|
{
|
||||||
|
ui->stdOutput->appendPlainText(s);
|
||||||
|
QScrollBar *bar = ui->stdOutput->verticalScrollBar();
|
||||||
|
bar->setValue(bar->maximum());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::on_process_readyRead()
|
||||||
|
{
|
||||||
|
QByteArray data = m_process->readAllStandardOutput();
|
||||||
|
writeOutput(QString::fromUtf8(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::on_process_errorOccurred(QProcess::ProcessError error)
|
||||||
|
{
|
||||||
|
QString msg;
|
||||||
|
switch (error) {
|
||||||
|
case 0:
|
||||||
|
msg = tr("Failed to start");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
msg = tr("Crasged");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
msg = tr("Timedout");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
msg = tr("Read error");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
msg = tr("Write error");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
msg = tr("Unknown error");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg = tr("Unexpected error");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto res = QMessageBox::critical(this, "pglab", msg, QMessageBox::Close);
|
||||||
|
if (res == QMessageBox::Yes) {
|
||||||
|
QApplication::quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::on_process_finished(int exitCode, QProcess::ExitStatus )
|
||||||
|
{
|
||||||
|
writeOutput(tr("Completed, with exitcode %1\n").arg(exitCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::setParams(QStringList &args)
|
||||||
|
{
|
||||||
|
QString short_args("-");
|
||||||
|
if (ui->chkbxVerbose->checkState() == Qt::Checked)
|
||||||
|
short_args += "v";
|
||||||
|
if (ui->chkbxClean->checkState() == Qt::Checked)
|
||||||
|
short_args += "c";
|
||||||
|
if (ui->chkbxCreate->checkState() == Qt::Checked)
|
||||||
|
short_args += "C";
|
||||||
|
if (ui->chkbxIncludeBlobs->checkState() == Qt::Checked)
|
||||||
|
short_args += "b";
|
||||||
|
switch (ui->what->currentIndex()) {
|
||||||
|
case 1:
|
||||||
|
short_args += "a";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
short_args += "s";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ui->oids->checkState() == Qt::Checked)
|
||||||
|
short_args += "o";
|
||||||
|
if (ui->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()));
|
||||||
|
QDir dir(fi.absolutePath());
|
||||||
|
if (!dir.exists())
|
||||||
|
dir.mkdir(fi.absolutePath());
|
||||||
|
|
||||||
|
args << "-f" << ui->editFilename->text(); // R"-(c:\temp\backup.sql)-";
|
||||||
|
|
||||||
|
int format_index = ui->backupFormat->currentIndex();
|
||||||
|
auto format_model_base = ui->backupFormat->model();
|
||||||
|
BackupFormatModel *bfm = dynamic_cast<BackupFormatModel *>(format_model_base);
|
||||||
|
if (bfm) {
|
||||||
|
QVariant v = bfm->data(bfm->index(format_index, 1));
|
||||||
|
QString format("-F");
|
||||||
|
format += v.toString();
|
||||||
|
args << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
int jobs = ui->jobs->value();
|
||||||
|
if (jobs > 0)
|
||||||
|
args << "-j" << QString::number(jobs);
|
||||||
|
|
||||||
|
int compression = ui->compression->value();
|
||||||
|
if (compression >= 0)
|
||||||
|
args << "-Z" << QString::number(compression);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::on_btnStart_clicked()
|
||||||
|
{
|
||||||
|
ui->stdOutput->clear();
|
||||||
|
|
||||||
|
QString program = R"-(C:\Prog\bigsql\pg96\bin\pg_dump.exe)-";
|
||||||
|
QStringList arguments;
|
||||||
|
setParams(arguments);
|
||||||
|
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
m_config.writeToEnvironment(env);
|
||||||
|
env.insert("SESSIONNAME", "Console");
|
||||||
|
auto p = new QProcess(this);
|
||||||
|
ConnectTo(p);
|
||||||
|
p->setProcessEnvironment(env);
|
||||||
|
p->start(program, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::on_backupFormat_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
int format_index = ui->backupFormat->currentIndex();
|
||||||
|
auto format_model_base = ui->backupFormat->model();
|
||||||
|
BackupFormatModel *bfm = dynamic_cast<BackupFormatModel *>(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);
|
||||||
|
if (!comp_enable)
|
||||||
|
ui->compression->setValue(-1);
|
||||||
|
|
||||||
|
bool jobs_enable = (format == "d");
|
||||||
|
ui->jobs->setEnabled(jobs_enable);
|
||||||
|
if (!jobs_enable)
|
||||||
|
ui->jobs->setValue(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackupDialog::on_selectDestination_clicked()
|
||||||
|
{
|
||||||
|
QString home_dir = QStandardPaths::locate(QStandardPaths::HomeLocation, "", QStandardPaths::LocateDirectory);
|
||||||
|
QString fn = QFileDialog::getSaveFileName(this, tr("Save backup"), home_dir,
|
||||||
|
tr("Backup file (*.backup)"));
|
||||||
|
if (!fn.isEmpty()) {
|
||||||
|
ui->editFilename->setText(QDir::toNativeSeparators(fn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
#ifndef BACKUPDIALOG_H
|
#ifndef BACKUPDIALOG_H
|
||||||
#define BACKUPDIALOG_H
|
#define BACKUPDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include "ConnectionConfig.h"
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class BackupDialog;
|
class BackupDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class QStringList;
|
||||||
|
|
||||||
class BackupDialog : public QDialog
|
class BackupDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -15,8 +19,26 @@ public:
|
||||||
explicit BackupDialog(QWidget *parent = 0);
|
explicit BackupDialog(QWidget *parent = 0);
|
||||||
~BackupDialog();
|
~BackupDialog();
|
||||||
|
|
||||||
|
void ConnectTo(QProcess *process);
|
||||||
|
|
||||||
|
void disconnectCurrentProcess();
|
||||||
|
void setConfig(const ConnectionConfig &cfg);
|
||||||
private:
|
private:
|
||||||
Ui::BackupDialog *ui;
|
Ui::BackupDialog *ui;
|
||||||
|
QProcess *m_process = nullptr;
|
||||||
|
ConnectionConfig m_config;
|
||||||
|
|
||||||
|
void writeOutput(QString s);
|
||||||
|
|
||||||
|
void setParams(QStringList &args);
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void on_process_readyRead();
|
||||||
|
void on_process_errorOccurred(QProcess::ProcessError error);
|
||||||
|
void on_process_finished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
void on_btnStart_clicked();
|
||||||
|
void on_backupFormat_currentIndexChanged(int index);
|
||||||
|
void on_selectDestination_clicked();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BACKUPDIALOG_H
|
#endif // BACKUPDIALOG_H
|
||||||
|
|
|
||||||
|
|
@ -6,205 +6,300 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>645</width>
|
<width>650</width>
|
||||||
<height>745</height>
|
<height>745</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Dialog</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="widget" native="true">
|
<widget class="QPushButton" name="btnStart">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>76</x>
|
<x>270</x>
|
||||||
<y>9</y>
|
<y>630</y>
|
||||||
<width>232</width>
|
<width>75</width>
|
||||||
<height>41</height>
|
<height>23</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<property name="text">
|
||||||
|
<string>START</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>30</x>
|
||||||
|
<y>90</y>
|
||||||
|
<width>601</width>
|
||||||
|
<height>501</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 1</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="lineEdit"/>
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Filename</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QWidget" name="widget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="editFilename"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton">
|
<widget class="QPushButton" name="selectDestination">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>PushButton</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>9</x>
|
|
||||||
<y>98</y>
|
|
||||||
<width>34</width>
|
|
||||||
<height>16</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Format</string>
|
<string>Format</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QComboBox" name="comboBox">
|
</item>
|
||||||
<property name="geometry">
|
<item row="1" column="1">
|
||||||
<rect>
|
<widget class="QComboBox" name="backupFormat">
|
||||||
<x>76</x>
|
<property name="modelColumn">
|
||||||
<y>98</y>
|
<number>0</number>
|
||||||
<width>69</width>
|
|
||||||
<height>20</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>9</x>
|
|
||||||
<y>9</y>
|
|
||||||
<width>42</width>
|
|
||||||
<height>16</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Filename</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>9</x>
|
|
||||||
<y>124</y>
|
|
||||||
<width>26</width>
|
|
||||||
<height>16</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Jobs:</string>
|
<string>Jobs:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QSpinBox" name="spinBox">
|
</item>
|
||||||
<property name="geometry">
|
<item row="2" column="1">
|
||||||
<rect>
|
<widget class="QSpinBox" name="jobs"/>
|
||||||
<x>76</x>
|
</item>
|
||||||
<y>124</y>
|
<item row="3" column="1">
|
||||||
<width>37</width>
|
<widget class="QCheckBox" name="chkbxVerbose">
|
||||||
<height>20</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QCheckBox" name="checkBox">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>76</x>
|
|
||||||
<y>150</y>
|
|
||||||
<width>70</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Verbose</string>
|
<string>Verbose</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>9</x>
|
|
||||||
<y>173</y>
|
|
||||||
<width>61</width>
|
|
||||||
<height>16</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Compression</string>
|
<string>Compression</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QSpinBox" name="spinBox_2">
|
</item>
|
||||||
<property name="geometry">
|
<item row="4" column="1">
|
||||||
<rect>
|
<widget class="QSpinBox" name="compression">
|
||||||
<x>76</x>
|
<property name="toolTip">
|
||||||
<y>173</y>
|
<string>-1 means default, 0-9 is no compression to max compression</string>
|
||||||
<width>37</width>
|
</property>
|
||||||
<height>20</height>
|
<property name="minimum">
|
||||||
</rect>
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>-1</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QCheckBox" name="checkBox_2">
|
</item>
|
||||||
<property name="geometry">
|
<item row="6" column="1">
|
||||||
<rect>
|
<widget class="QCheckBox" name="chkbxIncludeBlobs">
|
||||||
<x>70</x>
|
|
||||||
<y>210</y>
|
|
||||||
<width>70</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Data only</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QCheckBox" name="checkBox_3">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>70</x>
|
|
||||||
<y>230</y>
|
|
||||||
<width>171</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Include blobs</string>
|
<string>Include blobs</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QCheckBox" name="checkBox_4">
|
</item>
|
||||||
<property name="geometry">
|
<item row="7" column="1">
|
||||||
<rect>
|
<widget class="QCheckBox" name="chkbxClean">
|
||||||
<x>70</x>
|
|
||||||
<y>260</y>
|
|
||||||
<width>70</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Clean</string>
|
<string>Clean</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QCheckBox" name="checkBox_5">
|
</item>
|
||||||
<property name="geometry">
|
<item row="8" column="1">
|
||||||
<rect>
|
<widget class="QCheckBox" name="chkbxCreate">
|
||||||
<x>70</x>
|
|
||||||
<y>280</y>
|
|
||||||
<width>70</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Create</string>
|
<string>Create</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="label_4">
|
</item>
|
||||||
<property name="geometry">
|
<item row="9" column="1">
|
||||||
<rect>
|
<widget class="QCheckBox" name="noOwner">
|
||||||
<x>20</x>
|
|
||||||
<y>320</y>
|
|
||||||
<width>47</width>
|
|
||||||
<height>13</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Encoding</string>
|
<string>No owner</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QComboBox" name="comboBox_2">
|
</item>
|
||||||
<property name="geometry">
|
<item row="10" column="1">
|
||||||
<rect>
|
<widget class="QCheckBox" name="oids">
|
||||||
<x>70</x>
|
<property name="text">
|
||||||
<y>320</y>
|
<string>Oids</string>
|
||||||
<width>69</width>
|
|
||||||
<height>22</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QComboBox" name="what">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>data + schema</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>data only (-a)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>schema-only (-s)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>What</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="1">
|
||||||
|
<widget class="QCheckBox" name="noAcl">
|
||||||
|
<property name="text">
|
||||||
|
<string>No privileges/acl</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 2</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="stdOutput">
|
||||||
|
<property name="palette">
|
||||||
|
<palette>
|
||||||
|
<active>
|
||||||
|
<colorrole role="Text">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>255</red>
|
||||||
|
<green>255</green>
|
||||||
|
<blue>255</blue>
|
||||||
|
</color>
|
||||||
|
</brush>
|
||||||
|
</colorrole>
|
||||||
|
<colorrole role="Base">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>0</red>
|
||||||
|
<green>0</green>
|
||||||
|
<blue>0</blue>
|
||||||
|
</color>
|
||||||
|
</brush>
|
||||||
|
</colorrole>
|
||||||
|
</active>
|
||||||
|
<inactive>
|
||||||
|
<colorrole role="Text">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>255</red>
|
||||||
|
<green>255</green>
|
||||||
|
<blue>255</blue>
|
||||||
|
</color>
|
||||||
|
</brush>
|
||||||
|
</colorrole>
|
||||||
|
<colorrole role="Base">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>0</red>
|
||||||
|
<green>0</green>
|
||||||
|
<blue>0</blue>
|
||||||
|
</color>
|
||||||
|
</brush>
|
||||||
|
</colorrole>
|
||||||
|
</inactive>
|
||||||
|
<disabled>
|
||||||
|
<colorrole role="Text">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>120</red>
|
||||||
|
<green>120</green>
|
||||||
|
<blue>120</blue>
|
||||||
|
</color>
|
||||||
|
</brush>
|
||||||
|
</colorrole>
|
||||||
|
<colorrole role="Base">
|
||||||
|
<brush brushstyle="SolidPattern">
|
||||||
|
<color alpha="255">
|
||||||
|
<red>240</red>
|
||||||
|
<green>240</green>
|
||||||
|
<blue>240</blue>
|
||||||
|
</color>
|
||||||
|
</brush>
|
||||||
|
</colorrole>
|
||||||
|
</disabled>
|
||||||
|
</palette>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Source Code Pro</family>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="lineWrapMode">
|
||||||
|
<enum>QPlainTextEdit::NoWrap</enum>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="plainText">
|
||||||
|
<string>Test text.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#include "connectionconfig.h"
|
#include "connectionconfig.h"
|
||||||
|
#include "util.h"
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
@ -259,3 +261,60 @@ void ConnectionConfig::clean()
|
||||||
{
|
{
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
PGHOST behaves the same as the host connection parameter.
|
||||||
|
PGHOSTADDR behaves the same as the hostaddr connection parameter. This can be set instead of or in addition to PGHOST to avoid DNS lookup overhead.
|
||||||
|
PGPORT behaves the same as the port connection parameter.
|
||||||
|
PGDATABASE behaves the same as the dbname connection parameter.
|
||||||
|
PGUSER behaves the same as the user connection parameter.
|
||||||
|
PGPASSWORD behaves the same as the password connection parameter. Use of this environment variable is not recommended for security reasons, as some operating systems allow non-root users to see process environment variables via ps; instead consider using the ~/.pgpass file (see Section 31.15).
|
||||||
|
PGPASSFILE specifies the name of the password file to use for lookups. If not set, it defaults to ~/.pgpass (see Section 31.15).
|
||||||
|
PGSERVICE behaves the same as the service connection parameter.
|
||||||
|
PGSERVICEFILE specifies the name of the per-user connection service file. If not set, it defaults to ~/.pg_service.conf (see Section 31.16).
|
||||||
|
PGREALM sets the Kerberos realm to use with PostgreSQL, if it is different from the local realm. If PGREALM is set, libpq applications will attempt authentication with servers for this realm and use separate ticket files to avoid conflicts with local ticket files. This environment variable is only used if GSSAPI authentication is selected by the server.
|
||||||
|
PGOPTIONS behaves the same as the options connection parameter.
|
||||||
|
PGAPPNAME behaves the same as the application_name connection parameter.
|
||||||
|
PGSSLMODE behaves the same as the sslmode connection parameter.
|
||||||
|
PGREQUIRESSL behaves the same as the requiressl connection parameter.
|
||||||
|
PGSSLCOMPRESSION behaves the same as the sslcompression connection parameter.
|
||||||
|
PGSSLCERT behaves the same as the sslcert connection parameter.
|
||||||
|
PGSSLKEY behaves the same as the sslkey connection parameter.
|
||||||
|
PGSSLROOTCERT behaves the same as the sslrootcert connection parameter.
|
||||||
|
PGSSLCRL behaves the same as the sslcrl connection parameter.
|
||||||
|
PGREQUIREPEER behaves the same as the requirepeer connection parameter.
|
||||||
|
PGKRBSRVNAME behaves the same as the krbsrvname connection parameter.
|
||||||
|
PGGSSLIB behaves the same as the gsslib connection parameter.
|
||||||
|
PGCONNECT_TIMEOUT behaves the same as the connect_timeout connection parameter.
|
||||||
|
PGCLIENTENCODING behaves the same as the client_encoding connection parameter.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ConnectionConfig::writeToEnvironment(QProcessEnvironment &env) const
|
||||||
|
{
|
||||||
|
strToEnv(env, "PGHOST", m_host);
|
||||||
|
strToEnv(env, "PGHOSTADDR", m_hostaddr);
|
||||||
|
strToEnv(env, "PGPORT", m_port);
|
||||||
|
strToEnv(env, "PGDATABASE", m_dbname);
|
||||||
|
strToEnv(env, "PGUSER", m_user);
|
||||||
|
strToEnv(env, "PGPASSWORD", m_password);
|
||||||
|
strToEnv(env, "PGSSLMODE", m_sslMode);
|
||||||
|
strToEnv(env, "PGSSLCERT", m_sslCert);
|
||||||
|
strToEnv(env, "PGSSLKEY", m_sslKey);
|
||||||
|
strToEnv(env, "PGSSLROOTCERT", m_sslRootCert);
|
||||||
|
strToEnv(env, "PGSSLCRL", m_sslCrl);
|
||||||
|
strToEnv(env, "PGSSLCOMPRESSION", "0");
|
||||||
|
strToEnv(env, "PGCONNECT_TIMEOUT", "10");
|
||||||
|
env.insert("PGCLIENTENCODING", "utf8");
|
||||||
|
|
||||||
|
env.remove("PGREQUIRESSL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectionConfig::strToEnv(QProcessEnvironment &env, const QString &var, const std::string &val)
|
||||||
|
{
|
||||||
|
if (val.empty())
|
||||||
|
env.remove(var);
|
||||||
|
else
|
||||||
|
env.insert(var, stdStrToQ(val));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
enum class SslMode {
|
enum class SslMode {
|
||||||
disable=0,
|
disable=0,
|
||||||
allow=1,
|
allow=1,
|
||||||
|
|
@ -19,6 +20,9 @@ enum class PasswordMode {
|
||||||
DontSave
|
DontSave
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QProcessEnvironment;
|
||||||
|
class QString;
|
||||||
|
|
||||||
class ConnectionConfig {
|
class ConnectionConfig {
|
||||||
public:
|
public:
|
||||||
ConnectionConfig();
|
ConnectionConfig();
|
||||||
|
|
@ -64,6 +68,8 @@ public:
|
||||||
|
|
||||||
bool isSameDatabase(const ConnectionConfig &rhs) const;
|
bool isSameDatabase(const ConnectionConfig &rhs) const;
|
||||||
|
|
||||||
|
void writeToEnvironment(QProcessEnvironment &env) const;
|
||||||
|
|
||||||
bool dirty() const;
|
bool dirty() const;
|
||||||
void clean();
|
void clean();
|
||||||
private:
|
private:
|
||||||
|
|
@ -86,6 +92,8 @@ private:
|
||||||
|
|
||||||
bool m_dirty = false;
|
bool m_dirty = false;
|
||||||
|
|
||||||
|
static void strToEnv(QProcessEnvironment &env, const QString &var, const std::string &val);
|
||||||
|
|
||||||
static std::vector<const char*> s_keywords;
|
static std::vector<const char*> s_keywords;
|
||||||
mutable std::vector<const char*> m_values;
|
mutable std::vector<const char*> m_values;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ ConnectionListModel::ConnectionListModel(ConnectionList *conns, QObject *parent)
|
||||||
|
|
||||||
ConnectionListModel::~ConnectionListModel()
|
ConnectionListModel::~ConnectionListModel()
|
||||||
{
|
{
|
||||||
delete m_connections;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConnectionListModel::rowCount(const QModelIndex &parent) const
|
int ConnectionListModel::rowCount(const QModelIndex &parent) const
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,8 @@ void ConnectionManagerWindow::on_actionQuit_application_triggered()
|
||||||
|
|
||||||
void ConnectionManagerWindow::on_actionBackup_database_triggered()
|
void ConnectionManagerWindow::on_actionBackup_database_triggered()
|
||||||
{
|
{
|
||||||
// BACKUP
|
auto ci = ui->listView->selectionModel()->currentIndex();
|
||||||
|
m_masterController->openBackupDlgForConnection(ci.row());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionManagerWindow::on_actionManage_server_triggered()
|
void ConnectionManagerWindow::on_actionManage_server_triggered()
|
||||||
|
|
@ -111,6 +112,8 @@ void ConnectionManagerWindow::on_actionManage_server_triggered()
|
||||||
m_masterController->openServerWindowForConnection(ci.row());
|
m_masterController->openServerWindowForConnection(ci.row());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <botan/botan.h>
|
#include <botan/botan.h>
|
||||||
//#include <botan/base64.h>
|
//#include <botan/base64.h>
|
||||||
//#include <botan/pbkdf.h>
|
//#include <botan/pbkdf.h>
|
||||||
|
|
@ -118,6 +121,7 @@ void ConnectionManagerWindow::on_actionManage_server_triggered()
|
||||||
//#include <botan/hex.h>
|
//#include <botan/hex.h>
|
||||||
#include <botan/cryptobox.h>
|
#include <botan/cryptobox.h>
|
||||||
|
|
||||||
|
|
||||||
void ConnectionManagerWindow::on_testButton_clicked()
|
void ConnectionManagerWindow::on_testButton_clicked()
|
||||||
{
|
{
|
||||||
std::string error = Botan::runtime_version_check(BOTAN_VERSION_MAJOR,
|
std::string error = Botan::runtime_version_check(BOTAN_VERSION_MAJOR,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "ConnectionListModel.h"
|
#include "ConnectionListModel.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "ServerWindow.h"
|
#include "ServerWindow.h"
|
||||||
|
#include "BackupDialog.h"
|
||||||
|
|
||||||
|
|
||||||
MasterController::MasterController(QObject *parent) : QObject(parent)
|
MasterController::MasterController(QObject *parent) : QObject(parent)
|
||||||
|
|
@ -45,6 +46,18 @@ void MasterController::openSqlWindowForConnection(int connection_index)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MasterController::openBackupDlgForConnection(int connection_index)
|
||||||
|
{
|
||||||
|
auto cc = m_connectionListModel->get(connection_index);
|
||||||
|
m_connectionListModel->save(connection_index);
|
||||||
|
if (cc.valid()) {
|
||||||
|
auto w = new BackupDialog(nullptr); //new ServerWindow(this, nullptr);
|
||||||
|
w->setAttribute( Qt::WA_DeleteOnClose );
|
||||||
|
w->setConfig(cc.get());
|
||||||
|
w->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MasterController::openServerWindowForConnection(int connection_index)
|
void MasterController::openServerWindowForConnection(int connection_index)
|
||||||
{
|
{
|
||||||
auto cc = m_connectionListModel->get(connection_index);
|
auto cc = m_connectionListModel->get(connection_index);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ public:
|
||||||
void showConnectionManager();
|
void showConnectionManager();
|
||||||
void openSqlWindowForConnection(int connection_index);
|
void openSqlWindowForConnection(int connection_index);
|
||||||
void openServerWindowForConnection(int connection_index);
|
void openServerWindowForConnection(int connection_index);
|
||||||
|
void openBackupDlgForConnection(int connection_index);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
||||||
10
src/src.pro
10
src/src.pro
|
|
@ -73,7 +73,8 @@ SOURCES += main.cpp\
|
||||||
Pgsql_Result.cpp \
|
Pgsql_Result.cpp \
|
||||||
Pgsql_Row.cpp \
|
Pgsql_Row.cpp \
|
||||||
Pgsql_Value.cpp \
|
Pgsql_Value.cpp \
|
||||||
ConnectionList.cpp
|
ConnectionList.cpp \
|
||||||
|
ProcessStdioWidget.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
sqlparser.h \
|
sqlparser.h \
|
||||||
|
|
@ -108,7 +109,6 @@ HEADERS += \
|
||||||
ParamListModel.h \
|
ParamListModel.h \
|
||||||
MainWindow.h \
|
MainWindow.h \
|
||||||
SqlSyntaxHighlighter.h \
|
SqlSyntaxHighlighter.h \
|
||||||
SqlLexer.h \
|
|
||||||
ServerWindow.h \
|
ServerWindow.h \
|
||||||
ASyncWindow.h \
|
ASyncWindow.h \
|
||||||
DatabasesTableModel.h \
|
DatabasesTableModel.h \
|
||||||
|
|
@ -123,7 +123,8 @@ HEADERS += \
|
||||||
Pgsql_Result.h \
|
Pgsql_Result.h \
|
||||||
Pgsql_Row.h \
|
Pgsql_Row.h \
|
||||||
Pgsql_Value.h \
|
Pgsql_Value.h \
|
||||||
ConnectionList.h
|
ConnectionList.h \
|
||||||
|
ProcessStdioWidget.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
DatabaseWindow.ui \
|
DatabaseWindow.ui \
|
||||||
|
|
@ -132,7 +133,8 @@ FORMS += mainwindow.ui \
|
||||||
TuplesResultWidget.ui \
|
TuplesResultWidget.ui \
|
||||||
QueryTab.ui \
|
QueryTab.ui \
|
||||||
BackupDialog.ui \
|
BackupDialog.ui \
|
||||||
ServerWindow.ui
|
ServerWindow.ui \
|
||||||
|
ProcessStdioWidget.ui
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources.qrc
|
resources.qrc
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,8 @@
|
||||||
|
|
||||||
class PgTypeContainer;
|
class PgTypeContainer;
|
||||||
|
|
||||||
class TypeSelectionItemModel : public QAbstractListModel
|
class TypeSelectionItemModel : public QAbstractListModel {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TypeSelectionItemModel(QObject *parent = 0);
|
explicit TypeSelectionItemModel(QObject *parent = 0);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue