Skip to content

Commit

Permalink
Get conversions from old data formats working
Browse files Browse the repository at this point in the history
  • Loading branch information
cjburkey01 committed May 23, 2024
1 parent 9952645 commit 194d7be
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 101 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ OUT
# Gource
my_captions.txt
source_visual.ppm
source_visual.mp4
source_visual.mp4

# Leftover from tests
*.tmp.sqlite3
33 changes: 12 additions & 21 deletions src/main/java/com/cjburkey/claimchunk/ClaimChunk.java
Original file line number Diff line number Diff line change
Expand Up @@ -393,28 +393,22 @@ private boolean initDataHandler() {
: createJsonDataHandler();
}*/
if (dataHandler == null) {
File sqliteFile = new File(getDataFolder(), "/data/claimAndPlayerData.sqlite3");
File dataFolder = new File(getDataFolder(), "/data");
File sqliteFile = new File(dataFolder, "/claimAndPlayerData.sqlite3");
File oldClaimedFile = new File(dataFolder, "/claimedChunks.json");
File oldPlayerFile = new File(dataFolder, "/playerData.json");
boolean oldUseDb = config.getUseDatabase();

IClaimChunkDataHandler oldDataHandler = null;
// UGLY HACK!
// RANKS ARE INITIALIZED AFTER DATA HANDLER, SO IF RANK FILE
// DOESN'T EXIST, WE CAN ASSUME THIS IS A NEW INSTALL RATHER THAN
// CONVERSION!
// AFTER 0.0.25 releases, 0.0.26 doesn't need to include this (but
// WILL require players to install 0.0.25 FIRST to upgrade from
// pre-0.0.25 if, say, 0.0.26 comes out while they're on 0.0.24).
if (!sqliteFile.exists() && new File(getDataFolder(), "/ranks.json").exists()) {
if (!sqliteFile.exists()
&& (oldUseDb || (oldClaimedFile.exists() && oldPlayerFile.exists()))) {
oldDataHandler =
(config.getUseDatabase())
oldUseDb
? ((config.getGroupRequests())
? new BulkMySQLDataHandler<>(
this,
this::createJsonDataHandler,
ignored -> {} /*JsonDataHandler::deleteFiles*/)
this, this::createJsonDataHandler, ignored -> {})
: new MySQLDataHandler<>(
this,
this::createJsonDataHandler,
ignored -> {} /*JsonDataHandler::deleteFiles*/))
this, this::createJsonDataHandler, ignored -> {}))
: createJsonDataHandler();
}

