271 lines
7.4 KiB
C++
Executable File
271 lines
7.4 KiB
C++
Executable File
/*
|
|
* @RDE_HEADER@
|
|
* Copy exercise from server to evaluation server
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Ehrlicher, NLSE, 2018-07-31
|
|
*/
|
|
|
|
#include "copy_database.h"
|
|
|
|
#include <ngldb/dbcommon.h>
|
|
#include <ngldb/dbconnection.h>
|
|
#include <ngldb/nsqlquery.h>
|
|
#include <ngltools/ngltools_filesystem.h>
|
|
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QProcess>
|
|
#include <QSettings>
|
|
|
|
namespace OcBaseDownload
|
|
{
|
|
CopyDatabase::CopyDatabase(NGL::INGLLogger &logger, QObject *parent)
|
|
: QObject(parent)
|
|
, m_proc(nullptr)
|
|
, m_logger(logger)
|
|
{}
|
|
|
|
bool CopyDatabase::init(const QString &dbHost, const QString &srcDbName, const QString &dstDbName)
|
|
{
|
|
m_dbHost = dbHost;
|
|
m_srcDbName = srcDbName;
|
|
m_dstDbName = dstDbName;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CopyDatabase::doCopy()
|
|
{
|
|
if (!runPgDump())
|
|
{
|
|
ERROR_LOG(m_logger) << "Error running pg_dump";
|
|
emit copyDbFailed();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CopyDatabase::dropDatabase(const QString &dbName)
|
|
{
|
|
return runDropDb(dbName);
|
|
}
|
|
|
|
bool CopyDatabase::runDropDb(const QString &dbName)
|
|
{
|
|
const QStringList args({QStringLiteral("-U"),
|
|
QStringLiteral("postgres"),
|
|
QStringLiteral("--if-exists"),
|
|
QStringLiteral("-h"),
|
|
m_dbHost,
|
|
dbName});
|
|
|
|
handleProcInit(executablePath(QStringLiteral("dropdb")), args);
|
|
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &CopyDatabase::onDropDbFinished);
|
|
m_proc->start();
|
|
return true;
|
|
}
|
|
|
|
void CopyDatabase::onDropDbFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
NOTICE_LOG(m_logger) << "onDropDbFinished: exitCode: " << exitCode << ", exitStatus: " << exitStatus;
|
|
|
|
if (exitCode > 0)
|
|
{
|
|
ERROR_LOG(m_logger) << "DropDb failed";
|
|
emit dropDatabaseFailed();
|
|
return;
|
|
}
|
|
|
|
emit dropDatabaseFinished();
|
|
}
|
|
|
|
bool CopyDatabase::runPgDump()
|
|
{
|
|
// start process
|
|
const QStringList args(
|
|
{
|
|
QStringLiteral("--column-inserts"),
|
|
QStringLiteral("-U"), QStringLiteral("postgres"),
|
|
QStringLiteral("-f"), getDumpFile(),
|
|
QStringLiteral("-h"), m_dbHost,
|
|
m_srcDbName
|
|
});
|
|
|
|
handleProcInit(executablePath(QStringLiteral("pg_dump")), args);
|
|
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &CopyDatabase::onPgDumpFinished);
|
|
|
|
m_proc->start();
|
|
|
|
return true;
|
|
}
|
|
|
|
void CopyDatabase::onPgDumpFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
NOTICE_LOG(m_logger) << "onProcessFinished: exitCode: " << exitCode << ", exitStatus: " << exitStatus;
|
|
runCreatedb();
|
|
}
|
|
|
|
void CopyDatabase::runCreatedb()
|
|
{
|
|
const QStringList args({QStringLiteral("-U"),
|
|
QStringLiteral("postgres"),
|
|
QStringLiteral("-h"),
|
|
m_dbHost,
|
|
m_dstDbName});
|
|
|
|
handleProcInit(executablePath(QStringLiteral("createdb")), args);
|
|
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &CopyDatabase::onCreateDbFinished);
|
|
m_proc->start();
|
|
}
|
|
|
|
void CopyDatabase::onCreateDbFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
NOTICE_LOG(m_logger) << "onCreateDbFinished: exitCode: " << exitCode << ", exitStatus: " << exitStatus;
|
|
|
|
if (exitCode > 0)
|
|
{
|
|
ERROR_LOG(m_logger) << "CreateDB failed";
|
|
emit copyDbFailed();
|
|
return;
|
|
}
|
|
runGrant();
|
|
//runPgLoad();
|
|
}
|
|
|
|
void CopyDatabase::runGrant()
|
|
{
|
|
|
|
const QString command = QStringLiteral("-c 'GRANT ALL ON DATABASE %1 to ets_exm'").arg(m_dstDbName);
|
|
const QStringList args({ QStringLiteral("-U"),
|
|
QStringLiteral("postgres"),
|
|
command,
|
|
QStringLiteral("-h"),
|
|
m_dbHost,
|
|
m_dstDbName });
|
|
|
|
handleProcInit(executablePath(QStringLiteral("psql")), args);
|
|
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &CopyDatabase::runPgLoad);
|
|
m_proc->start();
|
|
}
|
|
|
|
void CopyDatabase::runPgLoad()
|
|
{
|
|
const QStringList args({QStringLiteral("-U"),
|
|
QStringLiteral("postgres"),
|
|
QStringLiteral("-f"),
|
|
getDumpFile(),
|
|
QStringLiteral("-h"),
|
|
m_dbHost,
|
|
m_dstDbName});
|
|
|
|
handleProcInit(executablePath(QStringLiteral("psql")), args);
|
|
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &CopyDatabase::onPgLoadFinished);
|
|
m_proc->start();
|
|
}
|
|
|
|
void CopyDatabase::onPgLoadFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
NOTICE_LOG(m_logger) << "onPsqlFinished: exitCode: " << exitCode << ", exitStatus: " << exitStatus;
|
|
|
|
if (exitStatus == QProcess::ExitStatus::NormalExit)
|
|
QFile::remove(getDumpFile());
|
|
|
|
if (exitCode > 0)
|
|
{
|
|
ERROR_LOG(m_logger) << "Loading db failed";
|
|
emit copyDbFailed();
|
|
return;
|
|
}
|
|
runPgSetGrant();
|
|
}
|
|
|
|
void CopyDatabase::runPgSetGrant()
|
|
{
|
|
const QStringList args({QStringLiteral("-U"),
|
|
QStringLiteral("postgres"),
|
|
QStringLiteral("-c"), QStringLiteral("GRANT ALL ON DATABASE %1 to ets_admin").arg(m_dstDbName),
|
|
QStringLiteral("-h"),
|
|
m_dbHost,
|
|
m_dstDbName});
|
|
|
|
handleProcInit(executablePath(QStringLiteral("psql")), args);
|
|
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &CopyDatabase::onPgSetGrantFinished);
|
|
m_proc->start();
|
|
}
|
|
|
|
void CopyDatabase::onPgSetGrantFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
NOTICE_LOG(m_logger) << "onPsqlFinished: exitCode: " << exitCode << ", exitStatus: " << exitStatus;
|
|
|
|
if (exitCode > 0)
|
|
{
|
|
ERROR_LOG(m_logger) << "Set grants to ets_admin failed";
|
|
emit copyDbFailed();
|
|
return;
|
|
}
|
|
|
|
emit copyDbFinished();
|
|
}
|
|
|
|
|
|
void CopyDatabase::handleProcInit(const QString &program, const QStringList &args)
|
|
{
|
|
if (m_proc)
|
|
{
|
|
m_proc->disconnect(this);
|
|
m_proc->deleteLater();
|
|
}
|
|
m_proc = new QProcess(this);
|
|
NOTICE_LOG(m_logger) << "Starting process '" << program << "' with args '" << args.join(QLatin1Char(' ')) << "'";
|
|
m_proc->setProgram(program);
|
|
m_proc->setArguments(args);
|
|
connect(m_proc, &QProcess::errorOccurred,
|
|
this, &CopyDatabase::onErrorOccured);
|
|
}
|
|
|
|
void CopyDatabase::handleProcFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
if (!m_proc)
|
|
return;
|
|
if (exitCode != 0 || exitStatus != 0)
|
|
{
|
|
QByteArray out = m_proc->readAllStandardError();
|
|
if (!out.isEmpty())
|
|
out += '\n';
|
|
out += m_proc->readAllStandardOutput();
|
|
ERROR_LOG(m_logger) << "Process finished - exitCode: " << exitCode << ", exitStatus = " << exitStatus << ", " << out;
|
|
}
|
|
m_proc->disconnect(this);
|
|
m_proc->deleteLater();
|
|
m_proc = nullptr;
|
|
}
|
|
|
|
void CopyDatabase::onErrorOccured(QProcess::ProcessError error)
|
|
{
|
|
ERROR_LOG(m_logger) << "error: " << error << ", " << m_proc->readAllStandardOutput() << ", " << m_proc->readAllStandardError();
|
|
}
|
|
|
|
QString CopyDatabase::getDumpFile() const
|
|
{
|
|
return QDir::tempPath() + QLatin1Char('/') + m_srcDbName + QStringLiteral(".dump");
|
|
}
|
|
|
|
QString CopyDatabase::executablePath(const QString &program)
|
|
{
|
|
QString errStr;
|
|
const QString ret = NGL::postgresExecutablePath(program, errStr);
|
|
if (!errStr.isEmpty())
|
|
WARNING_LOG(m_logger) << errStr;
|
|
return ret;
|
|
}
|
|
|
|
} // namespace DBAdministration
|