diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellVerboseIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellVerboseIntegrationTest.java index 9ac006d2..56a02d2b 100644 --- a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellVerboseIntegrationTest.java +++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellVerboseIntegrationTest.java @@ -170,19 +170,22 @@ public void paramsAndListVariables() throws CommandException { assertTrue(shell.getAll().isEmpty()); long randomLong = System.currentTimeMillis(); + String stringInput = "\"randomString\""; + shell.set("string", stringInput); Optional result = shell.set("bob", String.valueOf(randomLong)); assertTrue(result.isPresent()); assertEquals(randomLong, result.get()); - shell.execute("RETURN { bob }"); + shell.execute("RETURN { bob }, $string"); ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); verify(logger).printOut(captor.capture()); List queryResult = captor.getAllValues(); assertThat(queryResult.get(0), containsString("| { bob }")); - assertThat(queryResult.get(0), containsString("\n| " + randomLong+ " |\n")); + assertThat(queryResult.get(0), containsString("| " + randomLong + " | " + stringInput + " |")); assertEquals(randomLong, shell.getAll().get("bob")); + assertEquals("randomString", shell.getAll().get("string")); } @Test diff --git a/cypher-shell/src/main/java/org/neo4j/shell/CypherShell.java b/cypher-shell/src/main/java/org/neo4j/shell/CypherShell.java index aab634dd..c247fc75 100644 --- a/cypher-shell/src/main/java/org/neo4j/shell/CypherShell.java +++ b/cypher-shell/src/main/java/org/neo4j/shell/CypherShell.java @@ -10,14 +10,17 @@ import org.neo4j.shell.prettyprint.PrettyPrinter; import org.neo4j.shell.state.BoltResult; import org.neo4j.shell.state.BoltStateHandler; +import org.neo4j.shell.state.ParamValue; import javax.annotation.Nonnull; +import java.util.AbstractMap; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; /** * A possibly interactive shell for evaluating cypher statements. @@ -25,7 +28,7 @@ public class CypherShell implements StatementExecuter, Connector, TransactionHandler, VariableHolder { // Final space to catch newline protected static final Pattern cmdNamePattern = Pattern.compile("^\\s*(?[^\\s]+)\\b(?.*)\\s*$"); - protected final Map queryParams = new HashMap<>(); + protected final Map queryParams = new HashMap<>(); private final Logger logger; private final BoltStateHandler boltStateHandler; private final PrettyPrinter prettyPrinter; @@ -80,7 +83,7 @@ public void execute(@Nonnull final String cmdString) throws ExitException, Comma * @param cypher non-empty cypher text to executeLine */ protected void executeCypher(@Nonnull final String cypher) throws CommandException { - final Optional result = boltStateHandler.runCypher(cypher, queryParams); + final Optional result = boltStateHandler.runCypher(cypher, getAll()); result.ifPresent(boltResult -> logger.printOut(prettyPrinter.format(boltResult))); } @@ -156,13 +159,13 @@ public Optional set(@Nonnull String name, @Nonnull String valueString) throws Co final BoltResult result = setParamsAndValidate(name, valueString); String parameterName = CypherVariablesFormatter.unescapedCypherVariable(name); final Object value = result.getRecords().get(0).get(parameterName).asObject(); - queryParams.put(parameterName, value); + queryParams.put(parameterName, new ParamValue(valueString, value)); return Optional.ofNullable(value); } private BoltResult setParamsAndValidate(@Nonnull String name, @Nonnull String valueString) throws CommandException { String cypher = "RETURN " + valueString + " as " + name; - final Optional result = boltStateHandler.runCypher(cypher, queryParams); + final Optional result = boltStateHandler.runCypher(cypher, getAll()); if (!result.isPresent() || result.get().getRecords().isEmpty()) { throw new CommandException("Failed to set value of parameter"); } @@ -172,6 +175,16 @@ private BoltResult setParamsAndValidate(@Nonnull String name, @Nonnull String va @Override @Nonnull public Map getAll() { + return queryParams.entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + value -> value.getValue().getValue())); + } + + @Nonnull + @Override + public Map getAllAsUserInput() { return queryParams; } diff --git a/cypher-shell/src/main/java/org/neo4j/shell/VariableHolder.java b/cypher-shell/src/main/java/org/neo4j/shell/VariableHolder.java index c5452c36..c2398605 100644 --- a/cypher-shell/src/main/java/org/neo4j/shell/VariableHolder.java +++ b/cypher-shell/src/main/java/org/neo4j/shell/VariableHolder.java @@ -1,6 +1,7 @@ package org.neo4j.shell; import org.neo4j.shell.exception.CommandException; +import org.neo4j.shell.state.ParamValue; import javax.annotation.Nonnull; import java.util.Map; @@ -22,4 +23,10 @@ public interface VariableHolder { */ @Nonnull Map getAll(); + + /** + * @return map of all currently set variables and their values corresponding to the user valueString + */ + @Nonnull + Map getAllAsUserInput(); } diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Params.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Params.java index bd1c3dd0..9200d390 100644 --- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Params.java +++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Params.java @@ -78,21 +78,21 @@ public void execute(@Nonnull final String argString) throws ExitException, Comma private void listParam(@Nonnull String name) throws CommandException { String parameterName = CypherVariablesFormatter.unescapedCypherVariable(name); - if (!variableHolder.getAll().containsKey(parameterName)) { + if (!this.variableHolder.getAllAsUserInput().containsKey(parameterName)) { throw new CommandException("Unknown parameter: " + name); } - listParam(name.length(), name, variableHolder.getAll().get(parameterName)); + listParam(name.length(), name, this.variableHolder.getAllAsUserInput().get(parameterName).getValueAsString()); } private void listParam(int leftColWidth, @Nonnull String key, @Nonnull Object value) { - logger.printOut(String.format("%-" + leftColWidth + "s => %s", key, value)); + logger.printOut(String.format(":param %-" + leftColWidth + "s => %s", key, value)); } private void listAllParams() { - List keys = variableHolder.getAll().keySet().stream().sorted().collect(Collectors.toList()); + List keys = variableHolder.getAllAsUserInput().keySet().stream().sorted().collect(Collectors.toList()); int leftColWidth = keys.stream().map((s) -> escape(s).length()).reduce(0, Math::max); - keys.stream().forEach(k -> listParam(leftColWidth, escape(k), variableHolder.getAll().get(k))); + keys.forEach(key -> listParam(leftColWidth, escape(key), variableHolder.getAllAsUserInput().get(key).getValueAsString())); } } diff --git a/cypher-shell/src/main/java/org/neo4j/shell/state/ParamValue.java b/cypher-shell/src/main/java/org/neo4j/shell/state/ParamValue.java new file mode 100644 index 00000000..16a8853d --- /dev/null +++ b/cypher-shell/src/main/java/org/neo4j/shell/state/ParamValue.java @@ -0,0 +1,22 @@ +package org.neo4j.shell.state; + +/** + * Handles queryparams value and user inputString + */ +public class ParamValue { + private final String valueAsString; + private final Object value; + + public ParamValue(String valueAsString, Object value) { + this.valueAsString = valueAsString; + this.value = value; + } + + public Object getValue() { + return value; + } + + public String getValueAsString() { + return valueAsString; + } +} diff --git a/cypher-shell/src/test/java/org/neo4j/shell/commands/ParamsTest.java b/cypher-shell/src/test/java/org/neo4j/shell/commands/ParamsTest.java index a6430793..4481969d 100644 --- a/cypher-shell/src/test/java/org/neo4j/shell/commands/ParamsTest.java +++ b/cypher-shell/src/test/java/org/neo4j/shell/commands/ParamsTest.java @@ -7,7 +7,9 @@ import org.neo4j.shell.VariableHolder; import org.neo4j.shell.exception.CommandException; import org.neo4j.shell.log.Logger; +import org.neo4j.shell.state.ParamValue; +import java.util.AbstractMap; import java.util.HashMap; import static org.hamcrest.CoreMatchers.containsString; @@ -21,7 +23,7 @@ public class ParamsTest { @Rule public final ExpectedException thrown = ExpectedException.none(); - private HashMap vars; + private HashMap vars; private Logger logger; private Params cmd; @@ -30,7 +32,7 @@ public void setup() throws CommandException { vars = new HashMap<>(); logger = mock(Logger.class); VariableHolder shell = mock(VariableHolder.class); - when(shell.getAll()).thenReturn(vars); + when(shell.getAllAsUserInput()).thenReturn(vars); cmd = new Params(logger, shell); } @@ -52,72 +54,74 @@ public void helpNotNull() { @Test public void runCommand() throws CommandException { // given - vars.put("var", 9); + String var = "var"; + int value = 9; + vars.put(var, new ParamValue(String.valueOf(value), value)); // when cmd.execute(""); // then - verify(logger).printOut("var => 9"); + verify(logger).printOut(":param var => 9"); verifyNoMoreInteractions(logger); } @Test public void runCommandAlignment() throws CommandException { // given - vars.put("var", 9); - vars.put("param", 99999); + vars.put("var", new ParamValue(String.valueOf(9), 9)); + vars.put("param", new ParamValue(String.valueOf(99999), 99999)); // when cmd.execute(""); // then - verify(logger).printOut("param => 99999"); - verify(logger).printOut("var => 9"); + verify(logger).printOut(":param param => 99999"); + verify(logger).printOut(":param var => 9"); verifyNoMoreInteractions(logger); } @Test public void runCommandWithArg() throws CommandException { // given - vars.put("var", 9); - vars.put("param", 9999); + vars.put("var", new ParamValue(String.valueOf(9), 9)); + vars.put("param", new ParamValue(String.valueOf(9999), 9999)); // when cmd.execute("var"); // then - verify(logger).printOut("var => 9"); + verify(logger).printOut(":param var => 9"); verifyNoMoreInteractions(logger); } @Test public void runCommandWithArgWithExtraSpace() throws CommandException { // given - vars.put("var", 9); - vars.put("param", 9999); + vars.put("var", new ParamValue(String.valueOf(9), 9)); + vars.put("param", new ParamValue(String.valueOf(9999), 9999)); // when cmd.execute(" var"); // then - verify(logger).printOut("var => 9"); + verify(logger).printOut(":param var => 9"); verifyNoMoreInteractions(logger); } @Test public void runCommandWithArgWithBackticks() throws CommandException { // given - vars.put("var", 9); - vars.put("param", 9999); + vars.put("var", new ParamValue(String.valueOf(9), 9)); + vars.put("param", new ParamValue(String.valueOf(9999), 9999)); // when cmd.execute("`var`"); // then - verify(logger).printOut("`var` => 9"); + verify(logger).printOut(":param `var` => 9"); verifyNoMoreInteractions(logger); } @Test public void runCommandWithSpecialCharacters() throws CommandException { // given - vars.put("var `", 9); - vars.put("param", 9999); + vars.put("var `", new ParamValue(String.valueOf(9), 9)); + vars.put("param", new ParamValue(String.valueOf(9999), 9999)); // when cmd.execute("`var ```"); // then - verify(logger).printOut("`var ``` => 9"); + verify(logger).printOut(":param `var ``` => 9"); verifyNoMoreInteractions(logger); } @@ -127,7 +131,7 @@ public void runCommandWithUnknownArg() throws CommandException { thrown.expect(CommandException.class); thrown.expectMessage(containsString("Unknown parameter: bob")); // given - vars.put("var", 9); + vars.put("var", new ParamValue(String.valueOf(9), 9)); // when cmd.execute("bob"); }