Expand All @@ -425,22 +419,19 @@ private boolean initDataHandler() {
IDataConverter.copyConvert(oldDataHandler, dataHandler);
oldDataHandler.exit();

File dataFolder = new File(getDataFolder(), "/data");
File oldClaimedFile = new File(dataFolder, "/claimedChunks.json");
File oldPlayerFile = new File(dataFolder, "/playerData.json");
if (oldClaimedFile.exists()) {
Files.move(
oldClaimedFile.toPath(),
new File(dataFolder, "/OLD_claimedChunks.json").toPath());
}
if (oldPlayerFile.exists()) {
Files.move(
oldClaimedFile.toPath(),
oldPlayerFile.toPath(),
new File(dataFolder, "/OLD_playerData.json").toPath());
}
} catch (Exception e) {
throw new RuntimeException(
"Failed to initialize previous data handler to convert old data!");
"Failed to initialize previous data handler to convert old data!", e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class ChunkPlayerPermissions {

Expand Down Expand Up @@ -141,4 +142,17 @@ public Map<String, Boolean> toPermissionsMap() {

return chunkPlayerPermissions;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ChunkPlayerPermissions that = (ChunkPlayerPermissions) o;
return permissionFlags == that.permissionFlags;
}

@Override
public int hashCode() {
return Objects.hash(permissionFlags);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ FOREIGN KEY(other_player_uuid) REFERENCES player_data(player_uuid)
}

// Use this method to determine if a column exists in a table to perform migrations
// TODO: MAYBE CHECK IF THIS WORKS
@SuppressWarnings("unused")
public static boolean columnExists(String tableName, String columnName) {
return SqlClosure.sqlExecute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -68,6 +65,7 @@ public void close() {
public void addClaimedChunk(DataChunk chunk) {
SqlClosure.sqlExecute(
connection -> {
// Add the chunk
try (PreparedStatement statement =
connection.prepareStatement(
"""
Expand All @@ -83,8 +81,45 @@ INSERT INTO chunk_data (
int next = setChunkPosParams(statement, 1, chunk.chunk);
statement.setString(next, chunk.player.toString());
statement.execute();
return null;
}

// Add the player permissions
if (!chunk.playerPermissions.isEmpty()) {
String permsInsertPrefixSql =
"""
INSERT INTO chunk_permissions (
chunk_id,
other_player_uuid,
permission_bits
) VALUES
""";

// Better way to do this?
String permsValsSql =
chunk.playerPermissions.entrySet().stream()
.map(
ignored ->
replaceChunkIdQuery(
"""
(%%SELECT_CHUNK_ID_SQL%%, ?, ?)
"""))
.collect(Collectors.joining(","));

try (PreparedStatement statement =
connection.prepareStatement(permsInsertPrefixSql + permsValsSql)) {
int currentParam = 1;
for (Map.Entry<UUID, ChunkPlayerPermissions> entry :
chunk.playerPermissions.entrySet()) {
currentParam =
setChunkPosParams(statement, currentParam, chunk.chunk);
statement.setString(currentParam++, entry.getKey().toString());
statement.setInt(currentParam++, entry.getValue().permissionFlags);
}
statement.execute();
}
}

return null;
});
}

Expand Down Expand Up @@ -327,10 +362,10 @@ public Collection<DataChunk> getAllChunks() {

String otherUuid = resultSet.getString("other_player_uuid");
if (otherUuid != null) {
UUID otherPlayer =
UUID.fromString(otherUuid);
UUID otherPlayer = UUID.fromString(otherUuid);
ChunkPlayerPermissions chunkPerms =
new ChunkPlayerPermissions(resultSet.getInt("permission_bits"));
new ChunkPlayerPermissions(
resultSet.getInt("permission_bits"));

permissions
.computeIfAbsent(pos, ignoredPos -> new HashMap<>())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.cjburkey.claimchunk.data.sqlite;

import com.cjburkey.claimchunk.chunk.DataChunk;

import javax.persistence.*;

@Table(name = "chunk_data")
Expand All @@ -26,11 +24,4 @@ public class SqlDataChunk {

@SuppressWarnings("unused")
public SqlDataChunk() {}

public SqlDataChunk(DataChunk chunk) {
this.world = chunk.chunk.world();
this.x = chunk.chunk.x();
this.z = chunk.chunk.z();
this.uuid = chunk.player.toString();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.cjburkey.claimchunk.data.sqlite;

import com.cjburkey.claimchunk.player.FullPlayerData;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
Expand Down Expand Up @@ -30,13 +28,4 @@ public class SqlDataPlayer {

@SuppressWarnings("unused")
public SqlDataPlayer() {}

public SqlDataPlayer(FullPlayerData player) {
this.uuid = player.player.toString();
this.lastIgn = player.lastIgn;
this.chunkName = player.chunkName;
this.lastOnlineTime = player.lastOnlineTime;
this.alert = player.alert;
this.extraMaxClaims = player.extraMaxClaims;
}
}
55 changes: 39 additions & 16 deletions src/test/java/com/cjburkey/claimchunk/TestSQLPlease.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cjburkey.claimchunk;

import com.cjburkey.claimchunk.chunk.ChunkPlayerPermissions;
import com.cjburkey.claimchunk.chunk.ChunkPos;
import com.cjburkey.claimchunk.chunk.DataChunk;
import com.cjburkey.claimchunk.data.sqlite.SqLiteTableMigrationManager;
Expand All @@ -9,42 +10,64 @@
import org.junit.jupiter.api.Test;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Objects;
import java.util.UUID;

class TestSQLPlease {

@Test
void ensureSomeColumnsExistsAfterInitializing() {
void ensureNoDataLoss() {
File dbFile = randomDbFile();
dbFile.deleteOnExit();

try (SqLiteWrapper ignoredWrapper = new SqLiteWrapper(dbFile, false)) {
// Make sure that instantiating SqLiteWrapper created the tables
assert SqLiteTableMigrationManager.columnExists("player_data", "player_uuid");
assert SqLiteTableMigrationManager.columnExists("chunk_data", "owner_uuid");
assert SqLiteTableMigrationManager.columnExists("chunk_permissions", "permission_bits");
assert !SqLiteTableMigrationManager.columnExists("chunk_hell", "permission_bits");
assert !SqLiteTableMigrationManager.columnExists("player_data", "fake_col");

// Add a random player
UUID plyUuid = UUID.randomUUID();
ignoredWrapper.addPlayer(
new FullPlayerData(
plyUuid, "SomeGuysName", null, System.currentTimeMillis(), true, 0));

// Add a chunk to the player
// Make fake accessors and permissions
UUID accessorUuid1 = UUID.randomUUID();
UUID accessorUuid2 = UUID.randomUUID();
ChunkPlayerPermissions permissions1 = new ChunkPlayerPermissions(0b11111111);
ChunkPlayerPermissions permissions2 = new ChunkPlayerPermissions(0b10101101);

// Add a chunk to the player and give the permissions to the other players
ChunkPos chunkPos = new ChunkPos("world", 10, -3);
ignoredWrapper.addClaimedChunk(
new DataChunk(chunkPos, plyUuid, new HashMap<>(), false));
DataChunk chunkData = new DataChunk(chunkPos, plyUuid, new HashMap<>(), false);
chunkData.playerPermissions.put(accessorUuid1, permissions1);
chunkData.playerPermissions.put(accessorUuid2, permissions2);
ignoredWrapper.addClaimedChunk(chunkData);

// Load the chunk after adding it
Collection<DataChunk> loadedChunks = ignoredWrapper.getAllChunks();
DataChunk loadedChunk = loadedChunks.iterator().next();
Objects.requireNonNull(loadedChunk);

// Make sure the chunk exists when we load from the database
assert ignoredWrapper.getAllChunks().stream()
.anyMatch(
chunk -> chunk.player.equals(plyUuid) && chunk.chunk.equals(chunkPos));
assert loadedChunk.player.equals(plyUuid) && loadedChunk.chunk.equals(chunkPos);
// Make sure the chunk permission got loaded correctly
assert Objects.equals(permissions1, loadedChunk.playerPermissions.get(accessorUuid1));
assert Objects.equals(permissions2, loadedChunk.playerPermissions.get(accessorUuid2));
}
}

//noinspection ResultOfMethodCallIgnored
dbFile.delete();
@Test
void ensureSomeColumnsExistsAfterInitializing() {
File dbFile = randomDbFile();
dbFile.deleteOnExit();

try (SqLiteWrapper ignoredWrapper = new SqLiteWrapper(dbFile, false)) {
// Make sure that instantiating SqLiteWrapper created the tables
assert SqLiteTableMigrationManager.columnExists("player_data", "player_uuid");
assert SqLiteTableMigrationManager.columnExists("chunk_data", "owner_uuid");
assert SqLiteTableMigrationManager.columnExists("chunk_permissions", "permission_bits");
assert !SqLiteTableMigrationManager.columnExists("chunk_hell", "permission_bits");
assert !SqLiteTableMigrationManager.columnExists("player_data", "fake_col");
}
}

protected static File randomDbFile() {
Expand Down

0 comments on commit 194d7be

Please sign in to comment.