Add compound key repo support
This commit is contained in:
+3
@@ -417,6 +417,9 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
|
||||
// setters and getters //
|
||||
//=====================//
|
||||
|
||||
@Override
|
||||
public DhSectionPos getKey() { return this.sectionPos; }
|
||||
|
||||
@Override
|
||||
public DhSectionPos getSectionPos() { return this.sectionPos; }
|
||||
|
||||
|
||||
+3
@@ -447,6 +447,9 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo
|
||||
// getters //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
public DhSectionPos getKey() { return this.sectionPos; }
|
||||
|
||||
@Override
|
||||
public DhSectionPos getSectionPos() { return this.sectionPos; }
|
||||
|
||||
|
||||
+3
@@ -309,6 +309,9 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp
|
||||
// getters and setters //
|
||||
//=====================//
|
||||
|
||||
@Override
|
||||
public DhSectionPos getKey() { return this.sectionPos; }
|
||||
|
||||
@Override
|
||||
public DhSectionPos getSectionPos() { return this.sectionPos; }
|
||||
|
||||
|
||||
+1
-1
@@ -427,7 +427,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
|
||||
public DhSectionPos getSectionPos() { return this.sectionPos; }
|
||||
@Override
|
||||
public String getPrimaryKeyString() { return this.sectionPos.serialize(); }
|
||||
public DhSectionPos getKey() { return this.sectionPos; }
|
||||
|
||||
public byte getDataDetailLevel() { return (byte) (this.sectionPos.getDetailLevel() - SECTION_SIZE_OFFSET); }
|
||||
|
||||
|
||||
+1
-2
@@ -17,7 +17,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
@@ -158,7 +157,7 @@ public abstract class AbstractDataSourceHandler<TDataSource extends IDataSource<
|
||||
TDataSource dataSource = null;
|
||||
try
|
||||
{
|
||||
DataSourceDto dto = this.repo.getByPrimaryKey(pos.serialize());
|
||||
DataSourceDto dto = this.repo.getByKey(pos);
|
||||
if (dto != null)
|
||||
{
|
||||
// load from file
|
||||
|
||||
@@ -16,12 +16,10 @@ import java.io.IOException;
|
||||
*
|
||||
* @param <TDhLevel> what type of level this data source can be created from
|
||||
*/
|
||||
public interface IDataSource<TDhLevel extends IDhLevel> extends IBaseDTO
|
||||
public interface IDataSource<TDhLevel extends IDhLevel> extends IBaseDTO<DhSectionPos>
|
||||
{
|
||||
|
||||
DhSectionPos getSectionPos();
|
||||
@Override
|
||||
default String getPrimaryKeyString() { return this.getSectionPos().serialize(); }
|
||||
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@ public class FullDataFileHandler
|
||||
while (possibleChildList.size() != 0)
|
||||
{
|
||||
DhSectionPos possiblePos = possibleChildList.remove(possibleChildList.size()-1);
|
||||
if (this.repo.existsWithPrimaryKey(possiblePos.serialize()))
|
||||
if (this.repo.existsWithKey(possiblePos))
|
||||
{
|
||||
samplePosList.add(possiblePos);
|
||||
}
|
||||
|
||||
+1
-1
@@ -193,7 +193,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.repo.existsWithPrimaryKey(genPos.serialize()))
|
||||
if (this.repo.existsWithKey(genPos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractDataSourceRepo extends AbstractDhRepo<DataSourceDto>
|
||||
public abstract class AbstractDataSourceRepo extends AbstractDhRepo<DhSectionPos, DataSourceDto>
|
||||
{
|
||||
public AbstractDataSourceRepo(String databaseType, String databaseLocation) throws SQLException
|
||||
{
|
||||
@@ -35,10 +35,6 @@ public abstract class AbstractDataSourceRepo extends AbstractDhRepo<DataSourceDt
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getPrimaryKeyName() { return "DhSectionPos"; }
|
||||
|
||||
|
||||
//=======================//
|
||||
// repo required methods //
|
||||
//=======================//
|
||||
@@ -70,9 +66,6 @@ public abstract class AbstractDataSourceRepo extends AbstractDhRepo<DataSourceDt
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createSelectPrimaryKeySql(String primaryKey) { return "SELECT * FROM "+this.getTableName()+" WHERE DhSectionPos = '"+primaryKey+"'"; }
|
||||
|
||||
@Override
|
||||
public PreparedStatement createInsertStatement(DataSourceDto dto) throws SQLException
|
||||
{
|
||||
@@ -90,7 +83,7 @@ public abstract class AbstractDataSourceRepo extends AbstractDhRepo<DataSourceDt
|
||||
PreparedStatement statement = this.createPreparedStatement(sql);
|
||||
|
||||
int i = 1;
|
||||
statement.setObject(i++, dto.getPrimaryKeyString());
|
||||
statement.setObject(i++, dto.pos.serialize());
|
||||
|
||||
statement.setObject(i++, dto.checksum);
|
||||
statement.setObject(i++, dto.dataVersion);
|
||||
@@ -133,7 +126,7 @@ public abstract class AbstractDataSourceRepo extends AbstractDhRepo<DataSourceDt
|
||||
|
||||
statement.setObject(i++, dto.dataArray);
|
||||
|
||||
statement.setObject(i++, dto.getPrimaryKeyString());
|
||||
statement.setObject(i++, dto.pos.serialize());
|
||||
|
||||
return statement;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.core.sql;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
@@ -31,15 +30,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
/**
|
||||
* Handles interfacing with SQL databases.
|
||||
*
|
||||
* @param <TDTO> DTO stands for "Data Table Object"
|
||||
* @param <TDTO> DTO stands for "Data Transfer Object"
|
||||
*/
|
||||
public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
public abstract class AbstractDhRepo<TKey, TDTO extends IBaseDTO<TKey>>
|
||||
{
|
||||
public static final int TIMEOUT_SECONDS = 30;
|
||||
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
private static final ConcurrentHashMap<String, Connection> CONNECTIONS_BY_CONNECTION_STRING = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<AbstractDhRepo<?>, String> ACTIVE_CONNECTION_STRINGS_BY_REPO = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<AbstractDhRepo<?, ?>, String> ACTIVE_CONNECTION_STRINGS_BY_REPO = new ConcurrentHashMap<>();
|
||||
|
||||
private final String connectionString;
|
||||
private final Connection connection;
|
||||
@@ -107,10 +106,10 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
// high level DB //
|
||||
//===============//
|
||||
|
||||
public TDTO get(TDTO dto) { return this.getByPrimaryKey(dto.getPrimaryKeyString()); }
|
||||
public TDTO getByPrimaryKey(String primaryKey)
|
||||
public TDTO get(TDTO dto) { return this.getByKey(dto.getKey()); }
|
||||
public TDTO getByKey(TKey primaryKey)
|
||||
{
|
||||
Map<String, Object> objectMap = this.queryDictionaryFirst(this.createSelectPrimaryKeySql(primaryKey));
|
||||
Map<String, Object> objectMap = this.queryDictionaryFirst(this.createSelectByKeySql(primaryKey));
|
||||
if (objectMap != null && !objectMap.isEmpty())
|
||||
{
|
||||
return this.convertDictionaryToDto(objectMap);
|
||||
@@ -124,7 +123,7 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
|
||||
public void save(TDTO dto)
|
||||
{
|
||||
if (this.getByPrimaryKey(dto.getPrimaryKeyString()) != null)
|
||||
if (this.getByKey(dto.getKey()) != null)
|
||||
{
|
||||
this.update(dto);
|
||||
}
|
||||
@@ -141,7 +140,7 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
}
|
||||
catch (DbConnectionClosedException ignored)
|
||||
{
|
||||
LOGGER.warn("Attempted to insert ["+this.dtoClass.getSimpleName()+"] with primary key ["+(dto != null ? dto.getPrimaryKeyString() : "NULL")+"] on closed repo ["+this.connectionString+"].");
|
||||
LOGGER.warn("Attempted to insert ["+this.dtoClass.getSimpleName()+"] with primary key ["+(dto != null ? dto.getKey() : "NULL")+"] on closed repo ["+this.connectionString+"].");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
@@ -158,7 +157,7 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
}
|
||||
catch (DbConnectionClosedException e)
|
||||
{
|
||||
LOGGER.warn("Attempted to update ["+this.dtoClass.getSimpleName()+"] with primary key ["+(dto != null ? dto.getPrimaryKeyString() : "NULL")+"] on closed repo ["+this.connectionString+"].");
|
||||
LOGGER.warn("Attempted to update ["+this.dtoClass.getSimpleName()+"] with primary key ["+(dto != null ? dto.getKey() : "NULL")+"] on closed repo ["+this.connectionString+"].");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
@@ -169,10 +168,10 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
}
|
||||
|
||||
|
||||
public void delete(TDTO dto) { this.deleteByPrimaryKey(dto.getPrimaryKeyString()); }
|
||||
public void deleteByPrimaryKey(String primaryKey)
|
||||
public void delete(TDTO dto) { this.deleteWithKey(dto.getKey()); }
|
||||
public void deleteWithKey(TKey key)
|
||||
{
|
||||
String whereEqualStatement = this.createWherePrimaryKeySql(primaryKey);
|
||||
String whereEqualStatement = this.createWhereStatement(key);
|
||||
this.queryDictionaryFirst("DELETE FROM "+this.getTableName()+" WHERE "+whereEqualStatement);
|
||||
}
|
||||
|
||||
@@ -180,10 +179,10 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
public void deleteAll() { this.queryDictionaryFirst("DELETE FROM "+this.getTableName()); }
|
||||
|
||||
|
||||
public boolean exists(TDTO dto) { return this.existsWithPrimaryKey(dto.getPrimaryKeyString()); }
|
||||
public boolean existsWithPrimaryKey(String primaryKey)
|
||||
public boolean exists(TDTO dto) { return this.existsWithKey(dto.getKey()); }
|
||||
public boolean existsWithKey(TKey key)
|
||||
{
|
||||
String whereEqualStatement = this.createWherePrimaryKeySql(primaryKey);
|
||||
String whereEqualStatement = this.createWhereStatement(key);
|
||||
Map<String, Object> result = this.queryDictionaryFirst("SELECT EXISTS(SELECT 1 FROM "+this.getTableName()+" WHERE "+whereEqualStatement+") as 'existingCount';");
|
||||
return result != null && (int)result.get("existingCount") != 0;
|
||||
}
|
||||
@@ -379,10 +378,7 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
/** Example: <code> Id = '0' </code> */
|
||||
public String createWherePrimaryKeySql(TDTO dto) { return this.createWherePrimaryKeySql(dto.getPrimaryKeyString()); }
|
||||
/** Example: <code> Id = '0' </code> */
|
||||
public String createWherePrimaryKeySql(String primaryKeyValue) { return this.getPrimaryKeyName()+" = '"+primaryKeyValue+"'"; }
|
||||
public String createWhereStatement(TDTO dto) { return this.createWhereStatement(dto.getKey()); }
|
||||
|
||||
public static List<Map<String, Object>> convertResultSetToDictionaryList(ResultSet resultSet) throws SQLException
|
||||
{
|
||||
@@ -440,12 +436,17 @@ public abstract class AbstractDhRepo<TDTO extends IBaseDTO>
|
||||
//==================//
|
||||
|
||||
public abstract String getTableName();
|
||||
public abstract String getPrimaryKeyName();
|
||||
|
||||
@Nullable
|
||||
public abstract TDTO convertDictionaryToDto(Map<String, Object> objectMap) throws ClassCastException;
|
||||
|
||||
public abstract String createSelectPrimaryKeySql(String primaryKey);
|
||||
public String createSelectByKeySql(TKey key) { return "SELECT * FROM "+this.getTableName()+" WHERE "+this.createWhereStatement(key); }
|
||||
/**
|
||||
* Example:
|
||||
* <code> Id = '0' </code>
|
||||
* <code> ColOne = '0' AND ColTwo = '2' </code>
|
||||
*/
|
||||
public abstract String createWhereStatement(TKey key);
|
||||
|
||||
public abstract PreparedStatement createInsertStatement(TDTO dto) throws SQLException;
|
||||
public abstract PreparedStatement createUpdateStatement(TDTO dto) throws SQLException;
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.io.InputStream;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/** handles storing both {@link IFullDataSource}'s and {@link ColumnRenderSource}'s in the database. */
|
||||
public class DataSourceDto implements IBaseDTO
|
||||
public class DataSourceDto implements IBaseDTO<DhSectionPos>
|
||||
{
|
||||
public DhSectionPos pos;
|
||||
public int checksum;
|
||||
@@ -49,6 +49,11 @@ public class DataSourceDto implements IBaseDTO
|
||||
public final byte[] dataArray;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public DataSourceDto(DhSectionPos pos, int checksum, byte dataDetailLevel, EDhApiWorldGenerationStep worldGenStep, String dataType, byte binaryDataFormatVersion, byte[] dataArray)
|
||||
{
|
||||
this.pos = pos;
|
||||
@@ -63,9 +68,6 @@ public class DataSourceDto implements IBaseDTO
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPrimaryKeyString() { return this.pos.serialize(); }
|
||||
|
||||
/** @return a stream for the data contained in this DTO. */
|
||||
public DhDataInputStream getInputStream() throws IOException
|
||||
{
|
||||
@@ -74,4 +76,14 @@ public class DataSourceDto implements IBaseDTO
|
||||
return compressedStream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// overrides //
|
||||
//===========//
|
||||
|
||||
@Override
|
||||
public DhSectionPos getKey() { return this.pos; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class DatabaseUpdater
|
||||
// script running //
|
||||
//================//
|
||||
|
||||
public static <TDTO extends IBaseDTO> void runAutoUpdateScripts(AbstractDhRepo<TDTO> repo) throws SQLException
|
||||
public static <TKey, TDTO extends IBaseDTO<TKey>> void runAutoUpdateScripts(AbstractDhRepo<TKey, TDTO> repo) throws SQLException
|
||||
{
|
||||
// get the resource scripts
|
||||
ArrayList<SqlScript> scriptList;
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.sql;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class FullDataRepo extends AbstractDataSourceRepo
|
||||
@@ -35,4 +37,7 @@ public class FullDataRepo extends AbstractDataSourceRepo
|
||||
@Override
|
||||
public String getTableName() { return TABLE_NAME; }
|
||||
|
||||
@Override
|
||||
public String createWhereStatement(DhSectionPos pos) { return "DhSectionPos = '"+pos.serialize()+"'"; }
|
||||
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@ package com.seibel.distanthorizons.core.sql;
|
||||
* DTO = DataTable Object <br>
|
||||
* Any object that's stored in the database should extend this object.
|
||||
*/
|
||||
public interface IBaseDTO
|
||||
public interface IBaseDTO<TKey>
|
||||
{
|
||||
String getPrimaryKeyString();
|
||||
TKey getKey();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.sql;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class RenderDataRepo extends AbstractDataSourceRepo
|
||||
@@ -35,4 +37,7 @@ public class RenderDataRepo extends AbstractDataSourceRepo
|
||||
@Override
|
||||
public String getTableName() { return TABLE_NAME; }
|
||||
|
||||
@Override
|
||||
public String createWhereStatement(DhSectionPos pos) { return "DhSectionPos = '"+pos.serialize()+"'"; }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package testItems.sql;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.sql.IBaseDTO;
|
||||
|
||||
public class TestCompoundKeyDto implements IBaseDTO<DhChunkPos>
|
||||
{
|
||||
public DhChunkPos id;
|
||||
public String value;
|
||||
|
||||
|
||||
|
||||
public TestCompoundKeyDto(DhChunkPos id, String value)
|
||||
{
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DhChunkPos getKey() { return this.id; }
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (other.getClass() != this.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TestCompoundKeyDto otherDto = (TestCompoundKeyDto) other;
|
||||
|
||||
return otherDto.id.equals(this.id)
|
||||
&& otherDto.value.equals(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.id + ", " + this.value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package testItems.sql;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.sql.AbstractDhRepo;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestCompoundKeyRepo extends AbstractDhRepo<DhChunkPos, TestCompoundKeyDto>
|
||||
{
|
||||
|
||||
public TestCompoundKeyRepo(String databaseType, String databaseLocation) throws SQLException
|
||||
{
|
||||
super(databaseType, databaseLocation, TestCompoundKeyDto.class);
|
||||
|
||||
// note: this should only ever be done with the test repo.
|
||||
// All long term tables should be created using a sql Script.
|
||||
String createTableSql =
|
||||
"CREATE TABLE IF NOT EXISTS "+this.getTableName()+"(\n" +
|
||||
"XPos INT NOT NULL\n" +
|
||||
",ZPos INT NOT NULL\n" +
|
||||
"\n" +
|
||||
",Value TEXT NULL\n" +
|
||||
"\n" +
|
||||
",PRIMARY KEY (XPos, ZPos)" +
|
||||
");";
|
||||
this.queryDictionaryFirst(createTableSql);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTableName() { return "TestCompound"; }
|
||||
@Override
|
||||
public String createWhereStatement(DhChunkPos key) { return "XPos = '"+key.x+"' AND ZPos = '"+key.z+"'"; }
|
||||
|
||||
|
||||
@Override
|
||||
public TestCompoundKeyDto convertDictionaryToDto(Map<String, Object> objectMap) throws ClassCastException
|
||||
{
|
||||
int xPos = (int) objectMap.get("XPos");
|
||||
int zPos = (int) objectMap.get("ZPos");
|
||||
String value = (String) objectMap.get("Value");
|
||||
|
||||
return new TestCompoundKeyDto(new DhChunkPos(xPos, zPos), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement createInsertStatement(TestCompoundKeyDto dto) throws SQLException
|
||||
{
|
||||
String sql =
|
||||
"INSERT INTO "+this.getTableName()+" \n" +
|
||||
"(XPos, ZPos, Value) \n" +
|
||||
"VALUES(?,?,?);";
|
||||
PreparedStatement statement = this.createPreparedStatement(sql);
|
||||
|
||||
int i = 1; // post-increment for the win!
|
||||
statement.setObject(i++, dto.id.x);
|
||||
statement.setObject(i++, dto.id.z);
|
||||
|
||||
statement.setObject(i++, dto.value);
|
||||
|
||||
return statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement createUpdateStatement(TestCompoundKeyDto dto) throws SQLException
|
||||
{
|
||||
String sql =
|
||||
"UPDATE "+this.getTableName()+" \n" +
|
||||
"SET \n" +
|
||||
" Value = ? \n" +
|
||||
"WHERE XPos = ? AND ZPos = ?";
|
||||
PreparedStatement statement = this.createPreparedStatement(sql);
|
||||
|
||||
int i = 1;
|
||||
statement.setObject(i++, dto.value);
|
||||
|
||||
statement.setObject(i++, dto.id.x);
|
||||
statement.setObject(i++, dto.id.z);
|
||||
|
||||
return statement;
|
||||
}
|
||||
|
||||
}
|
||||
+9
-12
@@ -25,12 +25,12 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
public class TestDataRepo extends AbstractDhRepo<TestDto>
|
||||
public class TestPrimaryKeyRepo extends AbstractDhRepo<Integer, TestSingleKeyDto>
|
||||
{
|
||||
|
||||
public TestDataRepo(String databaseType, String databaseLocation) throws SQLException
|
||||
public TestPrimaryKeyRepo(String databaseType, String databaseLocation) throws SQLException
|
||||
{
|
||||
super(databaseType, databaseLocation, TestDto.class);
|
||||
super(databaseType, databaseLocation, TestSingleKeyDto.class);
|
||||
|
||||
// note: this should only ever be done with the test repo.
|
||||
// All long term tables should be created using a sql Script.
|
||||
@@ -49,26 +49,23 @@ public class TestDataRepo extends AbstractDhRepo<TestDto>
|
||||
|
||||
@Override
|
||||
public String getTableName() { return "Test"; }
|
||||
@Override
|
||||
public String getPrimaryKeyName() { return "Id"; }
|
||||
@Override
|
||||
public String createWhereStatement(Integer keyString) { return "Id = '"+keyString+"'"; }
|
||||
|
||||
|
||||
@Override
|
||||
public TestDto convertDictionaryToDto(Map<String, Object> objectMap) throws ClassCastException
|
||||
public TestSingleKeyDto convertDictionaryToDto(Map<String, Object> objectMap) throws ClassCastException
|
||||
{
|
||||
int id = (int) objectMap.get("Id");
|
||||
String value = (String) objectMap.get("Value");
|
||||
long longValue = (Long) objectMap.get("LongValue");
|
||||
byte byteValue = (Byte) objectMap.get("ByteValue");
|
||||
|
||||
return new TestDto(id, value, longValue, byteValue);
|
||||
return new TestSingleKeyDto(id, value, longValue, byteValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createSelectPrimaryKeySql(String primaryKey) { return "SELECT * FROM "+this.getTableName()+" WHERE Id = '"+primaryKey+"'"; }
|
||||
|
||||
@Override
|
||||
public PreparedStatement createInsertStatement(TestDto dto) throws SQLException
|
||||
public PreparedStatement createInsertStatement(TestSingleKeyDto dto) throws SQLException
|
||||
{
|
||||
String sql =
|
||||
"INSERT INTO "+this.getTableName()+" \n" +
|
||||
@@ -87,7 +84,7 @@ public class TestDataRepo extends AbstractDhRepo<TestDto>
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement createUpdateStatement(TestDto dto) throws SQLException
|
||||
public PreparedStatement createUpdateStatement(TestSingleKeyDto dto) throws SQLException
|
||||
{
|
||||
String sql =
|
||||
"UPDATE "+this.getTableName()+" \n" +
|
||||
+7
-5
@@ -20,16 +20,18 @@
|
||||
package testItems.sql;
|
||||
|
||||
import com.seibel.distanthorizons.core.sql.IBaseDTO;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class TestDto implements IBaseDTO
|
||||
public class TestSingleKeyDto implements IBaseDTO<Integer>
|
||||
{
|
||||
public int id;
|
||||
public String value;
|
||||
public long longValue;
|
||||
public byte byteValue;
|
||||
|
||||
public TestDto(int id, String value, long longValue, byte byteValue)
|
||||
|
||||
|
||||
|
||||
public TestSingleKeyDto(int id, String value, long longValue, byte byteValue)
|
||||
{
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
@@ -38,7 +40,7 @@ public class TestDto implements IBaseDTO
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryKeyString() { return this.id+""; }
|
||||
public Integer getKey() { return this.id; }
|
||||
|
||||
|
||||
@Override
|
||||
@@ -50,7 +52,7 @@ public class TestDto implements IBaseDTO
|
||||
}
|
||||
else
|
||||
{
|
||||
TestDto otherDto = (TestDto) other;
|
||||
TestSingleKeyDto otherDto = (TestSingleKeyDto) other;
|
||||
|
||||
return otherDto.id == this.id
|
||||
&& otherDto.value.equals(this.value)
|
||||
@@ -19,11 +19,15 @@
|
||||
|
||||
package tests;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.sql.DatabaseUpdater;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import testItems.sql.TestDataRepo;
|
||||
import testItems.sql.TestDto;
|
||||
import testItems.sql.TestCompoundKeyRepo;
|
||||
import testItems.sql.TestCompoundKeyDto;
|
||||
import testItems.sql.TestPrimaryKeyRepo;
|
||||
import testItems.sql.TestSingleKeyDto;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
@@ -35,28 +39,29 @@ import java.util.Map;
|
||||
public class DhRepoSqliteTest
|
||||
{
|
||||
public static String DATABASE_TYPE = "jdbc:sqlite";
|
||||
public static String DB_FILE_NAME = "test.sqlite";
|
||||
|
||||
|
||||
@Test
|
||||
public void testFileSqlite()
|
||||
|
||||
@BeforeClass
|
||||
public static void testSetup()
|
||||
{
|
||||
String dbFileName = "test.sqlite";
|
||||
|
||||
|
||||
File dbFile = new File(dbFileName);
|
||||
File dbFile = new File(DB_FILE_NAME);
|
||||
if (dbFile.exists())
|
||||
{
|
||||
Assert.assertTrue("unable to delete old test DB File.", dbFile.delete());
|
||||
}
|
||||
|
||||
|
||||
TestDataRepo testDataRepo = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testPrimaryKeyRepo()
|
||||
{
|
||||
TestPrimaryKeyRepo primaryKeyRepo = null;
|
||||
try
|
||||
{
|
||||
testDataRepo = new TestDataRepo(DATABASE_TYPE, dbFileName);
|
||||
|
||||
dbFile = new File(dbFileName);
|
||||
Assert.assertTrue("dbFile not created", dbFile.exists());
|
||||
primaryKeyRepo = new TestPrimaryKeyRepo(DATABASE_TYPE, DB_FILE_NAME);
|
||||
|
||||
|
||||
|
||||
@@ -65,15 +70,15 @@ public class DhRepoSqliteTest
|
||||
//==========================//
|
||||
|
||||
// check that the schema table is created
|
||||
Map<String, Object> autoUpdateTablePresentResult = testDataRepo.queryDictionaryFirst("SELECT name FROM sqlite_master WHERE type='table' AND name='"+DatabaseUpdater.SCHEMA_TABLE_NAME+"';");
|
||||
Map<String, Object> autoUpdateTablePresentResult = primaryKeyRepo.queryDictionaryFirst("SELECT name FROM sqlite_master WHERE type='table' AND name='"+DatabaseUpdater.SCHEMA_TABLE_NAME+"';");
|
||||
if (autoUpdateTablePresentResult == null || autoUpdateTablePresentResult.get("name") == null)
|
||||
{
|
||||
Assert.fail("Auto DB update table missing.");
|
||||
}
|
||||
|
||||
// check that the update scripts aren't run multiple times
|
||||
TestDataRepo altDataRepoOne = new TestDataRepo(DATABASE_TYPE, dbFileName);
|
||||
TestDataRepo altDataRepoTwo = new TestDataRepo(DATABASE_TYPE, dbFileName);
|
||||
TestPrimaryKeyRepo altDataRepoOne = new TestPrimaryKeyRepo(DATABASE_TYPE, DB_FILE_NAME);
|
||||
TestPrimaryKeyRepo altDataRepoTwo = new TestPrimaryKeyRepo(DATABASE_TYPE, DB_FILE_NAME);
|
||||
|
||||
|
||||
|
||||
@@ -82,39 +87,39 @@ public class DhRepoSqliteTest
|
||||
//===========//
|
||||
|
||||
// insert
|
||||
TestDto insertDto = new TestDto(0, "a", 0L, (byte) 0);
|
||||
testDataRepo.save(insertDto);
|
||||
TestSingleKeyDto insertDto = new TestSingleKeyDto(0, "a", 0L, (byte) 0);
|
||||
primaryKeyRepo.save(insertDto);
|
||||
|
||||
// get
|
||||
TestDto getDto = testDataRepo.getByPrimaryKey("0");
|
||||
TestSingleKeyDto getDto = primaryKeyRepo.getByKey(0);
|
||||
Assert.assertNotNull("get failed, null returned", getDto);
|
||||
Assert.assertEquals("get/insert failed, not equal", insertDto, getDto);
|
||||
|
||||
// exists - DTO present
|
||||
Assert.assertTrue("DTO exists failed", testDataRepo.exists(insertDto));
|
||||
Assert.assertTrue("DTO exists failed", testDataRepo.existsWithPrimaryKey(insertDto.getPrimaryKeyString()));
|
||||
Assert.assertTrue("DTO exists failed", primaryKeyRepo.exists(insertDto));
|
||||
Assert.assertTrue("DTO exists failed", primaryKeyRepo.existsWithKey(insertDto.getKey()));
|
||||
|
||||
|
||||
// update
|
||||
TestDto updateMetaFile = new TestDto(0, "b", Long.MAX_VALUE, Byte.MAX_VALUE);
|
||||
testDataRepo.save(updateMetaFile);
|
||||
TestSingleKeyDto updateMetaFile = new TestSingleKeyDto(0, "b", Long.MAX_VALUE, Byte.MAX_VALUE);
|
||||
primaryKeyRepo.save(updateMetaFile);
|
||||
|
||||
// get
|
||||
getDto = testDataRepo.getByPrimaryKey("0");
|
||||
getDto = primaryKeyRepo.getByKey(0);
|
||||
Assert.assertNotNull("get failed, null returned", getDto);
|
||||
Assert.assertEquals("get/insert failed, not equal", updateMetaFile, getDto);
|
||||
|
||||
|
||||
// delete
|
||||
testDataRepo.delete(updateMetaFile);
|
||||
primaryKeyRepo.delete(updateMetaFile);
|
||||
|
||||
// get
|
||||
getDto = testDataRepo.getByPrimaryKey("0");
|
||||
getDto = primaryKeyRepo.getByKey(0);
|
||||
Assert.assertNull("delete failed, not null returned", getDto);
|
||||
|
||||
// exists - DTO absent
|
||||
Assert.assertFalse("DTO exists failed", testDataRepo.exists(insertDto));
|
||||
Assert.assertFalse("DTO exists failed", testDataRepo.existsWithPrimaryKey(insertDto.getPrimaryKeyString()));
|
||||
Assert.assertFalse("DTO exists failed", primaryKeyRepo.exists(insertDto));
|
||||
Assert.assertFalse("DTO exists failed", primaryKeyRepo.existsWithKey(insertDto.getKey()));
|
||||
|
||||
}
|
||||
catch (SQLException e)
|
||||
@@ -123,11 +128,75 @@ public class DhRepoSqliteTest
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (testDataRepo != null)
|
||||
if (primaryKeyRepo != null)
|
||||
{
|
||||
testDataRepo.close();
|
||||
primaryKeyRepo.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompoundKeyRepo()
|
||||
{
|
||||
TestCompoundKeyRepo compoundKeyRepo = null;
|
||||
try
|
||||
{
|
||||
compoundKeyRepo = new TestCompoundKeyRepo(DATABASE_TYPE, DB_FILE_NAME);
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// DTO tests //
|
||||
//===========//
|
||||
|
||||
// insert
|
||||
TestCompoundKeyDto insertDto = new TestCompoundKeyDto(new DhChunkPos(1, 2), "a");
|
||||
compoundKeyRepo.save(insertDto);
|
||||
|
||||
// get
|
||||
TestCompoundKeyDto getDto = compoundKeyRepo.getByKey(new DhChunkPos(1, 2));
|
||||
Assert.assertNotNull("get failed, null returned", getDto);
|
||||
Assert.assertEquals("get/insert failed, not equal", insertDto, getDto);
|
||||
|
||||
// exists - DTO present
|
||||
Assert.assertTrue("DTO exists failed", compoundKeyRepo.exists(insertDto));
|
||||
Assert.assertTrue("DTO exists failed", compoundKeyRepo.existsWithKey(insertDto.getKey()));
|
||||
|
||||
|
||||
// update
|
||||
TestCompoundKeyDto updateMetaFile = new TestCompoundKeyDto(new DhChunkPos(1, 2), "b");
|
||||
compoundKeyRepo.save(updateMetaFile);
|
||||
|
||||
// get
|
||||
getDto = compoundKeyRepo.getByKey(new DhChunkPos(1, 2));
|
||||
Assert.assertNotNull("get failed, null returned", getDto);
|
||||
Assert.assertEquals("get/insert failed, not equal", updateMetaFile, getDto);
|
||||
|
||||
|
||||
// delete
|
||||
compoundKeyRepo.delete(updateMetaFile);
|
||||
|
||||
// get
|
||||
getDto = compoundKeyRepo.getByKey(new DhChunkPos(1, 2));
|
||||
Assert.assertNull("delete failed, not null returned", getDto);
|
||||
|
||||
// exists - DTO absent
|
||||
Assert.assertFalse("DTO exists failed", compoundKeyRepo.exists(insertDto));
|
||||
Assert.assertFalse("DTO exists failed", compoundKeyRepo.existsWithKey(insertDto.getKey()));
|
||||
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (compoundKeyRepo != null)
|
||||
{
|
||||
compoundKeyRepo.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user