Files
qt5-legatus-legacy/Lts/Services/OcBaseDownload/copy_database.cpp
T
2026-08-13 18:33:10 +02:00

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