-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
316 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ checkouts | |
|
||
# OpenBVE images | ||
*.bmp | ||
/test.sqlite | ||
|
||
# manifold | ||
build.properties | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,34 @@ | ||
package cn.zbx1425.worldcomment; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import cn.zbx1425.worldcomment.data.Database; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.sql.SQLException; | ||
|
||
public class Main { | ||
|
||
public static final String MOD_ID = "worldcomment"; | ||
|
||
public static final Logger LOGGER = LogManager.getLogger("Subnoteica"); | ||
public static final Logger LOGGER = LoggerFactory.getLogger("Subnoteica"); | ||
|
||
public static void init() { | ||
|
||
ServerPlatform.registerServerStartingEvent(server -> { | ||
try { | ||
Database.loadDatabase(server); | ||
} catch (SQLException e) { | ||
LOGGER.error("Failed to open database", e); | ||
throw new RuntimeException(e); | ||
} | ||
}); | ||
ServerPlatform.registerServerStoppingEvent(server -> { | ||
try { | ||
Database.INSTANCE.close(); | ||
} catch (SQLException e) { | ||
LOGGER.error("Failed to close database", e); | ||
throw new RuntimeException(e); | ||
} | ||
}); | ||
} | ||
|
||
} |
77 changes: 77 additions & 0 deletions
77
common/src/main/java/cn/zbx1425/worldcomment/data/CommentEntry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package cn.zbx1425.worldcomment.data; | ||
|
||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.core.UUIDUtil; | ||
import net.minecraft.resources.ResourceLocation; | ||
import net.minecraft.world.level.ChunkPos; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.sql.Types; | ||
import java.util.UUID; | ||
|
||
public class CommentEntry { | ||
|
||
public int id; | ||
public long timestamp; | ||
public boolean deleted; | ||
public ResourceLocation dimension; | ||
public ChunkPos region; | ||
public BlockPos location; | ||
public UUID initiator; | ||
public String initiatorName; | ||
public int messageType; | ||
public String message; | ||
public String imageUrl; | ||
|
||
public CommentEntry(CommentTable table, ResultSet result) throws SQLException { | ||
int iota = 0; | ||
id = result.getInt(++iota); | ||
timestamp = result.getLong(++iota); | ||
deleted = result.getBoolean(++iota); | ||
dimension = table.db.dimensions.getDimensionById(result.getInt(++iota)); | ||
region = new ChunkPos(result.getLong(++iota)); | ||
location = new BlockPos(result.getInt(++iota), result.getInt(++iota), result.getInt(++iota)); | ||
initiator = uuidFromByteArray(result.getBytes(++iota)); | ||
initiatorName = result.getString(++iota); | ||
messageType = result.getInt(++iota); | ||
message = result.getString(++iota); | ||
imageUrl = result.getString(++iota); | ||
} | ||
|
||
private static UUID uuidFromByteArray(byte[] bytes) { | ||
ByteBuffer bb = ByteBuffer.wrap(bytes); | ||
return new UUID(bb.getLong(), bb.getLong()); | ||
} | ||
|
||
public void insertOrUpdate(CommentTable table) throws SQLException { | ||
table.db.execute(""" | ||
INSERT OR REPLACE INTO comments ( | ||
id, timestamp, deleted, level, region, locationX, locationY, locationZ, initiator, initiatorName, messageType, message, imageUrl | ||
) VALUES ( | ||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? | ||
); | ||
""", params -> { | ||
int iota = 0; | ||
if (id == 0) { | ||
params.setNull(++iota, Types.INTEGER); | ||
} else { | ||
params.setInt(++iota, id); | ||
} | ||
params.setLong(++iota, timestamp); | ||
params.setBoolean(++iota, deleted); | ||
params.setInt(++iota, table.db.dimensions.getDimensionId(dimension)); | ||
params.setLong(++iota, region.toLong()); | ||
params.setInt(++iota, location.getX()); | ||
params.setInt(++iota, location.getY()); | ||
params.setInt(++iota, location.getZ()); | ||
params.setBytes(++iota, UUIDUtil.uuidToByteArray(initiator)); | ||
params.setString(++iota, initiatorName); | ||
params.setInt(++iota, messageType); | ||
params.setString(++iota, message); | ||
params.setString(++iota, imageUrl); | ||
}); | ||
} | ||
|
||
} |
51 changes: 51 additions & 0 deletions
51
common/src/main/java/cn/zbx1425/worldcomment/data/CommentTable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package cn.zbx1425.worldcomment.data; | ||
|
||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
|
||
public class CommentTable { | ||
|
||
public final Database db; | ||
public int maxId; | ||
|
||
public CommentTable(Database db) { | ||
this.db = db; | ||
} | ||
|
||
public void init() throws SQLException { | ||
db.execute(""" | ||
CREATE TABLE IF NOT EXISTS comments ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
timestamp INTEGER, | ||
deleted INTEGER, | ||
level INTEGER, | ||
region INTEGER, | ||
locationX INTEGER, | ||
locationY INTEGER, | ||
locationZ INTEGER, | ||
initiator BLOB, | ||
initiatorName TEXT, | ||
messageType INTEGER, | ||
message TEXT, | ||
imageUrl TEXT | ||
); | ||
CREATE INDEX IF NOT EXISTS regionIndex ON comments ( | ||
level, | ||
region | ||
); | ||
CREATE INDEX IF NOT EXISTS timestampIndex ON comments ( | ||
timestamp | ||
); | ||
"""); | ||
} | ||
|
||
public void fetchMaxId() throws SQLException { | ||
try (ResultSet result = db.executeQuery("SELECT id FROM comments ORDER BY id DESC LIMIT 1;")) { | ||
if (!result.next()) { | ||
maxId = 0; | ||
} else { | ||
maxId = result.getInt(1); | ||
} | ||
} | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
common/src/main/java/cn/zbx1425/worldcomment/data/Database.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package cn.zbx1425.worldcomment.data; | ||
|
||
import net.minecraft.server.MinecraftServer; | ||
import net.minecraft.world.level.storage.LevelResource; | ||
|
||
import java.nio.file.Path; | ||
import java.sql.*; | ||
import java.util.HashMap; | ||
import java.util.function.Consumer; | ||
|
||
public class Database { | ||
|
||
public static Database INSTANCE; | ||
|
||
private final Connection dbConn; | ||
|
||
public final CommentTable comments; | ||
|
||
public final DimensionTable dimensions; | ||
|
||
public Database(Path dbPath) throws SQLException { | ||
dbConn = DriverManager.getConnection("jdbc:sqlite:" + dbPath); | ||
comments = new CommentTable(this); | ||
dimensions = new DimensionTable(this); | ||
init(); | ||
} | ||
|
||
public static void loadDatabase(MinecraftServer server) throws SQLException { | ||
INSTANCE = new Database( | ||
Path.of(server.getWorldPath(LevelResource.ROOT).toString(), "world-comment.db") | ||
); | ||
} | ||
|
||
public void close() throws SQLException { | ||
for (PreparedStatement stmt : preparedStatements.values()) { | ||
stmt.close(); | ||
} | ||
preparedStatements.clear(); | ||
dbConn.close(); | ||
} | ||
|
||
private void init() throws SQLException { | ||
comments.init(); | ||
dimensions.init(); | ||
} | ||
|
||
private final HashMap<String, PreparedStatement> preparedStatements = new HashMap<>(); | ||
|
||
public void execute(String command) throws SQLException { | ||
prepareStatement(command).execute(); | ||
} | ||
|
||
public void execute(String command, StatementConsumer params) throws SQLException { | ||
PreparedStatement stmt = prepareStatement(command); | ||
params.accept(stmt); | ||
stmt.execute(); | ||
} | ||
|
||
public ResultSet executeQuery(String command) throws SQLException { | ||
return prepareStatement(command).executeQuery(); | ||
} | ||
|
||
public ResultSet executeQuery(String command, StatementConsumer params) throws SQLException { | ||
PreparedStatement stmt = prepareStatement(command); | ||
params.accept(stmt); | ||
return stmt.executeQuery(); | ||
} | ||
|
||
private PreparedStatement prepareStatement(String command) throws SQLException { | ||
PreparedStatement stmt = preparedStatements.get(command); | ||
if (stmt == null) { | ||
stmt = dbConn.prepareStatement(command); | ||
preparedStatements.put(command, stmt); | ||
} | ||
return stmt; | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
common/src/main/java/cn/zbx1425/worldcomment/data/DimensionTable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package cn.zbx1425.worldcomment.data; | ||
|
||
import it.unimi.dsi.fastutil.objects.Object2IntMap; | ||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; | ||
import it.unimi.dsi.fastutil.objects.ObjectArrayList; | ||
import it.unimi.dsi.fastutil.objects.ObjectList; | ||
import net.minecraft.resources.ResourceLocation; | ||
|
||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
|
||
public class DimensionTable { | ||
|
||
public Database db; | ||
|
||
public Object2IntMap<ResourceLocation> dimensionMap = new Object2IntOpenHashMap<>(); | ||
public ObjectList<ResourceLocation> idMap = new ObjectArrayList<>(); | ||
|
||
public DimensionTable(Database db) { | ||
this.db = db; | ||
} | ||
|
||
public void init() throws SQLException { | ||
db.execute(""" | ||
CREATE TABLE IF NOT EXISTS dimensions ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
resourceLocation TEXT | ||
); | ||
"""); | ||
dimensionMap.clear(); | ||
try (ResultSet result = db.executeQuery("SELECT * FROM dimensions;")) { | ||
while (result.next()) { | ||
ResourceLocation name = new ResourceLocation(result.getString(2)); | ||
int id = result.getInt(1); | ||
dimensionMap.put(name, id); | ||
idMap.size(Math.max(idMap.size(), id)); | ||
idMap.set(id - 1, name); | ||
} | ||
} | ||
} | ||
|
||
public int getMaxId() throws SQLException { | ||
try (ResultSet result = db.executeQuery("SELECT id FROM dimensions ORDER BY id DESC LIMIT 1;")) { | ||
if (!result.next()) { | ||
return 0; | ||
} else { | ||
return result.getInt(1); | ||
} | ||
} | ||
} | ||
|
||
public ResourceLocation getDimensionById(int id) { | ||
return idMap.get(id - 1); | ||
} | ||
|
||
public int getDimensionId(ResourceLocation dimension) throws SQLException { | ||
if (!dimensionMap.containsKey(dimension)) { | ||
db.execute("INSERT INTO dimensions (resourceLocation) VALUES (?);", params -> { | ||
params.setString(1, dimension.toString()); | ||
}); | ||
int newId = getMaxId(); | ||
dimensionMap.put(dimension, newId); | ||
idMap.size(Math.max(idMap.size(), newId)); | ||
idMap.set(newId - 1, dimension); | ||
return newId; | ||
} else { | ||
return dimensionMap.getInt(dimension); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
common/src/main/java/cn/zbx1425/worldcomment/data/StatementConsumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package cn.zbx1425.worldcomment.data; | ||
|
||
import java.sql.PreparedStatement; | ||
import java.sql.SQLException; | ||
|
||
@FunctionalInterface | ||
public interface StatementConsumer { | ||
|
||
void accept(PreparedStatement stmt) throws SQLException; | ||
} |