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">
|
<project version="4">
|
||||||
<component name="SqlDialectMappings">
|
<component name="SqlDialectMappings">
|
||||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/720ef4bc-36c4-4861-8776-49b639600223/console.sql" dialect="PostgreSQL" />
|
<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>
|
</component>
|
||||||
</project>
|
</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;
|
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.HttpMethod;
|
||||||
import at.nanopenguin.mtcg.http.HttpRequest;
|
import at.nanopenguin.mtcg.http.HttpRequest;
|
||||||
import at.nanopenguin.mtcg.http.HttpStatus;
|
import at.nanopenguin.mtcg.http.HttpStatus;
|
||||||
import at.nanopenguin.mtcg.http.Response;
|
import at.nanopenguin.mtcg.http.Response;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CardsService implements Service {
|
public class CardsService implements Service {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response handleRequest(HttpRequest request) throws JsonProcessingException {
|
public Response handleRequest(HttpRequest request) throws JsonProcessingException, SQLException, ArrayIndexOutOfBoundsException {
|
||||||
try {
|
|
||||||
if (request.getPath().split("/")[1].equals("cards") && request.getMethod() == HttpMethod.GET) {
|
|
||||||
return new Response(HttpStatus.NOT_IMPLEMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.getPath().split("/")[1].equals("deck")) {
|
UUID authToken = SessionHandler.tokenFromHttpHeader(request.getHttpHeader("Authorization"));
|
||||||
return switch (request.getMethod()) {
|
if (SessionHandler.getInstance().verifyUUID(authToken) != TokenValidity.VALID)
|
||||||
case GET -> new Response(HttpStatus.NOT_IMPLEMENTED);
|
return new Response(HttpStatus.UNAUTHORIZED);
|
||||||
case PUT -> new Response(HttpStatus.NOT_IMPLEMENTED); // String[] array = new ObjectMapper().readValue(request.getBody(), String[].class)
|
UUID userUuid = SessionHandler.getInstance().userUuidFromToken(authToken);
|
||||||
default -> new Response(HttpStatus.NOT_FOUND);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Response(HttpStatus.NOT_FOUND);
|
if (request.getPath().split("/")[1].equals("cards") && request.getMethod() == HttpMethod.GET) {
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
val result = UserCards.get(userUuid, false);
|
||||||
return new Response(HttpStatus.BAD_REQUEST);
|
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 MISSING, INVALID -> new Response(HttpStatus.UNAUTHORIZED);
|
||||||
case FORBIDDEN -> new Response(HttpStatus.FORBIDDEN);
|
case FORBIDDEN -> new Response(HttpStatus.FORBIDDEN);
|
||||||
case VALID -> new Response(
|
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.CREATED :
|
||||||
HttpStatus.CONFLICT);
|
HttpStatus.CONFLICT);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import lombok.val;
|
|||||||
|
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -80,11 +81,29 @@ public final class DbQuery {
|
|||||||
return DriverManager.getConnection(connectionString);
|
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()) {
|
if (parameters.isEmpty()) {
|
||||||
return "";
|
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 {
|
private static int executeUpdate(String sql, List<Object> parameterValues) throws SQLException {
|
||||||
@ -98,6 +117,11 @@ public final class DbQuery {
|
|||||||
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (val value : parameterValues) {
|
for (val value : parameterValues) {
|
||||||
|
if (value instanceof List<?>) {
|
||||||
|
for (Object o : (List<?>) value)
|
||||||
|
statementExecutor.setObject(i++, o);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
statementExecutor.setObject(i++, value);
|
statementExecutor.setObject(i++, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +140,11 @@ public final class DbQuery {
|
|||||||
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (val value : parameterValues) {
|
for (val value : parameterValues) {
|
||||||
|
if (value instanceof List<?>) {
|
||||||
|
for (Object o : (List<?>) value)
|
||||||
|
statementExecutor.setObject(i++, o);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
statementExecutor.setObject(i++, value);
|
statementExecutor.setObject(i++, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +163,11 @@ public final class DbQuery {
|
|||||||
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
new PreparedStatementExecutor(connection.prepareStatement(sql));
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (val value : parameterValues) {
|
for (val value : parameterValues) {
|
||||||
|
if (value instanceof List<?>) {
|
||||||
|
for (Object o : (List<?>) value)
|
||||||
|
statementExecutor.setObject(i++, o);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
statementExecutor.setObject(i++, value);
|
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.");
|
if (this.parameters.isEmpty()) throw new SQLException("No parameters provided for INSERT statement.");
|
||||||
|
|
||||||
String columns = this.parameters.keySet().stream()
|
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(", "));
|
.collect(Collectors.joining(", "));
|
||||||
|
|
||||||
return String.format("INSERT INTO %s (%s) VALUES (%s) ON CONFLICT DO NOTHING%s;",
|
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;",
|
String sql = String.format("SELECT %s FROM %s%s;",
|
||||||
columnJoiner,
|
columnJoiner,
|
||||||
table.table,
|
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()));
|
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.parameters.isEmpty()) throw new SQLException();
|
||||||
if (this.conditions.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,
|
table.table,
|
||||||
this.buildParameterizedString(this.parameters),
|
this.buildParameterizedString(this.parameters, ", "),
|
||||||
this.buildParameterizedString(this.conditions),
|
this.buildParameterizedString(this.conditions, " AND "),
|
||||||
hasReturn ? " RETURNING " + this.returnColumn : "");
|
hasReturn ? " RETURNING " + this.returnColumn : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,9 +260,9 @@ public final class DbQuery {
|
|||||||
private int delete() throws SQLException {
|
private int delete() throws SQLException {
|
||||||
if (this.conditions.isEmpty()) throw new 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,
|
table.table,
|
||||||
this.buildParameterizedString(this.conditions));
|
this.buildParameterizedString(this.conditions, " AND "));
|
||||||
|
|
||||||
return executeUpdate(sql, new ArrayList<>(this.conditions.values()));
|
return executeUpdate(sql, new ArrayList<>(this.conditions.values()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,10 @@ public class Response {
|
|||||||
private final String contentType;
|
private final String contentType;
|
||||||
private final String content;
|
private final String content;
|
||||||
|
|
||||||
|
public Response(HttpStatus httpStatus, String content) {
|
||||||
|
this(httpStatus, "application/json", content);
|
||||||
|
}
|
||||||
|
|
||||||
public Response(HttpStatus httpStatus, String contentType, String content) {
|
public Response(HttpStatus httpStatus, String contentType, String content) {
|
||||||
this.httpStatus = httpStatus;
|
this.httpStatus = httpStatus;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user