-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add untested SQLite database table initialization
- Loading branch information
1 parent
d0681fd
commit 6e62267
Showing
4 changed files
with
172 additions
and
5 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
52 changes: 50 additions & 2 deletions
52
src/main/java/com/cjburkey/claimchunk/data/journaled/SqLiteWrapper.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 |
---|---|---|
@@ -1,14 +1,62 @@ | ||
package com.cjburkey.claimchunk.data.journaled; | ||
|
||
import lombok.Getter; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.sql.Connection; | ||
import java.sql.DriverManager; | ||
import java.sql.SQLException; | ||
|
||
public class SqLiteWrapper { | ||
|
||
private final File dbFile; | ||
private Connection connection; | ||
|
||
public SqLiteWrapper(File dbFile) { | ||
public SqLiteWrapper(@NotNull File dbFile) { | ||
this.dbFile = dbFile; | ||
|
||
try { | ||
TableMigrationManager.go(this::connectionOrDie); | ||
} catch (SQLException e) { | ||
throw new RuntimeException("Failed to initialize tables!", e); | ||
} | ||
} | ||
|
||
public @NotNull Connection ensureConnection() throws RuntimeException, SQLException { | ||
if (connection != null && !connection.isClosed()) { | ||
return connection; | ||
} | ||
try { | ||
if (!dbFile.exists()) { | ||
//noinspection ResultOfMethodCallIgnored | ||
dbFile.createNewFile(); | ||
} | ||
|
||
Class.forName("org.sqlite.JDBC"); | ||
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile); | ||
return connection; | ||
} catch (IOException e) { | ||
throw new RuntimeException("Failed to create new file " + dbFile, e); | ||
} catch (ClassNotFoundException e) { | ||
throw new RuntimeException( | ||
"Cannot find SQLite JDBC class? Not sure how this can happen. Please submit an" | ||
+ " issue on GitHub", | ||
e); | ||
} | ||
} | ||
|
||
public @NotNull Connection connectionOrDie() { | ||
try { | ||
return ensureConnection(); | ||
} catch (SQLException e) { | ||
throw new RuntimeException("SQL Exception", e); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public @Nullable Connection getOpenConnection() { | ||
return connection; | ||
} | ||
} |
117 changes: 117 additions & 0 deletions
117
src/main/java/com/cjburkey/claimchunk/data/journaled/TableMigrationManager.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,117 @@ | ||
package com.cjburkey.claimchunk.data.journaled; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.sql.Connection; | ||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.util.function.Supplier; | ||
|
||
/** This class is responsible for creating, loading, and upgrading the database file. */ | ||
public class TableMigrationManager { | ||
|
||
public static void go(Supplier<Connection> connectionSupplier) | ||
throws RuntimeException, SQLException { | ||
try (Connection connection = ensureConnection(connectionSupplier)) { | ||
// Make tables if they don't exist | ||
initializeTables(connection); | ||
|
||
// Call migration check methods here. | ||
} | ||
} | ||
|
||
private static @NotNull Connection ensureConnection(Supplier<Connection> connectionSupplier) | ||
throws RuntimeException { | ||
Connection connection = connectionSupplier.get(); | ||
try { | ||
if (connection != null && !connection.isClosed()) { | ||
return connection; | ||
} else { | ||
throw new RuntimeException("Connection provided was not valid."); | ||
} | ||
} catch (SQLException e) { | ||
throw new RuntimeException( | ||
"Failed to create connection to ClaimChunk SQLite database file", e); | ||
} | ||
} | ||
|
||
private static void initializeTables(Connection connection) throws SQLException { | ||
tryCreateTables(connection); | ||
|
||
// Call migration methods here. | ||
// Add table column exist checks inside each method to make this method | ||
// cleaner. | ||
} | ||
|
||
// TODO: CHECK THESE WORK! | ||
private static void tryCreateTables(Connection connection) throws SQLException { | ||
// Player data table | ||
connection | ||
.prepareCall( | ||
""" | ||
CREATE TABLE IF NOT EXISTS player_data ( | ||
player_id INTEGER PRIMARY KEY, | ||
player_uuid VARCHAR(36) UNIQUE NOT NULL, | ||
last_ign VARCHAR(32) NOT NULL, | ||
chunk_name VARCHAR(32), | ||
last_online_time INTEGER NOT NULL, | ||
alerts_enabled INTEGER NOT NULL, | ||
extra_max_claims INTEGER NOT NULL, | ||
) STRICT | ||
""") | ||
.execute(); | ||
|
||
// Chunk data table | ||
connection | ||
.prepareCall( | ||
""" | ||
CREATE TABLE IF NOT EXISTS chunk_data ( | ||
chunk_id INTEGER PRIMARY KEY, | ||
chunk_world VARCHAR(32) NOT NULL, | ||
chunk_x INTEGER NOT NULL, | ||
chunk_z INTEGER NOT NULL, | ||
owner_id INTEGER NOT NULL, | ||
FOREIGN KEY(owner_id) REFERENCES player_data(player_id) | ||
) STRICT | ||
""") | ||
.execute(); | ||
|
||
// Granular chunk player permission table | ||
connection | ||
.prepareCall( | ||
""" | ||
CREATE TABLE IF NOT EXISTS chunk_permissions ( | ||
chunk_id INTEGER NOT NULL, | ||
other_player_id INTEGER NOT NULL, | ||
permission_bits INTEGER NOT NULL, | ||
FOREIGN KEY(chunk_id) REFERENCES chunk_data(chunk_id) | ||
FOREIGN KEY(other_player_id) REFERENCES player_data(player_id) | ||
) STRICT | ||
""") | ||
.execute(); | ||
} | ||
|
||
// Use this method to determine if a column exists in a table to perform migrations | ||
// TODO: MAYBE CHECK IF THIS WORKS | ||
@SuppressWarnings("unused") | ||
private static boolean columnExists(Connection connection, String tableName, String columnName) | ||
throws SQLException { | ||
PreparedStatement statement = | ||
connection.prepareCall( | ||
""" | ||
SELECT COUNT(*) FROM pragma_table_info(?) WHERE name=? | ||
"""); | ||
statement.setString(1, tableName); | ||
statement.setString(2, columnName); | ||
ResultSet resultSet = statement.executeQuery(); | ||
int count = resultSet.getInt(1); | ||
return count > 0; | ||
} | ||
|
||
// Whenever a column is added or moved or transformed or whatever, add a | ||
// method here to perform that transformation and call it in initialize_tables. | ||
|
||
} |