Skip to content

Commit

Permalink
relates to #178: update commands per spec, improved tests (#236)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Senic authored Mar 9, 2023
1 parent 665ce63 commit e3a4f54
Show file tree
Hide file tree
Showing 12 changed files with 1,963 additions and 1,347 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
implementation = Object.class,
example =
"""
{"$set" : {"location": "New York"},
"$unset" : {"new_data": 1}
""")
{
"$set" : {"location": "New York"},
"$unset" : {"new_data": 1}
}
""")
public record UpdateClause(EnumMap<UpdateOperator, ObjectNode> updateOperationDefs) {
/**
* Method that will validate update operation definitions of the clause and construct an ordered
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.stargate.sgv2.jsonapi.api.model.command.clause.update.UpdateClause;
import javax.annotation.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

@Schema(
Expand All @@ -16,8 +17,15 @@
@JsonTypeName("updateMany")
public record UpdateManyCommand(
@Valid @JsonProperty("filter") FilterClause filterClause,
@Valid @JsonProperty("update") UpdateClause updateClause,
@NotNull @Valid @JsonProperty("update") UpdateClause updateClause,
@Nullable Options options)
implements ReadCommand, Filterable {
public record Options(boolean upsert) {}

@Schema(name = "UpdateManyCommand.Options", description = "Options for updating many documents.")
public record Options(
@Schema(
description =
"When `true`, if no documents match the `filter` clause the command will create a new _empty_ document and apply the `update` clause to the empty document.",
defaultValue = "false")
boolean upsert) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.stargate.sgv2.jsonapi.api.model.command.clause.update.UpdateClause;
import javax.annotation.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.eclipse.microprofile.openapi.annotations.media.Schema;

@Schema(
Expand All @@ -16,8 +17,15 @@
@JsonTypeName("updateOne")
public record UpdateOneCommand(
@Valid @JsonProperty("filter") FilterClause filterClause,
@Valid @JsonProperty("update") UpdateClause updateClause,
@NotNull @Valid @JsonProperty("update") UpdateClause updateClause,
@Nullable Options options)
implements ReadCommand, Filterable {
public record Options(boolean upsert) {}

@Schema(name = "UpdateOneCommand.Options", description = "Options for updating a document.")
public record Options(
@Schema(
description =
"When `true`, if no documents match the `filter` clause the command will create a new _empty_ document and apply the `update` clause to the empty document.",
defaultValue = "false")
boolean upsert) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.stargate.sgv2.jsonapi.api.model.command.CommandContext;
import io.stargate.sgv2.jsonapi.api.model.command.impl.UpdateManyCommand;
import io.stargate.sgv2.jsonapi.api.model.command.impl.UpdateOneCommand;
import io.stargate.sgv2.jsonapi.service.bridge.config.DocumentConfig;
import io.stargate.sgv2.jsonapi.service.operation.model.Operation;
import io.stargate.sgv2.jsonapi.service.operation.model.ReadOperation;
Expand All @@ -16,11 +15,11 @@
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

/** Resolves the {@link UpdateOneCommand } */
/** Resolves the {@link UpdateManyCommand } */
@ApplicationScoped
public class UpdateManyCommandResolver extends FilterableResolver<UpdateManyCommand>
implements CommandResolver<UpdateManyCommand> {
private Shredder shredder;
private final Shredder shredder;
private final DocumentConfig documentConfig;

@Inject
Expand All @@ -40,7 +39,12 @@ public Class<UpdateManyCommand> getCommandClass() {
public Operation resolveCommand(CommandContext ctx, UpdateManyCommand command) {
ReadOperation readOperation = resolve(ctx, command);
DocumentUpdater documentUpdater = DocumentUpdater.construct(command.updateClause());
boolean upsert = command.options() != null && command.options().upsert();

// resolve upsert
UpdateManyCommand.Options options = command.options();
boolean upsert = options != null && options.upsert();

// return op
return new ReadAndUpdateOperation(
ctx,
readOperation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ public Class<UpdateOneCommand> getCommandClass() {
public Operation resolveCommand(CommandContext ctx, UpdateOneCommand command) {
ReadOperation readOperation = resolve(ctx, command);
DocumentUpdater documentUpdater = DocumentUpdater.construct(command.updateClause());
boolean upsert = command.options() != null && command.options().upsert();

// resolve upsert
UpdateOneCommand.Options options = command.options();
boolean upsert = options != null && options.upsert();

// return op
return new ReadAndUpdateOperation(
ctx,
readOperation,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.stargate.sgv2.jsonapi.api.model.command.impl;

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
import io.stargate.sgv2.common.testprofiles.NoGlobalResourcesTestProfile;
import java.util.Set;
import javax.inject.Inject;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

@QuarkusTest
@TestProfile(NoGlobalResourcesTestProfile.Impl.class)
class UpdateManyCommandTest {

@Inject ObjectMapper objectMapper;

@Inject Validator validator;

@Nested
class Validation {

@Test
public void noUpdateClause() throws Exception {
String json =
"""
{
"updateMany": {
"filter": {"name": "Aaron"}
}
}
""";

UpdateManyCommand command = objectMapper.readValue(json, UpdateManyCommand.class);
Set<ConstraintViolation<UpdateManyCommand>> result = validator.validate(command);

assertThat(result)
.isNotEmpty()
.extracting(ConstraintViolation::getMessage)
.contains("must not be null");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.stargate.sgv2.jsonapi.api.model.command.impl;

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
import io.stargate.sgv2.common.testprofiles.NoGlobalResourcesTestProfile;
import java.util.Set;
import javax.inject.Inject;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

@QuarkusTest
@TestProfile(NoGlobalResourcesTestProfile.Impl.class)
class UpdateOneCommandTest {

@Inject ObjectMapper objectMapper;

@Inject Validator validator;

@Nested
class Validation {

@Test
public void noUpdateClause() throws Exception {
String json =
"""
{
"updateOne": {
"filter": {"name": "Aaron"}
}
}
""";

UpdateOneCommand command = objectMapper.readValue(json, UpdateOneCommand.class);
Set<ConstraintViolation<UpdateOneCommand>> result = validator.validate(command);

assertThat(result)
.isNotEmpty()
.extracting(ConstraintViolation::getMessage)
.contains("must not be null");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ public void deleteWithDynamicRetry() {
candidatesAssert2.assertExecuteCount().isOne();
deleteAssert.assertExecuteCount().isOne();
deleteAssert2.assertExecuteCount().isOne();
// then result

// then result
CommandResult result = execute.get();
Expand Down
Loading

0 comments on commit e3a4f54

Please sign in to comment.