Akonadi

server/dbmigrator/main.cpp
1/*
2 SPDX-FileCopyrightText: 2024 g10 Code GmbH
3 SPDX-FileContributor: Daniel Vrátil <dvratil@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "akonadifull-version.h"
9#include "dbmigrator.h"
10
11#include <KAboutData>
12#include <KAboutLicense>
13#include <KLocalizedString>
14
15#include <QCommandLineOption>
16#include <QCommandLineParser>
17#include <QCoreApplication>
18
19#include <iostream>
20
21using namespace Akonadi::Server;
22
23class CLIDelegate : public UIDelegate
24{
25public:
26 Result questionYesNo(const QString &question) override
27 {
28 std::cout << qUtf8Printable(question)
29 << qUtf8Printable(i18nc("Options for user to input to command line prompt, parenthesis indicate "
30 "which letter to type, capitalized option is default",
31 " [(y)es/(N)o] "));
32 std::cout.flush();
33 std::string answer;
34 std::getline(std::cin, answer);
35
36 const auto yes = i18nc("Letter for option \"(y)es\" prompted from command line", "y");
37
38 if (answer.size() > 0 && std::tolower(answer[0]) == yes[0].toLatin1()) {
39 return Result::Yes;
40 }
41 return Result::No;
42 }
43
44 Result questionYesNoSkip(const QString &question) override
45 {
46 std::cout << qUtf8Printable(question)
47 << qUtf8Printable(i18nc("Options for user to input to command line prompt, parenthesis indicate "
48 "which letter to type, capitalized option is default",
49 " [(y)es/(N)o/(s)kip] "));
50
51 std::cout.flush();
52 std::string answer;
53 std::getline(std::cin, answer);
54
55 const auto yes = i18nc("Letter for option \"(y)es\" prompted from command line", "y");
56 const auto skip = i18nc("Letter for option \"(s)kip\" prompted from command line", "s");
57
58 if (answer.size() > 0 && std::tolower(answer[0]) == yes[0].toLatin1()) {
59 return Result::Yes;
60 }
61 if (answer.size() > 0 && std::tolower(answer[0]) == skip[0].toLatin1()) {
62 return Result::Skip;
63 }
64 return Result::No;
65 }
66};
67
68int main(int argc, char **argv)
69{
70 Q_INIT_RESOURCE(akonadidb);
71
72 QCoreApplication app(argc, argv);
73 KLocalizedString::setApplicationDomain("akonadi-db-migrator");
74 KAboutData about(QStringLiteral("akonadi-db-migrator"),
75 i18n("Akonadi DB Migrator"),
76 QStringLiteral(AKONADI_FULL_VERSION),
77 i18n("Akonadi DB Migrator"),
79 i18n("(c) 2024 g10 Code GmbH"));
81
82 QCommandLineParser parser;
83 about.setupCommandLine(&parser);
84 const QCommandLineOption engineOpt{QStringLiteral("newengine"),
85 i18n("The new DB engine to use. Possible values are \"sqlite\", \"mysql\" and \"postgres\""),
86 QStringLiteral("ENGINE")};
87 parser.addOption(engineOpt);
88 parser.process(app);
89
90 const auto targetEngine = parser.value(engineOpt).toLower();
91 if (targetEngine != QLatin1StringView("sqlite") && targetEngine != QLatin1StringView("mysql") && targetEngine != QLatin1StringView("postgres")) {
92 std::cerr << qUtf8Printable(i18nc("@info:shell", "Invalid target engine: %1.", targetEngine)) << std::endl;
93 return 1;
94 }
95
96 CLIDelegate delegate;
97 DbMigrator migrator(targetEngine, &delegate);
98 QObject::connect(&migrator, &DbMigrator::info, &app, [](const QString &message) {
99 std::cout << qUtf8Printable(message) << std::endl;
100 });
101 QObject::connect(&migrator, &DbMigrator::error, &app, [](const QString &message) {
102 std::cerr << qUtf8Printable(message) << std::endl;
103 });
104 QObject::connect(&migrator, &DbMigrator::migrationCompleted, &app, [](bool success) {
105 if (success) {
106 std::cout << qUtf8Printable(i18nc("@info:status", "Migration completed successfully.")) << std::endl;
107 } else {
108 std::cout << qUtf8Printable(i18nc("@info:status", "Migration failed.")) << std::endl;
109 }
110 qApp->quit();
111 });
112 QObject::connect(&migrator, &DbMigrator::progress, &app, [](const QString &table, int tablesDone, int tablesTotal) {
113 std::cout << qUtf8Printable(i18nc("@info:progress", "Migrating table %1 (%2/%3)...", table, tablesDone, tablesTotal)) << std::endl;
114 });
115 QString lastTable;
116 int lastPerc = -1;
117 QObject::connect(&migrator, &DbMigrator::tableProgress, &app, [&lastTable, &lastPerc](const QString &table, int rowsDone, int rowsTotal) {
118 const int perc = rowsDone * 100 / rowsTotal;
119 if (lastTable != table) {
120 lastPerc = -1;
121 }
122 if (perc % 10 != 0 || perc == lastPerc) {
123 return;
124 }
125 lastPerc = perc;
126 lastTable = table;
127 std::cout << qUtf8Printable(i18nc("@info:progress", "%1%...", perc)) << std::endl;
128 });
129
130 QMetaObject::invokeMethod(&migrator, &DbMigrator::startMigration, Qt::QueuedConnection);
131
132 return app.exec();
133}
static void setApplicationData(const KAboutData &aboutData)
static void setApplicationDomain(const QByteArray &domain)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
bool addOption(const QCommandLineOption &option)
void process(const QCoreApplication &app)
QString value(const QCommandLineOption &option) const const
bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString toLower() const const
QueuedConnection
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 3 2024 11:44:22 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.