Skip to content

Commit 49c121e

Browse files
committed
refactor: add a class to handle the migration logic.
It should cover upgrade, downgrade as well as upgrade from unbranded to branded, from legacy to branded and from legacy to unbranded. Signed-off-by: Camila Ayres <hello@camilasan.com>
1 parent 3d9b37a commit 49c121e

3 files changed

Lines changed: 199 additions & 0 deletions

File tree

src/libsync/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ set(libsync_SRCS
164164
creds/keychainchunk.cpp
165165
caseclashconflictsolver.h
166166
caseclashconflictsolver.cpp
167+
settings/migration.h
168+
settings/migration.cpp
167169
)
168170

169171
if (WIN32)

src/libsync/settings/migration.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: GPL-2.0-or-later
4+
*/
5+
6+
#include <QLoggingCategory>
7+
8+
#include "migration.h"
9+
#include "theme.h"
10+
#include "configfile.h"
11+
#include "version.h"
12+
13+
namespace OCC {
14+
15+
Q_LOGGING_CATEGORY(lcMigration, "nextcloud.settings.migration", QtInfoMsg)
16+
17+
Migration::Migration()
18+
{
19+
_migrationPhase = MigrationPhase::NotStarted;
20+
_migrationType = MigrationType::UnbrandedToUnbranded;
21+
_versionChangeType = VersionChangeType::NoVersionChange;
22+
}
23+
24+
QVersionNumber Migration::currentVersion() const
25+
{
26+
return QVersionNumber::fromString(MIRALL_VERSION_STRING);
27+
}
28+
29+
QVersionNumber Migration::previousVersion() const
30+
{
31+
return QVersionNumber::fromString(ConfigFile().clientPreviousVersionString());
32+
}
33+
34+
QVersionNumber Migration::configVersion() const
35+
{
36+
return QVersionNumber::fromString(ConfigFile().clientVersionString());
37+
}
38+
39+
void Migration::setMigrationPhase(const MigrationPhase phase)
40+
{
41+
// do not rollback
42+
if (phase > _migrationPhase) {
43+
_migrationPhase = phase;
44+
}
45+
}
46+
47+
Migration::MigrationPhase Migration::migrationPhase() const
48+
{
49+
return _migrationPhase;
50+
}
51+
52+
void Migration::setMigrationType(const MigrationType type)
53+
{
54+
_migrationType = type;
55+
}
56+
57+
Migration::MigrationType Migration::migrationType() const
58+
{
59+
return _migrationType;
60+
}
61+
62+
Migration::VersionChangeType Migration::versionChangeType() const
63+
{
64+
return _versionChangeType;
65+
}
66+
67+
void Migration::setVersionChangeType(const VersionChangeType type)
68+
{
69+
_versionChangeType = type;
70+
}
71+
72+
bool Migration::isUpgrade()
73+
{
74+
const auto isUpgrade = currentVersion() > previousVersion();
75+
if (isUpgrade) {
76+
setVersionChangeType(VersionChangeType::Upgrade);
77+
}
78+
return versionChangeType() == VersionChangeType::Upgrade;
79+
}
80+
81+
bool Migration::isDowngrade()
82+
{
83+
const auto isDowngrade = previousVersion() > currentVersion();
84+
if (isDowngrade) {
85+
setVersionChangeType(VersionChangeType::Downgrade);
86+
}
87+
return versionChangeType() == VersionChangeType::Downgrade;
88+
}
89+
90+
bool Migration::versionChanged()
91+
{
92+
return isUpgrade() || isDowngrade();
93+
}
94+
95+
bool Migration::shouldTryUnbrandedToBrandedMigration() const
96+
{
97+
const auto isUnbrandedToBranded = migrationPhase() == Migration::MigrationPhase::SetupFolders
98+
&& Theme::instance()->appName() != ConfigFile::unbrandedAppName;
99+
if (isUnbrandedToBranded) {
100+
Migration().setMigrationType(MigrationType::UnbrandedToBranded);
101+
}
102+
return migrationType() == MigrationType::UnbrandedToBranded;
103+
}
104+
105+
bool Migration::isUnbrandedToBrandedMigration() const
106+
{
107+
return isInProgress() && migrationType() == MigrationType::UnbrandedToBranded;
108+
}
109+
110+
bool Migration::shouldTryToMigrate()
111+
{
112+
return !isClientVersionSet() && (isUpgrade() || isDowngrade());
113+
}
114+
115+
bool Migration::isClientVersionSet() const
116+
{
117+
const auto configVersionNumber = configVersion();
118+
const auto previousVersionNumber = previousVersion();
119+
return !configVersionNumber.isNull() && !previousVersionNumber.isNull()
120+
&& configVersionNumber == previousVersionNumber;
121+
}
122+
123+
bool Migration::isInProgress() const
124+
{
125+
const auto currentPhase = migrationPhase();
126+
return currentPhase != MigrationPhase::NotStarted
127+
&& currentPhase != MigrationPhase::Done;
128+
}
129+
130+
}

src/libsync/settings/migration.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: GPL-2.0-or-later
4+
*/
5+
6+
#ifndef MIGRATION_H
7+
#define MIGRATION_H
8+
9+
#include <QVersionNumber>
10+
#include "owncloudlib.h"
11+
12+
namespace OCC {
13+
14+
class OWNCLOUDSYNC_EXPORT Migration
15+
{
16+
public:
17+
Migration();
18+
19+
enum MigrationPhase {
20+
NotStarted,
21+
SetupConfigFile,
22+
SetupUsers,
23+
SetupFolders,
24+
Done
25+
};
26+
27+
enum MigrationType {
28+
UnbrandedToUnbranded,
29+
UnbrandedToBranded,
30+
LegacyToUnbranded,
31+
LegacyToBranded
32+
};
33+
34+
enum VersionChangeType {
35+
NoVersionChange,
36+
Upgrade,
37+
Downgrade
38+
};
39+
40+
[[nodiscard]] QVersionNumber previousVersion() const;
41+
[[nodiscard]] QVersionNumber currentVersion() const;
42+
[[nodiscard]] QVersionNumber configVersion() const;
43+
44+
[[nodiscard]] MigrationPhase migrationPhase() const;
45+
[[nodiscard]] MigrationType migrationType() const;
46+
[[nodiscard]] VersionChangeType versionChangeType() const;
47+
48+
void setMigrationPhase(const MigrationPhase phase);
49+
void setMigrationType(const MigrationType type);
50+
void setVersionChangeType(const VersionChangeType type);
51+
52+
[[nodiscard]] bool isUpgrade();
53+
[[nodiscard]] bool isDowngrade();
54+
[[nodiscard]] bool versionChanged();
55+
[[nodiscard]] bool shouldTryUnbrandedToBrandedMigration() const;
56+
[[nodiscard]] bool isUnbrandedToBrandedMigration() const;
57+
[[nodiscard]] bool shouldTryToMigrate();
58+
[[nodiscard]] bool isClientVersionSet() const;
59+
[[nodiscard]] bool isInProgress() const;
60+
61+
private:
62+
MigrationPhase _migrationPhase;
63+
MigrationType _migrationType;
64+
VersionChangeType _versionChangeType;
65+
};
66+
}
67+
#endif // MIGRATION_H

0 commit comments

Comments
 (0)