All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.github.dailystruggle.rtp.common.database.options.SQLiteDatabaseAccessor Maven / Gradle / Ivy
package io.github.dailystruggle.rtp.common.database.options;
import io.github.dailystruggle.rtp.common.RTP;
import io.github.dailystruggle.rtp.common.database.DatabaseAccessor;
import io.github.dailystruggle.rtp.common.playerData.TeleportData;
import io.github.dailystruggle.rtp.common.serverSide.substitutions.RTPLocation;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.sql.*;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class SQLiteDatabaseAccessor extends DatabaseAccessor {
private final String url;
public SQLiteDatabaseAccessor(String url) {
this.url = url;
}
@Override
public String name() {
return url;
}
@Override
public @NotNull Connection connect() {
Connection res;
String filePath = url.substring(url.lastIndexOf(":") + 1);
File databaseFile = new File(filePath);
try {
if (!databaseFile.exists()) {
databaseFile.getParentFile().mkdirs();
databaseFile.createNewFile();
}
res = DriverManager.getConnection(url);
} catch (SQLException | IOException e) {
e.printStackTrace();
return null;
}
return res;
}
@Override
public void processQueries(long availableTime) {
if (readQueue.size() == 0 && writeQueue.size() == 0) return;
if (stop.get()) return;
Connection database = connect();
if (database == null) return;
if (stop.get()) {
disconnect(database);
return;
}
long dt;
long start = System.nanoTime();
while (writeQueue.size() > 0) {
if (stop.get()) {
disconnect(database);
return;
}
Map.Entry> writeRequest = writeQueue.poll();
if (writeRequest == null) throw new IllegalStateException("invalid database write request");
if (writeRequest.getValue() == null) throw new IllegalStateException("invalid database write request");
if (writeRequest.getValue().size() == 0) throw new IllegalStateException("invalid database write request");
long localStart = System.nanoTime();
try {
write(database, writeRequest.getKey(), writeRequest.getValue());
} catch (Exception e) {
writeQueue.add(writeRequest);
disconnect(database);
return;
}
long localStop = System.nanoTime();
if (localStop < localStart) localStart = -(Long.MAX_VALUE - localStart);
long diff = localStop - localStart;
if (avgTimeWrite == 0) avgTimeWrite = diff;
else avgTimeWrite = ((avgTimeWrite * 7) / 8) + (diff / 8);
if (localStop < start) start = -(Long.MAX_VALUE - start); //overflow correction
dt = localStop - start;
if (dt + avgTimeWrite > availableTime) break;
}
while (readQueue.size() > 0) {
if (stop.get()) {
disconnect(database);
return;
}
Map.Entry, CompletableFuture>>>> readRequest = readQueue.poll();
if (readRequest == null) throw new IllegalStateException("null database read request");
long localStart = System.nanoTime();
Map.Entry keyObj = readRequest.getValue().getKey();
Map.Entry lookup =
new AbstractMap.SimpleEntry<>(keyObj.getKey().object.toString(), keyObj.getValue().object);
Optional> read;
try {
read = read(database, readRequest.getKey(), lookup);
} catch (Exception e) {
readQueue.add(readRequest);
disconnect(database);
return;
}
readRequest.getValue().getValue().complete(read);
long localStop = System.nanoTime();
if (localStop < localStart) localStart = -(Long.MAX_VALUE - localStart);
long diff = localStop - localStart;
if (avgTimeRead == 0) avgTimeRead = diff;
else avgTimeRead = ((avgTimeRead * 7) / 8) + (diff / 8);
if (localStop < start) start = -(Long.MAX_VALUE - start); //overflow correction
dt = localStop - start;
if (dt + avgTimeRead > availableTime) break;
}
disconnect(database);
}
@Override
public void startup() {
DriverManager.setLoginTimeout(30);
Connection connection = connect();
@NotNull Optional> read = read(connection, "referenceData", new AbstractMap.SimpleEntry<>("UUID", new UUID(0, 0)));
if (!read.isPresent()) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
return;
}
//get full table
String tableName = "teleportData";
String sql = "SELECT * FROM " + tableName;
Statement statement;
try {
statement = connection.createStatement();
try {
statement.execute(sql);
} catch (SQLException e) {
connection.close();
return;
}
ResultSet resultSet;
try {
resultSet = statement.getResultSet();
} catch (SQLException e) {
connection.close();
return;
}
if (resultSet == null) {
connection.close();
return;
}
//each data
while (resultSet.next()) {
String uuidStr = resultSet.getString("UUID");
if (uuidStr == null) continue;
UUID uuid = UUID.fromString(uuidStr);
TeleportData teleportData = new TeleportData();
teleportData.completed = true;
teleportData.time = Long.parseLong(resultSet.getString("time"));
teleportData.selectedLocation = new RTPLocation(
RTP.serverAccessor.getRTPWorld(UUID.fromString(resultSet.getString("selectedWorldId"))),
Integer.parseInt(resultSet.getString("selectedX")),
Integer.parseInt(resultSet.getString("selectedY")),
Integer.parseInt(resultSet.getString("selectedZ"))
);
if (teleportData.selectedLocation.world() == null) continue;
teleportData.originalLocation = new RTPLocation(
RTP.serverAccessor.getRTPWorld(UUID.fromString(resultSet.getString("originalWorldId"))),
Integer.parseInt(resultSet.getString("originalX")),
Integer.parseInt(resultSet.getString("originalY")),
Integer.parseInt(resultSet.getString("originalZ"))
);
if (teleportData.originalLocation.world() == null) continue;
teleportData.cost = Double.parseDouble(resultSet.getString("cost"));
RTP.getInstance().latestTeleportData.put(uuid, teleportData);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (IllegalArgumentException ignored) {
}
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public @NotNull Optional> read(Connection connection, String tableName, Map.Entry lookup) {
String sql = "PRAGMA table_info(" + tableName + ");";
Statement statement;
Map column_info = new HashMap<>();
try {
statement = connection.createStatement();
statement.execute(sql);
ResultSet resultSet = statement.getResultSet();
if (resultSet == null) return Optional.empty();
while (resultSet.next()) {
column_info.put(resultSet.getString("name"), resultSet.getString("type"));
}
} catch (SQLException e) {
return Optional.empty();
}
//validate and add necessary column_info
Map row = new HashMap<>();
sql = "SELECT * FROM " + tableName + " WHERE " + lookup.getKey() + " = " + "\"" + lookup.getValue().toString() + "\"";
try {
statement.execute(sql);
ResultSet resultSet = statement.getResultSet();
for (String key : column_info.keySet()) {
Object object = resultSet.getObject(key);
if (object == null || object.equals("NULL")) continue;
row.put(key, object);
}
return Optional.of(row);
} catch (SQLException ignored) {
}
return Optional.empty();
}
@Override
public void write(Connection connection, String tableName, Map keyValuePairs) {
if (keyValuePairs == null) throw new IllegalStateException();
if (keyValuePairs.size() == 0) throw new IllegalStateException();
//get table info for validation
String sql = "PRAGMA table_info(" + tableName + ");";
Statement statement;
Map columns = new HashMap<>();
try {
statement = connection.createStatement();
statement.execute(sql);
ResultSet resultSet;
try {
resultSet = statement.getResultSet();
} catch (SQLException e) {
StringBuilder create = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " (");
for (Map.Entry entry : keyValuePairs.entrySet()) {
create = create.append("\"").append(entry.getKey().object.toString()).append("\" ").append("TEXT").append(", ");
}
create = create.replace(create.lastIndexOf(","), create.length(), "");
create = create.append(");");
statement.execute(create.toString());
if (keyValuePairs.containsKey(new TableObj("UUID"))) {
String unique = "CREATE UNIQUE INDEX IF NOT EXISTS " + "UID" + " ON " + tableName + " (" + "UUID" + ");";
statement.execute(unique);
}
statement.execute(sql);
resultSet = statement.getResultSet();
}
if (resultSet == null) {
StringBuilder create = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " (");
for (Map.Entry entry : keyValuePairs.entrySet()) {
create = create.append(entry.getKey().object.toString()).append(" ").append("TEXT").append(", ");
}
create = create.replace(create.lastIndexOf(","), create.length(), "");
create = create.append(");");
statement.execute(create.toString());
if (keyValuePairs.containsKey(new TableObj("UUID"))) {
String unique = "CREATE UNIQUE INDEX IF NOT EXISTS " + "UID" + " ON " + tableName + " (" + "UUID" + ");";
statement.execute(unique);
}
statement.execute(sql);
resultSet = statement.getResultSet();
}
Objects.requireNonNull(resultSet);
int i = 0;
while (resultSet.next()) {
i++;
columns.put(resultSet.getString("name"), resultSet.getString("type"));
}
if (i == 0) {
StringBuilder create = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " (");
for (Map.Entry entry : keyValuePairs.entrySet()) {
create = create.append(entry.getKey().object.toString()).append(" ").append("TEXT").append(", ");
}
create = create.replace(create.lastIndexOf(","), create.length(), "");
create = create.append(");");
statement.execute(create.toString());
if (keyValuePairs.containsKey(new TableObj("UUID"))) {
String unique = "CREATE UNIQUE INDEX IF NOT EXISTS " + "UID" + " ON " + tableName + " (" + "UUID" + ");";
statement.execute(unique);
}
statement.execute(sql);
resultSet = statement.getResultSet();
while (resultSet.next()) {
columns.put(resultSet.getString("name"), resultSet.getString("type"));
}
}
} catch (SQLException e) {
throw new IllegalStateException();
}
//validate and add necessary columns
List keys = new ArrayList<>();
List values = new ArrayList<>();
for (Map.Entry entry : keyValuePairs.entrySet()) {
String key = entry.getKey().object.toString();
keys.add(key);
values.add("\"" + entry.getValue().object.toString() + "\"");
if (columns.containsKey(key)) continue;
String typeStr;
switch (entry.getValue().expectedType) {
case INT:
typeStr = "INTEGER";
break;
case REAL:
typeStr = "REAL";
break;
case TEXT:
typeStr = "TEXT";
break;
case BLOB:
typeStr = "BLOB";
break;
default:
throw new IllegalStateException("Unexpected value: " + entry.getKey().expectedType);
}
sql = "ALTER TABLE " + tableName + " ADD " + key + " " + typeStr + ";";
try {
statement.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
StringBuilder builder = new StringBuilder("INSERT OR REPLACE INTO ").append(tableName).append(" (");
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
builder = builder.append("\"").append(key).append("\"");
if (i < keys.size() - 1) builder = builder.append(',');
}
builder = builder.append(") VALUES(");
for (int i = 0; i < values.size(); i++) {
String value = values.get(i);
builder = builder.append(value);
if (i < values.size() - 1) builder = builder.append(',');
}
builder = builder.append(");");
try {
statement.execute(builder.toString());
} catch (SQLException e) {
throw new IllegalStateException();
}
}
@Override
public void disconnect(Connection connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}