diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
index 546db64..5b21d2d 100644
--- a/.idea/sqldialects.xml
+++ b/.idea/sqldialects.xml
@@ -2,6 +2,5 @@
-
\ No newline at end of file
diff --git a/src/at/nanopenguin/mtcg/application/UserCards.java b/src/at/nanopenguin/mtcg/application/UserCards.java
new file mode 100644
index 0000000..a33d400
--- /dev/null
+++ b/src/at/nanopenguin/mtcg/application/UserCards.java
@@ -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 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;
+ }
+}
diff --git a/src/at/nanopenguin/mtcg/application/service/CardsService.java b/src/at/nanopenguin/mtcg/application/service/CardsService.java
index 22c0e92..ba358e1 100644
--- a/src/at/nanopenguin/mtcg/application/service/CardsService.java
+++ b/src/at/nanopenguin/mtcg/application/service/CardsService.java
@@ -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);
}
}
diff --git a/src/at/nanopenguin/mtcg/application/service/PackagesService.java b/src/at/nanopenguin/mtcg/application/service/PackagesService.java
index ba56586..17b04fe 100644
--- a/src/at/nanopenguin/mtcg/application/service/PackagesService.java
+++ b/src/at/nanopenguin/mtcg/application/service/PackagesService.java
@@ -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>() {
- })) ?
+ Package.create(new ObjectMapper().readValue(request.getBody(), new TypeReference>() {})) ?
HttpStatus.CREATED :
HttpStatus.CONFLICT);
};
diff --git a/src/at/nanopenguin/mtcg/db/DbQuery.java b/src/at/nanopenguin/mtcg/db/DbQuery.java
index c017f7d..f98bb9b 100644
--- a/src/at/nanopenguin/mtcg/db/DbQuery.java
+++ b/src/at/nanopenguin/mtcg/db/DbQuery.java
@@ -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 parameters) {
+ private String buildParameterizedString(@NonNull SortedMap 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