test database for blocks db
parent
783f761860
commit
308b170baa
|
@ -2,6 +2,7 @@ package io.rudin.minetest.tileserver.config;
|
|||
|
||||
import org.aeonbits.owner.Config;
|
||||
import org.aeonbits.owner.Config.Sources;
|
||||
import org.jooq.SQLDialect;
|
||||
|
||||
@Sources({
|
||||
"file:./tileserver.properties"
|
||||
|
@ -140,6 +141,10 @@ public interface TileServerConfig extends Config {
|
|||
@DefaultValue("org.postgresql.Driver")
|
||||
String minetestDatabaseDriver();
|
||||
|
||||
@Key("minetest.db.dialect")
|
||||
@DefaultValue("POSTGRES")
|
||||
SQLDialect minetestDatabaseDialect();
|
||||
|
||||
/*
|
||||
Tile cache DB
|
||||
*/
|
||||
|
|
|
@ -28,7 +28,7 @@ public class MapDBDSLContextProvider implements Provider<DSLContext> {
|
|||
|
||||
@Override
|
||||
public DSLContext get() {
|
||||
return DSL.using(ds, SQLDialect.POSTGRES);
|
||||
return DSL.using(ds, cfg.minetestDatabaseDialect());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,22 +14,21 @@ public class MapDBDatasourceProvider implements Provider<DataSource> {
|
|||
|
||||
@Inject
|
||||
public MapDBDatasourceProvider(TileServerConfig cfg) {
|
||||
this.cfg = cfg;
|
||||
}
|
||||
|
||||
private final TileServerConfig cfg;
|
||||
|
||||
@Override
|
||||
@Singleton
|
||||
public DataSource get() {
|
||||
|
||||
HikariConfig hikariConfig = new HikariConfig();
|
||||
hikariConfig.setUsername(cfg.minetestDatabaseUsername());
|
||||
hikariConfig.setPassword(cfg.minetestDatabasePassword());
|
||||
hikariConfig.setJdbcUrl(cfg.minetestDatabaseUrl());
|
||||
hikariConfig.setDriverClassName(cfg.minetestDatabaseDriver());
|
||||
|
||||
return new HikariDataSource(hikariConfig);
|
||||
ds = new HikariDataSource(hikariConfig);
|
||||
}
|
||||
|
||||
private final HikariDataSource ds;
|
||||
|
||||
@Override
|
||||
@Singleton
|
||||
public DataSource get() {
|
||||
return ds;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,22 +15,21 @@ public class TileDBDatasourceProvider implements Provider<DataSource> {
|
|||
|
||||
@Inject
|
||||
public TileDBDatasourceProvider(TileServerConfig cfg) {
|
||||
this.cfg = cfg;
|
||||
}
|
||||
|
||||
private final TileServerConfig cfg;
|
||||
|
||||
@Override
|
||||
@Singleton
|
||||
public DataSource get() {
|
||||
|
||||
HikariConfig hikariConfig = new HikariConfig();
|
||||
hikariConfig.setUsername(cfg.tileDatabaseUsername());
|
||||
hikariConfig.setPassword(cfg.tileDatabasePassword());
|
||||
hikariConfig.setJdbcUrl(cfg.tileDatabaseUrl());
|
||||
hikariConfig.setDriverClassName(cfg.tileDatabaseDriver());
|
||||
|
||||
return new HikariDataSource(hikariConfig);
|
||||
this.ds = new HikariDataSource(hikariConfig);
|
||||
}
|
||||
|
||||
private final HikariDataSource ds;
|
||||
|
||||
@Override
|
||||
@Singleton
|
||||
public DataSource get() {
|
||||
return ds;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package io.rudin.minetest.tileserver;
|
||||
|
||||
import io.rudin.minetest.tileserver.accessor.Coordinate;
|
||||
import io.rudin.minetest.tileserver.base.TileServerTest;
|
||||
import io.rudin.minetest.tileserver.blockdb.tables.Blocks;
|
||||
import io.rudin.minetest.tileserver.blockdb.tables.records.BlocksRecord;
|
||||
import io.rudin.minetest.tileserver.job.UpdateChangedTilesJob;
|
||||
import io.rudin.minetest.tileserver.qualifier.MapDB;
|
||||
import io.rudin.minetest.tileserver.service.BlocksRecordService;
|
||||
import io.rudin.minetest.tileserver.service.TileCache;
|
||||
import org.jooq.DSLContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static io.rudin.minetest.tileserver.blockdb.tables.Blocks.BLOCKS;
|
||||
|
||||
public class UpdateChangedTilesTest extends TileServerTest {
|
||||
|
||||
|
||||
@Inject UpdateChangedTilesJob changedTilesJob;
|
||||
@Inject TileCache tileCache;
|
||||
@Inject @MapDB DSLContext ctx;
|
||||
|
||||
|
||||
@Test
|
||||
public void test() throws IOException {
|
||||
|
||||
byte[] tile = tileCache.get(0, 0, 1, 13);
|
||||
Assert.assertNull(tile);
|
||||
|
||||
changedTilesJob.run();
|
||||
|
||||
tile = tileCache.get(0, 0, 1, 13);
|
||||
Assert.assertNotNull(tile);
|
||||
|
||||
BlocksRecord block = ctx.selectFrom(BLOCKS)
|
||||
.where(BLOCKS.POSX.eq(0).and(BLOCKS.POSY.eq(0).and(BLOCKS.POSZ.eq(0))))
|
||||
.fetchOne();
|
||||
|
||||
block.setMtime(System.currentTimeMillis());
|
||||
block.update();
|
||||
|
||||
changedTilesJob.run();
|
||||
|
||||
tile = tileCache.get(0, 0, 1, 13);
|
||||
Assert.assertNotNull(tile);
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -5,31 +5,44 @@ import com.google.inject.Injector;
|
|||
import com.google.inject.Key;
|
||||
import com.google.inject.Provider;
|
||||
import io.rudin.minetest.tileserver.DBMigration;
|
||||
import io.rudin.minetest.tileserver.blockdb.tables.Blocks;
|
||||
import io.rudin.minetest.tileserver.blockdb.tables.records.BlocksRecord;
|
||||
import io.rudin.minetest.tileserver.config.TileServerConfig;
|
||||
import io.rudin.minetest.tileserver.module.ConfigModule;
|
||||
import io.rudin.minetest.tileserver.module.DBModule;
|
||||
import io.rudin.minetest.tileserver.module.ServiceModule;
|
||||
import io.rudin.minetest.tileserver.module.TestServiceModule;
|
||||
import io.rudin.minetest.tileserver.qualifier.MapDB;
|
||||
import io.rudin.minetest.tileserver.util.StreamUtil;
|
||||
import org.aeonbits.owner.ConfigFactory;
|
||||
import org.jooq.DSLContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.rudin.minetest.tileserver.blockdb.tables.Blocks.BLOCKS;
|
||||
|
||||
public class TileServerTest {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(TileServerTest.class);
|
||||
|
||||
@Before
|
||||
public void init() throws SQLException {
|
||||
public void init() throws SQLException, IOException {
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put("minetest.db.url", "jdbc:h2:mem:tileserver");
|
||||
properties.put("minetest.db.url", "jdbc:h2:mem:tileserver;DB_CLOSE_DELAY=-1");
|
||||
properties.put("minetest.db.username", "sa");
|
||||
properties.put("minetest.db.password", "");
|
||||
properties.put("minetest.db.driver", "org.h2.Driver");
|
||||
properties.put("minetest.db.dialect", "H2");
|
||||
|
||||
TileServerConfig cfg = ConfigFactory.create(TileServerConfig.class, properties);
|
||||
|
||||
|
@ -43,16 +56,53 @@ public class TileServerTest {
|
|||
try (Connection connection = dataSource.getConnection()){
|
||||
connection.createStatement().execute("drop all objects");
|
||||
connection.createStatement().execute("runscript from 'classpath:/minetest-db.sql'");
|
||||
|
||||
}
|
||||
|
||||
//does not work: create function plsql not available in h2
|
||||
//injector.getInstance(DBMigration.class).migrate();
|
||||
|
||||
uploadMapBlocksToDatabase();
|
||||
|
||||
logger.info("Environment set up, injecting members");
|
||||
|
||||
injector.injectMembers(this);
|
||||
}
|
||||
|
||||
private Injector injector;
|
||||
|
||||
private void uploadMapBlocksToDatabase() throws IOException {
|
||||
DSLContext ctx = injector.getInstance(Key.get(DSLContext.class, MapDB.class));
|
||||
File mapBlockDir = new File("testdata/mapblocks");
|
||||
for (File file: mapBlockDir.listFiles()){
|
||||
|
||||
if (file.getName().startsWith("."))
|
||||
continue;
|
||||
|
||||
String[] parts = file.getName().split("[.]");
|
||||
|
||||
int posx = Integer.parseInt(parts[0]);
|
||||
int posy = Integer.parseInt(parts[1]);
|
||||
int posz = Integer.parseInt(parts[2]);
|
||||
|
||||
ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||
|
||||
try (InputStream input = new FileInputStream(file)){
|
||||
StreamUtil.copyStream(input, data);
|
||||
}
|
||||
|
||||
BlocksRecord record = ctx.newRecord(BLOCKS);
|
||||
record.setMtime(System.currentTimeMillis());
|
||||
record.setPosy(posy);
|
||||
record.setPosx(posx);
|
||||
record.setPosz(posz);
|
||||
record.setData(data.toByteArray());
|
||||
record.insert();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void after(){
|
||||
}
|
||||
|
|
|
@ -7,10 +7,7 @@ import io.rudin.minetest.tileserver.config.TileServerConfig;
|
|||
import io.rudin.minetest.tileserver.provider.ColorTableProvider;
|
||||
import io.rudin.minetest.tileserver.provider.ExecutorProvider;
|
||||
import io.rudin.minetest.tileserver.provider.LayerConfigProvider;
|
||||
import io.rudin.minetest.tileserver.service.BlocksRecordLocalService;
|
||||
import io.rudin.minetest.tileserver.service.BlocksRecordService;
|
||||
import io.rudin.minetest.tileserver.service.EventBus;
|
||||
import io.rudin.minetest.tileserver.service.TileCache;
|
||||
import io.rudin.minetest.tileserver.service.*;
|
||||
import io.rudin.minetest.tileserver.service.impl.*;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -28,7 +25,8 @@ public class TestServiceModule extends AbstractModule {
|
|||
bind(ExecutorService.class).toProvider(ExecutorProvider.class);
|
||||
bind(ScheduledExecutorService.class).toProvider(ExecutorProvider.class);
|
||||
bind(LayerConfig.class).toProvider(LayerConfigProvider.class);
|
||||
bind(MapBlockRenderService.class).to(DefaultMapBlockRenderService.class);
|
||||
|
||||
bind(BlocksRecordService.class).to(BlocksRecordLocalService.class);
|
||||
bind(BlocksRecordService.class).to(BlocksRecordDatabaseService.class);
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package io.rudin.minetest.tileserver.service;
|
||||
|
||||
import io.rudin.minetest.tileserver.accessor.Coordinate;
|
||||
import io.rudin.minetest.tileserver.blockdb.tables.records.BlocksRecord;
|
||||
import io.rudin.minetest.tileserver.service.impl.BlocksRecordDatabaseService;
|
||||
import io.rudin.minetest.tileserver.util.StreamUtil;
|
||||
import sun.security.action.OpenFileInputStreamAction;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
public class BlocksRecordLocalService implements BlocksRecordService {
|
||||
|
||||
private final Map<Coordinate, BlocksRecord> cache = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public List<BlocksRecord> getTopDownYStride(int x, int z, int minY, int maxY) {
|
||||
|
||||
List<BlocksRecord> result = new ArrayList<>();
|
||||
|
||||
for (int y=minY; y<=maxY; y++){
|
||||
Coordinate coordinate = new Coordinate(x, y, z);
|
||||
|
||||
Optional<BlocksRecord> optionalRecord = get(coordinate);
|
||||
if (optionalRecord.isPresent())
|
||||
result.add(optionalRecord.get());
|
||||
}
|
||||
|
||||
result.sort(Comparator.comparingInt(BlocksRecord::getPosy));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static File getLocalMapBlockFile(Coordinate coordinate){
|
||||
File mapblockDir = new File("testdata/mapblocks");
|
||||
if (!mapblockDir.isDirectory())
|
||||
mapblockDir.mkdir();
|
||||
|
||||
return new File(mapblockDir, coordinate.x + "." + coordinate.y + "." + coordinate.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BlocksRecord> get(Coordinate coords) {
|
||||
BlocksRecord record = cache.get(coords);
|
||||
|
||||
if (record != null)
|
||||
return Optional.of(record);
|
||||
|
||||
File file = getLocalMapBlockFile(coords);
|
||||
|
||||
if (!file.isFile())
|
||||
return Optional.empty();
|
||||
|
||||
try (InputStream input = new FileInputStream(file)){
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
StreamUtil.copyStream(input, output);
|
||||
|
||||
record = new BlocksRecord();
|
||||
record.setData(output.toByteArray());
|
||||
record.setMtime(file.lastModified());
|
||||
record.setPosx(coords.x);
|
||||
record.setPosy(coords.y);
|
||||
record.setPosz(coords.z);
|
||||
cache.put(coords, record);
|
||||
return Optional.of(record);
|
||||
|
||||
} catch (Exception e){
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(BlocksRecord block) {
|
||||
cache.put(new Coordinate(block), block);
|
||||
}
|
||||
}
|
|
@ -15,4 +15,7 @@
|
|||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<logger name="org.jooq" level="info">
|
||||
</logger>
|
||||
|
||||
</configuration>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
|
||||
create table blocks(
|
||||
posx int not null,
|
||||
posy int not null,
|
||||
posz int not null,
|
||||
data bytea,
|
||||
create table "blocks"(
|
||||
"posx" int not null,
|
||||
"posy" int not null,
|
||||
"posz" int not null,
|
||||
"data" bytea,
|
||||
"mtime" bigint not null default 0,
|
||||
|
||||
PRIMARY KEY(posx,posy,posz)
|
||||
);
|
||||
PRIMARY KEY("posx","posy","posz")
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue