added db handler
~6h work
This commit is contained in:
parent
fad46df96c
commit
ad335a545a
@ -1,6 +1,5 @@
|
||||
package at.nanopenguin.mtcg.application.service;
|
||||
|
||||
import at.nanopenguin.mtcg.application.service.schemas.UserCredentials;
|
||||
import at.nanopenguin.mtcg.http.HttpMethod;
|
||||
import at.nanopenguin.mtcg.http.HttpRequest;
|
||||
import at.nanopenguin.mtcg.http.HttpStatus;
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
package at.nanopenguin.mtcg.application.service.schemas;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize
|
||||
@JsonDeserialize
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record Card(String id, String name, Float damage) {
|
||||
}
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
package at.nanopenguin.mtcg.application.service.schemas;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize
|
||||
@JsonDeserialize
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record TradingDeal(String id, String cardToTrade, String type, Float minimumDamage) {
|
||||
}
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
package at.nanopenguin.mtcg.application.service.schemas;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize
|
||||
@JsonDeserialize
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record UserCredentials(String username, String password) {
|
||||
}
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
package at.nanopenguin.mtcg.application.service.schemas;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize
|
||||
@JsonDeserialize
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record UserData(String name, String bio, String image) {
|
||||
}
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
package at.nanopenguin.mtcg.application.service.schemas;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize
|
||||
@JsonDeserialize
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public record UserStats(String name, Integer elo, Integer wins, Integer losses) {
|
||||
}
|
||||
|
||||
138
src/at/nanopenguin/mtcg/db/DbQuery.java
Normal file
138
src/at/nanopenguin/mtcg/db/DbQuery.java
Normal file
@ -0,0 +1,138 @@
|
||||
package at.nanopenguin.mtcg.db;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Singular;
|
||||
import lombok.val;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Builder
|
||||
public final class DbQuery {
|
||||
private static final String connectionString = "jdbc:postgres://localhost:5432/mydb?user=postgres&password=postgres";
|
||||
|
||||
@NonNull
|
||||
private final SqlCommand command;
|
||||
@NonNull
|
||||
private final Table table;
|
||||
@Singular
|
||||
private List<String> columns;
|
||||
@Singular
|
||||
private SortedMap<String, Object> parameters;
|
||||
@Singular
|
||||
private SortedMap<String, Object> conditions;
|
||||
|
||||
public static class DbQueryBuilder {
|
||||
public ResultSet executeQuery() throws SQLException {
|
||||
DbQuery dbQuery = this.build();
|
||||
if (dbQuery.command != SqlCommand.SELECT) throw new SQLException();
|
||||
return dbQuery.read();
|
||||
}
|
||||
|
||||
public int executeUpdate() throws SQLException {
|
||||
DbQuery dbQuery = this.build();
|
||||
return switch (dbQuery.command) {
|
||||
case INSERT -> dbQuery.create();
|
||||
case UPDATE -> dbQuery.update();
|
||||
case DELETE -> dbQuery.delete();
|
||||
default -> throw new SQLException();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static Connection connect() throws SQLException {
|
||||
return DriverManager.getConnection(connectionString);
|
||||
}
|
||||
|
||||
private String buildParameterizedString(@NonNull SortedMap<String, Object> parameters) {
|
||||
if (!parameters.isEmpty()) {
|
||||
return String.join(" = ?, ", parameters.keySet()) + " = ?";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private int create() throws SQLException {
|
||||
if (this.parameters.isEmpty()) throw new SQLException("No parameters provided for INSERT statement.");
|
||||
|
||||
try (Connection connection = connect()) {
|
||||
String columns = this.parameters.keySet().stream()
|
||||
.filter(columnName -> columnName.matches("[a-zA-Z0-9_]+"))
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
String sql = String.format("INSERT INTO %s (%s) VALUES (%s);", table.table, columns, String.join(", ", Collections.nCopies(this.parameters.size(), "?")));
|
||||
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
|
||||
int i = 1;
|
||||
for (val entry : this.parameters.entrySet()) {
|
||||
preparedStatement.setObject(i++, entry.getValue());
|
||||
}
|
||||
|
||||
return preparedStatement.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ResultSet read() throws SQLException {
|
||||
try (Connection connection = connect()) {
|
||||
StringJoiner columnJoiner = new StringJoiner(", ");
|
||||
if (this.columns.isEmpty()) {
|
||||
columnJoiner.add("*");
|
||||
}
|
||||
this.columns.forEach(columnJoiner::add);
|
||||
|
||||
String sql = String.format("SELECT %s FROM %s%s;", columnJoiner, table.table,
|
||||
this.conditions.isEmpty() ? "" : " WHERE (" + this.buildParameterizedString(this.conditions) + ")");
|
||||
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
|
||||
int i = 1;
|
||||
for (val entry : this.conditions.entrySet()) {
|
||||
preparedStatement.setObject(i++, entry.getValue());
|
||||
}
|
||||
|
||||
return preparedStatement.executeQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int update() throws SQLException {
|
||||
if (this.parameters.isEmpty()) throw new SQLException();
|
||||
if (this.conditions.isEmpty()) throw new SQLException();
|
||||
|
||||
try (Connection connection = connect()) {
|
||||
String sql = String.format("UPDATE %s SET %s WHERE (%s);", table.table,
|
||||
this.buildParameterizedString(this.parameters),
|
||||
this.buildParameterizedString(this.conditions));
|
||||
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
||||
|
||||
int i = 1;
|
||||
for (val entry : this.parameters.entrySet()) {
|
||||
preparedStatement.setObject(i++, entry.getValue());
|
||||
}
|
||||
for (val entry : this.conditions.entrySet()) {
|
||||
preparedStatement.setObject(i++, entry.getValue());
|
||||
}
|
||||
|
||||
return preparedStatement.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private int delete() throws SQLException {
|
||||
if (this.conditions.isEmpty()) throw new SQLException();
|
||||
try (Connection connection = connect()) {
|
||||
|
||||
String sql = String.format("DELETE FROM %s WHERE (%s);", table.table, this.buildParameterizedString(this.conditions));
|
||||
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
|
||||
int i = 1;
|
||||
for (val entry : this.conditions.entrySet()) {
|
||||
preparedStatement.setObject(i++, entry.getValue());
|
||||
}
|
||||
|
||||
return preparedStatement.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
src/at/nanopenguin/mtcg/db/SqlCommand.java
Normal file
8
src/at/nanopenguin/mtcg/db/SqlCommand.java
Normal file
@ -0,0 +1,8 @@
|
||||
package at.nanopenguin.mtcg.db;
|
||||
|
||||
public enum SqlCommand {
|
||||
INSERT,
|
||||
SELECT,
|
||||
UPDATE,
|
||||
DELETE,
|
||||
}
|
||||
10
src/at/nanopenguin/mtcg/db/Table.java
Normal file
10
src/at/nanopenguin/mtcg/db/Table.java
Normal file
@ -0,0 +1,10 @@
|
||||
package at.nanopenguin.mtcg.db;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum Table {
|
||||
USERS("users");
|
||||
|
||||
public final String table;
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
package at.nanopenguin.mtcg.http;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum HttpStatus {
|
||||
OK(200, "OK"),
|
||||
CREATED(201, "Created"),
|
||||
@ -15,9 +18,4 @@ public enum HttpStatus {
|
||||
|
||||
public final int statusCode;
|
||||
public final String statusMessage;
|
||||
|
||||
HttpStatus(int code, String message) {
|
||||
this.statusCode = code;
|
||||
this.statusMessage = message;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package at.nanopenguin.mtcg.http;
|
||||
|
||||
import at.nanopenguin.mtcg.application.service.Service;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -9,15 +10,11 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class RequestHandler implements Runnable {
|
||||
private final Socket serviceSocket;
|
||||
private final Router router;
|
||||
|
||||
public RequestHandler(Socket serviceSocket, Router router) {
|
||||
this.serviceSocket = serviceSocket;
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
@ -1,22 +1,19 @@
|
||||
package at.nanopenguin.mtcg.http;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class Server {
|
||||
private final int port; // 16-bit unsigned, not enforced
|
||||
private final int threads;
|
||||
private final Router router;
|
||||
|
||||
public Server(int port, int threads, Router router) {
|
||||
this.port = port;
|
||||
this.threads = threads;
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
try (ServerSocket listener = new ServerSocket(this.port)) {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user