Add support for postgres databases (#443)
* Refactor : wrap every single SQL query inside an interface * Feat : create every SQL request for postgres * Refactor : rename SQLQueryAbstractFactory to SQLQueryFactory * Feat : add dialect settings to blue map ! * Feat : Create two new storageClass for different storage approche * Feat : add read BYTEA support * Fix : remove unuseful println * Fix : remove edited sql.conf * Refactor / Feat : support for mysql * Lots of tiny tweaks --------- Co-authored-by: Lukas Rieger (Blue) <TBlueF@users.noreply.github.com>
This commit is contained in:
parent
c807699c7c
commit
f149b823a7
|
@ -31,7 +31,7 @@ import de.bluecolored.bluemap.core.storage.sql.SQLStorage;
|
||||||
public enum StorageType {
|
public enum StorageType {
|
||||||
|
|
||||||
FILE (FileConfig.class, FileStorage::new),
|
FILE (FileConfig.class, FileStorage::new),
|
||||||
SQL (SQLConfig.class, SQLStorage::new);
|
SQL (SQLConfig.class, SQLStorage::create);
|
||||||
|
|
||||||
private final Class<? extends StorageConfig> configType;
|
private final Class<? extends StorageConfig> configType;
|
||||||
private final StorageFactory<? extends StorageConfig> storageFactory;
|
private final StorageFactory<? extends StorageConfig> storageFactory;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package de.bluecolored.bluemap.core.storage.sql;
|
||||||
|
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.dialect.MySQLDialect;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
|
public class MySQLStorage extends SQLStorage{
|
||||||
|
|
||||||
|
public MySQLStorage(SQLStorageSettings config) throws MalformedURLException, SQLDriverException {
|
||||||
|
super(MySQLDialect.INSTANCE, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
package de.bluecolored.bluemap.core.storage.sql;
|
||||||
|
|
||||||
|
import com.flowpowered.math.vector.Vector2i;
|
||||||
|
import de.bluecolored.bluemap.core.storage.CompressedInputStream;
|
||||||
|
import de.bluecolored.bluemap.core.storage.Compression;
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.dialect.PostgresDialect;
|
||||||
|
import de.bluecolored.bluemap.core.util.WrappedOutputStream;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class PostgreSQLStorage extends SQLStorage {
|
||||||
|
|
||||||
|
public PostgreSQLStorage(SQLStorageSettings config) throws MalformedURLException, SQLDriverException {
|
||||||
|
super(PostgresDialect.INSTANCE, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream writeMapTile(String mapId, int lod, Vector2i tile) throws IOException {
|
||||||
|
Compression compression = lod == 0 ? this.hiresCompression : Compression.NONE;
|
||||||
|
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
||||||
|
return new WrappedOutputStream(compression.compress(byteOut), () -> {
|
||||||
|
int mapFK = getMapFK(mapId);
|
||||||
|
int tileCompressionFK = getMapTileCompressionFK(compression);
|
||||||
|
|
||||||
|
recoveringConnection(connection -> {
|
||||||
|
byte[] byteData = byteOut.toByteArray();
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(byteData);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement(this.dialect.writeMapTile());
|
||||||
|
statement.setInt(1, mapFK);
|
||||||
|
statement.setInt(2, lod);
|
||||||
|
statement.setInt(3, tile.getX());
|
||||||
|
statement.setInt(4, tile.getY());
|
||||||
|
statement.setInt(5, tileCompressionFK);
|
||||||
|
statement.setBinaryStream(6, inputStream);
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
}, 2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream writeMeta(String mapId, String name) {
|
||||||
|
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
|
||||||
|
return new WrappedOutputStream(byteOut, () -> {
|
||||||
|
int mapFK = getMapFK(mapId);
|
||||||
|
recoveringConnection(connection -> {
|
||||||
|
byte[] byteData = byteOut.toByteArray();
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(byteData);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement(this.dialect.writeMeta());
|
||||||
|
statement.setInt(1, mapFK);
|
||||||
|
statement.setString(2, name);
|
||||||
|
statement.setBinaryStream(3, inputStream);
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
}, 2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<CompressedInputStream> readMapTile(String mapId, int lod, Vector2i tile) throws IOException {
|
||||||
|
Compression compression = lod == 0 ? this.hiresCompression : Compression.NONE;
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] data = recoveringConnection(connection -> {
|
||||||
|
ResultSet result = executeQuery(connection,
|
||||||
|
this.dialect.readMapTile(),
|
||||||
|
mapId,
|
||||||
|
lod,
|
||||||
|
tile.getX(),
|
||||||
|
tile.getY(),
|
||||||
|
compression.getTypeId()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.next()) {
|
||||||
|
return result.getBytes(1);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, 2);
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream inputStream = new ByteArrayInputStream(data);
|
||||||
|
return Optional.of(new CompressedInputStream(inputStream, compression));
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new IOException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<InputStream> readMeta(String mapId, String name) throws IOException {
|
||||||
|
try {
|
||||||
|
byte[] data = recoveringConnection(connection -> {
|
||||||
|
ResultSet result = executeQuery(connection,
|
||||||
|
this.dialect.readMeta(),
|
||||||
|
mapId,
|
||||||
|
escapeMetaName(name)
|
||||||
|
);
|
||||||
|
if (result.next()) {
|
||||||
|
return result.getBytes(1);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, 2);
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream inputStream = new ByteArrayInputStream(data);
|
||||||
|
return Optional.of(inputStream);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new IOException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -30,6 +30,8 @@ import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
import de.bluecolored.bluemap.core.BlueMap;
|
import de.bluecolored.bluemap.core.BlueMap;
|
||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
import de.bluecolored.bluemap.core.storage.*;
|
import de.bluecolored.bluemap.core.storage.*;
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.dialect.DialectType;
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.dialect.SQLQueryDialect;
|
||||||
import de.bluecolored.bluemap.core.util.WrappedOutputStream;
|
import de.bluecolored.bluemap.core.util.WrappedOutputStream;
|
||||||
import org.apache.commons.dbcp2.*;
|
import org.apache.commons.dbcp2.*;
|
||||||
import org.apache.commons.pool2.ObjectPool;
|
import org.apache.commons.pool2.ObjectPool;
|
||||||
|
@ -48,10 +50,12 @@ import java.util.*;
|
||||||
import java.util.concurrent.CompletionException;
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class SQLStorage extends Storage {
|
public abstract class SQLStorage extends Storage {
|
||||||
|
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final Compression hiresCompression;
|
|
||||||
|
protected final SQLQueryDialect dialect;
|
||||||
|
protected final Compression hiresCompression;
|
||||||
|
|
||||||
private final LoadingCache<String, Integer> mapFKs = Caffeine.newBuilder()
|
private final LoadingCache<String, Integer> mapFKs = Caffeine.newBuilder()
|
||||||
.executor(BlueMap.THREAD_POOL)
|
.executor(BlueMap.THREAD_POOL)
|
||||||
|
@ -62,9 +66,9 @@ public class SQLStorage extends Storage {
|
||||||
|
|
||||||
private volatile boolean closed;
|
private volatile boolean closed;
|
||||||
|
|
||||||
public SQLStorage(SQLStorageSettings config) throws MalformedURLException, SQLDriverException {
|
public SQLStorage(SQLQueryDialect dialect, SQLStorageSettings config) throws MalformedURLException, SQLDriverException {
|
||||||
|
this.dialect = dialect;
|
||||||
this.closed = false;
|
this.closed = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (config.getDriverClass().isPresent()) {
|
if (config.getDriverClass().isPresent()) {
|
||||||
if (config.getDriverJar().isPresent()) {
|
if (config.getDriverJar().isPresent()) {
|
||||||
|
@ -115,9 +119,7 @@ public class SQLStorage extends Storage {
|
||||||
byteOut.writeTo(blobOut);
|
byteOut.writeTo(blobOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,this.dialect.writeMapTile(),
|
||||||
"REPLACE INTO `bluemap_map_tile` (`map`, `lod`, `x`, `z`, `compression`, `data`) " +
|
|
||||||
"VALUES (?, ?, ?, ?, ?, ?)",
|
|
||||||
mapFK,
|
mapFK,
|
||||||
lod,
|
lod,
|
||||||
tile.getX(),
|
tile.getX(),
|
||||||
|
@ -139,17 +141,7 @@ public class SQLStorage extends Storage {
|
||||||
try {
|
try {
|
||||||
byte[] data = recoveringConnection(connection -> {
|
byte[] data = recoveringConnection(connection -> {
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
"SELECT t.`data` " +
|
this.dialect.readMapTile(),
|
||||||
"FROM `bluemap_map_tile` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
" INNER JOIN `bluemap_map_tile_compression` c " +
|
|
||||||
" ON t.`compression` = c.`id` " +
|
|
||||||
"WHERE m.`map_id` = ? " +
|
|
||||||
"AND t.`lod` = ? " +
|
|
||||||
"AND t.`x` = ? " +
|
|
||||||
"AND t.`z` = ? " +
|
|
||||||
"AND c.`compression` = ?",
|
|
||||||
mapId,
|
mapId,
|
||||||
lod,
|
lod,
|
||||||
tile.getX(),
|
tile.getX(),
|
||||||
|
@ -179,17 +171,7 @@ public class SQLStorage extends Storage {
|
||||||
try {
|
try {
|
||||||
TileInfo tileInfo = recoveringConnection(connection -> {
|
TileInfo tileInfo = recoveringConnection(connection -> {
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
"SELECT t.`changed`, LENGTH(t.`data`) as 'size' " +
|
this.dialect.readMapTileInfo(),
|
||||||
"FROM `bluemap_map_tile` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
" INNER JOIN `bluemap_map_tile_compression` c " +
|
|
||||||
" ON t.`compression` = c.`id` " +
|
|
||||||
"WHERE m.`map_id` = ? " +
|
|
||||||
"AND t.`lod` = ? " +
|
|
||||||
"AND t.`x` = ? " +
|
|
||||||
"AND t.`z` = ? " +
|
|
||||||
"AND c.`compression` = ?",
|
|
||||||
mapId,
|
mapId,
|
||||||
lod,
|
lod,
|
||||||
tile.getX(),
|
tile.getX(),
|
||||||
|
@ -238,15 +220,7 @@ public class SQLStorage extends Storage {
|
||||||
public void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOException {
|
public void deleteMapTile(String mapId, int lod, Vector2i tile) throws IOException {
|
||||||
try {
|
try {
|
||||||
recoveringConnection(connection ->
|
recoveringConnection(connection ->
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,this.dialect.deleteMapTile(),
|
||||||
"DELETE t " +
|
|
||||||
"FROM `bluemap_map_tile` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
"WHERE m.`map_id` = ? " +
|
|
||||||
"AND t.`lod` = ? " +
|
|
||||||
"AND t.`x` = ? " +
|
|
||||||
"AND t.`z` = ?",
|
|
||||||
mapId,
|
mapId,
|
||||||
lod,
|
lod,
|
||||||
tile.getX(),
|
tile.getX(),
|
||||||
|
@ -271,8 +245,7 @@ public class SQLStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"REPLACE INTO `bluemap_map_meta` (`map`, `key`, `value`) " +
|
this.dialect.writeMeta(),
|
||||||
"VALUES (?, ?, ?)",
|
|
||||||
mapFK,
|
mapFK,
|
||||||
escapeMetaName(name),
|
escapeMetaName(name),
|
||||||
dataBlob
|
dataBlob
|
||||||
|
@ -289,12 +262,7 @@ public class SQLStorage extends Storage {
|
||||||
try {
|
try {
|
||||||
byte[] data = recoveringConnection(connection -> {
|
byte[] data = recoveringConnection(connection -> {
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
"SELECT t.`value` " +
|
this.dialect.readMeta(),
|
||||||
"FROM `bluemap_map_meta` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
"WHERE m.`map_id` = ? " +
|
|
||||||
"AND t.`key` = ?",
|
|
||||||
mapId,
|
mapId,
|
||||||
escapeMetaName(name)
|
escapeMetaName(name)
|
||||||
);
|
);
|
||||||
|
@ -319,12 +287,7 @@ public class SQLStorage extends Storage {
|
||||||
try {
|
try {
|
||||||
MetaInfo tileInfo = recoveringConnection(connection -> {
|
MetaInfo tileInfo = recoveringConnection(connection -> {
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
"SELECT LENGTH(t.`value`) as 'size' " +
|
this.dialect.readMetaSize(),
|
||||||
"FROM `bluemap_map_meta` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
"WHERE m.`map_id` = ? " +
|
|
||||||
"AND t.`key` = ?",
|
|
||||||
mapId,
|
mapId,
|
||||||
escapeMetaName(name)
|
escapeMetaName(name)
|
||||||
);
|
);
|
||||||
|
@ -361,12 +324,7 @@ public class SQLStorage extends Storage {
|
||||||
try {
|
try {
|
||||||
recoveringConnection(connection ->
|
recoveringConnection(connection ->
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"DELETE t " +
|
this.dialect.purgeMeta(),
|
||||||
"FROM `bluemap_map_meta` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
"WHERE m.`map_id` = ? " +
|
|
||||||
"AND t.`key` = ?",
|
|
||||||
mapId,
|
mapId,
|
||||||
escapeMetaName(name)
|
escapeMetaName(name)
|
||||||
), 2);
|
), 2);
|
||||||
|
@ -381,28 +339,18 @@ public class SQLStorage extends Storage {
|
||||||
try {
|
try {
|
||||||
recoveringConnection(connection -> {
|
recoveringConnection(connection -> {
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"DELETE t " +
|
this.dialect.purgeMapTile(),
|
||||||
"FROM `bluemap_map_tile` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
"WHERE m.`map_id` = ?",
|
|
||||||
mapId
|
mapId
|
||||||
);
|
);
|
||||||
|
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"DELETE t " +
|
this.dialect.purgeMapMeta(),
|
||||||
"FROM `bluemap_map_meta` t " +
|
|
||||||
" INNER JOIN `bluemap_map` m " +
|
|
||||||
" ON t.`map` = m.`id` " +
|
|
||||||
"WHERE m.`map_id` = ?",
|
|
||||||
mapId
|
mapId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"DELETE " +
|
this.dialect.purgeMap(),
|
||||||
"FROM `bluemap_map` " +
|
|
||||||
"WHERE `map_id` = ?",
|
|
||||||
mapId
|
mapId
|
||||||
);
|
);
|
||||||
}, 2);
|
}, 2);
|
||||||
|
@ -420,7 +368,7 @@ public class SQLStorage extends Storage {
|
||||||
try {
|
try {
|
||||||
return recoveringConnection(connection -> {
|
return recoveringConnection(connection -> {
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
"SELECT `map_id` FROM `bluemap_map`"
|
this.dialect.selectMapIds()
|
||||||
);
|
);
|
||||||
Collection<String> mapIds = new ArrayList<>();
|
Collection<String> mapIds = new ArrayList<>();
|
||||||
while (result.next()) {
|
while (result.next()) {
|
||||||
|
@ -440,15 +388,10 @@ public class SQLStorage extends Storage {
|
||||||
// initialize and get schema-version
|
// initialize and get schema-version
|
||||||
String schemaVersionString = recoveringConnection(connection -> {
|
String schemaVersionString = recoveringConnection(connection -> {
|
||||||
connection.createStatement().executeUpdate(
|
connection.createStatement().executeUpdate(
|
||||||
"CREATE TABLE IF NOT EXISTS `bluemap_storage_meta` (" +
|
this.dialect.initializeStorageMeta());
|
||||||
"`key` varchar(255) NOT NULL, " +
|
|
||||||
"`value` varchar(255) DEFAULT NULL, " +
|
|
||||||
"PRIMARY KEY (`key`)" +
|
|
||||||
")");
|
|
||||||
|
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
"SELECT `value` FROM `bluemap_storage_meta` " +
|
this.dialect.selectStorageMeta(),
|
||||||
"WHERE `key` = ?",
|
|
||||||
"schema_version"
|
"schema_version"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -456,8 +399,7 @@ public class SQLStorage extends Storage {
|
||||||
return result.getString("value");
|
return result.getString("value");
|
||||||
} else {
|
} else {
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"INSERT INTO `bluemap_storage_meta` (`key`, `value`) " +
|
this.dialect.insertStorageMeta(),
|
||||||
"VALUES (?, ?)",
|
|
||||||
"schema_version", "0"
|
"schema_version", "0"
|
||||||
);
|
);
|
||||||
return "0";
|
return "0";
|
||||||
|
@ -482,51 +424,22 @@ public class SQLStorage extends Storage {
|
||||||
recoveringConnection(connection -> {
|
recoveringConnection(connection -> {
|
||||||
|
|
||||||
connection.createStatement().executeUpdate(
|
connection.createStatement().executeUpdate(
|
||||||
"CREATE TABLE `bluemap_map` (" +
|
this.dialect.initializeMap()
|
||||||
"`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT," +
|
|
||||||
"`map_id` VARCHAR(255) NOT NULL," +
|
|
||||||
"PRIMARY KEY (`id`)," +
|
|
||||||
"UNIQUE INDEX `map_id` (`map_id`)" +
|
|
||||||
");"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
connection.createStatement().executeUpdate(
|
connection.createStatement().executeUpdate(
|
||||||
"CREATE TABLE `bluemap_map_tile_compression` (" +
|
this.dialect.initializeMapTileCompression()
|
||||||
"`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT," +
|
|
||||||
"`compression` VARCHAR(255) NOT NULL," +
|
|
||||||
"PRIMARY KEY (`id`)," +
|
|
||||||
"UNIQUE INDEX `compression` (`compression`)" +
|
|
||||||
");"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
connection.createStatement().executeUpdate(
|
connection.createStatement().executeUpdate(
|
||||||
"CREATE TABLE `bluemap_map_meta` (" +
|
this.dialect.initializeMapMeta());
|
||||||
"`map` SMALLINT UNSIGNED NOT NULL," +
|
|
||||||
"`key` varchar(255) NOT NULL," +
|
|
||||||
"`value` LONGBLOB NOT NULL," +
|
|
||||||
"PRIMARY KEY (`map`, `key`)," +
|
|
||||||
"CONSTRAINT `fk_bluemap_map_meta_map` FOREIGN KEY (`map`) REFERENCES `bluemap_map` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
|
|
||||||
")");
|
|
||||||
|
|
||||||
connection.createStatement().executeUpdate(
|
connection.createStatement().executeUpdate(
|
||||||
"CREATE TABLE `bluemap_map_tile` (" +
|
this.dialect.initializeMapTile()
|
||||||
"`map` SMALLINT UNSIGNED NOT NULL," +
|
|
||||||
"`lod` SMALLINT UNSIGNED NOT NULL," +
|
|
||||||
"`x` INT NOT NULL," +
|
|
||||||
"`z` INT NOT NULL," +
|
|
||||||
"`compression` SMALLINT UNSIGNED NOT NULL," +
|
|
||||||
"`changed` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP," +
|
|
||||||
"`data` LONGBLOB NOT NULL," +
|
|
||||||
"PRIMARY KEY (`map`, `lod`, `x`, `z`)," +
|
|
||||||
"CONSTRAINT `fk_bluemap_map_tile_map` FOREIGN KEY (`map`) REFERENCES `bluemap_map` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT," +
|
|
||||||
"CONSTRAINT `fk_bluemap_map_tile_compression` FOREIGN KEY (`compression`) REFERENCES `bluemap_map_tile_compression` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
|
|
||||||
");"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"UPDATE `bluemap_storage_meta` " +
|
this.dialect.updateStorageMeta(),
|
||||||
"SET `value` = ? " +
|
|
||||||
"WHERE `key` = ?",
|
|
||||||
"3", "schema_version"
|
"3", "schema_version"
|
||||||
);
|
);
|
||||||
}, 2);
|
}, 2);
|
||||||
|
@ -544,36 +457,27 @@ public class SQLStorage extends Storage {
|
||||||
|
|
||||||
// delete potential files that are already in the new format to avoid constraint-issues
|
// delete potential files that are already in the new format to avoid constraint-issues
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"DELETE FROM `bluemap_map_meta`" +
|
this.dialect.deleteMapMeta(),
|
||||||
"WHERE `key` IN (?, ?, ?)",
|
|
||||||
"settings.json", "textures.json", ".rstate"
|
"settings.json", "textures.json", ".rstate"
|
||||||
);
|
);
|
||||||
|
|
||||||
// rename files
|
// rename files
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"UPDATE `bluemap_map_meta` " +
|
this.dialect.updateMapMeta(),
|
||||||
"SET `key` = ? " +
|
|
||||||
"WHERE `key` = ?",
|
|
||||||
"settings.json", "settings"
|
"settings.json", "settings"
|
||||||
);
|
);
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"UPDATE `bluemap_map_meta` " +
|
this.dialect.updateMapMeta(),
|
||||||
"SET `key` = ? " +
|
|
||||||
"WHERE `key` = ?",
|
|
||||||
"textures.json", "textures"
|
"textures.json", "textures"
|
||||||
);
|
);
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"UPDATE `bluemap_map_meta` " +
|
this.dialect.updateMapMeta(),
|
||||||
"SET `key` = ? " +
|
|
||||||
"WHERE `key` = ?",
|
|
||||||
".rstate", "render_state"
|
".rstate", "render_state"
|
||||||
);
|
);
|
||||||
|
|
||||||
// update schemaVersion
|
// update schemaVersion
|
||||||
executeUpdate(connection,
|
executeUpdate(connection,
|
||||||
"UPDATE `bluemap_storage_meta` " +
|
this.dialect.updateStorageMeta(),
|
||||||
"SET `value` = ? " +
|
|
||||||
"WHERE `key` = ?",
|
|
||||||
"3", "schema_version"
|
"3", "schema_version"
|
||||||
);
|
);
|
||||||
}, 2);
|
}, 2);
|
||||||
|
@ -603,7 +507,7 @@ public class SQLStorage extends Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultSet executeQuery(Connection connection, @Language("sql") String sql, Object... parameters) throws SQLException {
|
protected ResultSet executeQuery(Connection connection, @Language("sql") String sql, Object... parameters) throws SQLException {
|
||||||
// we only use this prepared statement once, but the DB-Driver caches those and reuses them
|
// we only use this prepared statement once, but the DB-Driver caches those and reuses them
|
||||||
PreparedStatement statement = connection.prepareStatement(sql);
|
PreparedStatement statement = connection.prepareStatement(sql);
|
||||||
for (int i = 0; i < parameters.length; i++) {
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
@ -613,7 +517,7 @@ public class SQLStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("UnusedReturnValue")
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
private int executeUpdate(Connection connection, @Language("sql") String sql, Object... parameters) throws SQLException {
|
protected int executeUpdate(Connection connection, @Language("sql") String sql, Object... parameters) throws SQLException {
|
||||||
// we only use this prepared statement once, but the DB-Driver caches those and reuses them
|
// we only use this prepared statement once, but the DB-Driver caches those and reuses them
|
||||||
PreparedStatement statement = connection.prepareStatement(sql);
|
PreparedStatement statement = connection.prepareStatement(sql);
|
||||||
for (int i = 0; i < parameters.length; i++) {
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
@ -623,12 +527,12 @@ public class SQLStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("SameParameterValue")
|
@SuppressWarnings("SameParameterValue")
|
||||||
private void recoveringConnection(ConnectionConsumer action, int tries) throws SQLException, IOException {
|
protected void recoveringConnection(ConnectionConsumer action, int tries) throws SQLException, IOException {
|
||||||
recoveringConnection((ConnectionFunction<Void>) action, tries);
|
recoveringConnection((ConnectionFunction<Void>) action, tries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("SameParameterValue")
|
@SuppressWarnings("SameParameterValue")
|
||||||
private <R> R recoveringConnection(ConnectionFunction<R> action, int tries) throws SQLException, IOException {
|
protected <R> R recoveringConnection(ConnectionFunction<R> action, int tries) throws SQLException, IOException {
|
||||||
SQLException sqlException = null;
|
SQLException sqlException = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -657,7 +561,7 @@ public class SQLStorage extends Storage {
|
||||||
throw sqlException;
|
throw sqlException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMapFK(String mapId) throws SQLException {
|
protected int getMapFK(String mapId) throws SQLException {
|
||||||
try {
|
try {
|
||||||
return Objects.requireNonNull(mapFKs.get(mapId));
|
return Objects.requireNonNull(mapFKs.get(mapId));
|
||||||
} catch (CompletionException ex) {
|
} catch (CompletionException ex) {
|
||||||
|
@ -670,7 +574,7 @@ public class SQLStorage extends Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMapTileCompressionFK(Compression compression) throws SQLException {
|
int getMapTileCompressionFK(Compression compression) throws SQLException {
|
||||||
try {
|
try {
|
||||||
return Objects.requireNonNull(mapTileCompressionFKs.get(compression));
|
return Objects.requireNonNull(mapTileCompressionFKs.get(compression));
|
||||||
} catch (CompletionException ex) {
|
} catch (CompletionException ex) {
|
||||||
|
@ -698,9 +602,7 @@ public class SQLStorage extends Storage {
|
||||||
return recoveringConnection(connection -> {
|
return recoveringConnection(connection -> {
|
||||||
int key;
|
int key;
|
||||||
ResultSet result = executeQuery(connection,
|
ResultSet result = executeQuery(connection,
|
||||||
//language=SQL
|
this.dialect.lookupFK(table,idField,valueField),
|
||||||
"SELECT `" + idField + "` FROM `" + table + "` " +
|
|
||||||
"WHERE `" + valueField + "` = ?",
|
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -708,8 +610,7 @@ public class SQLStorage extends Storage {
|
||||||
key = result.getInt("id");
|
key = result.getInt("id");
|
||||||
} else {
|
} else {
|
||||||
PreparedStatement statement = connection.prepareStatement(
|
PreparedStatement statement = connection.prepareStatement(
|
||||||
"INSERT INTO `" + table + "` (`" + valueField + "`) " +
|
this.dialect.insertFK(table,valueField),
|
||||||
"VALUES (?)",
|
|
||||||
Statement.RETURN_GENERATED_KEYS
|
Statement.RETURN_GENERATED_KEYS
|
||||||
);
|
);
|
||||||
statement.setString(1, value);
|
statement.setString(1, value);
|
||||||
|
@ -774,6 +675,12 @@ public class SQLStorage extends Storage {
|
||||||
return new PoolingDataSource<>(connectionPool);
|
return new PoolingDataSource<>(connectionPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SQLStorage create(SQLStorageSettings settings) throws Exception {
|
||||||
|
String dbUrl = settings.getConnectionUrl();
|
||||||
|
String provider = dbUrl.strip().split(":", 3)[1];
|
||||||
|
return DialectType.getStorage(provider,settings);
|
||||||
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ConnectionConsumer extends ConnectionFunction<Void> {
|
public interface ConnectionConsumer extends ConnectionFunction<Void> {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package de.bluecolored.bluemap.core.storage.sql.dialect;
|
||||||
|
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.MySQLStorage;
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.PostgreSQLStorage;
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.SQLStorage;
|
||||||
|
import de.bluecolored.bluemap.core.storage.sql.SQLStorageSettings;
|
||||||
|
|
||||||
|
public enum DialectType {
|
||||||
|
|
||||||
|
MYSQL (MySQLStorage::new, "mysql"),
|
||||||
|
MARIADB (MySQLStorage::new, "mariadb"),
|
||||||
|
POSTGRESQL (PostgreSQLStorage::new,"postgresql");
|
||||||
|
|
||||||
|
private final SQLStorageFactory storageFactory;
|
||||||
|
private final String dialectName;
|
||||||
|
|
||||||
|
DialectType(SQLStorageFactory storageFactory, String dialectName) {
|
||||||
|
this.storageFactory = storageFactory;
|
||||||
|
this.dialectName = dialectName;
|
||||||
|
}
|
||||||
|
public String getDialectName() {
|
||||||
|
return dialectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SQLStorage getStorage(String dialectName, SQLStorageSettings settings) throws Exception {
|
||||||
|
for (DialectType dialect : values()) {
|
||||||
|
if (dialect.getDialectName().equals(dialectName)) {
|
||||||
|
return dialect.storageFactory.provide(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface SQLStorageFactory {
|
||||||
|
SQLStorage provide(SQLStorageSettings config) throws Exception;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
package de.bluecolored.bluemap.core.storage.sql.dialect;
|
||||||
|
|
||||||
|
import org.intellij.lang.annotations.Language;
|
||||||
|
|
||||||
|
public class MySQLDialect implements SQLQueryDialect {
|
||||||
|
|
||||||
|
public static final MySQLDialect INSTANCE = new MySQLDialect();
|
||||||
|
|
||||||
|
private MySQLDialect() {};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String writeMapTile() {
|
||||||
|
return "REPLACE INTO `bluemap_map_tile` (`map`, `lod`, `x`, `z`, `compression`, `data`) " +
|
||||||
|
"VALUES (?, ?, ?, ?, ?, ?)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String readMapTile() {
|
||||||
|
return "SELECT t.`data` " +
|
||||||
|
"FROM `bluemap_map_tile` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
" INNER JOIN `bluemap_map_tile_compression` c " +
|
||||||
|
" ON t.`compression` = c.`id` " +
|
||||||
|
"WHERE m.`map_id` = ? " +
|
||||||
|
"AND t.`lod` = ? " +
|
||||||
|
"AND t.`x` = ? " +
|
||||||
|
"AND t.`z` = ? " +
|
||||||
|
"AND c.`compression` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String readMapTileInfo() {
|
||||||
|
return "SELECT t.`changed`, LENGTH(t.`data`) as 'size' " +
|
||||||
|
"FROM `bluemap_map_tile` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
" INNER JOIN `bluemap_map_tile_compression` c " +
|
||||||
|
" ON t.`compression` = c.`id` " +
|
||||||
|
"WHERE m.`map_id` = ? " +
|
||||||
|
"AND t.`lod` = ? " +
|
||||||
|
"AND t.`x` = ? " +
|
||||||
|
"AND t.`z` = ? " +
|
||||||
|
"AND c.`compression` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String deleteMapTile() {
|
||||||
|
return "DELETE t " +
|
||||||
|
"FROM `bluemap_map_tile` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
"WHERE m.`map_id` = ? " +
|
||||||
|
"AND t.`lod` = ? " +
|
||||||
|
"AND t.`x` = ? " +
|
||||||
|
"AND t.`z` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String writeMeta() {
|
||||||
|
return "REPLACE INTO `bluemap_map_meta` (`map`, `key`, `value`) " +
|
||||||
|
"VALUES (?, ?, ?)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String readMeta() {
|
||||||
|
return "SELECT t.`value` " +
|
||||||
|
"FROM `bluemap_map_meta` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
"WHERE m.`map_id` = ? " +
|
||||||
|
"AND t.`key` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String readMetaSize() {
|
||||||
|
return "SELECT LENGTH(t.`value`) as 'size' " +
|
||||||
|
"FROM `bluemap_map_meta` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
"WHERE m.`map_id` = ? " +
|
||||||
|
"AND t.`key` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String purgeMeta() {
|
||||||
|
return "DELETE t " +
|
||||||
|
"FROM `bluemap_map_meta` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
"WHERE m.`map_id` = ? " +
|
||||||
|
"AND t.`key` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String purgeMapTile() {
|
||||||
|
return "DELETE t " +
|
||||||
|
"FROM `bluemap_map_tile` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
"WHERE m.`map_id` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String purgeMapMeta() {
|
||||||
|
return "DELETE t " +
|
||||||
|
"FROM `bluemap_map_meta` t " +
|
||||||
|
" INNER JOIN `bluemap_map` m " +
|
||||||
|
" ON t.`map` = m.`id` " +
|
||||||
|
"WHERE m.`map_id` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String purgeMap() {
|
||||||
|
return "DELETE " +
|
||||||
|
"FROM `bluemap_map` " +
|
||||||
|
"WHERE `map_id` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String selectMapIds() {
|
||||||
|
return "SELECT `map_id` FROM `bluemap_map`";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String initializeStorageMeta() {
|
||||||
|
return "CREATE TABLE IF NOT EXISTS `bluemap_storage_meta` (" +
|
||||||
|
"`key` varchar(255) NOT NULL, " +
|
||||||
|
"`value` varchar(255) DEFAULT NULL, " +
|
||||||
|
"PRIMARY KEY (`key`)" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String selectStorageMeta() {
|
||||||
|
return "SELECT `value` FROM `bluemap_storage_meta` " +
|
||||||
|
"WHERE `key` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String insertStorageMeta() {
|
||||||
|
return "INSERT INTO `bluemap_storage_meta` (`key`, `value`) " +
|
||||||
|
"VALUES (?, ?)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String initializeMap() {
|
||||||
|
return "CREATE TABLE `bluemap_map` (" +
|
||||||
|
"`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT," +
|
||||||
|
"`map_id` VARCHAR(255) NOT NULL," +
|
||||||
|
"PRIMARY KEY (`id`)," +
|
||||||
|
"UNIQUE INDEX `map_id` (`map_id`)" +
|
||||||
|
");";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String initializeMapTileCompression() {
|
||||||
|
return "CREATE TABLE `bluemap_map_tile_compression` (" +
|
||||||
|
"`id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT," +
|
||||||
|
"`compression` VARCHAR(255) NOT NULL," +
|
||||||
|
"PRIMARY KEY (`id`)," +
|
||||||
|
"UNIQUE INDEX `compression` (`compression`)" +
|
||||||
|
");";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String initializeMapMeta() {
|
||||||
|
return "CREATE TABLE `bluemap_map_meta` (" +
|
||||||
|
"`map` SMALLINT UNSIGNED NOT NULL," +
|
||||||
|
"`key` varchar(255) NOT NULL," +
|
||||||
|
"`value` LONGBLOB NOT NULL," +
|
||||||
|
"PRIMARY KEY (`map`, `key`)," +
|
||||||
|
"CONSTRAINT `fk_bluemap_map_meta_map` FOREIGN KEY (`map`) REFERENCES `bluemap_map` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String initializeMapTile() {
|
||||||
|
return "CREATE TABLE `bluemap_map_tile` (" +
|
||||||
|
"`map` SMALLINT UNSIGNED NOT NULL," +
|
||||||
|
"`lod` SMALLINT UNSIGNED NOT NULL," +
|
||||||
|
"`x` INT NOT NULL," +
|
||||||
|
"`z` INT NOT NULL," +
|
||||||
|
"`compression` SMALLINT UNSIGNED NOT NULL," +
|
||||||
|
"`changed` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP," +
|
||||||
|
"`data` LONGBLOB NOT NULL," +
|
||||||
|
"PRIMARY KEY (`map`, `lod`, `x`, `z`)," +
|
||||||
|
"CONSTRAINT `fk_bluemap_map_tile_map` FOREIGN KEY (`map`) REFERENCES `bluemap_map` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT," +
|
||||||
|
"CONSTRAINT `fk_bluemap_map_tile_compression` FOREIGN KEY (`compression`) REFERENCES `bluemap_map_tile_compression` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
|
||||||
|
");";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String updateStorageMeta() {
|
||||||
|
return "UPDATE `bluemap_storage_meta` " +
|
||||||
|
"SET `value` = ? " +
|
||||||
|
"WHERE `key` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String deleteMapMeta() {
|
||||||
|
return "DELETE FROM `bluemap_map_meta`" +
|
||||||
|
"WHERE `key` IN (?, ?, ?)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String updateMapMeta() {
|
||||||
|
return "UPDATE `bluemap_map_meta` " +
|
||||||
|
"SET `key` = ? " +
|
||||||
|
"WHERE `key` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String lookupFK(String table, String idField, String valueField) {
|
||||||
|
return "SELECT `" + idField + "` FROM `" + table + "` " +
|
||||||
|
"WHERE `" + valueField + "` = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("MySQL")
|
||||||
|
public String insertFK(String table, String valueField) {
|
||||||
|
return "INSERT INTO `" + table + "` (`" + valueField + "`) " +
|
||||||
|
"VALUES (?)";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
package de.bluecolored.bluemap.core.storage.sql.dialect;
|
||||||
|
|
||||||
|
import org.intellij.lang.annotations.Language;
|
||||||
|
|
||||||
|
public class PostgresDialect implements SQLQueryDialect {
|
||||||
|
|
||||||
|
public static final PostgresDialect INSTANCE = new PostgresDialect();
|
||||||
|
|
||||||
|
private PostgresDialect() {};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String writeMapTile() {
|
||||||
|
return "INSERT INTO bluemap_map_tile (map, lod, x, z, compression, data) " +
|
||||||
|
"VALUES (?, ?, ?, ?, ?, ?) " +
|
||||||
|
"ON CONFLICT (map, lod, x, z) DO UPDATE SET compression = EXCLUDED.compression, data = EXCLUDED.data";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String readMapTile() {
|
||||||
|
return "SELECT t.data " +
|
||||||
|
"FROM bluemap_map_tile t " +
|
||||||
|
" INNER JOIN bluemap_map m " +
|
||||||
|
" ON t.map = m.id " +
|
||||||
|
" INNER JOIN bluemap_map_tile_compression c " +
|
||||||
|
" ON t.compression = c.id " +
|
||||||
|
"WHERE m.map_id = ? " +
|
||||||
|
"AND t.lod = ? " +
|
||||||
|
"AND t.x = ? " +
|
||||||
|
"AND t.z = ? " +
|
||||||
|
"AND c.compression = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String readMapTileInfo() {
|
||||||
|
return "SELECT t.changed, OCTET_LENGTH(t.data) as size " +
|
||||||
|
"FROM bluemap_map_tile t " +
|
||||||
|
" INNER JOIN bluemap_map m " +
|
||||||
|
" ON t.map = m.id " +
|
||||||
|
" INNER JOIN bluemap_map_tile_compression c " +
|
||||||
|
" ON t.compression = c.id " +
|
||||||
|
"WHERE m.map_id = ? " +
|
||||||
|
"AND t.lod = ? " +
|
||||||
|
"AND t.x = ? " +
|
||||||
|
"AND t.z = ? " +
|
||||||
|
"AND c.compression = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String deleteMapTile() {
|
||||||
|
return "DELETE FROM bluemap_map_tile t " +
|
||||||
|
"USING bluemap_map m " +
|
||||||
|
"WHERE t.map = m.id " +
|
||||||
|
"AND m.map_id = ? " +
|
||||||
|
"AND t.lod = ? " +
|
||||||
|
"AND t.x = ? " +
|
||||||
|
"AND t.z = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String writeMeta() {
|
||||||
|
return "INSERT INTO bluemap_map_meta (map, key, value) " +
|
||||||
|
"VALUES (?, ?, ?) " +
|
||||||
|
"ON CONFLICT (map, key) DO UPDATE SET value = EXCLUDED.value";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String readMeta() {
|
||||||
|
return "SELECT t.value " +
|
||||||
|
"FROM bluemap_map_meta t " +
|
||||||
|
" INNER JOIN bluemap_map m " +
|
||||||
|
" ON t.map = m.id " +
|
||||||
|
"WHERE m.map_id = ? " +
|
||||||
|
"AND t.key = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String readMetaSize() {
|
||||||
|
return "SELECT OCTET_LENGTH(t.value) as size " +
|
||||||
|
"FROM bluemap_map_meta t " +
|
||||||
|
" INNER JOIN bluemap_map m " +
|
||||||
|
" ON t.map = m.id " +
|
||||||
|
"WHERE m.map_id = ? " +
|
||||||
|
"AND t.key = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String purgeMeta() {
|
||||||
|
return "DELETE FROM bluemap_map_meta t " +
|
||||||
|
"USING bluemap_map m " +
|
||||||
|
"WHERE t.map = m.id " +
|
||||||
|
"AND m.map_id = ? " +
|
||||||
|
"AND t.key = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String purgeMapTile() {
|
||||||
|
return "DELETE FROM bluemap_map_tile t " +
|
||||||
|
"USING bluemap_map m " +
|
||||||
|
"WHERE t.map = m.id " +
|
||||||
|
"AND m.map_id = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String purgeMapMeta() {
|
||||||
|
return "DELETE FROM bluemap_map_meta t " +
|
||||||
|
"USING bluemap_map m " +
|
||||||
|
"WHERE t.map = m.id " +
|
||||||
|
"AND m.map_id = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String purgeMap() {
|
||||||
|
return "DELETE FROM bluemap_map " +
|
||||||
|
"WHERE map_id = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String selectMapIds() {
|
||||||
|
return "SELECT map_id FROM bluemap_map";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String initializeStorageMeta() {
|
||||||
|
return "CREATE TABLE IF NOT EXISTS bluemap_storage_meta (" +
|
||||||
|
"key varchar(255) PRIMARY KEY, " +
|
||||||
|
"value varchar(255)" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String selectStorageMeta() {
|
||||||
|
return "SELECT value FROM bluemap_storage_meta " +
|
||||||
|
"WHERE key = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String insertStorageMeta() {
|
||||||
|
return "INSERT INTO bluemap_storage_meta (key, value) " +
|
||||||
|
"VALUES (?, ?) " +
|
||||||
|
"ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String initializeMap() {
|
||||||
|
return "CREATE TABLE IF NOT EXISTS bluemap_map (" +
|
||||||
|
"id SERIAL PRIMARY KEY, " +
|
||||||
|
"map_id VARCHAR(255) UNIQUE NOT NULL" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String initializeMapTileCompression() {
|
||||||
|
return "CREATE TABLE IF NOT EXISTS bluemap_map_tile_compression (" +
|
||||||
|
"id SERIAL PRIMARY KEY, " +
|
||||||
|
"compression VARCHAR(255) UNIQUE NOT NULL" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String initializeMapMeta() {
|
||||||
|
return "CREATE TABLE IF NOT EXISTS bluemap_map_meta (" +
|
||||||
|
"map SMALLINT REFERENCES bluemap_map(id) ON UPDATE RESTRICT ON DELETE RESTRICT, " +
|
||||||
|
"key varchar(255) NOT NULL, " +
|
||||||
|
"value BYTEA NOT NULL, " +
|
||||||
|
"PRIMARY KEY (map, key)" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String initializeMapTile() {
|
||||||
|
return "CREATE TABLE IF NOT EXISTS bluemap_map_tile (" +
|
||||||
|
"map SMALLINT REFERENCES bluemap_map(id) ON UPDATE RESTRICT ON DELETE RESTRICT, " +
|
||||||
|
"lod SMALLINT NOT NULL, " +
|
||||||
|
"x INT NOT NULL, " +
|
||||||
|
"z INT NOT NULL, " +
|
||||||
|
"compression SMALLINT REFERENCES bluemap_map_tile_compression(id) ON UPDATE RESTRICT ON DELETE RESTRICT, " +
|
||||||
|
"changed TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, " +
|
||||||
|
"data BYTEA NOT NULL, " +
|
||||||
|
"PRIMARY KEY (map, lod, x, z)" +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String updateStorageMeta() {
|
||||||
|
return "UPDATE bluemap_storage_meta " +
|
||||||
|
"SET value = ? " +
|
||||||
|
"WHERE key = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String deleteMapMeta() {
|
||||||
|
return "DELETE FROM bluemap_map_meta " +
|
||||||
|
"WHERE key IN (?, ?, ?)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String updateMapMeta() {
|
||||||
|
return "UPDATE bluemap_map_meta " +
|
||||||
|
"SET key = ? " +
|
||||||
|
"WHERE key = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String lookupFK(String table, String idField, String valueField) {
|
||||||
|
return "SELECT " + idField + " FROM " + table +
|
||||||
|
" WHERE " + valueField + " = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Language("PostgreSQL")
|
||||||
|
public String insertFK(String table, String valueField) {
|
||||||
|
return "INSERT INTO " + table + " (" + valueField + ") " +
|
||||||
|
"VALUES (?)";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package de.bluecolored.bluemap.core.storage.sql.dialect;
|
||||||
|
|
||||||
|
import org.intellij.lang.annotations.Language;
|
||||||
|
|
||||||
|
public interface SQLQueryDialect {
|
||||||
|
@Language("sql")
|
||||||
|
String writeMapTile();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String readMapTile();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String readMapTileInfo();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String deleteMapTile();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String writeMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String readMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String readMetaSize();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String purgeMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String purgeMapTile();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String purgeMapMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String purgeMap();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String selectMapIds();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String initializeStorageMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String selectStorageMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String insertStorageMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String initializeMap();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String initializeMapTileCompression();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String initializeMapMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String initializeMapTile();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String updateStorageMeta(); // can be use twice in init
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String deleteMapMeta();
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String updateMapMeta(); // can be used twice in init
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String lookupFK(String table, String idField, String valueField);
|
||||||
|
|
||||||
|
@Language("sql")
|
||||||
|
String insertFK(String table, String valueField);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue