Skip to content
This repository was archived by the owner on Jul 6, 2023. It is now read-only.

Commit a38a6b1

Browse files
authored
Merge pull request #138 from pontusmelke/param-lambdas
Don't send parameter lambdas to server
2 parents ba67fab + 367f55d commit a38a6b1

File tree

9 files changed

+47
-64
lines changed

9 files changed

+47
-64
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ ext {
7171

7272
argparse4jVersion = '0.7.0'
7373
junitVersion = '4.12'
74+
evaluatorVersion = '3.5.4'
7475
neo4jJavaDriverVersion = '1.7.0'
7576
findbugsVersion = '3.0.0'
7677
jansiVersion = '1.13'

cypher-shell/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ distributions {
3737

3838
dependencies {
3939
compile "net.sourceforge.argparse4j:argparse4j:$argparse4jVersion"
40+
compile "org.neo4j:neo4j-cypher-expression-evaluator:$evaluatorVersion"
4041
compile "org.neo4j.driver:neo4j-java-driver:$neo4jJavaDriverVersion"
4142
compileOnly "com.google.code.findbugs:annotations:$findbugsVersion"
4243
compile "org.fusesource.jansi:jansi:$jansiVersion"

cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellVerboseIntegrationTest.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
import org.neo4j.shell.exception.CommandException;
1313
import org.neo4j.shell.prettyprint.PrettyConfig;
1414

15-
import java.util.Optional;
16-
1715
import static org.hamcrest.CoreMatchers.*;
1816
import static org.hamcrest.MatcherAssert.assertThat;
1917
import static org.junit.Assert.assertEquals;
@@ -160,10 +158,8 @@ public void paramsAndListVariables() throws CommandException {
160158
long randomLong = System.currentTimeMillis();
161159
String stringInput = "\"randomString\"";
162160
shell.setParameter("string", stringInput);
163-
164-
Optional<Object> bob = shell.setParameter("bob", String.valueOf(randomLong));
165-
assertTrue(bob.isPresent());
166-
assertEquals(randomLong, bob.get());
161+
Object paramValue = shell.setParameter("bob", String.valueOf(randomLong));
162+
assertEquals(randomLong, paramValue);
167163

168164
shell.execute("RETURN { bob }, $string");
169165

@@ -179,9 +175,8 @@ public void paramsAndListVariablesWithSpecialCharacters() throws CommandExceptio
179175
assertTrue(shell.allParameterValues().isEmpty());
180176

181177
long randomLong = System.currentTimeMillis();
182-
Optional<Object> bob = shell.setParameter("`bob`", String.valueOf(randomLong));
183-
assertTrue(bob.isPresent());
184-
assertEquals(randomLong, bob.get());
178+
Object paramValue = shell.setParameter("`bob`", String.valueOf(randomLong));
179+
assertEquals(randomLong, paramValue);
185180

186181
shell.execute("RETURN { `bob` }");
187182

cypher-shell/src/main/java/org/neo4j/shell/CypherShell.java

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.neo4j.shell;
22

3-
import org.neo4j.driver.v1.Record;
3+
import org.neo4j.cypher.internal.evaluator.EvaluationException;
4+
import org.neo4j.cypher.internal.evaluator.Evaluator;
5+
import org.neo4j.cypher.internal.evaluator.ExpressionEvaluator;
46
import org.neo4j.shell.commands.Command;
57
import org.neo4j.shell.commands.CommandExecutable;
68
import org.neo4j.shell.commands.CommandHelper;
@@ -33,7 +35,8 @@ public class CypherShell implements StatementExecuter, Connector, TransactionHan
3335
private final LinePrinter linePrinter;
3436
private final BoltStateHandler boltStateHandler;
3537
private final PrettyPrinter prettyPrinter;
36-
protected CommandHelper commandHelper;
38+
private CommandHelper commandHelper;
39+
private ExpressionEvaluator evaluator = Evaluator.expressionEvaluator();
3740

3841
public CypherShell(@Nonnull LinePrinter linePrinter, @Nonnull PrettyConfig prettyConfig) {
3942
this(linePrinter, new BoltStateHandler(), new PrettyPrinter(prettyConfig));
@@ -52,7 +55,7 @@ protected CypherShell(@Nonnull LinePrinter linePrinter,
5255
* @param text to trim
5356
* @return text without trailing semicolons
5457
*/
55-
static String stripTrailingSemicolons(@Nonnull String text) {
58+
protected static String stripTrailingSemicolons(@Nonnull String text) {
5659
int end = text.length();
5760
while (end > 0 && text.substring(0, end).endsWith(";")) {
5861
end -= 1;
@@ -83,7 +86,7 @@ public void execute(@Nonnull final String cmdString) throws ExitException, Comma
8386
*
8487
* @param cypher non-empty cypher text to executeLine
8588
*/
86-
protected void executeCypher(@Nonnull final String cypher) throws CommandException {
89+
private void executeCypher(@Nonnull final String cypher) throws CommandException {
8790
final Optional<BoltResult> result = boltStateHandler.runCypher(cypher, allParameterValues());
8891
result.ifPresent(boltResult -> prettyPrinter.format(boltResult, linePrinter));
8992
}
@@ -156,25 +159,15 @@ public boolean isTransactionOpen() {
156159

157160
@Override
158161
@Nonnull
159-
public Optional<Object> setParameter(@Nonnull String name, @Nonnull String valueString) throws CommandException {
160-
final Record records = evaluateParamOnServer(name, valueString);
161-
String parameterName = CypherVariablesFormatter.unescapedCypherVariable(name);
162-
final Object value = records.get(parameterName).asObject();
163-
queryParams.put(parameterName, new ParamValue(valueString, value));
164-
return Optional.ofNullable(value);
165-
}
166-
167-
private Record evaluateParamOnServer(@Nonnull String name, @Nonnull String valueString) throws CommandException {
168-
String cypher = "RETURN " + valueString + " as " + name;
169-
final Optional<BoltResult> resultOpt = boltStateHandler.runCypher(cypher, allParameterValues());
170-
if (!resultOpt.isPresent()) {
171-
throw new CommandException("Failed to set value of parameter");
162+
public Object setParameter(@Nonnull String name, @Nonnull String valueString) throws CommandException {
163+
try {
164+
String parameterName = CypherVariablesFormatter.unescapedCypherVariable(name);
165+
Object value = evaluator.evaluate(valueString, Object.class);
166+
queryParams.put(parameterName, new ParamValue(valueString, value));
167+
return value;
168+
} catch (EvaluationException e) {
169+
throw new CommandException(e.getMessage(), e);
172170
}
173-
List<Record> records = resultOpt.get().getRecords();
174-
if (records.size() != 1) {
175-
throw new CommandException("Failed to set value of parameter");
176-
}
177-
return records.get(0);
178171
}
179172

180173
@Override
@@ -193,7 +186,7 @@ public Map<String, ParamValue> getAllAsUserInput() {
193186
return queryParams;
194187
}
195188

196-
public void setCommandHelper(@Nonnull CommandHelper commandHelper) {
189+
void setCommandHelper(@Nonnull CommandHelper commandHelper) {
197190
this.commandHelper = commandHelper;
198191
}
199192

@@ -203,12 +196,7 @@ public void reset() {
203196
}
204197

205198
protected void addRuntimeHookToResetShell() {
206-
Runtime.getRuntime().addShutdownHook(new Thread() {
207-
@Override
208-
public void run() {
209-
reset();
210-
}
211-
});
199+
Runtime.getRuntime().addShutdownHook(new Thread(this::reset));
212200
}
213201

214202
}

cypher-shell/src/main/java/org/neo4j/shell/ParameterMap.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import javax.annotation.Nonnull;
77
import java.util.Map;
8-
import java.util.Optional;
98

109
/**
1110
* An object which keeps named parameters and allows them them to be set/unset.
@@ -14,8 +13,9 @@ public interface ParameterMap {
1413
/**
1514
* @param name of variable to set value for
1615
* @param valueString to interpret the value from
16+
* @return the evaluated value
1717
*/
18-
Optional setParameter(@Nonnull String name, @Nonnull String valueString) throws CommandException;
18+
Object setParameter(@Nonnull String name, @Nonnull String valueString) throws CommandException;
1919

2020
/**
2121
* @return map of all currently set variables and their values

cypher-shell/src/main/java/org/neo4j/shell/exception/AnsiFormattedException.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ public AnsiFormattedException(@Nullable String message) {
1616
this.message = AnsiFormattedText.from(message);
1717
}
1818

19+
public AnsiFormattedException(@Nullable String message, Throwable cause) {
20+
super(message, cause);
21+
this.message = AnsiFormattedText.from(message);
22+
}
23+
1924
public AnsiFormattedException(@Nonnull AnsiFormattedText message) {
2025
super(message.plainString());
2126
this.message = message;

cypher-shell/src/main/java/org/neo4j/shell/exception/CommandException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ public CommandException(@Nullable String msg) {
1313
super(msg);
1414
}
1515

16+
public CommandException(@Nullable String msg, Throwable cause) {
17+
super(msg, cause);
18+
}
19+
1620
public CommandException(@Nonnull AnsiFormattedText append) {
1721
super(append);
1822
}

cypher-shell/src/test/java/org/neo4j/shell/CypherShellTest.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.neo4j.shell.state.BoltResult;
2222
import org.neo4j.shell.state.BoltStateHandler;
2323
import org.neo4j.shell.state.ListBoltResult;
24-
import org.neo4j.shell.test.OfflineTestShell;
2524

2625
import java.io.IOException;
2726
import java.util.Optional;
@@ -108,16 +107,13 @@ public void verifyDelegationOfTransactionMethods() throws CommandException {
108107
}
109108

110109
@Test
111-
public void setWhenOfflineShouldThrow() throws CommandException {
112-
thrown.expect(CommandException.class);
113-
thrown.expectMessage("not connected");
114-
110+
public void setWhenOfflineShouldWork() throws CommandException {
115111
CypherShell shell = new OfflineTestShell(logger, mockedBoltStateHandler, mockedPrettyPrinter);
116112
when(mockedBoltStateHandler.isConnected()).thenReturn(false);
117-
118113
when(mockedBoltStateHandler.runCypher(anyString(), anyMap())).thenThrow(new CommandException("not connected"));
119114

120-
shell.setParameter("bob", "99");
115+
Object result = shell.setParameter("bob", "99");
116+
assertEquals(99L, result);
121117
}
122118

123119
@Test
@@ -143,9 +139,9 @@ public void setParamShouldAddParamWithSpecialCharactersAndValue() throws Command
143139

144140
assertTrue(offlineTestShell.allParameterValues().isEmpty());
145141

146-
Optional result = offlineTestShell.setParameter("`bo``b`", "99");
147-
assertEquals("99", result.get());
148-
assertEquals("99", offlineTestShell.allParameterValues().get("bo`b"));
142+
Object result = offlineTestShell.setParameter("`bo``b`", "99");
143+
assertEquals(99L, result);
144+
assertEquals(99L, offlineTestShell.allParameterValues().get("bo`b"));
149145
}
150146

151147
@Test
@@ -161,9 +157,9 @@ public void setParamShouldAddParam() throws CommandException {
161157

162158
assertTrue(offlineTestShell.allParameterValues().isEmpty());
163159

164-
Optional result = offlineTestShell.setParameter("`bob`", "99");
165-
assertEquals("99", result.get());
166-
assertEquals("99", offlineTestShell.allParameterValues().get("bob"));
160+
Object result = offlineTestShell.setParameter("`bob`", "99");
161+
assertEquals(99L, result);
162+
assertEquals(99L, offlineTestShell.allParameterValues().get("bob"));
167163
}
168164

169165
@Test
@@ -267,17 +263,13 @@ public void specifyingACypherStringShouldGiveAStringRunner() throws IOException
267263
}
268264

269265
@Test
270-
public void setWithSomeBoltError() throws CommandException {
271-
// then
272-
thrown.expect(CommandException.class);
273-
thrown.expectMessage("Failed to set value of parameter");
274-
266+
public void setParameterDoesNotTriggerByBoltError() throws CommandException {
275267
// given
276268
when(mockedBoltStateHandler.runCypher(anyString(), anyMap())).thenReturn(Optional.empty());
277-
278269
CypherShell shell = new CypherShell(logger, mockedBoltStateHandler, mockedPrettyPrinter);
279270

280271
// when
281-
shell.setParameter("bob", "99");
272+
Object result = shell.setParameter("bob", "99");
273+
assertEquals(99L, result);
282274
}
283275
}

cypher-shell/src/test/java/org/neo4j/shell/test/OfflineTestShell.java renamed to cypher-shell/src/test/java/org/neo4j/shell/OfflineTestShell.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
package org.neo4j.shell.test;
1+
package org.neo4j.shell;
22

33

4-
import org.neo4j.shell.CypherShell;
54
import org.neo4j.shell.log.Logger;
65
import org.neo4j.shell.prettyprint.PrettyPrinter;
76
import org.neo4j.shell.state.BoltStateHandler;
87

9-
import static org.mockito.Mockito.mock;
10-
118
/**
129
* This class initializes a {@link CypherShell} with a fake
1310
* {@link org.neo4j.shell.state.BoltStateHandler} which allows for faked sessions and faked results to test some basic

0 commit comments

Comments
 (0)