2020-01-10 17:54:36 +01:00
|
|
|
/*
|
|
|
|
* This file is part of BlueMap, licensed under the MIT License (MIT).
|
|
|
|
*
|
|
|
|
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
|
|
|
|
* Copyright (c) contributors
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
2022-04-20 22:54:27 +02:00
|
|
|
package de.bluecolored.bluemap.common.config.storage;
|
2020-01-10 17:54:36 +01:00
|
|
|
|
2022-07-24 12:10:00 +02:00
|
|
|
import de.bluecolored.bluemap.api.debug.DebugDump;
|
2024-04-06 01:26:16 +02:00
|
|
|
import de.bluecolored.bluemap.common.config.ConfigurationException;
|
|
|
|
import de.bluecolored.bluemap.core.storage.compression.Compression;
|
|
|
|
import de.bluecolored.bluemap.core.storage.sql.Database;
|
|
|
|
import de.bluecolored.bluemap.core.storage.sql.SQLStorage;
|
|
|
|
import de.bluecolored.bluemap.core.storage.sql.commandset.CommandSet;
|
|
|
|
import de.bluecolored.bluemap.core.util.Key;
|
|
|
|
import lombok.AccessLevel;
|
|
|
|
import lombok.Getter;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
2021-11-14 14:18:31 +01:00
|
|
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
2021-03-28 18:56:26 +02:00
|
|
|
|
2021-11-14 14:18:31 +01:00
|
|
|
import java.net.MalformedURLException;
|
|
|
|
import java.net.URL;
|
2024-04-06 01:26:16 +02:00
|
|
|
import java.net.URLClassLoader;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
2021-11-14 14:18:31 +01:00
|
|
|
import java.nio.file.Paths;
|
2024-04-06 01:26:16 +02:00
|
|
|
import java.sql.Driver;
|
2022-08-21 00:28:40 +02:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
2021-11-14 14:18:31 +01:00
|
|
|
import java.util.Optional;
|
2024-04-06 01:26:16 +02:00
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
2020-01-10 17:54:36 +01:00
|
|
|
|
2021-11-14 14:18:31 +01:00
|
|
|
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
|
|
|
|
@ConfigSerializable
|
2024-04-06 01:26:16 +02:00
|
|
|
@Getter
|
|
|
|
public class SQLConfig extends StorageConfig {
|
2020-08-23 23:29:14 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
private static final Pattern URL_DIALECT_PATTERN = Pattern.compile("jdbc:([^:]*)://.*");
|
2021-09-19 22:15:50 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
private String connectionUrl = "jdbc:mysql://localhost/bluemap?permitMysqlScheme";
|
2022-08-21 00:28:40 +02:00
|
|
|
private Map<String, String> connectionProperties = new HashMap<>();
|
2024-04-06 01:26:16 +02:00
|
|
|
@DebugDump private String dialect = null;
|
2022-08-21 00:28:40 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
@DebugDump private String driverJar = null;
|
|
|
|
@DebugDump private String driverClass = null;
|
|
|
|
@DebugDump private int maxConnections = -1;
|
2021-09-19 22:15:50 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
@DebugDump private String compression = Compression.GZIP.getKey().getFormatted();
|
2021-09-19 22:15:50 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
@DebugDump
|
|
|
|
@Getter(AccessLevel.NONE)
|
|
|
|
private transient URL driverJarURL = null;
|
2022-08-21 00:28:40 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
public Optional<URL> getDriverJar() throws ConfigurationException {
|
|
|
|
try {
|
|
|
|
if (driverJar == null) return Optional.empty();
|
2021-09-19 22:15:50 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
if (driverJarURL == null) {
|
|
|
|
driverJarURL = Paths.get(driverJar).toUri().toURL();
|
|
|
|
}
|
2021-09-19 22:15:50 +02:00
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
return Optional.of(driverJarURL);
|
|
|
|
} catch (MalformedURLException ex) {
|
|
|
|
throw new ConfigurationException("""
|
|
|
|
The configured driver-jar path is not formatted correctly!
|
|
|
|
Please check your 'driver-jar' setting in your configuration and make sure you have the correct path configured.
|
|
|
|
""".strip(), ex);
|
|
|
|
}
|
2021-09-19 22:15:50 +02:00
|
|
|
}
|
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
@SuppressWarnings("unused")
|
2021-11-14 14:18:31 +01:00
|
|
|
public Optional<String> getDriverClass() {
|
|
|
|
return Optional.ofNullable(driverClass);
|
2021-09-19 22:15:50 +02:00
|
|
|
}
|
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
public Compression getCompression() throws ConfigurationException {
|
|
|
|
return parseKey(Compression.REGISTRY, compression, "compression");
|
2021-09-19 22:15:50 +02:00
|
|
|
}
|
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
public Dialect getDialect() throws ConfigurationException {
|
|
|
|
String key = dialect;
|
|
|
|
|
|
|
|
// default from connection-url
|
|
|
|
if (key == null) {
|
|
|
|
Matcher matcher = URL_DIALECT_PATTERN.matcher(connectionUrl);
|
|
|
|
if (!matcher.find()) return Dialect.MYSQL;
|
|
|
|
key = Key.bluemap(matcher.group(1)).getFormatted();
|
|
|
|
}
|
|
|
|
|
|
|
|
return parseKey(Dialect.REGISTRY, key, "dialect");
|
2022-08-21 00:28:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2024-04-06 01:26:16 +02:00
|
|
|
public SQLStorage createStorage() throws ConfigurationException {
|
|
|
|
Driver driver = createDriver();
|
|
|
|
Database database;
|
|
|
|
if (driver != null) {
|
|
|
|
database = new Database(getConnectionUrl(), getConnectionProperties(), getMaxConnections(), driver);
|
|
|
|
} else {
|
|
|
|
database = new Database(getConnectionUrl(), getConnectionProperties(), getMaxConnections());
|
|
|
|
}
|
|
|
|
CommandSet commandSet = getDialect().createCommandSet(database);
|
|
|
|
return new SQLStorage(commandSet, getCompression());
|
2022-08-21 00:28:40 +02:00
|
|
|
}
|
|
|
|
|
2024-04-06 01:26:16 +02:00
|
|
|
private @Nullable Driver createDriver() throws ConfigurationException {
|
|
|
|
if (driverClass == null) return null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
// load driver class
|
|
|
|
Class<?> driverClazz;
|
|
|
|
URL driverJarUrl = getDriverJar().orElse(null);
|
|
|
|
if (driverJarUrl != null) {
|
|
|
|
|
|
|
|
// sanity-check if file exists
|
|
|
|
if (!Files.exists(Path.of(driverJarUrl.toURI()))) {
|
|
|
|
throw new ConfigurationException("""
|
|
|
|
The configured driver-jar was not found!
|
|
|
|
Please check your 'driver-jar' setting in your configuration and make sure you have the correct path configured.
|
|
|
|
""".strip());
|
|
|
|
}
|
|
|
|
|
|
|
|
ClassLoader classLoader = new URLClassLoader(new URL[]{driverJarUrl});
|
|
|
|
driverClazz = Class.forName(driverClass, true, classLoader);
|
|
|
|
} else {
|
|
|
|
driverClazz = Class.forName(driverClass);
|
|
|
|
}
|
|
|
|
|
|
|
|
// create driver
|
|
|
|
return (Driver) driverClazz.getDeclaredConstructor().newInstance();
|
|
|
|
} catch (ClassCastException ex) {
|
|
|
|
throw new ConfigurationException("""
|
|
|
|
The configured driver-class was found but is not of the correct class-type!
|
|
|
|
Please check your 'driver-class' setting in your configuration and make sure you have the correct class configured.
|
|
|
|
""".strip(), ex);
|
|
|
|
} catch (ClassNotFoundException ex) {
|
|
|
|
throw new ConfigurationException("""
|
|
|
|
The configured driver-class was not found!
|
|
|
|
Please check your 'driver-class' setting in your configuration and make sure you have the correct class configured.
|
|
|
|
""".strip(), ex);
|
|
|
|
} catch (ConfigurationException ex) {
|
|
|
|
throw ex;
|
|
|
|
} catch (Exception ex) {
|
|
|
|
throw new ConfigurationException("""
|
|
|
|
BlueMap failed to load the configured SQL-Driver!
|
|
|
|
Please check your 'driver-jar' and 'driver-class' settings in your configuration.
|
|
|
|
""".strip(), ex);
|
|
|
|
}
|
2021-11-14 14:18:31 +01:00
|
|
|
}
|
2021-09-19 22:15:50 +02:00
|
|
|
|
2020-01-10 17:54:36 +01:00
|
|
|
}
|