Implemented deck configuration
~3h work
This commit is contained in:
parent
2cc7a33c8c
commit
e6bfbe81e3
1
.idea/sqldialects.xml
generated
1
.idea/sqldialects.xml
generated
@ -2,6 +2,5 @@
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/720ef4bc-36c4-4861-8776-49b639600223/console.sql" dialect="PostgreSQL" />
|
||||
<file url="file://$PROJECT_DIR$/setup.sql" dialect="PostgreSQL" />
|
||||
</component>
|
||||
</project>
|
||||
57
src/at/nanopenguin/mtcg/application/UserCards.java
Normal file
57
src/at/nanopenguin/mtcg/application/UserCards.java
Normal file
@ -0,0 +1,57 @@
|
||||
package at.nanopenguin.mtcg.application;
|
||||
|
||||
import at.nanopenguin.mtcg.application.service.schemas.Card;
|
||||
import at.nanopenguin.mtcg.db.DbQuery;
|
||||
import at.nanopenguin.mtcg.db.SqlCommand;
|
||||
import at.nanopenguin.mtcg.db.Table;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.val;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserCards extends User {
|
||||
public static Card[] get(UUID userUuid, boolean deckOnly) throws SQLException {
|
||||
val dbQueryBuilder = DbQuery.builder()
|
||||
.command(SqlCommand.SELECT)
|
||||
.table(Table.CARDS)
|
||||
.column("uuid AS id")
|
||||
.column("name")
|
||||
.column("damage")
|
||||
.condition("owner", userUuid);
|
||||
if (deckOnly) dbQueryBuilder.condition("deck", true);
|
||||
ArrayList<Card> cards = new ArrayList<>();
|
||||
for (val row : dbQueryBuilder.executeQuery()) {
|
||||
cards.add(new ObjectMapper().convertValue(row, Card.class));
|
||||
}
|
||||
return cards.toArray(new Card[0]);
|
||||
}
|
||||
|
||||
public static synchronized boolean setDeck(UUID[] cards, UUID userUuid) throws SQLException {
|
||||
if (DbQuery.builder()
|
||||
.command(SqlCommand.SELECT)
|
||||
.table(Table.CARDS)
|
||||
.condition("owner", userUuid)
|
||||
.condition("uuid", Arrays.asList(cards))
|
||||
.executeQuery().size() != 4)
|
||||
return false;
|
||||
|
||||
DbQuery.builder()
|
||||
.command(SqlCommand.UPDATE)
|
||||
.table(Table.CARDS)
|
||||
.parameter("deck", false)
|
||||
.condition("owner", userUuid)
|
||||
.executeUpdate();
|
||||
|
||||
DbQuery.builder()
|
||||
.command(SqlCommand.UPDATE)
|
||||
.table(Table.CARDS)
|
||||
.parameter("deck", true)
|
||||
.condition("uuid", Arrays.asList(cards))
|
||||
.executeUpdate();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,34 +1,57 @@
|
||||
package at.nanopenguin.mtcg.application.service;
|
||||
|
||||
import at.nanopenguin.mtcg.application.SessionHandler;
|
||||
import at.nanopenguin.mtcg.application.TokenValidity;
|
||||
import at.nanopenguin.mtcg.application.User;
|
||||
import at.nanopenguin.mtcg.application.UserCards;
|
||||
import at.nanopenguin.mtcg.http.HttpMethod;
|
||||
import at.nanopenguin.mtcg.http.HttpRequest;
|
||||
import at.nanopenguin.mtcg.http.HttpStatus;
|
||||
import at.nanopenguin.mtcg.http.Response;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.val;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CardsService implements Service {
|
||||
|
||||
@Override
|
||||
public Response handleRequest(HttpRequest request) throws JsonProcessingException {
|
||||
try {
|
||||
if (request.getPath().split("/")[1].equals("cards") && request.getMethod() == HttpMethod.GET) {
|
||||
return new Response(HttpStatus.NOT_IMPLEMENTED);
|
||||
}
|
||||
public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException {
|
||||
|
||||
if (request.getPath().split("/")[1].equals("deck")) {
|
||||
return switch (request.getMethod()) {
|
||||
case GET -> new Response(HttpStatus.NOT_IMPLEMENTED);
|
||||
case PUT -> new Response(HttpStatus.NOT_IMPLEMENTED); // String[] array = new ObjectMapper().readValue(request.getBody(), String[].class)
|
||||
default -> new Response(HttpStatus.NOT_FOUND);
|
||||
};
|
||||
}
|
||||
UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization"));
|
||||
if (SessionHandler.getInstance().verifyUUID(authToken) != TokenValidity.VALID)
|
||||
return new Response(HttpStatus.UNAUTHORIZED);
|
||||
UUID userUuid = SessionHandler.getInstance().userUuidFromToken(authToken);
|
||||
|
||||
return new Response(HttpStatus.NOT_FOUND);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return new Response(HttpStatus.BAD_REQUEST);
|
||||
if (request.getPath().split("/")[1].equals("cards") && request.getMethod() == HttpMethod.GET) {
|
||||
val result = UserCards.get(userUuid, false);
|
||||
if (result.length == 0) return new Response(HttpStatus.NO_CONTENT);
|
||||
return new Response(HttpStatus.OK, new ObjectMapper().writeValueAsString(result));
|
||||
}
|
||||
|
||||
if (request.getPath().split("/")[1].equals("deck")) {
|
||||
return switch (request.getMethod()) {
|
||||
case GET -> {
|
||||
val result = UserCards.get(userUuid, true);
|
||||
if (result.length == 0) yield new Response(HttpStatus.NO_CONTENT);
|
||||
yield new Response(HttpStatus.OK, new ObjectMapper().writeValueAsString(result));
|
||||
}
|
||||
case PUT -> {
|
||||
UUID[] cards = new ObjectMapper().readValue(request.getBody(), UUID[].class);
|
||||
if (cards.length != 4)
|
||||
yield new Response(HttpStatus.BAD_REQUEST);
|
||||
yield new Response(UserCards.setDeck(cards, userUuid) ? HttpStatus.OK : HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
default -> new Response(HttpStatus.NOT_FOUND);
|
||||
};
|
||||
}
|
||||
|
||||
return new Response(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,8 +30,7 @@ public class PackagesService implements Service {
|
||||
case MISSING, INVALID -> new Response(HttpStatus.UNAUTHORIZED);
|
||||
case FORBIDDEN -> new Response(HttpStatus.FORBIDDEN);
|
||||
case VALID -> new Response(
|
||||
Package.create(new ObjectMapper().readValue(request.getBody(), new TypeReference<List<Card>>() {
|
||||
})) ?
|
||||
Package.create(new ObjectMapper().readValue(request.getBody(), new TypeReference<List<Card>>() {})) ?
|
||||
HttpStatus.CREATED :
|
||||
HttpStatus.CONFLICT);
|
||||
};
|
||||
|
||||
@ -7,6 +7,7 @@ import lombok.val;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -80,11 +81,29 @@ public final class DbQuery {
|
||||
return DriverManager.getConnection(connectionString);
|
||||
}
|
||||
|
||||
private String buildParameterizedString(@NonNull SortedMap<String, Object> parameters) {
|
||||
private String buildParameterizedString(@NonNull SortedMap<String, Object> parameters, String separator) {
|
||||
if (parameters.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return String.join(" = ?, ", parameters.keySet()) + " = ?";
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
for (val parameter : parameters.entrySet()) {
|
||||
if (!stringBuilder.isEmpty()) stringBuilder.append(separator);
|
||||
if (parameter.getValue() instanceof List) {
|
||||
stringBuilder
|
||||
.append(parameter.getKey())
|
||||
.append(" IN (")
|
||||
.append(String.join("", Collections.nCopies(((List<?>) parameter.getValue()).size() - 1, "?, ")))
|
||||
.append("?)");
|
||||
continue;
|
||||
}
|
||||
|
||||
stringBuilder
|
||||
.append(parameter.getKey())
|
||||
.append(" = ?");
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static int executeUpdate(String sql, List<Object> parameterValues) throws SQLException {
|
||||
@ -98,6 +117,11 @@ public final class DbQuery {
|
||||
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
||||
int i = 1;
|
||||
for (val value : parameterValues) {
|
||||
if (value instanceof List<?>) {
|
||||
for (Object o : (List<?>) value)
|
||||
statementExecutor.setObject(i++, o);
|
||||
continue;
|
||||
}
|
||||
statementExecutor.setObject(i++, value);
|
||||
}
|
||||
|
||||
@ -116,6 +140,11 @@ public final class DbQuery {
|
||||
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
||||
int i = 1;
|
||||
for (val value : parameterValues) {
|
||||
if (value instanceof List<?>) {
|
||||
for (Object o : (List<?>) value)
|
||||
statementExecutor.setObject(i++, o);
|
||||
continue;
|
||||
}
|
||||
statementExecutor.setObject(i++, value);
|
||||
}
|
||||
|
||||
@ -134,6 +163,11 @@ public final class DbQuery {
|
||||
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
||||
int i = 1;
|
||||
for (val value : parameterValues) {
|
||||
if (value instanceof List<?>) {
|
||||
for (Object o : (List<?>) value)
|
||||
statementExecutor.setObject(i++, o);
|
||||
continue;
|
||||
}
|
||||
statementExecutor.setObject(i++, value);
|
||||
}
|
||||
|
||||
@ -157,7 +191,7 @@ public final class DbQuery {
|
||||
if (this.parameters.isEmpty()) throw new SQLException("No parameters provided for INSERT statement.");
|
||||
|
||||
String columns = this.parameters.keySet().stream()
|
||||
.filter(columnName -> columnName.matches("[a-zA-Z0-9_]+"))
|
||||
.filter(columnName -> columnName.matches("^[a-zA-Z0-9_]+( AS [a-zA-Z0-9_]+)?$"))
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
return String.format("INSERT INTO %s (%s) VALUES (%s) ON CONFLICT DO NOTHING%s;",
|
||||
@ -188,7 +222,7 @@ public final class DbQuery {
|
||||
String sql = String.format("SELECT %s FROM %s%s;",
|
||||
columnJoiner,
|
||||
table.table,
|
||||
this.conditions.isEmpty() ? "" : " WHERE (" + this.buildParameterizedString(this.conditions) + ")");
|
||||
this.conditions.isEmpty() ? "" : " WHERE " + this.buildParameterizedString(this.conditions, " AND "));
|
||||
|
||||
return executeQuery(sql, new ArrayList<>(this.conditions.values()));
|
||||
}
|
||||
@ -197,10 +231,10 @@ public final class DbQuery {
|
||||
if (this.parameters.isEmpty()) throw new SQLException();
|
||||
if (this.conditions.isEmpty()) throw new SQLException();
|
||||
|
||||
return String.format("UPDATE %s SET %s WHERE (%s)%s;",
|
||||
return String.format("UPDATE %s SET %s WHERE %s%s;",
|
||||
table.table,
|
||||
this.buildParameterizedString(this.parameters),
|
||||
this.buildParameterizedString(this.conditions),
|
||||
this.buildParameterizedString(this.parameters, ", "),
|
||||
this.buildParameterizedString(this.conditions, " AND "),
|
||||
hasReturn ? " RETURNING " + this.returnColumn : "");
|
||||
}
|
||||
|
||||
@ -226,9 +260,9 @@ public final class DbQuery {
|
||||
private int delete() throws SQLException {
|
||||
if (this.conditions.isEmpty()) throw new SQLException();
|
||||
|
||||
String sql = String.format("DELETE FROM %s WHERE (%s);",
|
||||
String sql = String.format("DELETE FROM %s WHERE %s;",
|
||||
table.table,
|
||||
this.buildParameterizedString(this.conditions));
|
||||
this.buildParameterizedString(this.conditions, " AND "));
|
||||
|
||||
return executeUpdate(sql, new ArrayList<>(this.conditions.values()));
|
||||
}
|
||||
|
||||
@ -9,6 +9,10 @@ public class Response {
|
||||
private final String contentType;
|
||||
private final String content;
|
||||
|
||||
public Response(HttpStatus httpStatus, String content) {
|
||||
this(httpStatus, "application/json", content);
|
||||
}
|
||||
|
||||
public Response(HttpStatus httpStatus, String contentType, String content) {
|
||||
this.httpStatus = httpStatus;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user