Skip to content

Commit 70f7633

Browse files
[upgradetool] MapDB database upgrade from 1.x to 3.x
* Add MapDBUpgrader which converts MapDB 1.0.9 database files to MapDB 3.1.0. Database format is not compatible. Though MapDB stores only the last state of persisted items, it helps to ensure a smooth transistion. For the implementation both versions of MapDB are required, which leads to conflicts in the namespace. Thus, MapDB 1.0.9 package is modified using the maven-shade-plugin. Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
1 parent e065bea commit 70f7633

5 files changed

Lines changed: 198 additions & 1 deletion

File tree

tools/mapdb1-shaded/pom.xml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- mapdb1-shaded/pom.xml -->
3+
<project>
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>org.openhab.core.tools</groupId>
8+
<artifactId>org.openhab.core.reactor.tools</artifactId>
9+
<version>5.2.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<groupId>org.openhab.core</groupId>
13+
<artifactId>mapdb1-shaded</artifactId>
14+
<version>1.0.9</version>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>org.mapdb</groupId>
19+
<artifactId>mapdb</artifactId>
20+
<version>1.0.9</version>
21+
</dependency>
22+
</dependencies>
23+
24+
<build>
25+
<plugins>
26+
<plugin>
27+
<groupId>org.apache.maven.plugins</groupId>
28+
<artifactId>maven-shade-plugin</artifactId>
29+
<version>3.5.1</version>
30+
<executions>
31+
<execution>
32+
<goals>
33+
<goal>shade</goal>
34+
</goals>
35+
<phase>package</phase>
36+
<configuration>
37+
<shadedArtifactAttached>false</shadedArtifactAttached>
38+
<createDependencyReducedPom>true</createDependencyReducedPom>
39+
<relocations>
40+
<relocation>
41+
<pattern>org.mapdb</pattern>
42+
<shadedPattern>org.mapdb.v1</shadedPattern>
43+
</relocation>
44+
<!-- Relocate MapDB 1.x transitive deps to avoid conflicts -->
45+
<relocation>
46+
<pattern>com.google.guava</pattern>
47+
<shadedPattern>org.mapdb.v1.guava</shadedPattern>
48+
</relocation>
49+
</relocations>
50+
<filters>
51+
<filter>
52+
<artifact>*:*</artifact>
53+
<excludes>
54+
<exclude>META-INF/*.SF</exclude>
55+
<exclude>META-INF/*.DSA</exclude>
56+
<exclude>META-INF/*.RSA</exclude>
57+
</excludes>
58+
</filter>
59+
</filters>
60+
</configuration>
61+
</execution>
62+
</executions>
63+
</plugin>
64+
</plugins>
65+
</build>
66+
</project>

tools/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<modules>
2020
<module>archetype</module>
2121
<module>i18n-plugin</module>
22+
<module>mapdb1-shaded</module>
2223
<module>upgradetool</module>
2324
</modules>
2425

tools/upgradetool/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@
121121
<artifactId>indriya</artifactId>
122122
<version>2.2.3</version>
123123
</dependency>
124+
<dependency>
125+
<groupId>org.openhab.core</groupId>
126+
<artifactId>mapdb1-shaded</artifactId>
127+
<version>1.0.9</version>
128+
</dependency>
129+
<dependency>
130+
<groupId>org.mapdb</groupId>
131+
<artifactId>mapdb</artifactId>
132+
<version>3.1.0</version>
133+
</dependency>
124134
</dependencies>
125135

126136
<build>

tools/upgradetool/src/main/java/org/openhab/core/tools/UpgradeTool.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public class UpgradeTool {
5858
new YamlConfigurationV1TagsUpgrader(), // Added in 5.0
5959
new HomeAssistantAddonUpgrader(), // Added in 5.1
6060
new HomieAddonUpgrader(), // Added in 5.1
61-
new PersistenceUpgrader() // Added in 5.1
61+
new PersistenceUpgrader(), // Added in 5.1
62+
new MapDBUpgrader() // Added in 5.2
6263
);
6364

6465
private static final Logger LOGGER = LoggerFactory.getLogger(UpgradeTool.class);
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (c) 2010-2026 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.core.tools.internal;
14+
15+
import java.io.File;
16+
import java.nio.file.Path;
17+
import java.util.Map;
18+
import java.util.concurrent.ConcurrentMap;
19+
20+
import org.eclipse.jdt.annotation.NonNullByDefault;
21+
import org.eclipse.jdt.annotation.Nullable;
22+
import org.mapdb.DB;
23+
import org.mapdb.DBMaker;
24+
import org.mapdb.Serializer;
25+
import org.openhab.core.tools.Upgrader;
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
/**
30+
* The {@link MapDBUpgrader} removes the default persistence strategy.
31+
*
32+
* It upgrades MapDB data from v1 to v3.
33+
*
34+
* @author Holger Friedrich - Initial Contribution
35+
*/
36+
@NonNullByDefault
37+
public class MapDBUpgrader implements Upgrader {
38+
private final Logger logger = LoggerFactory.getLogger(MapDBUpgrader.class);
39+
40+
@Override
41+
public String getName() {
42+
return "mapDBv1 to v3 upgrader";
43+
}
44+
45+
@Override
46+
public String getDescription() {
47+
return "Move persistence default strategy configuration to all persistence configuration without strategy defined";
48+
}
49+
50+
@Override
51+
public boolean execute(@Nullable Path userdataPath, @Nullable Path confPath) {
52+
if (userdataPath == null) {
53+
logger.error("{} skipped: no userdata directory found.", getName());
54+
return false;
55+
}
56+
57+
try {
58+
final Path DB_DIR = userdataPath.resolve("persistence").resolve("mapdb");
59+
final String DB_V1_FILE_NAME = "storage.mapdb";
60+
final String DB_V3_FILE_NAME = "storage3.mapdb";
61+
62+
File dbv1File = DB_DIR.resolve(DB_V1_FILE_NAME).toFile();
63+
if (dbv1File.exists()) {
64+
logger.info("Found MapDB v1 file at {}, starting upgrade to v3", dbv1File.getAbsolutePath());
65+
} else {
66+
logger.info("No MapDB v1 file found at {}, skipping MapDB upgrade", dbv1File.getAbsolutePath());
67+
return true; // No old DB, nothing to upgrade, but not an error
68+
}
69+
// Open old store with MapDB 1.x (fully qualified to avoid name clash)
70+
org.mapdb.v1.DB oldDb = org.mapdb.v1.DBMaker.newFileDB(dbv1File).readOnly().make();
71+
72+
// Open new store with MapDB 3.x (imported normally)
73+
File dbv3File = DB_DIR.resolve(DB_V3_FILE_NAME).toFile();
74+
if (dbv3File.exists()) {
75+
logger.warn("MapDB v3 file already exists at {}, it will be renamed to .bak",
76+
dbv3File.getAbsolutePath());
77+
78+
File backupFile = new File(dbv3File.getAbsolutePath() + ".bak");
79+
if (backupFile.exists()) {
80+
backupFile.delete();
81+
}
82+
if (!dbv3File.renameTo(backupFile)) {
83+
logger.error("Failed to rename existing MapDB v3 file at {}, aborting upgrade",
84+
dbv3File.getAbsolutePath());
85+
return false;
86+
}
87+
}
88+
DB newDb = DBMaker.fileDB(dbv3File).fileMmapEnable().make();
89+
90+
try {
91+
Map<String, String> oldMap = oldDb.getTreeMap("itemStore");
92+
93+
ConcurrentMap<String, String> newMap = newDb.treeMap("itemStore", Serializer.STRING, Serializer.STRING)
94+
.createOrOpen();
95+
96+
newMap.putAll(oldMap);
97+
newDb.commit();
98+
99+
logger.info("Migrated " + newMap.size() + " entries.");
100+
} finally {
101+
oldDb.close();
102+
newDb.close();
103+
}
104+
105+
// finally remove MapDB 1.x file to mark the update as successful and avoid re-doing migration on --force
106+
File backupFile = new File(dbv1File.getAbsolutePath() + ".bak");
107+
if (backupFile.exists()) {
108+
backupFile.delete();
109+
}
110+
dbv1File.renameTo(backupFile);
111+
logger.info("MapDB upgrade completed successfully, old file renamed to .bak.");
112+
113+
return true;
114+
} catch (Throwable e) {
115+
logger.error("Error during MapDB upgrade: ", e);
116+
return false;
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)