diff --git a/build.gradle b/build.gradle
index 975ce1fa..c3522575 100644
--- a/build.gradle
+++ b/build.gradle
@@ -11,6 +11,7 @@ buildscript {
allprojects {
apply plugin: 'java'
+ apply plugin: 'checkstyle'
sourceCompatibility = 1.8
targetCompatibility = 1.8
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 00000000..b4885d2b
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cypher-shell/build.gradle b/cypher-shell/build.gradle
index 9945b5ea..096b0531 100644
--- a/cypher-shell/build.gradle
+++ b/cypher-shell/build.gradle
@@ -70,3 +70,7 @@ dependencies {
testCompile "org.hamcrest:java-hamcrest:$hamcrestVersion"
testCompileOnly "com.google.code.findbugs:annotations:$findbugsVersion"
}
+
+checkstyle {
+ toolVersion = '8.35'
+}
\ No newline at end of file
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/MainIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/MainIntegrationTest.java
index d7de275e..617da537 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/MainIntegrationTest.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/MainIntegrationTest.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import org.junit.Before;
@@ -50,19 +69,6 @@ public class MainIntegrationTest
{
private static String USER = "neo4j";
private static String PASSWORD = "neo";
-
- private static class ShellAndConnection
- {
- CypherShell shell;
- ConnectionConfig connectionConfig;
-
- ShellAndConnection( CypherShell shell, ConnectionConfig connectionConfig )
- {
- this.shell = shell;
- this.connectionConfig = connectionConfig;
- }
- }
-
@Rule
public final ExpectedException exception = ExpectedException.none();
private String inputString = String.format( "%s%n%s%n", USER, PASSWORD );
@@ -76,131 +82,148 @@ private static class ShellAndConnection
private ByteBuffer inputBuffer;
@Before
- public void setup() {
+ public void setup()
+ {
// given
- inputBuffer = ByteBuffer.allocate(256);
- inputBuffer.put(inputString.getBytes());
- inputStream = new ByteArrayInputStream(inputBuffer.array());
+ inputBuffer = ByteBuffer.allocate( 256 );
+ inputBuffer.put( inputString.getBytes() );
+ inputStream = new ByteArrayInputStream( inputBuffer.array() );
baos = new ByteArrayOutputStream();
- printStream = new PrintStream(baos);
+ printStream = new PrintStream( baos );
- main = new Main(inputStream, printStream);
+ main = new Main( inputStream, printStream );
cliArgs = new CliArgs();
- cliArgs.setUsername("", "");
- cliArgs.setPassword("", "");
+ cliArgs.setUsername( "", "" );
+ cliArgs.setPassword( "", "" );
ShellAndConnection sac = getShell( cliArgs );
shell = sac.shell;
connectionConfig = sac.connectionConfig;
}
- private void ensureUser() throws Exception {
- if (majorVersion(shell.getServerVersion() ) >= 4) {
- shell.execute(":use " + SYSTEM_DB_NAME);
- shell.execute("CREATE OR REPLACE USER foo SET PASSWORD 'pass';");
- shell.execute("GRANT ROLE reader TO foo;");
- shell.execute(":use");
- } else {
- try {
- shell.execute("CALL dbms.security.createUser('foo', 'pass', true)");
- } catch (ClientException e) {
- if (e.code().equalsIgnoreCase("Neo.ClientError.General.InvalidArguments") && e.getMessage().contains("already exists")) {
- shell.execute("CALL dbms.security.deleteUser('foo')");
- shell.execute("CALL dbms.security.createUser('foo', 'pass', true)");
+ private void ensureUser() throws Exception
+ {
+ if ( majorVersion( shell.getServerVersion() ) >= 4 )
+ {
+ shell.execute( ":use " + SYSTEM_DB_NAME );
+ shell.execute( "CREATE OR REPLACE USER foo SET PASSWORD 'pass';" );
+ shell.execute( "GRANT ROLE reader TO foo;" );
+ shell.execute( ":use" );
+ }
+ else
+ {
+ try
+ {
+ shell.execute( "CALL dbms.security.createUser('foo', 'pass', true)" );
+ }
+ catch ( ClientException e )
+ {
+ if ( e.code().equalsIgnoreCase( "Neo.ClientError.General.InvalidArguments" ) && e.getMessage().contains( "already exists" ) )
+ {
+ shell.execute( "CALL dbms.security.deleteUser('foo')" );
+ shell.execute( "CALL dbms.security.createUser('foo', 'pass', true)" );
}
}
}
}
- private void ensureDefaultDatabaseStarted() throws Exception {
+ private void ensureDefaultDatabaseStarted() throws Exception
+ {
CliArgs cliArgs = new CliArgs();
- cliArgs.setUsername("neo4j", "");
- cliArgs.setPassword("neo", "");
- cliArgs.setDatabase("system");
- ShellAndConnection sac = getShell(cliArgs);
- main.connectMaybeInteractively(sac.shell, sac.connectionConfig, true, false, true);
- sac.shell.execute("START DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME);
+ cliArgs.setUsername( "neo4j", "" );
+ cliArgs.setPassword( "neo", "" );
+ cliArgs.setDatabase( "system" );
+ ShellAndConnection sac = getShell( cliArgs );
+ main.connectMaybeInteractively( sac.shell, sac.connectionConfig, true, false, true );
+ sac.shell.execute( "START DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME );
}
@Test
- public void promptsOnWrongAuthenticationIfInteractive() throws Exception {
+ public void promptsOnWrongAuthenticationIfInteractive() throws Exception
+ {
// when
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
- main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
// then
// should be connected
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
// should have prompted and set the username and password
- assertEquals(format("username: neo4j%npassword: ***%n"), baos.toString());
- assertEquals("neo4j", connectionConfig.username());
- assertEquals("neo", connectionConfig.password());
+ assertEquals( format( "username: neo4j%npassword: ***%n" ), baos.toString() );
+ assertEquals( "neo4j", connectionConfig.username() );
+ assertEquals( "neo", connectionConfig.password() );
}
@Test
- public void promptsOnPasswordChangeRequired() throws Exception {
+ public void promptsOnPasswordChangeRequired() throws Exception
+ {
int majorVersion = getVersionAndCreateUserWithPasswordChangeRequired();
- connectionConfig = getConnectionConfig(cliArgs);
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ connectionConfig = getConnectionConfig( cliArgs );
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
// when
- inputBuffer.put(String.format("foo%npass%nnewpass%n").getBytes());
+ inputBuffer.put( String.format( "foo%npass%nnewpass%n" ).getBytes() );
baos.reset();
- main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
// then
- assertTrue(shell.isConnected());
- if (majorVersion >= 4) {
+ assertTrue( shell.isConnected() );
+ if ( majorVersion >= 4 )
+ {
// should have prompted to change the password
String expectedChangePasswordOutput = format( "username: foo%npassword: ****%nPassword change required%nnew password: *******%n" );
- assertEquals( expectedChangePasswordOutput, baos.toString());
- assertEquals("foo", connectionConfig.username());
- assertEquals("newpass", connectionConfig.password());
- assertNull(connectionConfig.newPassword());
+ assertEquals( expectedChangePasswordOutput, baos.toString() );
+ assertEquals( "foo", connectionConfig.username() );
+ assertEquals( "newpass", connectionConfig.password() );
+ assertNull( connectionConfig.newPassword() );
// Should be able to execute read query
- shell.execute("MATCH (n) RETURN count(n)");
- } else {
+ shell.execute( "MATCH (n) RETURN count(n)" );
+ }
+ else
+ {
// in 3.x we do not get credentials expired exception on connection, but when we try to access data
String expectedChangePasswordOutput = format( "username: foo%npassword: ****%n" );
- assertEquals( expectedChangePasswordOutput, baos.toString());
- assertEquals("foo", connectionConfig.username());
- assertEquals("pass", connectionConfig.password());
+ assertEquals( expectedChangePasswordOutput, baos.toString() );
+ assertEquals( "foo", connectionConfig.username() );
+ assertEquals( "pass", connectionConfig.password() );
// Should get exception with instructions on how to change password using procedure
- exception.expect(ClientException.class);
- exception.expectMessage("CALL dbms.changePassword");
- shell.execute("MATCH (n) RETURN count(n)");
+ exception.expect( ClientException.class );
+ exception.expectMessage( "CALL dbms.changePassword" );
+ shell.execute( "MATCH (n) RETURN count(n)" );
}
}
@Test
- public void allowUserToUpdateExpiredPasswordInteractivelyWithoutBeingPrompted() throws Exception {
+ public void allowUserToUpdateExpiredPasswordInteractivelyWithoutBeingPrompted() throws Exception
+ {
//given a user that require a password change
int majorVersion = getVersionAndCreateUserWithPasswordChangeRequired();
//when the user attempts a non-interactive password update
- assumeTrue(majorVersion >= 4 );
+ assumeTrue( majorVersion >= 4 );
baos.reset();
assertEquals( EXIT_SUCCESS, main.runShell( args( SYSTEM_DB_NAME, "foo", "pass",
- "ALTER CURRENT USER SET PASSWORD from \"pass\" to \"pass2\";" ), shell, mock( Logger.class ) ) );
+ "ALTER CURRENT USER SET PASSWORD from \"pass\" to \"pass2\";" ), shell, mock( Logger.class ) ) );
//we shouldn't ask for a new password
assertEquals( "", baos.toString() );
//then the new user should be able to successfully connect, and run a command
assertEquals( format( "n%n42%n" ),
- executeNonInteractively( args( DEFAULT_DEFAULT_DB_NAME,
- "foo", "pass2", "RETURN 42 AS n" ) ) );
+ executeNonInteractively( args( DEFAULT_DEFAULT_DB_NAME,
+ "foo", "pass2", "RETURN 42 AS n" ) ) );
}
@Test
- public void shouldFailIfNonInteractivelySettingPasswordOnNonSystemDb() throws Exception {
+ public void shouldFailIfNonInteractivelySettingPasswordOnNonSystemDb() throws Exception
+ {
//given a user that require a password change
int majorVersion = getVersionAndCreateUserWithPasswordChangeRequired();
@@ -209,11 +232,12 @@ public void shouldFailIfNonInteractivelySettingPasswordOnNonSystemDb() throws Ex
//then
assertEquals( EXIT_FAILURE, main.runShell( args( DEFAULT_DEFAULT_DB_NAME, "foo", "pass",
- "ALTER CURRENT USER SET PASSWORD from \"pass\" to \"pass2\";" ), shell, mock( Logger.class ) ) );
+ "ALTER CURRENT USER SET PASSWORD from \"pass\" to \"pass2\";" ), shell, mock( Logger.class ) ) );
}
@Test
- public void shouldBePromptedIfRunningNonInteractiveCypherThatDoesntUpdatePassword() throws Exception {
+ public void shouldBePromptedIfRunningNonInteractiveCypherThatDoesntUpdatePassword() throws Exception
+ {
//given a user that require a password change
int majorVersion = getVersionAndCreateUserWithPasswordChangeRequired();
@@ -224,19 +248,20 @@ public void shouldBePromptedIfRunningNonInteractiveCypherThatDoesntUpdatePasswor
inputBuffer.put( String.format( "pass2%n" ).getBytes() );
baos.reset();
assertEquals( EXIT_SUCCESS, main.runShell( args( DEFAULT_DEFAULT_DB_NAME, "foo", "pass",
- "MATCH (n) RETURN n" ), shell, mock( Logger.class ) ) );
+ "MATCH (n) RETURN n" ), shell, mock( Logger.class ) ) );
//then should ask for a new password
assertEquals( format( "Password change required%nnew password: *****%n" ), baos.toString() );
//then the new user should be able to successfully connect, and run a command
assertEquals( format( "n%n42%n" ),
- executeNonInteractively( args( DEFAULT_DEFAULT_DB_NAME,
- "foo", "pass2", "RETURN 42 AS n" ) ) );
+ executeNonInteractively( args( DEFAULT_DEFAULT_DB_NAME,
+ "foo", "pass2", "RETURN 42 AS n" ) ) );
}
@Test
- public void shouldNotBePromptedIfRunningWithExplicitNonInteractiveCypherThatDoesntUpdatePassword() throws Exception {
+ public void shouldNotBePromptedIfRunningWithExplicitNonInteractiveCypherThatDoesntUpdatePassword() throws Exception
+ {
//given a user that require a password change
int majorVersion = getVersionAndCreateUserWithPasswordChangeRequired();
@@ -253,35 +278,39 @@ public void shouldNotBePromptedIfRunningWithExplicitNonInteractiveCypherThatDoes
}
@Test
- public void doesNotPromptToStdOutOnWrongAuthenticationIfOutputRedirected() throws Exception {
+ public void doesNotPromptToStdOutOnWrongAuthenticationIfOutputRedirected() throws Exception
+ {
// when
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
// Redirect System.in and System.out
InputStream stdIn = System.in;
PrintStream stdOut = System.out;
- System.setIn(inputStream);
- System.setOut(printStream);
+ System.setIn( inputStream );
+ System.setOut( printStream );
// Create a Main with the standard in and out
- try {
+ try
+ {
Main realMain = new Main();
- realMain.connectMaybeInteractively(shell, connectionConfig, true, false, true);
+ realMain.connectMaybeInteractively( shell, connectionConfig, true, false, true );
// then
// should be connected
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
// should have prompted silently and set the username and password
- assertEquals("neo4j", connectionConfig.username());
- assertEquals("neo", connectionConfig.password());
+ assertEquals( "neo4j", connectionConfig.username() );
+ assertEquals( "neo", connectionConfig.password() );
String out = baos.toString();
- assertEquals("", out);
- } finally {
+ assertEquals( "", out );
+ }
+ finally
+ {
// Restore in and out
- System.setIn(stdIn);
- System.setOut(stdOut);
+ System.setIn( stdIn );
+ System.setOut( stdOut );
}
}
@@ -299,7 +328,7 @@ public void wrongPortWithBolt() throws Exception
exception.expect( ServiceUnavailableException.class );
exception.expectMessage( "Unable to connect to localhost:1234, ensure the database is running and that there is a working network connection to it" );
- main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
}
@Test
@@ -316,122 +345,131 @@ public void wrongPortWithNeo4j() throws Exception
exception.expect( ServiceUnavailableException.class );
// The error message here may be subject to change and is not stable across versions so let us not assert on it
- main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
}
@Test
- public void shouldAskForCredentialsWhenConnectingWithAFile() throws Exception {
+ public void shouldAskForCredentialsWhenConnectingWithAFile() throws Exception
+ {
//given
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
//when
CliArgs cliArgs = new CliArgs();
- cliArgs.setInputFilename(fileFromResource("single.cypher"));
- ShellAndConnection sac = getShell(cliArgs);
+ cliArgs.setInputFilename( fileFromResource( "single.cypher" ) );
+ ShellAndConnection sac = getShell( cliArgs );
CypherShell shell = sac.shell;
ConnectionConfig connectionConfig = sac.connectionConfig;
- main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
// then we should have prompted and set the username and password
assertEquals( format( "username: neo4j%npassword: ***%n" ), baos.toString() );
- assertEquals("neo4j", connectionConfig.username());
- assertEquals("neo", connectionConfig.password());
+ assertEquals( "neo4j", connectionConfig.username() );
+ assertEquals( "neo", connectionConfig.password() );
}
@Test
- public void shouldReadSingleCypherStatementsFromFile() throws Exception {
- assertEquals(format( "result%n42%n" ), executeFileNonInteractively(fileFromResource("single.cypher")));
+ public void shouldReadSingleCypherStatementsFromFile() throws Exception
+ {
+ assertEquals( format( "result%n42%n" ), executeFileNonInteractively( fileFromResource( "single.cypher" ) ) );
}
@Test
- public void shouldReadEmptyCypherStatementsFile() throws Exception {
- assertEquals("", executeFileNonInteractively(fileFromResource("empty.cypher")));
+ public void shouldReadEmptyCypherStatementsFile() throws Exception
+ {
+ assertEquals( "", executeFileNonInteractively( fileFromResource( "empty.cypher" ) ) );
}
@Test
- public void shouldReadMultipleCypherStatementsFromFile() throws Exception {
- assertEquals(format( "result%n42%n" +
+ public void shouldReadMultipleCypherStatementsFromFile() throws Exception
+ {
+ assertEquals( format( "result%n42%n" +
"result%n1337%n" +
- "result%n\"done\"%n"), executeFileNonInteractively(fileFromResource("multiple.cypher")));
+ "result%n\"done\"%n" ), executeFileNonInteractively( fileFromResource( "multiple.cypher" ) ) );
}
@Test
- public void shouldFailIfInputFileDoesntExist() throws Exception {
+ public void shouldFailIfInputFileDoesntExist() throws Exception
+ {
//given
ByteArrayOutputStream out = new ByteArrayOutputStream();
- Logger logger = new AnsiLogger( false, Format.VERBOSE, new PrintStream( out ), new PrintStream( out ));
+ Logger logger = new AnsiLogger( false, Format.VERBOSE, new PrintStream( out ), new PrintStream( out ) );
//when
- executeFileNonInteractively("what.cypher", logger);
+ executeFileNonInteractively( "what.cypher", logger );
//then
- assertEquals( format("what.cypher (No such file or directory)%n"), out.toString());
+ assertEquals( format( "what.cypher (No such file or directory)%n" ), out.toString() );
}
@Test
- public void shouldHandleInvalidCypherFromFile() throws Exception {
+ public void shouldHandleInvalidCypherFromFile() throws Exception
+ {
//given
- Logger logger = mock(Logger.class);
-
+ Logger logger = mock( Logger.class );
// when
- String actual = executeFileNonInteractively( fileFromResource( "invalid.cypher" ), logger);
+ String actual = executeFileNonInteractively( fileFromResource( "invalid.cypher" ), logger );
//then we print the first valid row
assertEquals( format( "result%n42%n" ), actual );
//and print errors to the error log
- verify(logger).printError(any( ClientException.class ));
- verifyNoMoreInteractions(logger);
+ verify( logger ).printError( any( ClientException.class ) );
+ verifyNoMoreInteractions( logger );
}
@Test
- public void shouldReadSingleCypherStatementsFromFileInteractively() throws Exception {
+ public void shouldReadSingleCypherStatementsFromFileInteractively() throws Exception
+ {
// given
ToStringLinePrinter linePrinter = new ToStringLinePrinter();
CypherShell shell = interactiveShell( linePrinter );
// when
- shell.execute( ":source " + fileFromResource( "single.cypher" ));
+ shell.execute( ":source " + fileFromResource( "single.cypher" ) );
exit( shell );
// then
- assertEquals( format("result%n42%n"), linePrinter.result() );
+ assertEquals( format( "result%n42%n" ), linePrinter.result() );
}
@Test
- public void shouldReadMultipleCypherStatementsFromFileInteractively() throws Exception {
+ public void shouldReadMultipleCypherStatementsFromFileInteractively() throws Exception
+ {
// given
ToStringLinePrinter linePrinter = new ToStringLinePrinter();
CypherShell shell = interactiveShell( linePrinter );
// when
- shell.execute( ":source " + fileFromResource( "multiple.cypher" ));
+ shell.execute( ":source " + fileFromResource( "multiple.cypher" ) );
exit( shell );
// then
- assertEquals(format( "result%n42%n" +
- "result%n1337%n" +
- "result%n\"done\"%n"), linePrinter.result() );
+ assertEquals( format( "result%n42%n" +
+ "result%n1337%n" +
+ "result%n\"done\"%n" ), linePrinter.result() );
}
@Test
- public void shouldReadEmptyCypherStatementsFromFileInteractively() throws Exception {
+ public void shouldReadEmptyCypherStatementsFromFileInteractively() throws Exception
+ {
// given
ToStringLinePrinter linePrinter = new ToStringLinePrinter();
CypherShell shell = interactiveShell( linePrinter );
// when
- shell.execute( ":source " + fileFromResource( "empty.cypher" ));
+ shell.execute( ":source " + fileFromResource( "empty.cypher" ) );
exit( shell );
// then
- assertEquals("", linePrinter.result() );
+ assertEquals( "", linePrinter.result() );
}
@Test
- public void shouldHandleInvalidCypherStatementsFromFileInteractively() throws Exception {
+ public void shouldHandleInvalidCypherStatementsFromFileInteractively() throws Exception
+ {
// given
ToStringLinePrinter linePrinter = new ToStringLinePrinter();
CypherShell shell = interactiveShell( linePrinter );
@@ -439,234 +477,261 @@ public void shouldHandleInvalidCypherStatementsFromFileInteractively() throws Ex
// then
exception.expect( ClientException.class );
exception.expectMessage( "Invalid input 'T" );
- shell.execute( ":source " + fileFromResource( "invalid.cypher" ));
+ shell.execute( ":source " + fileFromResource( "invalid.cypher" ) );
}
@Test
- public void shouldFailIfInputFileDoesntExistInteractively() throws Exception {
+ public void shouldFailIfInputFileDoesntExistInteractively() throws Exception
+ {
// given
ToStringLinePrinter linePrinter = new ToStringLinePrinter();
CypherShell shell = interactiveShell( linePrinter );
// expect
- exception.expect( CommandException.class);
+ exception.expect( CommandException.class );
exception.expectMessage( "Cannot find file: 'what.cypher'" );
exception.expectCause( isA( FileNotFoundException.class ) );
shell.execute( ":source what.cypher" );
}
@Test
- public void doesNotStartWhenDefaultDatabaseUnavailableIfInteractive() throws Exception {
- shell.setCommandHelper(new CommandHelper(mock(Logger.class), Historian.empty, shell));
- inputBuffer.put(String.format("neo4j%nneo%n").getBytes());
+ public void doesNotStartWhenDefaultDatabaseUnavailableIfInteractive() throws Exception
+ {
+ shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell ) );
+ inputBuffer.put( String.format( "neo4j%nneo%n" ).getBytes() );
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
// when
- main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
// Multiple databases are only available from 4.0
assumeTrue( majorVersion( shell.getServerVersion() ) >= 4 );
// then
// should be connected
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
// should have prompted and set the username and password
String expectedLoginOutput = format( "username: neo4j%npassword: ***%n" );
- assertEquals(expectedLoginOutput, baos.toString());
- assertEquals("neo4j", connectionConfig.username());
- assertEquals("neo", connectionConfig.password());
+ assertEquals( expectedLoginOutput, baos.toString() );
+ assertEquals( "neo4j", connectionConfig.username() );
+ assertEquals( "neo", connectionConfig.password() );
// Stop the default database
- shell.execute(":use " + SYSTEM_DB_NAME);
- shell.execute("STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME);
+ shell.execute( ":use " + SYSTEM_DB_NAME );
+ shell.execute( "STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME );
- try {
+ try
+ {
shell.disconnect();
// Should get exception that database is unavailable when trying to connect
- main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
- fail("No exception thrown");
- } catch(TransientException|ServiceUnavailableException e) {
- expectDatabaseUnavailable(e, "neo4j");
- } finally {
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
+ fail( "No exception thrown" );
+ }
+ catch ( TransientException | ServiceUnavailableException e )
+ {
+ expectDatabaseUnavailable( e, "neo4j" );
+ }
+ finally
+ {
// Start the default database again
ensureDefaultDatabaseStarted();
}
}
@Test
- public void startsAgainstSystemDatabaseWhenDefaultDatabaseUnavailableIfInteractive() throws Exception {
- shell.setCommandHelper(new CommandHelper(mock(Logger.class), Historian.empty, shell));
+ public void startsAgainstSystemDatabaseWhenDefaultDatabaseUnavailableIfInteractive() throws Exception
+ {
+ shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell ) );
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
// when
- main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
// Multiple databases are only available from 4.0
assumeTrue( majorVersion( shell.getServerVersion() ) >= 4 );
// then
// should be connected
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
// should have prompted and set the username and password
String expectedLoginOutput = format( "username: neo4j%npassword: ***%n" );
- assertEquals(expectedLoginOutput, baos.toString());
- assertEquals("neo4j", connectionConfig.username());
- assertEquals("neo", connectionConfig.password());
+ assertEquals( expectedLoginOutput, baos.toString() );
+ assertEquals( "neo4j", connectionConfig.username() );
+ assertEquals( "neo", connectionConfig.password() );
// Stop the default database
- shell.execute(":use " + SYSTEM_DB_NAME);
- shell.execute("STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME);
+ shell.execute( ":use " + SYSTEM_DB_NAME );
+ shell.execute( "STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME );
- try {
+ try
+ {
shell.disconnect();
// Connect to system database
CliArgs cliArgs = new CliArgs();
- cliArgs.setUsername("neo4j", "");
- cliArgs.setPassword("neo", "");
- cliArgs.setDatabase("system");
- ShellAndConnection sac = getShell(cliArgs);
+ cliArgs.setUsername( "neo4j", "" );
+ cliArgs.setPassword( "neo", "" );
+ cliArgs.setDatabase( "system" );
+ ShellAndConnection sac = getShell( cliArgs );
// Use the new shell and connection config from here on
shell = sac.shell;
connectionConfig = sac.connectionConfig;
- main.connectMaybeInteractively(shell, connectionConfig, true, false, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, false, true );
// then
- assertTrue(shell.isConnected());
- } finally {
+ assertTrue( shell.isConnected() );
+ }
+ finally
+ {
// Start the default database again
ensureDefaultDatabaseStarted();
}
}
@Test
- public void switchingToUnavailableDatabaseIfInteractive() throws Exception {
- shell.setCommandHelper(new CommandHelper(mock(Logger.class), Historian.empty, shell));
- inputBuffer.put(String.format("neo4j%nneo%n").getBytes());
+ public void switchingToUnavailableDatabaseIfInteractive() throws Exception
+ {
+ shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell ) );
+ inputBuffer.put( String.format( "neo4j%nneo%n" ).getBytes() );
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
// when
- main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
// Multiple databases are only available from 4.0
- assumeTrue(majorVersion( shell.getServerVersion() ) >= 4);
+ assumeTrue( majorVersion( shell.getServerVersion() ) >= 4 );
// then
// should be connected
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
// should have prompted and set the username and password
String expectedLoginOutput = format( "username: neo4j%npassword: ***%n" );
- assertEquals(expectedLoginOutput, baos.toString());
- assertEquals("neo4j", connectionConfig.username());
- assertEquals("neo", connectionConfig.password());
+ assertEquals( expectedLoginOutput, baos.toString() );
+ assertEquals( "neo4j", connectionConfig.username() );
+ assertEquals( "neo", connectionConfig.password() );
// Stop the default database
- shell.execute(":use " + SYSTEM_DB_NAME);
- shell.execute("STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME);
+ shell.execute( ":use " + SYSTEM_DB_NAME );
+ shell.execute( "STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME );
- try {
+ try
+ {
// Should get exception that database is unavailable when trying to connect
- shell.execute(":use " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME);
- fail("No exception thrown");
- } catch(TransientException|ServiceUnavailableException e) {
- expectDatabaseUnavailable(e, "neo4j");
- } finally {
+ shell.execute( ":use " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME );
+ fail( "No exception thrown" );
+ }
+ catch ( TransientException | ServiceUnavailableException e )
+ {
+ expectDatabaseUnavailable( e, "neo4j" );
+ }
+ finally
+ {
// Start the default database again
ensureDefaultDatabaseStarted();
}
}
@Test
- public void switchingToUnavailableDefaultDatabaseIfInteractive() throws Exception {
- shell.setCommandHelper(new CommandHelper(mock(Logger.class), Historian.empty, shell));
- inputBuffer.put(String.format("neo4j%nneo%n").getBytes());
+ public void switchingToUnavailableDefaultDatabaseIfInteractive() throws Exception
+ {
+ shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell ) );
+ inputBuffer.put( String.format( "neo4j%nneo%n" ).getBytes() );
- assertEquals("", connectionConfig.username());
- assertEquals("", connectionConfig.password());
+ assertEquals( "", connectionConfig.username() );
+ assertEquals( "", connectionConfig.password() );
// when
- main.connectMaybeInteractively(shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
// Multiple databases are only available from 4.0
- assumeTrue(majorVersion( shell.getServerVersion() ) >= 4);
+ assumeTrue( majorVersion( shell.getServerVersion() ) >= 4 );
// then
// should be connected
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
// should have prompted and set the username and password
String expectedLoginOutput = format( "username: neo4j%npassword: ***%n" );
- assertEquals(expectedLoginOutput, baos.toString());
- assertEquals("neo4j", connectionConfig.username());
- assertEquals("neo", connectionConfig.password());
+ assertEquals( expectedLoginOutput, baos.toString() );
+ assertEquals( "neo4j", connectionConfig.username() );
+ assertEquals( "neo", connectionConfig.password() );
// Stop the default database
- shell.execute(":use " + SYSTEM_DB_NAME);
- shell.execute("STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME);
+ shell.execute( ":use " + SYSTEM_DB_NAME );
+ shell.execute( "STOP DATABASE " + DatabaseManager.DEFAULT_DEFAULT_DB_NAME );
- try {
+ try
+ {
// Should get exception that database is unavailable when trying to connect
- shell.execute(":use");
- fail("No exception thrown");
- } catch(TransientException|ServiceUnavailableException e) {
- expectDatabaseUnavailable(e, "neo4j");
- } finally {
+ shell.execute( ":use" );
+ fail( "No exception thrown" );
+ }
+ catch ( TransientException | ServiceUnavailableException e )
+ {
+ expectDatabaseUnavailable( e, "neo4j" );
+ }
+ finally
+ {
// Start the default database again
ensureDefaultDatabaseStarted();
}
}
- private void expectDatabaseUnavailable(Throwable e, String dbName) {
- String msg = new AnsiLogger(false).getFormattedMessage(e);
- assertThat(msg, anyOf(
- containsString("Database '" + dbName +"' is unavailable"),
- containsString("Unable to get a routing table for database '" + dbName + "' because this database is unavailable")
- ));
+ private void expectDatabaseUnavailable( Throwable e, String dbName )
+ {
+ String msg = new AnsiLogger( false ).getFormattedMessage( e );
+ assertThat( msg, anyOf(
+ containsString( "Database '" + dbName + "' is unavailable" ),
+ containsString( "Unable to get a routing table for database '" + dbName + "' because this database is unavailable" )
+ ) );
}
- private String executeFileNonInteractively(String filename) {
- return executeFileNonInteractively(filename, mock(Logger.class));
+ private String executeFileNonInteractively( String filename )
+ {
+ return executeFileNonInteractively( filename, mock( Logger.class ) );
}
- private String executeFileNonInteractively(String filename, Logger logger) {
+ private String executeFileNonInteractively( String filename, Logger logger )
+ {
CliArgs cliArgs = new CliArgs();
cliArgs.setUsername( USER, "" );
cliArgs.setPassword( PASSWORD, "" );
- cliArgs.setInputFilename(filename);
+ cliArgs.setInputFilename( filename );
- return executeNonInteractively( cliArgs, logger );
+ return executeNonInteractively( cliArgs, logger );
}
- private String executeNonInteractively(CliArgs cliArgs) {
- return executeNonInteractively(cliArgs, mock(Logger.class));
+ private String executeNonInteractively( CliArgs cliArgs )
+ {
+ return executeNonInteractively( cliArgs, mock( Logger.class ) );
}
- private String executeNonInteractively(CliArgs cliArgs, Logger logger)
+ private String executeNonInteractively( CliArgs cliArgs, Logger logger )
{
ToStringLinePrinter linePrinter = new ToStringLinePrinter();
ShellAndConnection sac = getShell( cliArgs, linePrinter );
CypherShell shell = sac.shell;
- main.runShell(cliArgs, shell, logger);
+ main.runShell( cliArgs, shell, logger );
return linePrinter.result();
}
- private String fileFromResource(String filename)
+ private String fileFromResource( String filename )
{
- return getClass().getClassLoader().getResource(filename).getFile();
+ return getClass().getClassLoader().getResource( filename ).getFile();
}
private CypherShell interactiveShell( LinePrinter linePrinter ) throws Exception
{
PrettyConfig prettyConfig = new PrettyConfig( new CliArgs() );
CypherShell shell = new CypherShell( linePrinter, prettyConfig, true, new ShellParameterMap() );
- main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
- shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell) );
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
+ shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell ) );
return shell;
}
@@ -701,7 +766,7 @@ private void exit( CypherShell shell ) throws CommandException
try
{
shell.execute( ":exit" );
- fail("Should have exited");
+ fail( "Should have exited" );
}
catch ( ExitException e )
{
@@ -709,7 +774,7 @@ private void exit( CypherShell shell ) throws CommandException
}
}
- private CliArgs args(String db, String user, String pass, String cypher)
+ private CliArgs args( String db, String user, String pass, String cypher )
{
CliArgs cliArgs = new CliArgs();
cliArgs.setUsername( user, "" );
@@ -719,10 +784,11 @@ private CliArgs args(String db, String user, String pass, String cypher)
return cliArgs;
}
- private int getVersionAndCreateUserWithPasswordChangeRequired() throws Exception {
+ private int getVersionAndCreateUserWithPasswordChangeRequired() throws Exception
+ {
shell.setCommandHelper( new CommandHelper( mock( Logger.class ), Historian.empty, shell ) );
- main.connectMaybeInteractively( shell, connectionConfig, true, true, true);
+ main.connectMaybeInteractively( shell, connectionConfig, true, true, true );
String expectedLoginOutput = format( "username: neo4j%npassword: ***%n" );
assertEquals( expectedLoginOutput, baos.toString() );
ensureUser();
@@ -730,4 +796,16 @@ private int getVersionAndCreateUserWithPasswordChangeRequired() throws Exception
shell.disconnect();
return majorVersion;
}
+
+ private static class ShellAndConnection
+ {
+ CypherShell shell;
+ ConnectionConfig connectionConfig;
+
+ ShellAndConnection( CypherShell shell, ConnectionConfig connectionConfig )
+ {
+ this.shell = shell;
+ this.connectionConfig = connectionConfig;
+ }
+ }
}
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/StringLinePrinter.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/StringLinePrinter.java
index ed03598b..973fd7ea 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/StringLinePrinter.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/StringLinePrinter.java
@@ -1,22 +1,45 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import org.neo4j.shell.prettyprint.LinePrinter;
import org.neo4j.shell.prettyprint.OutputFormatter;
-public class StringLinePrinter implements LinePrinter {
+public class StringLinePrinter implements LinePrinter
+{
private StringBuilder sb = new StringBuilder();
@Override
- public void printOut(String line) {
- sb.append(line).append(OutputFormatter.NEWLINE);
+ public void printOut( String line )
+ {
+ sb.append( line ).append( OutputFormatter.NEWLINE );
}
- public void clear() {
- sb.setLength(0);
+ public void clear()
+ {
+ sb.setLength( 0 );
}
- public String output() {
+ public String output()
+ {
return sb.toString();
}
}
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellFailureIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellFailureIntegrationTest.java
index 76722374..678573dd 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellFailureIntegrationTest.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellFailureIntegrationTest.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.junit.Before;
@@ -13,23 +32,26 @@
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.prettyprint.PrettyConfig;
-public class CypherShellFailureIntegrationTest extends CypherShellIntegrationTest {
+public class CypherShellFailureIntegrationTest extends CypherShellIntegrationTest
+{
@Rule
public final ExpectedException thrown = ExpectedException.none();
private StringLinePrinter linePrinter = new StringLinePrinter();
@Before
- public void setUp() {
+ public void setUp()
+ {
linePrinter.clear();
- shell = new CypherShell(linePrinter, new PrettyConfig(Format.VERBOSE, true, 1000), false, new ShellParameterMap());
+ shell = new CypherShell( linePrinter, new PrettyConfig( Format.VERBOSE, true, 1000 ), false, new ShellParameterMap() );
}
@Test
- public void cypherWithNoPasswordShouldReturnValidError() throws CommandException {
- thrown.expect(AuthenticationException.class);
- thrown.expectMessage("The client is unauthorized due to authentication failure.");
+ public void cypherWithNoPasswordShouldReturnValidError() throws CommandException
+ {
+ thrown.expect( AuthenticationException.class );
+ thrown.expectMessage( "The client is unauthorized due to authentication failure." );
- connect("");
+ connect( "" );
}
}
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellIntegrationTest.java
index 20f13796..13e9f101 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellIntegrationTest.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellIntegrationTest.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.neo4j.shell.ConnectionConfig;
@@ -11,7 +30,8 @@ abstract class CypherShellIntegrationTest
{
CypherShell shell;
- void connect(String password) throws CommandException {
+ void connect( String password ) throws CommandException
+ {
shell.connect( new ConnectionConfig( "bolt", "localhost", 7687, "neo4j", password, Encryption.DEFAULT, ABSENT_DB_NAME ) );
}
}
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellMultiDatabaseIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellMultiDatabaseIntegrationTest.java
index 0390a5c1..44d21d04 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellMultiDatabaseIntegrationTest.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellMultiDatabaseIntegrationTest.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.junit.After;
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellPlainIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellPlainIntegrationTest.java
index afbdedeb..b48f104a 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellPlainIntegrationTest.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellPlainIntegrationTest.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.junit.After;
@@ -21,83 +40,90 @@
import static org.neo4j.shell.prettyprint.OutputFormatter.NEWLINE;
import static org.neo4j.shell.util.Versions.version;
-public class CypherShellPlainIntegrationTest extends CypherShellIntegrationTest {
+public class CypherShellPlainIntegrationTest extends CypherShellIntegrationTest
+{
@Rule
public final ExpectedException thrown = ExpectedException.none();
private StringLinePrinter linePrinter = new StringLinePrinter();
@Before
- public void setUp() throws Exception {
+ public void setUp() throws Exception
+ {
linePrinter.clear();
- shell = new CypherShell(linePrinter, new PrettyConfig(Format.PLAIN, true, 1000), false, new ShellParameterMap());
+ shell = new CypherShell( linePrinter, new PrettyConfig( Format.PLAIN, true, 1000 ), false, new ShellParameterMap() );
connect( "neo" );
}
@After
- public void tearDown() throws Exception {
- shell.execute("MATCH (n) DETACH DELETE (n)");
+ public void tearDown() throws Exception
+ {
+ shell.execute( "MATCH (n) DETACH DELETE (n)" );
}
@Test
- public void periodicCommitWorks() throws CommandException {
- shell.execute("USING PERIODIC COMMIT\n" +
- "LOAD CSV FROM 'https://neo4j.com/docs/cypher-refcard/3.2/csv/artists.csv' AS line\n" +
- "CREATE (:Artist {name: line[1], year: toInteger(line[2])});");
+ public void periodicCommitWorks() throws CommandException
+ {
+ shell.execute( "USING PERIODIC COMMIT\n" +
+ "LOAD CSV FROM 'https://neo4j.com/docs/cypher-refcard/3.2/csv/artists.csv' AS line\n" +
+ "CREATE (:Artist {name: line[1], year: toInteger(line[2])});" );
linePrinter.clear();
- shell.execute("MATCH (a:Artist) WHERE a.name = 'Europe' RETURN a.name");
+ shell.execute( "MATCH (a:Artist) WHERE a.name = 'Europe' RETURN a.name" );
- assertThat(linePrinter.output(), containsString("a.name"+ NEWLINE+"\"Europe\""));
+ assertThat( linePrinter.output(), containsString( "a.name" + NEWLINE + "\"Europe\"" ) );
}
@Test
- public void cypherWithProfileStatements() throws CommandException {
+ public void cypherWithProfileStatements() throws CommandException
+ {
//when
- shell.execute("CYPHER RUNTIME=INTERPRETED PROFILE RETURN null");
+ shell.execute( "CYPHER RUNTIME=INTERPRETED PROFILE RETURN null" );
//then
String actual = linePrinter.output();
// This assertion checks everything except for time and cypher
- assertThat(actual, containsString("Plan: \"PROFILE\""));
- assertThat(actual, containsString("Statement: \"READ_ONLY\""));
- assertThat(actual, containsString("Planner: \"COST\""));
- assertThat(actual, containsString("Runtime: \"INTERPRETED\""));
- assertThat(actual, containsString("DbHits: 0"));
- assertThat(actual, containsString("Rows: 1"));
- assertThat(actual, containsString("null"));
- assertThat(actual, containsString("NULL"));
+ assertThat( actual, containsString( "Plan: \"PROFILE\"" ) );
+ assertThat( actual, containsString( "Statement: \"READ_ONLY\"" ) );
+ assertThat( actual, containsString( "Planner: \"COST\"" ) );
+ assertThat( actual, containsString( "Runtime: \"INTERPRETED\"" ) );
+ assertThat( actual, containsString( "DbHits: 0" ) );
+ assertThat( actual, containsString( "Rows: 1" ) );
+ assertThat( actual, containsString( "null" ) );
+ assertThat( actual, containsString( "NULL" ) );
}
@Test
- public void cypherWithProfileWithMemory() throws CommandException {
+ public void cypherWithProfileWithMemory() throws CommandException
+ {
// given
String serverVersion = shell.getServerVersion();
// Memory profile are only available from 4.1
- assumeThat( version(serverVersion), greaterThanOrEqualTo(version("4.1")));
+ assumeThat( version( serverVersion ), greaterThanOrEqualTo( version( "4.1" ) ) );
//when
- shell.execute("CYPHER RUNTIME=INTERPRETED PROFILE RETURN null");
+ shell.execute( "CYPHER RUNTIME=INTERPRETED PROFILE RETURN null" );
//then
String actual = linePrinter.output();
- System.out.println(actual);
- assertThat(actual, containsString("Memory (Bytes): 0"));
+ System.out.println( actual );
+ assertThat( actual, containsString( "Memory (Bytes): 0" ) );
}
@Test
- public void cypherWithExplainStatements() throws CommandException {
+ public void cypherWithExplainStatements() throws CommandException
+ {
//when
- shell.execute("CYPHER RUNTIME=INTERPRETED EXPLAIN RETURN null");
+ shell.execute( "CYPHER RUNTIME=INTERPRETED EXPLAIN RETURN null" );
//then
String actual = linePrinter.output();
// This assertion checks everything except for time and cypher
- assertThat(actual, containsString("Plan: \"EXPLAIN\""));
- assertThat(actual, containsString("Statement: \"READ_ONLY\""));
- assertThat(actual, containsString("Planner: \"COST\""));
- assertThat(actual, containsString("Runtime: \"INTERPRETED\""));
+ assertThat( actual, containsString( "Plan: \"EXPLAIN\"" ) );
+ assertThat( actual, containsString( "Statement: \"READ_ONLY\"" ) );
+ assertThat( actual, containsString( "Planner: \"COST\"" ) );
+ assertThat( actual, containsString( "Runtime: \"INTERPRETED\"" ) );
}
@Test
@@ -106,15 +132,15 @@ public void shouldUseParamFromCLIArgs() throws EvaluationException, CommandExcep
// given a CLI arg
ShellParameterMap parameterMap = new ShellParameterMap();
parameterMap.setParameter( "foo", "'bar'" );
- shell = new CypherShell( linePrinter, new PrettyConfig( Format.PLAIN, true, 1000), false, parameterMap );
+ shell = new CypherShell( linePrinter, new PrettyConfig( Format.PLAIN, true, 1000 ), false, parameterMap );
connect( "neo" );
//when
- shell.execute("CYPHER RETURN $foo");
+ shell.execute( "CYPHER RETURN $foo" );
//then
String actual = linePrinter.output();
- assertThat(actual, containsString("$foo"));
- assertThat(actual, containsString("bar"));
+ assertThat( actual, containsString( "$foo" ) );
+ assertThat( actual, containsString( "bar" ) );
}
}
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellProtocolIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellProtocolIntegrationTest.java
index a4d52547..c7715f06 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellProtocolIntegrationTest.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellProtocolIntegrationTest.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.junit.Test;
@@ -16,49 +35,55 @@
import static org.neo4j.shell.util.Versions.majorVersion;
import static org.neo4j.shell.util.Versions.minorVersion;
-public class CypherShellProtocolIntegrationTest{
+public class CypherShellProtocolIntegrationTest
+{
@Test
- public void shouldConnectWithBoltProtocol() throws Exception {
- CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000), false, new ShellParameterMap());
+ public void shouldConnectWithBoltProtocol() throws Exception
+ {
+ CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000 ), false, new ShellParameterMap() );
shell.connect( new ConnectionConfig( "bolt", "localhost", 7687, "neo4j", "neo", Encryption.DEFAULT, ABSENT_DB_NAME ) );
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
}
@Test
- public void shouldConnectWithNeo4jProtocol() throws Exception {
- CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000), false, new ShellParameterMap());
+ public void shouldConnectWithNeo4jProtocol() throws Exception
+ {
+ CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000 ), false, new ShellParameterMap() );
// This should work even on older databases without the neo4j protocol, by falling back to bolt
shell.connect( new ConnectionConfig( "neo4j", "localhost", 7687, "neo4j", "neo", Encryption.DEFAULT, ABSENT_DB_NAME ) );
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
}
@Test
- public void shouldConnectWithBoltSSCProtocol() throws Exception {
- CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000), false, new ShellParameterMap());
+ public void shouldConnectWithBoltSSCProtocol() throws Exception
+ {
+ CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000 ), false, new ShellParameterMap() );
// Given 3.X series where X > 1, where SSC are the default. Hard to test in 4.0 sadly.
- onlyIn3_2to3_6( shell);
+ onlyIn3_2to3_6( shell );
shell.connect( new ConnectionConfig( "bolt+ssc", "localhost", 7687, "neo4j", "neo", Encryption.DEFAULT, ABSENT_DB_NAME ) );
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
}
@Test
- public void shouldConnectWithNeo4jSSCProtocol() throws Exception {
- CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000), false, new ShellParameterMap());
+ public void shouldConnectWithNeo4jSSCProtocol() throws Exception
+ {
+ CypherShell shell = new CypherShell( new StringLinePrinter(), new PrettyConfig( Format.PLAIN, true, 1000 ), false, new ShellParameterMap() );
// Given 3.X series where X > 1, where SSC are the default. Hard to test in 4.0 sadly.
- onlyIn3_2to3_6( shell);
+ onlyIn3_2to3_6( shell );
// This should work by falling back to bolt+ssc
shell.connect( new ConnectionConfig( "neo4j+ssc", "localhost", 7687, "neo4j", "neo", Encryption.DEFAULT, ABSENT_DB_NAME ) );
- assertTrue(shell.isConnected());
+ assertTrue( shell.isConnected() );
}
// Here should be tests for "neo4j+s" and "bolt+s", but we don't have the infrastructure for those.
- private void onlyIn3_2to3_6( CypherShell shell) throws Exception {
+ private void onlyIn3_2to3_6( CypherShell shell ) throws Exception
+ {
// Default connection settings
shell.connect( new ConnectionConfig( "bolt", "localhost", 7687, "neo4j", "neo", Encryption.DEFAULT, ABSENT_DB_NAME ) );
assumeTrue( majorVersion( shell.getServerVersion() ) == 3 );
- assumeTrue( minorVersion( shell.getServerVersion() ) > 1 );
+ assumeTrue( minorVersion( shell.getServerVersion() ) > 1 );
shell.disconnect();
}
}
diff --git a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellTransactionIntegrationTest.java b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellTransactionIntegrationTest.java
index a8702806..3c0f733d 100644
--- a/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellTransactionIntegrationTest.java
+++ b/cypher-shell/src/integration-test/java/org/neo4j/shell/commands/CypherShellTransactionIntegrationTest.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.junit.Before;
@@ -92,7 +111,7 @@ public void failureInTxScenarioWithCypherFollowing() throws CommandException
shell.execute( "RETURN 42" );
// then
- assertThat(linePrinter.output(), containsString("42"));
+ assertThat( linePrinter.output(), containsString( "42" ) );
}
@Test
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 18ae4a0c..597f24df 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
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.junit.After;
@@ -26,116 +45,129 @@
import static org.neo4j.shell.util.Versions.majorVersion;
import static org.neo4j.shell.util.Versions.version;
-public class CypherShellVerboseIntegrationTest extends CypherShellIntegrationTest {
+public class CypherShellVerboseIntegrationTest extends CypherShellIntegrationTest
+{
@Rule
public final ExpectedException thrown = ExpectedException.none();
private StringLinePrinter linePrinter = new StringLinePrinter();
@Before
- public void setUp() throws Exception {
+ public void setUp() throws Exception
+ {
linePrinter.clear();
- shell = new CypherShell(linePrinter, new PrettyConfig(Format.VERBOSE, true, 1000), false, new ShellParameterMap());
+ shell = new CypherShell( linePrinter, new PrettyConfig( Format.VERBOSE, true, 1000 ), false, new ShellParameterMap() );
connect( "neo" );
}
@After
- public void tearDown() throws Exception {
- shell.execute("MATCH (n) DETACH DELETE (n)");
+ public void tearDown() throws Exception
+ {
+ shell.execute( "MATCH (n) DETACH DELETE (n)" );
}
@Test
- public void cypherWithNoReturnStatements() throws CommandException {
+ public void cypherWithNoReturnStatements() throws CommandException
+ {
//when
- shell.execute("CREATE (:TestPerson {name: \"Jane Smith\"})");
+ shell.execute( "CREATE (:TestPerson {name: \"Jane Smith\"})" );
//then
- assertThat(linePrinter.output(), containsString("Added 1 nodes, Set 1 properties, Added 1 labels"));
+ assertThat( linePrinter.output(), containsString( "Added 1 nodes, Set 1 properties, Added 1 labels" ) );
}
@Test
- public void cypherWithReturnStatements() throws CommandException {
+ public void cypherWithReturnStatements() throws CommandException
+ {
//when
- shell.execute("CREATE (jane :TestPerson {name: \"Jane Smith\"}) RETURN jane");
+ shell.execute( "CREATE (jane :TestPerson {name: \"Jane Smith\"}) RETURN jane" );
//then
String output = linePrinter.output();
- assertThat(output, containsString("| jane "));
- assertThat(output, containsString("| (:TestPerson {name: \"Jane Smith\"}) |" ));
- assertThat(output, containsString("Added 1 nodes, Set 1 properties, Added 1 labels"));
+ assertThat( output, containsString( "| jane " ) );
+ assertThat( output, containsString( "| (:TestPerson {name: \"Jane Smith\"}) |" ) );
+ assertThat( output, containsString( "Added 1 nodes, Set 1 properties, Added 1 labels" ) );
}
@Test
- public void connectTwiceThrows() throws CommandException {
- thrown.expect(CommandException.class);
- thrown.expectMessage("Already connected");
+ public void connectTwiceThrows() throws CommandException
+ {
+ thrown.expect( CommandException.class );
+ thrown.expectMessage( "Already connected" );
- assertTrue("Shell should already be connected", shell.isConnected());
+ assertTrue( "Shell should already be connected", shell.isConnected() );
connect( "neo" );
}
@Test
- public void resetOutOfTxScenario() throws CommandException {
+ public void resetOutOfTxScenario() throws CommandException
+ {
//when
- shell.execute("CREATE (:TestPerson {name: \"Jane Smith\"})");
+ shell.execute( "CREATE (:TestPerson {name: \"Jane Smith\"})" );
shell.reset();
//then
- shell.execute("CREATE (:TestPerson {name: \"Jane Smith\"})");
- shell.execute("MATCH (n:TestPerson) RETURN n ORDER BY n.name");
+ shell.execute( "CREATE (:TestPerson {name: \"Jane Smith\"})" );
+ shell.execute( "MATCH (n:TestPerson) RETURN n ORDER BY n.name" );
String result = linePrinter.output();
- assertThat(result, containsString(
+ assertThat( result, containsString(
"| (:TestPerson {name: \"Jane Smith\"}) |\n" +
- "| (:TestPerson {name: \"Jane Smith\"}) |"));
+ "| (:TestPerson {name: \"Jane Smith\"}) |" ) );
}
@Test
- public void paramsAndListVariables() throws EvaluationException, CommandException {
- assertTrue(shell.getParameterMap().allParameterValues().isEmpty());
+ public void paramsAndListVariables() throws EvaluationException, CommandException
+ {
+ assertTrue( shell.getParameterMap().allParameterValues().isEmpty() );
long randomLong = System.currentTimeMillis();
String stringInput = "\"randomString\"";
- shell.getParameterMap().setParameter("string", stringInput);
- Object paramValue = shell.getParameterMap().setParameter("bob", String.valueOf(randomLong));
- assertEquals(randomLong, paramValue);
+ shell.getParameterMap().setParameter( "string", stringInput );
+ Object paramValue = shell.getParameterMap().setParameter( "bob", String.valueOf( randomLong ) );
+ assertEquals( randomLong, paramValue );
- shell.execute("RETURN $bob, $string");
+ shell.execute( "RETURN $bob, $string" );
String result = linePrinter.output();
- assertThat(result, containsString("| $bob"));
- assertThat(result, containsString("| " + randomLong + " | " + stringInput + " |"));
- assertEquals(randomLong, shell.getParameterMap().allParameterValues().get( "bob"));
- assertEquals("randomString", shell.getParameterMap().allParameterValues().get( "string"));
+ assertThat( result, containsString( "| $bob" ) );
+ assertThat( result, containsString( "| " + randomLong + " | " + stringInput + " |" ) );
+ assertEquals( randomLong, shell.getParameterMap().allParameterValues().get( "bob" ) );
+ assertEquals( "randomString", shell.getParameterMap().allParameterValues().get( "string" ) );
}
@Test
- public void paramsAndListVariablesWithSpecialCharacters() throws EvaluationException, CommandException {
- assertTrue(shell.getParameterMap().allParameterValues().isEmpty());
+ public void paramsAndListVariablesWithSpecialCharacters() throws EvaluationException, CommandException
+ {
+ assertTrue( shell.getParameterMap().allParameterValues().isEmpty() );
long randomLong = System.currentTimeMillis();
- Object paramValue = shell.getParameterMap().setParameter("`bob`", String.valueOf(randomLong));
- assertEquals(randomLong, paramValue);
+ Object paramValue = shell.getParameterMap().setParameter( "`bob`", String.valueOf( randomLong ) );
+ assertEquals( randomLong, paramValue );
- shell.execute("RETURN $`bob`");
+ shell.execute( "RETURN $`bob`" );
String result = linePrinter.output();
- assertThat(result, containsString("| $`bob`"));
- assertThat(result, containsString("\n| " + randomLong+ " |\n"));
- assertEquals(randomLong, shell.getParameterMap().allParameterValues().get("bob"));
+ assertThat( result, containsString( "| $`bob`" ) );
+ assertThat( result, containsString( "\n| " + randomLong + " |\n" ) );
+ assertEquals( randomLong, shell.getParameterMap().allParameterValues().get( "bob" ) );
}
@Test
- public void cypherWithOrder() throws CommandException {
+ public void cypherWithOrder() throws CommandException
+ {
// given
String serverVersion = shell.getServerVersion();
- assumeThat( version(serverVersion), greaterThanOrEqualTo(version("3.6")));
+ assumeThat( version( serverVersion ), greaterThanOrEqualTo( version( "3.6" ) ) );
// Make sure we are creating a new NEW index
- try {
+ try
+ {
shell.execute( "DROP INDEX ON :Person(age)" );
- } catch ( Exception e ) {
+ }
+ catch ( Exception e )
+ {
// ignore if the index didn't exist
}
@@ -143,7 +175,7 @@ public void cypherWithOrder() throws CommandException {
shell.execute( "CALL db.awaitIndexes()" );
//when
- shell.execute("CYPHER RUNTIME=INTERPRETED EXPLAIN MATCH (n:Person) WHERE n.age >= 18 RETURN n.name, n.age ORDER BY n.age");
+ shell.execute( "CYPHER RUNTIME=INTERPRETED EXPLAIN MATCH (n:Person) WHERE n.age >= 18 RETURN n.name, n.age ORDER BY n.age" );
//then
String actual = linePrinter.output();
@@ -152,13 +184,14 @@ public void cypherWithOrder() throws CommandException {
}
@Test
- public void cypherWithQueryDetails() throws CommandException {
+ public void cypherWithQueryDetails() throws CommandException
+ {
// given
String serverVersion = shell.getServerVersion();
- assumeThat( version(serverVersion), greaterThanOrEqualTo(version("4.1")));
+ assumeThat( version( serverVersion ), greaterThanOrEqualTo( version( "4.1" ) ) );
//when
- shell.execute("EXPLAIN MATCH (n) with n.age AS age RETURN age");
+ shell.execute( "EXPLAIN MATCH (n) with n.age AS age RETURN age" );
//then
String actual = linePrinter.output();
@@ -168,13 +201,14 @@ public void cypherWithQueryDetails() throws CommandException {
}
@Test
- public void cypherWithoutQueryDetails() throws CommandException {
+ public void cypherWithoutQueryDetails() throws CommandException
+ {
// given
String serverVersion = shell.getServerVersion();
- assumeThat( version(serverVersion), not(greaterThanOrEqualTo(version("4.1"))));
+ assumeThat( version( serverVersion ), not( greaterThanOrEqualTo( version( "4.1" ) ) ) );
//when
- shell.execute("EXPLAIN MATCH (n) with n.age AS age RETURN age");
+ shell.execute( "EXPLAIN MATCH (n) with n.age AS age RETURN age" );
//then
String actual = linePrinter.output();
@@ -183,65 +217,69 @@ public void cypherWithoutQueryDetails() throws CommandException {
}
@Test
- public void cypherWithExplainAndRulePlanner() throws CommandException {
+ public void cypherWithExplainAndRulePlanner() throws CommandException
+ {
//given (there is no rule planner in neo4j 4.0)
assumeTrue( majorVersion( shell.getServerVersion() ) < 4 );
//when
- shell.execute("CYPHER planner=rule EXPLAIN MATCH (e:E) WHERE e.bucket='Live' and e.id = 23253473 RETURN count(e)");
+ shell.execute( "CYPHER planner=rule EXPLAIN MATCH (e:E) WHERE e.bucket='Live' and e.id = 23253473 RETURN count(e)" );
//then
String actual = linePrinter.output();
- assertThat(actual, containsString("\"EXPLAIN\""));
- assertThat(actual, containsString("\"READ_ONLY\""));
- assertThat(actual, containsString("\"RULE\""));
- assertThat(actual, containsString("\"INTERPRETED\""));
+ assertThat( actual, containsString( "\"EXPLAIN\"" ) );
+ assertThat( actual, containsString( "\"READ_ONLY\"" ) );
+ assertThat( actual, containsString( "\"RULE\"" ) );
+ assertThat( actual, containsString( "\"INTERPRETED\"" ) );
}
@Test
- public void cypherWithProfileWithMemory() throws CommandException {
+ public void cypherWithProfileWithMemory() throws CommandException
+ {
// given
String serverVersion = shell.getServerVersion();
// Memory profile are only available from 4.1
- assumeThat( version(serverVersion), greaterThanOrEqualTo(version("4.1")));
+ assumeThat( version( serverVersion ), greaterThanOrEqualTo( version( "4.1" ) ) );
//when
- shell.execute("CYPHER RUNTIME=INTERPRETED PROFILE WITH 1 AS x RETURN DISTINCT x");
+ shell.execute( "CYPHER RUNTIME=INTERPRETED PROFILE WITH 1 AS x RETURN DISTINCT x" );
//then
String actual = linePrinter.output();
- assertThat(actual.replace( " ", "" ), containsString("|Plan|Statement|Version|Planner|Runtime|Time|DbHits|Rows|Memory(Bytes)|")); // First table
- assertThat(actual.replace( " ", "" ), containsString("|Operator|Details|EstimatedRows|Rows|DBHits|CacheH/M|Memory(Bytes)|")); // Second table
+ assertThat( actual.replace( " ", "" ), containsString( "|Plan|Statement|Version|Planner|Runtime|Time|DbHits|Rows|Memory(Bytes)|" ) ); // First table
+ assertThat( actual.replace( " ", "" ), containsString( "|Operator|Details|EstimatedRows|Rows|DBHits|CacheH/M|Memory(Bytes)|" ) ); // Second table
}
@Test
- public void shouldShowTheNumberOfRows() throws CommandException {
+ public void shouldShowTheNumberOfRows() throws CommandException
+ {
//when
- shell.execute("UNWIND [1,2,3] AS row RETURN row");
+ shell.execute( "UNWIND [1,2,3] AS row RETURN row" );
//then
String actual = linePrinter.output();
- assertThat(actual, containsString("3 rows available"));
+ assertThat( actual, containsString( "3 rows available" ) );
}
@Test
- public void shouldNotContainUnnecessaryNewLines() throws CommandException {
+ public void shouldNotContainUnnecessaryNewLines() throws CommandException
+ {
//when
- shell.execute("UNWIND [1,2,3] AS row RETURN row");
+ shell.execute( "UNWIND [1,2,3] AS row RETURN row" );
//then
String actual = linePrinter.output();
- assertThat(actual,
- containsString( String.format(
- "+-----+%n" +
- "| row |%n" +
- "+-----+%n" +
- "| 1 |%n" +
- "| 2 |%n" +
- "| 3 |%n" +
- "+-----+%n" +
- "%n" +
- "3 rows available after")));
+ assertThat( actual,
+ containsString( String.format(
+ "+-----+%n" +
+ "| row |%n" +
+ "+-----+%n" +
+ "| 1 |%n" +
+ "| 2 |%n" +
+ "| 3 |%n" +
+ "+-----+%n" +
+ "%n" +
+ "3 rows available after" ) ) );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/ConnectionConfig.java b/cypher-shell/src/main/java/org/neo4j/shell/ConnectionConfig.java
index 6db56e9f..50de7674 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/ConnectionConfig.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/ConnectionConfig.java
@@ -1,10 +1,30 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import javax.annotation.Nonnull;
import org.neo4j.shell.cli.Encryption;
-public class ConnectionConfig {
+public class ConnectionConfig
+{
public static final String USERNAME_ENV_VAR = "NEO4J_USERNAME";
public static final String PASSWORD_ENV_VAR = "NEO4J_PASSWORD";
public static final String DATABASE_ENV_VAR = "NEO4J_DATABASE";
@@ -18,90 +38,106 @@ public class ConnectionConfig {
private String newPassword;
private String database;
- public ConnectionConfig(@Nonnull String scheme,
- @Nonnull String host,
- int port,
- @Nonnull String username,
- @Nonnull String password,
- Encryption encryption,
- @Nonnull String database) {
+ public ConnectionConfig( @Nonnull String scheme,
+ @Nonnull String host,
+ int port,
+ @Nonnull String username,
+ @Nonnull String password,
+ Encryption encryption,
+ @Nonnull String database )
+ {
this.host = host;
this.port = port;
- this.username = fallbackToEnvVariable(username, USERNAME_ENV_VAR);
- this.password = fallbackToEnvVariable(password, PASSWORD_ENV_VAR);
+ this.username = fallbackToEnvVariable( username, USERNAME_ENV_VAR );
+ this.password = fallbackToEnvVariable( password, PASSWORD_ENV_VAR );
this.encryption = encryption;
this.scheme = scheme;
- this.database = fallbackToEnvVariable(database, DATABASE_ENV_VAR);
+ this.database = fallbackToEnvVariable( database, DATABASE_ENV_VAR );
}
/**
* @return preferredValue if not empty, else the contents of the fallback environment variable
*/
@Nonnull
- private static String fallbackToEnvVariable(@Nonnull String preferredValue, @Nonnull String fallbackEnvVar) {
- String result = System.getenv(fallbackEnvVar);
- if (result == null || !preferredValue.isEmpty()) {
+ private static String fallbackToEnvVariable( @Nonnull String preferredValue, @Nonnull String fallbackEnvVar )
+ {
+ String result = System.getenv( fallbackEnvVar );
+ if ( result == null || !preferredValue.isEmpty() )
+ {
result = preferredValue;
}
return result;
}
@Nonnull
- public String scheme() {
+ public String scheme()
+ {
return scheme;
}
@Nonnull
- public String host() {
+ public String host()
+ {
return host;
}
- public int port() {
+ public int port()
+ {
return port;
}
@Nonnull
- public String username() {
+ public String username()
+ {
return username;
}
@Nonnull
- public String password() {
+ public String password()
+ {
return password;
}
- public String newPassword() {
+ public String newPassword()
+ {
return newPassword;
}
@Nonnull
- public String driverUrl() {
- return String.format("%s://%s:%d", scheme(), host(), port());
+ public String driverUrl()
+ {
+ return String.format( "%s://%s:%d", scheme(), host(), port() );
}
@Nonnull
- public Encryption encryption() {
+ public Encryption encryption()
+ {
return encryption;
}
@Nonnull
- public String database() {
+ public String database()
+ {
return database;
}
- public void setUsername(@Nonnull String username) {
+ public void setUsername( @Nonnull String username )
+ {
this.username = username;
}
- public void setPassword(@Nonnull String password) {
+ public void setPassword( @Nonnull String password )
+ {
this.password = password;
}
- public void setNewPassword( String password) {
+ public void setNewPassword( String password )
+ {
this.newPassword = password;
}
- public boolean passwordChangeRequired() {
+ public boolean passwordChangeRequired()
+ {
return this.newPassword != null;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/Connector.java b/cypher-shell/src/main/java/org/neo4j/shell/Connector.java
index 121e5e5e..3f24f30e 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/Connector.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/Connector.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import javax.annotation.Nonnull;
@@ -8,7 +27,8 @@
/**
* An object with the ability to connect and disconnect.
*/
-public interface Connector {
+public interface Connector
+{
/**
* @return true if connected, false otherwise
@@ -16,22 +36,21 @@ public interface Connector {
boolean isConnected();
/**
- *
* @throws CommandException if connection failed
*/
- default void connect(@Nonnull ConnectionConfig connectionConfig) throws CommandException {
+ default void connect( @Nonnull ConnectionConfig connectionConfig ) throws CommandException
+ {
connect( connectionConfig, null );
}
/**
- *
* @throws CommandException if connection failed
*/
- void connect( @Nonnull ConnectionConfig connectionConfig, ThrowingAction action) throws CommandException;
+ void connect( @Nonnull ConnectionConfig connectionConfig, ThrowingAction action ) throws CommandException;
/**
- * Returns the version of Neo4j which the shell is connected to. If the version is before 3.1.0-M09, or we are not
- * connected yet, this returns the empty string.
+ * Returns the version of Neo4j which the shell is connected to. If the version is before 3.1.0-M09, or we are not connected yet, this returns the empty
+ * string.
*
* @return the version of neo4j (like '3.1.0') if connected and available, an empty string otherwise
*/
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 9ddb646f..767b7f9b 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/CypherShell.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/CypherShell.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import java.util.Optional;
@@ -23,9 +42,10 @@
/**
* A possibly interactive shell for evaluating cypher statements.
*/
-public class CypherShell implements StatementExecuter, Connector, TransactionHandler, DatabaseManager {
+public class CypherShell implements StatementExecuter, Connector, TransactionHandler, DatabaseManager
+{
// Final space to catch newline
- private static final Pattern cmdNamePattern = Pattern.compile("^\\s*(?[^\\s]+)\\b(?.*)\\s*$");
+ private static final Pattern cmdNamePattern = Pattern.compile( "^\\s*(?[^\\s]+)\\b(?.*)\\s*$" );
private final ParameterMap parameterMap;
private final LinePrinter linePrinter;
private final BoltStateHandler boltStateHandler;
@@ -33,17 +53,19 @@ public class CypherShell implements StatementExecuter, Connector, TransactionHan
private CommandHelper commandHelper;
private String lastNeo4jErrorCode;
- public CypherShell(@Nonnull LinePrinter linePrinter,
- @Nonnull PrettyConfig prettyConfig,
- boolean isInteractive,
- ParameterMap parameterMap) {
- this(linePrinter, new BoltStateHandler(isInteractive), new PrettyPrinter(prettyConfig), parameterMap);
+ public CypherShell( @Nonnull LinePrinter linePrinter,
+ @Nonnull PrettyConfig prettyConfig,
+ boolean isInteractive,
+ ParameterMap parameterMap )
+ {
+ this( linePrinter, new BoltStateHandler( isInteractive ), new PrettyPrinter( prettyConfig ), parameterMap );
}
- protected CypherShell(@Nonnull LinePrinter linePrinter,
- @Nonnull BoltStateHandler boltStateHandler,
- @Nonnull PrettyPrinter prettyPrinter,
- ParameterMap parameterMap) {
+ protected CypherShell( @Nonnull LinePrinter linePrinter,
+ @Nonnull BoltStateHandler boltStateHandler,
+ @Nonnull PrettyPrinter prettyPrinter,
+ ParameterMap parameterMap )
+ {
this.linePrinter = linePrinter;
this.boltStateHandler = boltStateHandler;
this.prettyPrinter = prettyPrinter;
@@ -55,81 +77,96 @@ protected CypherShell(@Nonnull LinePrinter linePrinter,
* @param text to trim
* @return text without trailing semicolons
*/
- protected static String stripTrailingSemicolons(@Nonnull String text) {
+ protected static String stripTrailingSemicolons( @Nonnull String text )
+ {
int end = text.length();
- while (end > 0 && text.substring(0, end).endsWith(";")) {
+ while ( end > 0 && text.substring( 0, end ).endsWith( ";" ) )
+ {
end -= 1;
}
- return text.substring(0, end);
+ return text.substring( 0, end );
}
@Override
- public void execute(@Nonnull final String cmdString) throws ExitException, CommandException {
+ public void execute( @Nonnull final String cmdString ) throws ExitException, CommandException
+ {
// See if it's a shell command
- final Optional cmd = getCommandExecutable(cmdString);
- if (cmd.isPresent()) {
- executeCmd(cmd.get());
+ final Optional cmd = getCommandExecutable( cmdString );
+ if ( cmd.isPresent() )
+ {
+ executeCmd( cmd.get() );
return;
}
// Else it will be parsed as Cypher, but for that we need to be connected
- if (!isConnected()) {
- throw new CommandException("Not connected to Neo4j");
+ if ( !isConnected() )
+ {
+ throw new CommandException( "Not connected to Neo4j" );
}
- executeCypher(cmdString);
+ executeCypher( cmdString );
}
@Override
- public String lastNeo4jErrorCode() {
+ public String lastNeo4jErrorCode()
+ {
return lastNeo4jErrorCode;
}
/**
- * Executes a piece of text as if it were Cypher. By default, all of the cypher is executed in single statement
- * (with an implicit transaction).
+ * Executes a piece of text as if it were Cypher. By default, all of the cypher is executed in single statement (with an implicit transaction).
*
* @param cypher non-empty cypher text to executeLine
*/
- private void executeCypher(@Nonnull final String cypher) throws CommandException {
- try {
- final Optional result = boltStateHandler.runCypher(cypher, parameterMap.allParameterValues());
- result.ifPresent(boltResult -> {
- prettyPrinter.format(boltResult, linePrinter);
- boltStateHandler.updateActualDbName(boltResult.getSummary());
- });
+ private void executeCypher( @Nonnull final String cypher ) throws CommandException
+ {
+ try
+ {
+ final Optional result = boltStateHandler.runCypher( cypher, parameterMap.allParameterValues() );
+ result.ifPresent( boltResult ->
+ {
+ prettyPrinter.format( boltResult, linePrinter );
+ boltStateHandler.updateActualDbName( boltResult.getSummary() );
+ } );
lastNeo4jErrorCode = null;
- } catch (Neo4jException e) {
- lastNeo4jErrorCode = getErrorCode(e);
+ }
+ catch ( Neo4jException e )
+ {
+ lastNeo4jErrorCode = getErrorCode( e );
throw boltStateHandler.handleException( e );
}
}
@Override
- public boolean isConnected() {
+ public boolean isConnected()
+ {
return boltStateHandler.isConnected();
}
@Nonnull
- protected Optional getCommandExecutable(@Nonnull final String line) {
- Matcher m = cmdNamePattern.matcher(line);
- if (commandHelper == null || !m.matches()) {
+ protected Optional getCommandExecutable( @Nonnull final String line )
+ {
+ Matcher m = cmdNamePattern.matcher( line );
+ if ( commandHelper == null || !m.matches() )
+ {
return Optional.empty();
}
- String name = m.group("name");
- String args = m.group("args");
+ String name = m.group( "name" );
+ String args = m.group( "args" );
- Command cmd = commandHelper.getCommand(name);
+ Command cmd = commandHelper.getCommand( name );
- if (cmd == null) {
+ if ( cmd == null )
+ {
return Optional.empty();
}
- return Optional.of(() -> cmd.execute(stripTrailingSemicolons(args)));
+ return Optional.of( () -> cmd.execute( stripTrailingSemicolons( args ) ) );
}
- protected void executeCmd(@Nonnull final CommandExecutable cmdExe) throws ExitException, CommandException {
+ protected void executeCmd( @Nonnull final CommandExecutable cmdExe ) throws ExitException, CommandException
+ {
cmdExe.execute();
}
@@ -141,63 +178,78 @@ protected void executeCmd(@Nonnull final CommandExecutable cmdExe) throws ExitEx
*/
@Override
public void connect( @Nonnull ConnectionConfig connectionConfig,
- ThrowingAction command) throws CommandException {
- boltStateHandler.connect(connectionConfig, command );
+ ThrowingAction command ) throws CommandException
+ {
+ boltStateHandler.connect( connectionConfig, command );
}
@Nonnull
@Override
- public String getServerVersion() {
+ public String getServerVersion()
+ {
return boltStateHandler.getServerVersion();
}
@Override
- public void beginTransaction() throws CommandException {
+ public void beginTransaction() throws CommandException
+ {
boltStateHandler.beginTransaction();
}
@Override
- public void commitTransaction() throws CommandException {
- try {
+ public void commitTransaction() throws CommandException
+ {
+ try
+ {
boltStateHandler.commitTransaction();
lastNeo4jErrorCode = null;
- } catch (Neo4jException e) {
- lastNeo4jErrorCode = getErrorCode(e);
+ }
+ catch ( Neo4jException e )
+ {
+ lastNeo4jErrorCode = getErrorCode( e );
throw e;
}
}
@Override
- public void rollbackTransaction() throws CommandException {
+ public void rollbackTransaction() throws CommandException
+ {
boltStateHandler.rollbackTransaction();
}
@Override
- public boolean isTransactionOpen() {
+ public boolean isTransactionOpen()
+ {
return boltStateHandler.isTransactionOpen();
}
- public void setCommandHelper(@Nonnull CommandHelper commandHelper) {
+ public void setCommandHelper( @Nonnull CommandHelper commandHelper )
+ {
this.commandHelper = commandHelper;
}
@Override
- public void reset() {
+ public void reset()
+ {
boltStateHandler.reset();
}
- protected void addRuntimeHookToResetShell() {
- Runtime.getRuntime().addShutdownHook(new Thread(this::reset));
+ protected void addRuntimeHookToResetShell()
+ {
+ Runtime.getRuntime().addShutdownHook( new Thread( this::reset ) );
}
@Override
- public void setActiveDatabase(String databaseName) throws CommandException
+ public void setActiveDatabase( String databaseName ) throws CommandException
{
- try {
- boltStateHandler.setActiveDatabase(databaseName);
+ try
+ {
+ boltStateHandler.setActiveDatabase( databaseName );
lastNeo4jErrorCode = null;
- } catch (Neo4jException e) {
- lastNeo4jErrorCode = getErrorCode(e);
+ }
+ catch ( Neo4jException e )
+ {
+ lastNeo4jErrorCode = getErrorCode( e );
throw e;
}
}
@@ -222,30 +274,36 @@ public ParameterMap getParameterMap()
return parameterMap;
}
- public void changePassword(@Nonnull ConnectionConfig connectionConfig) {
- boltStateHandler.changePassword(connectionConfig);
+ public void changePassword( @Nonnull ConnectionConfig connectionConfig )
+ {
+ boltStateHandler.changePassword( connectionConfig );
}
/**
* Used for testing purposes
*/
- public void disconnect() {
+ public void disconnect()
+ {
boltStateHandler.disconnect();
}
- private String getErrorCode(Neo4jException e) {
+ private String getErrorCode( Neo4jException e )
+ {
Neo4jException statusException = e;
// If we encountered a later suppressed Neo4jException we use that as the basis for the status instead
Throwable[] suppressed = e.getSuppressed();
- for (Throwable s : suppressed) {
- if (s instanceof Neo4jException) {
+ for ( Throwable s : suppressed )
+ {
+ if ( s instanceof Neo4jException )
+ {
statusException = (Neo4jException) s;
break;
}
}
- if (statusException instanceof ServiceUnavailableException || statusException instanceof DiscoveryException) {
+ if ( statusException instanceof ServiceUnavailableException || statusException instanceof DiscoveryException )
+ {
// Treat this the same way as a DatabaseUnavailable error for now.
return DATABASE_UNAVAILABLE_ERROR_CODE;
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/DatabaseManager.java b/cypher-shell/src/main/java/org/neo4j/shell/DatabaseManager.java
index 8961c561..ec0f49b5 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/DatabaseManager.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/DatabaseManager.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import org.neo4j.shell.exception.CommandException;
@@ -14,11 +33,10 @@ public interface DatabaseManager
String DATABASE_UNAVAILABLE_ERROR_CODE = "Neo.TransientError.General.DatabaseUnavailable";
/**
- * Sets the active database name as set by the user.
- * If the current state is connected, try to reconnect to that database.
- * If the current state is disconnected, simply update `activeDatabaseAsSetByUser`.
+ * Sets the active database name as set by the user. If the current state is connected, try to reconnect to that database. If the current state is
+ * disconnected, simply update `activeDatabaseAsSetByUser`.
*/
- void setActiveDatabase(String databaseName) throws CommandException;
+ void setActiveDatabase( String databaseName ) throws CommandException;
String getActiveDatabaseAsSetByUser();
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/Historian.java b/cypher-shell/src/main/java/org/neo4j/shell/Historian.java
index 292359ee..b38d40e8 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/Historian.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/Historian.java
@@ -1,33 +1,55 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
-import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.Nonnull;
/**
* An object which keeps a record of past commands
*/
-public interface Historian {
- /**
- *
- * @return a list of all past commands in the history, in order of execution (first command sorted first).
- */
- @Nonnull
- List getHistory();
-
- Historian empty = new Historian() {
+public interface Historian
+{
+ Historian empty = new Historian()
+ {
@Nonnull
@Override
- public List getHistory() {
+ public List getHistory()
+ {
return new ArrayList<>();
}
@Override
- public void flushHistory() {
+ public void flushHistory()
+ {
}
};
+ /**
+ * @return a list of all past commands in the history, in order of execution (first command sorted first).
+ */
+ @Nonnull
+ List getHistory();
+
/**
* Flush history to disk
*/
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/Main.java b/cypher-shell/src/main/java/org/neo4j/shell/Main.java
index 7b3533a6..98d30d2e 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/Main.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/Main.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import jline.console.ConsoleReader;
@@ -24,71 +43,82 @@
import static org.neo4j.shell.ShellRunner.isOutputInteractive;
import static org.neo4j.shell.util.Versions.isPasswordChangeRequiredException;
-public class Main {
- static final String NEO_CLIENT_ERROR_SECURITY_UNAUTHORIZED = "Neo.ClientError.Security.Unauthorized";
+public class Main
+{
public static final int EXIT_FAILURE = 1;
public static final int EXIT_SUCCESS = 0;
+ static final String NEO_CLIENT_ERROR_SECURITY_UNAUTHORIZED = "Neo.ClientError.Security.Unauthorized";
private final InputStream in;
private final PrintStream out;
private final boolean hasSpecialInteractiveOutputStream;
- public static void main(String[] args) {
- CliArgs cliArgs = CliArgHelper.parse(args);
-
- // if null, then command line parsing went wrong
- // CliArgs has already printed errors.
- if (cliArgs == null) {
- System.exit(1);
- }
-
- Main main = new Main();
- main.startShell(cliArgs);
- }
-
- Main() {
- this(System.in, System.out, false);
+ Main()
+ {
+ this( System.in, System.out, false );
}
/**
* For testing purposes
*/
- Main(final InputStream in, final PrintStream out) {
- this(in, out, true);
+ Main( final InputStream in, final PrintStream out )
+ {
+ this( in, out, true );
}
- private Main(final InputStream in, final PrintStream out, final boolean hasSpecialInteractiveOutputStream ) {
+ private Main( final InputStream in, final PrintStream out, final boolean hasSpecialInteractiveOutputStream )
+ {
this.in = in;
this.out = out;
this.hasSpecialInteractiveOutputStream = hasSpecialInteractiveOutputStream;
}
+ public static void main( String[] args )
+ {
+ CliArgs cliArgs = CliArgHelper.parse( args );
+
+ // if null, then command line parsing went wrong
+ // CliArgs has already printed errors.
+ if ( cliArgs == null )
+ {
+ System.exit( 1 );
+ }
+
+ Main main = new Main();
+ main.startShell( cliArgs );
+ }
+
/**
* Delegate for testing purposes
*/
- private OutputStream getOutputStreamForInteractivePrompt() {
+ private OutputStream getOutputStreamForInteractivePrompt()
+ {
return hasSpecialInteractiveOutputStream ? this.out : ShellRunner.getOutputStreamForInteractivePrompt();
}
- void startShell(@Nonnull CliArgs cliArgs) {
- if (cliArgs.getVersion()) {
- out.println("Cypher-Shell " + Build.version());
+ void startShell( @Nonnull CliArgs cliArgs )
+ {
+ if ( cliArgs.getVersion() )
+ {
+ out.println( "Cypher-Shell " + Build.version() );
}
- if (cliArgs.getDriverVersion()) {
- out.println("Neo4j Driver " + Build.driverVersion());
+ if ( cliArgs.getDriverVersion() )
+ {
+ out.println( "Neo4j Driver " + Build.driverVersion() );
}
- if (cliArgs.getVersion() || cliArgs.getDriverVersion()) {
+ if ( cliArgs.getVersion() || cliArgs.getDriverVersion() )
+ {
return;
}
Logger logger = new AnsiLogger( cliArgs.getDebugMode() );
PrettyConfig prettyConfig = new PrettyConfig( cliArgs );
CypherShell shell = new CypherShell( logger, prettyConfig, ShellRunner.shouldBeInteractive( cliArgs ),
- cliArgs.getParameters() );
+ cliArgs.getParameters() );
int exitCode = runShell( cliArgs, shell, logger );
System.exit( exitCode );
}
- int runShell(@Nonnull CliArgs cliArgs, @Nonnull CypherShell shell, Logger logger )
+ int runShell( @Nonnull CliArgs cliArgs, @Nonnull CypherShell shell, Logger logger )
{
ConnectionConfig connectionConfig = new ConnectionConfig(
cliArgs.getScheme(),
@@ -105,19 +135,19 @@ int runShell(@Nonnull CliArgs cliArgs, @Nonnull CypherShell shell, Logger logger
{
// Can only prompt for password if input has not been redirected
connectMaybeInteractively( shell, connectionConfig,
- !cliArgs.getNonInteractive() && isInputInteractive(),
- !cliArgs.getNonInteractive() && isOutputInteractive(),
- !cliArgs.getNonInteractive()/*Don't ask for password if using --non-interactive*/,
- () -> shell.execute( cliArgs.getCypher().get() ) );
+ !cliArgs.getNonInteractive() && isInputInteractive(),
+ !cliArgs.getNonInteractive() && isOutputInteractive(),
+ !cliArgs.getNonInteractive()/*Don't ask for password if using --non-interactive*/,
+ () -> shell.execute( cliArgs.getCypher().get() ) );
return EXIT_SUCCESS;
}
else
{
// Can only prompt for password if input has not been redirected
connectMaybeInteractively( shell, connectionConfig,
- !cliArgs.getNonInteractive() && isInputInteractive(),
+ !cliArgs.getNonInteractive() && isInputInteractive(),
!cliArgs.getNonInteractive() && isOutputInteractive(),
- !cliArgs.getNonInteractive()/*Don't ask for password if using --non-interactive*/);
+ !cliArgs.getNonInteractive()/*Don't ask for password if using --non-interactive*/ );
// Construct shellrunner after connecting, due to interrupt handling
ShellRunner shellRunner = ShellRunner.getShellRunner( cliArgs, shell, logger, connectionConfig );
CommandHelper commandHelper = new CommandHelper( logger, shellRunner.getHistorian(), shell );
@@ -134,12 +164,13 @@ int runShell(@Nonnull CliArgs cliArgs, @Nonnull CypherShell shell, Logger logger
}
}
- void connectMaybeInteractively(@Nonnull CypherShell shell,
- @Nonnull ConnectionConfig connectionConfig,
- boolean inputInteractive,
- boolean outputInteractive,
- boolean shouldPromptForPassword)
- throws Exception {
+ void connectMaybeInteractively( @Nonnull CypherShell shell,
+ @Nonnull ConnectionConfig connectionConfig,
+ boolean inputInteractive,
+ boolean outputInteractive,
+ boolean shouldPromptForPassword )
+ throws Exception
+ {
connectMaybeInteractively( shell, connectionConfig, inputInteractive, outputInteractive, shouldPromptForPassword, null );
}
@@ -147,139 +178,160 @@ void connectMaybeInteractively(@Nonnull CypherShell shell,
* Connect the shell to the server, and try to handle missing passwords and such
*/
private void connectMaybeInteractively( @Nonnull CypherShell shell,
- @Nonnull ConnectionConfig connectionConfig,
- boolean inputInteractive,
- boolean outputInteractive,
- boolean shouldPromptForPassword,
- ThrowingAction command )
- throws Exception {
+ @Nonnull ConnectionConfig connectionConfig,
+ boolean inputInteractive,
+ boolean outputInteractive,
+ boolean shouldPromptForPassword,
+ ThrowingAction command )
+ throws Exception
+ {
boolean didPrompt = false;
// Prompt directly in interactive mode if user provided username but not password
- if (inputInteractive && !connectionConfig.username().isEmpty() && connectionConfig.password().isEmpty()) {
- promptForUsernameAndPassword(connectionConfig, outputInteractive);
+ if ( inputInteractive && !connectionConfig.username().isEmpty() && connectionConfig.password().isEmpty() )
+ {
+ promptForUsernameAndPassword( connectionConfig, outputInteractive );
didPrompt = true;
}
- while (true) {
- try {
+ while ( true )
+ {
+ try
+ {
// Try to connect
- shell.connect(connectionConfig, command);
+ shell.connect( connectionConfig, command );
// If no exception occurred we are done
break;
- } catch (AuthenticationException e) {
+ }
+ catch ( AuthenticationException e )
+ {
// Fail if we already prompted,
// or do not have interactive input,
// or already tried with both username and password
- if (didPrompt || !inputInteractive || (!connectionConfig.username().isEmpty() && !connectionConfig.password().isEmpty())) {
+ if ( didPrompt || !inputInteractive || (!connectionConfig.username().isEmpty() && !connectionConfig.password().isEmpty()) )
+ {
throw e;
}
// Otherwise we prompt for username and password, and try to connect again
- promptForUsernameAndPassword(connectionConfig, outputInteractive);
+ promptForUsernameAndPassword( connectionConfig, outputInteractive );
didPrompt = true;
- } catch (Neo4jException e) {
- if (shouldPromptForPassword && isPasswordChangeRequiredException(e)) {
- promptForPasswordChange(connectionConfig, outputInteractive);
- shell.changePassword(connectionConfig);
+ }
+ catch ( Neo4jException e )
+ {
+ if ( shouldPromptForPassword && isPasswordChangeRequiredException( e ) )
+ {
+ promptForPasswordChange( connectionConfig, outputInteractive );
+ shell.changePassword( connectionConfig );
didPrompt = true;
- } else {
+ }
+ else
+ {
throw e;
}
}
}
}
- private void promptForUsernameAndPassword(ConnectionConfig connectionConfig, boolean outputInteractive) throws Exception {
+ private void promptForUsernameAndPassword( ConnectionConfig connectionConfig, boolean outputInteractive ) throws Exception
+ {
OutputStream promptOutputStream = getOutputStreamForInteractivePrompt();
- ConsoleReader consoleReader = new ConsoleReader(in, promptOutputStream);
+ ConsoleReader consoleReader = new ConsoleReader( in, promptOutputStream );
// Disable expansion of bangs: !
- consoleReader.setExpandEvents(false);
+ consoleReader.setExpandEvents( false );
// Ensure Reader does not handle user input for ctrl+C behaviour
- consoleReader.setHandleUserInterrupt(false);
+ consoleReader.setHandleUserInterrupt( false );
- try {
- if (connectionConfig.username().isEmpty()) {
+ try
+ {
+ if ( connectionConfig.username().isEmpty() )
+ {
String username = outputInteractive ?
- promptForNonEmptyText("username", consoleReader, null) :
- promptForText("username", consoleReader, null);
- connectionConfig.setUsername(username);
+ promptForNonEmptyText( "username", consoleReader, null ) :
+ promptForText( "username", consoleReader, null );
+ connectionConfig.setUsername( username );
}
- if (connectionConfig.password().isEmpty()) {
- connectionConfig.setPassword(promptForText("password", consoleReader, '*'));
+ if ( connectionConfig.password().isEmpty() )
+ {
+ connectionConfig.setPassword( promptForText( "password", consoleReader, '*' ) );
}
- } finally {
+ }
+ finally
+ {
consoleReader.close();
}
}
- private void promptForPasswordChange(ConnectionConfig connectionConfig, boolean outputInteractive) throws Exception {
+ private void promptForPasswordChange( ConnectionConfig connectionConfig, boolean outputInteractive ) throws Exception
+ {
OutputStream promptOutputStream = getOutputStreamForInteractivePrompt();
- ConsoleReader consoleReader = new ConsoleReader(in, promptOutputStream);
+ ConsoleReader consoleReader = new ConsoleReader( in, promptOutputStream );
// Disable expansion of bangs: !
- consoleReader.setExpandEvents(false);
+ consoleReader.setExpandEvents( false );
// Ensure Reader does not handle user input for ctrl+C behaviour
- consoleReader.setHandleUserInterrupt(false);
+ consoleReader.setHandleUserInterrupt( false );
- consoleReader.println("Password change required");
+ consoleReader.println( "Password change required" );
- try {
- if (connectionConfig.username().isEmpty()) {
+ try
+ {
+ if ( connectionConfig.username().isEmpty() )
+ {
String username = outputInteractive ?
- promptForNonEmptyText("username", consoleReader, null) :
- promptForText("username", consoleReader, null);
- connectionConfig.setUsername(username);
+ promptForNonEmptyText( "username", consoleReader, null ) :
+ promptForText( "username", consoleReader, null );
+ connectionConfig.setUsername( username );
}
- if (connectionConfig.password().isEmpty()) {
- connectionConfig.setPassword(promptForText("password", consoleReader, '*'));
+ if ( connectionConfig.password().isEmpty() )
+ {
+ connectionConfig.setPassword( promptForText( "password", consoleReader, '*' ) );
}
String newPassword = outputInteractive ?
- promptForNonEmptyText("new password", consoleReader, '*') :
- promptForText("new password", consoleReader, '*');
- connectionConfig.setNewPassword(newPassword);
- } finally {
+ promptForNonEmptyText( "new password", consoleReader, '*' ) :
+ promptForText( "new password", consoleReader, '*' );
+ connectionConfig.setNewPassword( newPassword );
+ }
+ finally
+ {
consoleReader.close();
}
}
/**
- * @param prompt
- * to display to the user
- * @param mask
- * single character to display instead of what the user is typing, use null if text is not secret
+ * @param prompt to display to the user
+ * @param mask single character to display instead of what the user is typing, use null if text is not secret
* @return the text which was entered
- * @throws Exception
- * in case of errors
+ * @throws Exception in case of errors
*/
@Nonnull
- private String promptForNonEmptyText(@Nonnull String prompt, @Nonnull ConsoleReader consoleReader, @Nullable Character mask) throws Exception {
- String text = promptForText(prompt, consoleReader, mask);
- if (!text.isEmpty()) {
+ private String promptForNonEmptyText( @Nonnull String prompt, @Nonnull ConsoleReader consoleReader, @Nullable Character mask ) throws Exception
+ {
+ String text = promptForText( prompt, consoleReader, mask );
+ if ( !text.isEmpty() )
+ {
return text;
}
consoleReader.println( prompt + " cannot be empty" );
consoleReader.println();
- return promptForNonEmptyText(prompt, consoleReader, mask);
+ return promptForNonEmptyText( prompt, consoleReader, mask );
}
/**
- * @param prompt
- * to display to the user
- * @param mask
- * single character to display instead of what the user is typing, use null if text is not secret
- * @param consoleReader
- * the reader
+ * @param prompt to display to the user
+ * @param mask single character to display instead of what the user is typing, use null if text is not secret
+ * @param consoleReader the reader
* @return the text which was entered
- * @throws Exception
- * in case of errors
+ * @throws Exception in case of errors
*/
@Nonnull
- private String promptForText(@Nonnull String prompt, @Nonnull ConsoleReader consoleReader, @Nullable Character mask) throws Exception {
- String line = consoleReader.readLine(prompt + ": ", mask);
- if (line == null) {
- throw new CommandException("No text could be read, exiting...");
+ private String promptForText( @Nonnull String prompt, @Nonnull ConsoleReader consoleReader, @Nullable Character mask ) throws Exception
+ {
+ String line = consoleReader.readLine( prompt + ": ", mask );
+ if ( line == null )
+ {
+ throw new CommandException( "No text could be read, exiting..." );
}
return line;
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/ParameterMap.java b/cypher-shell/src/main/java/org/neo4j/shell/ParameterMap.java
index 8827a3ea..83929886 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/ParameterMap.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/ParameterMap.java
@@ -1,21 +1,41 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
+import java.util.Map;
+import javax.annotation.Nonnull;
+
import org.neo4j.cypher.internal.evaluator.EvaluationException;
import org.neo4j.shell.state.ParamValue;
-import javax.annotation.Nonnull;
-import java.util.Map;
-
/**
* An object which keeps named parameters and allows them them to be set/unset.
*/
-public interface ParameterMap {
+public interface ParameterMap
+{
/**
- * @param name of variable to set value for
+ * @param name of variable to set value for
* @param valueString to interpret the value from
* @return the evaluated value
*/
- Object setParameter(@Nonnull String name, @Nonnull String valueString) throws EvaluationException;
+ Object setParameter( @Nonnull String name, @Nonnull String valueString ) throws EvaluationException;
/**
* @return map of all currently set variables and their values
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/ShellParameterMap.java b/cypher-shell/src/main/java/org/neo4j/shell/ShellParameterMap.java
index 0877a417..cbc09083 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/ShellParameterMap.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/ShellParameterMap.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import java.util.HashMap;
@@ -30,18 +49,18 @@ public Object setParameter( @Nonnull String name, @Nonnull String valueString )
@Nonnull
@Override
- public Map allParameterValues()
+ public Map allParameterValues()
{
return queryParams.entrySet()
.stream()
.collect( Collectors.toMap(
Map.Entry::getKey,
- value -> value.getValue().getValue()));
+ value -> value.getValue().getValue() ) );
}
@Nonnull
@Override
- public Map getAllAsUserInput()
+ public Map getAllAsUserInput()
{
return queryParams;
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/ShellRunner.java b/cypher-shell/src/main/java/org/neo4j/shell/ShellRunner.java
index 539904a3..322acf0c 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/ShellRunner.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/ShellRunner.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import org.apache.commons.io.output.NullOutputStream;
@@ -26,20 +45,8 @@
import static org.fusesource.jansi.internal.CLibrary.isatty;
import static org.neo4j.shell.system.Utils.isWindows;
-public interface ShellRunner {
-
- /**
- * Run and handle user input until end of file
- *
- * @return error code to exit with
- */
- int runUntilEnd();
-
- /**
- * @return an object which can provide the history of commands executed
- */
- @Nonnull
- Historian getHistorian();
+public interface ShellRunner
+{
/**
* Get an appropriate shellrunner depending on the given arguments and if we are running in a TTY.
@@ -52,19 +59,23 @@ public interface ShellRunner {
* @throws IOException
*/
@Nonnull
- static ShellRunner getShellRunner(@Nonnull CliArgs cliArgs,
- @Nonnull CypherShell cypherShell,
- @Nonnull Logger logger,
- @Nonnull ConnectionConfig connectionConfig) throws IOException {
- if (shouldBeInteractive(cliArgs)) {
+ static ShellRunner getShellRunner( @Nonnull CliArgs cliArgs,
+ @Nonnull CypherShell cypherShell,
+ @Nonnull Logger logger,
+ @Nonnull ConnectionConfig connectionConfig ) throws IOException
+ {
+ if ( shouldBeInteractive( cliArgs ) )
+ {
UserMessagesHandler userMessagesHandler =
- new UserMessagesHandler(connectionConfig, cypherShell.getServerVersion());
- return new InteractiveShellRunner(cypherShell, cypherShell, cypherShell, logger, new ShellStatementParser(),
- System.in, FileHistorian.getDefaultHistoryFile(), userMessagesHandler, connectionConfig);
- } else {
+ new UserMessagesHandler( connectionConfig, cypherShell.getServerVersion() );
+ return new InteractiveShellRunner( cypherShell, cypherShell, cypherShell, logger, new ShellStatementParser(),
+ System.in, FileHistorian.getDefaultHistoryFile(), userMessagesHandler, connectionConfig );
+ }
+ else
+ {
- return new NonInteractiveShellRunner(cliArgs.getFailBehavior(), cypherShell, logger,
- new ShellStatementParser(), getInputStream(cliArgs));
+ return new NonInteractiveShellRunner( cliArgs.getFailBehavior(), cypherShell, logger,
+ new ShellStatementParser(), getInputStream( cliArgs ) );
}
}
@@ -72,7 +83,8 @@ static ShellRunner getShellRunner(@Nonnull CliArgs cliArgs,
* @param cliArgs
* @return true if an interactive shellrunner should be used, false otherwise
*/
- static boolean shouldBeInteractive(@Nonnull CliArgs cliArgs) {
+ static boolean shouldBeInteractive( @Nonnull CliArgs cliArgs )
+ {
if ( cliArgs.getNonInteractive() || cliArgs.getInputFilename() != null )
{
return false;
@@ -82,21 +94,25 @@ static boolean shouldBeInteractive(@Nonnull CliArgs cliArgs) {
}
/**
- * Checks if STDIN is a TTY. In case TTY checking is not possible (lack of libc), then the check falls back to
- * the built in Java {@link System#console()} which checks if EITHER STDIN or STDOUT has been redirected.
+ * Checks if STDIN is a TTY. In case TTY checking is not possible (lack of libc), then the check falls back to the built in Java {@link System#console()}
+ * which checks if EITHER STDIN or STDOUT has been redirected.
*
- * @return true if the shell is reading from an interactive terminal, false otherwise (e.g., we are reading from a
- * file).
+ * @return true if the shell is reading from an interactive terminal, false otherwise (e.g., we are reading from a file).
*/
- static boolean isInputInteractive() {
- if (isWindows()) {
+ static boolean isInputInteractive()
+ {
+ if ( isWindows() )
+ {
// Input will never be a TTY on windows and it isatty seems to be able to block forever on Windows so avoid
// calling it.
return System.console() != null;
}
- try {
- return 1 == isatty(STDIN_FILENO);
- } catch (Throwable ignored) {
+ try
+ {
+ return 1 == isatty( STDIN_FILENO );
+ }
+ catch ( Throwable ignored )
+ {
// system is not using libc (like Alpine Linux)
// Fallback to checking stdin OR stdout
return System.console() != null;
@@ -104,21 +120,25 @@ static boolean isInputInteractive() {
}
/**
- * Checks if STDOUT is a TTY. In case TTY checking is not possible (lack of libc), then the check falls back to
- * the built in Java {@link System#console()} which checks if EITHER STDIN or STDOUT has been redirected.
+ * Checks if STDOUT is a TTY. In case TTY checking is not possible (lack of libc), then the check falls back to the built in Java {@link System#console()}
+ * which checks if EITHER STDIN or STDOUT has been redirected.
*
- * @return true if the shell is outputting to an interactive terminal, false otherwise (e.g., we are outputting
- * to a file)
+ * @return true if the shell is outputting to an interactive terminal, false otherwise (e.g., we are outputting to a file)
*/
- static boolean isOutputInteractive() {
- if (isWindows()) {
+ static boolean isOutputInteractive()
+ {
+ if ( isWindows() )
+ {
// Input will never be a TTY on windows and it isatty seems to be able to block forever on Windows so avoid
// calling it.
return System.console() != null;
}
- try {
- return 1 == isatty(STDOUT_FILENO);
- } catch (Throwable ignored) {
+ try
+ {
+ return 1 == isatty( STDOUT_FILENO );
+ }
+ catch ( Throwable ignored )
+ {
// system is not using libc (like Alpine Linux)
// Fallback to checking stdin OR stdout
return System.console() != null;
@@ -127,9 +147,10 @@ static boolean isOutputInteractive() {
/**
* If an input file has been defined use that, otherwise use STDIN
+ *
* @throws FileNotFoundException if the provided input file doesn't exist
*/
- static InputStream getInputStream(CliArgs cliArgs) throws FileNotFoundException
+ static InputStream getInputStream( CliArgs cliArgs ) throws FileNotFoundException
{
if ( cliArgs.getInputFilename() == null )
{
@@ -141,28 +162,53 @@ static InputStream getInputStream(CliArgs cliArgs) throws FileNotFoundException
}
}
- static OutputStream getOutputStreamForInteractivePrompt() {
- if (isWindows()) {
+ static OutputStream getOutputStreamForInteractivePrompt()
+ {
+ if ( isWindows() )
+ {
// Output will never be a TTY on windows and it isatty seems to be able to block forever on Windows so avoid
// calling it.
- if (System.console() != null) {
- return new WriterOutputStream(System.console().writer(), Charset.defaultCharset());
+ if ( System.console() != null )
+ {
+ return new WriterOutputStream( System.console().writer(), Charset.defaultCharset() );
}
- } else {
- try {
- if (1 == isatty(STDOUT_FILENO)) {
+ }
+ else
+ {
+ try
+ {
+ if ( 1 == isatty( STDOUT_FILENO ) )
+ {
return System.out;
- } else {
- return new FileOutputStream(new File("/dev/tty"));
}
- } catch (Throwable ignored) {
+ else
+ {
+ return new FileOutputStream( new File( "/dev/tty" ) );
+ }
+ }
+ catch ( Throwable ignored )
+ {
// system is not using libc (like Alpine Linux)
// Fallback to checking stdin OR stdout
- if (System.console() != null) {
- return new WriterOutputStream(System.console().writer(), Charset.defaultCharset());
+ if ( System.console() != null )
+ {
+ return new WriterOutputStream( System.console().writer(), Charset.defaultCharset() );
}
}
}
return new NullOutputStream();
}
+
+ /**
+ * Run and handle user input until end of file
+ *
+ * @return error code to exit with
+ */
+ int runUntilEnd();
+
+ /**
+ * @return an object which can provide the history of commands executed
+ */
+ @Nonnull
+ Historian getHistorian();
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/StatementExecuter.java b/cypher-shell/src/main/java/org/neo4j/shell/StatementExecuter.java
index 19825f08..e0359973 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/StatementExecuter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/StatementExecuter.java
@@ -1,22 +1,43 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.exception.ExitException;
-import javax.annotation.Nonnull;
-
/**
* An interface which executes statements
*/
-public interface StatementExecuter {
+public interface StatementExecuter
+{
/**
* Execute a statement
+ *
* @param statement to execute
- * @throws ExitException if a command to exit was executed
+ * @throws ExitException if a command to exit was executed
* @throws CommandException if something went wrong
*/
- void execute(@Nonnull String statement) throws ExitException, CommandException;
+ void execute( @Nonnull String statement ) throws ExitException, CommandException;
/**
* Stops any running statements
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/TransactionHandler.java b/cypher-shell/src/main/java/org/neo4j/shell/TransactionHandler.java
index 33c55853..48d34d05 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/TransactionHandler.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/TransactionHandler.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
import org.neo4j.shell.exception.CommandException;
@@ -5,22 +24,20 @@
/**
* An object capable of starting, committing, and rolling back transactions.
*/
-public interface TransactionHandler {
+public interface TransactionHandler
+{
/**
- *
* @throws CommandException if a new transaction could not be started
*/
void beginTransaction() throws CommandException;
/**
- *
* @throws CommandException if current transaction could not be committed
*/
void commitTransaction() throws CommandException;
/**
- *
* @throws CommandException if current transaction could not be rolled back
*/
void rollbackTransaction() throws CommandException;
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/TriFunction.java b/cypher-shell/src/main/java/org/neo4j/shell/TriFunction.java
index ee4a6290..486b7ab8 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/TriFunction.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/TriFunction.java
@@ -1,6 +1,26 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
@FunctionalInterface
-public interface TriFunction {
- OUT apply(IN1 in1, IN2 in2, IN3 in3);
+public interface TriFunction
+{
+ OUT apply( IN1 in1, IN2 in2, IN3 in3 );
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/UserMessagesHandler.java b/cypher-shell/src/main/java/org/neo4j/shell/UserMessagesHandler.java
index f9f74de2..eaad792c 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/UserMessagesHandler.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/UserMessagesHandler.java
@@ -1,49 +1,74 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.commands.Exit;
import org.neo4j.shell.commands.Help;
import org.neo4j.shell.log.AnsiFormattedText;
-import javax.annotation.Nonnull;
-
-public class UserMessagesHandler {
+public class UserMessagesHandler
+{
private ConnectionConfig connectionConfig;
private String serverVersion;
- public UserMessagesHandler(@Nonnull ConnectionConfig connectionConfig, @Nonnull String serverVersion) {
+ public UserMessagesHandler( @Nonnull ConnectionConfig connectionConfig, @Nonnull String serverVersion )
+ {
this.connectionConfig = connectionConfig;
this.serverVersion = serverVersion;
}
@Nonnull
- public String getWelcomeMessage() {
+ public String getWelcomeMessage()
+ {
String neo4j = "Neo4j";
- if (!serverVersion.isEmpty()) {
+ if ( !serverVersion.isEmpty() )
+ {
neo4j += " " + serverVersion;
}
- AnsiFormattedText welcomeMessage = AnsiFormattedText.from("Connected to ")
- .append(neo4j)
- .append(" at ")
- .bold().append(connectionConfig.driverUrl()).boldOff();
+ AnsiFormattedText welcomeMessage = AnsiFormattedText.from( "Connected to " )
+ .append( neo4j )
+ .append( " at " )
+ .bold().append( connectionConfig.driverUrl() ).boldOff();
- if (!connectionConfig.username().isEmpty()) {
+ if ( !connectionConfig.username().isEmpty() )
+ {
welcomeMessage = welcomeMessage
- .append(" as user ")
- .bold().append(connectionConfig.username()).boldOff();
+ .append( " as user " )
+ .bold().append( connectionConfig.username() ).boldOff();
}
return welcomeMessage
- .append(".\nType ")
- .bold().append(Help.COMMAND_NAME).boldOff()
- .append(" for a list of available commands or ")
- .bold().append(Exit.COMMAND_NAME).boldOff()
- .append(" to exit the shell.")
- .append("\nNote that Cypher queries must end with a ")
- .bold().append("semicolon.").boldOff().formattedString();
+ .append( ".\nType " )
+ .bold().append( Help.COMMAND_NAME ).boldOff()
+ .append( " for a list of available commands or " )
+ .bold().append( Exit.COMMAND_NAME ).boldOff()
+ .append( " to exit the shell." )
+ .append( "\nNote that Cypher queries must end with a " )
+ .bold().append( "semicolon." ).boldOff().formattedString();
}
@Nonnull
- public String getExitMessage() {
- return AnsiFormattedText.s().append("\nBye!").formattedString();
+ public String getExitMessage()
+ {
+ return AnsiFormattedText.s().append( "\nBye!" ).formattedString();
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/build/Build.java b/cypher-shell/src/main/java/org/neo4j/shell/build/Build.java
index 2ac06c2c..7bb32f4c 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/build/Build.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/build/Build.java
@@ -1,16 +1,36 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.build;
-import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
+import javax.annotation.Nonnull;
/**
* This class provides access to build time variables
*/
-public class Build {
+public class Build
+{
- private static Properties props = null;
+ private static Properties props;
/**
* Reads the build generated properties file the first time it is called.
@@ -18,17 +38,25 @@ public class Build {
* @return build properties
*/
@Nonnull
- private static Properties getProperties() {
- if (props == null) {
+ private static Properties getProperties()
+ {
+ if ( props == null )
+ {
props = new Properties();
- try (InputStream stream = Build.class.getClassLoader().getResourceAsStream("build.properties")) {
- if (stream == null) {
- throw new IllegalStateException("Cannot read build.properties");
- } else {
- props.load(stream);
+ try ( InputStream stream = Build.class.getClassLoader().getResourceAsStream( "build.properties" ) )
+ {
+ if ( stream == null )
+ {
+ throw new IllegalStateException( "Cannot read build.properties" );
}
- } catch (IOException e) {
- System.err.println("Could not read build properties: " + e.getMessage());
+ else
+ {
+ props.load( stream );
+ }
+ }
+ catch ( IOException e )
+ {
+ System.err.println( "Could not read build properties: " + e.getMessage() );
}
}
@@ -39,15 +67,17 @@ private static Properties getProperties() {
* @return the revision of the source code, or "dev" if no properties file could be read.
*/
@Nonnull
- public static String version() {
- return getProperties().getProperty("version", "dev");
+ public static String version()
+ {
+ return getProperties().getProperty( "version", "dev" );
}
/**
* @return the revision of the Neo4j Driver, or "dev" if no properties file could be read.
*/
@Nonnull
- public static String driverVersion() {
- return getProperties().getProperty("driverVersion", "dev");
+ public static String driverVersion()
+ {
+ return getProperties().getProperty( "driverVersion", "dev" );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/AddParamArgumentAction.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/AddParamArgumentAction.java
index f49c248d..663661b9 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/AddParamArgumentAction.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/AddParamArgumentAction.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import net.sourceforge.argparse4j.inf.Argument;
@@ -12,8 +31,7 @@
import org.neo4j.shell.util.ParameterSetter;
/**
- * Action that adds arguments to a ParameterMap.
- * This action always consumes an argument.
+ * Action that adds arguments to a ParameterMap. This action always consumes an argument.
*/
public class AddParamArgumentAction extends ParameterSetter implements ArgumentAction
{
@@ -22,11 +40,11 @@ public class AddParamArgumentAction extends ParameterSetter attrs, String flag, Object value ) throws ArgumentParserException
+ public void run( ArgumentParser parser, Argument arg, Map attrs, String flag, Object value ) throws ArgumentParserException
{
try
{
@@ -34,7 +52,7 @@ public void run( ArgumentParser parser, Argument arg, Map attrs,
}
catch ( Exception e )
{
- throw new ArgumentParserException(e.getMessage(), e, parser);
+ throw new ArgumentParserException( e.getMessage(), e, parser );
}
}
@@ -53,13 +71,13 @@ public boolean consumeArgument()
@Override
protected void onWrongUsage()
{
- throw new IllegalArgumentException("Incorrect usage.\nusage: --param \"name => value\"");
+ throw new IllegalArgumentException( "Incorrect usage.\nusage: --param \"name => value\"" );
}
@Override
protected void onWrongNumberOfArguments()
{
- throw new IllegalArgumentException("Incorrect number of arguments.\nusage: --param \"name => value\"");
+ throw new IllegalArgumentException( "Incorrect number of arguments.\nusage: --param \"name => value\"" );
}
@Override
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgHelper.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgHelper.java
index 7323dafa..1469b21c 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgHelper.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgHelper.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import net.sourceforge.argparse4j.ArgumentParsers;
@@ -16,8 +35,6 @@
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -32,23 +49,28 @@
/**
* Command line argument parsing and related stuff
*/
-public class CliArgHelper {
+public class CliArgHelper
+{
/**
* @param args to parse
* @return null in case of error, commandline arguments otherwise
*/
@Nullable
- public static CliArgs parse(@Nonnull String... args) {
+ public static CliArgs parse( @Nonnull String... args )
+ {
final CliArgs cliArgs = new CliArgs();
- final ArgumentParser parser = setupParser(cliArgs.getParameters());
+ final ArgumentParser parser = setupParser( cliArgs.getParameters() );
final Namespace ns;
- try {
- ns = parser.parseArgs(args);
- } catch (ArgumentParserException e) {
- parser.handleError(e);
+ try
+ {
+ ns = parser.parseArgs( args );
+ }
+ catch ( ArgumentParserException e )
+ {
+ parser.handleError( e );
return null;
}
return getCliArgs( cliArgs, parser, ns );
@@ -70,82 +92,87 @@ public static CliArgs parseAndThrow( @Nonnull String... args ) throws ArgumentPa
private static CliArgs getCliArgs( CliArgs cliArgs, ArgumentParser parser, Namespace ns )
{
// Parse address string, returns null on error
- final URI uri = parseURI( parser, ns.getString( "address"));
+ final URI uri = parseURI( parser, ns.getString( "address" ) );
- if (uri == null) {
+ if ( uri == null )
+ {
return null;
}
//---------------------
// Connection arguments
- cliArgs.setScheme(uri.getScheme(), "bolt");
- cliArgs.setHost(uri.getHost(), "localhost");
+ cliArgs.setScheme( uri.getScheme(), "bolt" );
+ cliArgs.setHost( uri.getHost(), "localhost" );
int port = uri.getPort();
- cliArgs.setPort(port == -1 ? 7687 : port);
+ cliArgs.setPort( port == -1 ? 7687 : port );
// Also parse username and password from address if available
parseUserInfo( uri, cliArgs );
// Only overwrite user/pass from address string if the arguments were specified
- String user = ns.getString("username");
- if (!user.isEmpty()) {
- cliArgs.setUsername(user, cliArgs.getUsername());
+ String user = ns.getString( "username" );
+ if ( !user.isEmpty() )
+ {
+ cliArgs.setUsername( user, cliArgs.getUsername() );
}
- String pass = ns.getString("password");
- if (!pass.isEmpty()) {
- cliArgs.setPassword(pass, cliArgs.getPassword());
+ String pass = ns.getString( "password" );
+ if ( !pass.isEmpty() )
+ {
+ cliArgs.setPassword( pass, cliArgs.getPassword() );
}
- cliArgs.setEncryption(Encryption.parse(ns.get("encryption")));
- cliArgs.setDatabase(ns.getString("database"));
- cliArgs.setInputFilename(ns.getString( "file" ) );
+ cliArgs.setEncryption( Encryption.parse( ns.get( "encryption" ) ) );
+ cliArgs.setDatabase( ns.getString( "database" ) );
+ cliArgs.setInputFilename( ns.getString( "file" ) );
//----------------
// Other arguments
// cypher string might not be given, represented by null
- cliArgs.setCypher(ns.getString("cypher"));
+ cliArgs.setCypher( ns.getString( "cypher" ) );
// Fail behavior as sensible default and returns a proper type
- cliArgs.setFailBehavior(ns.get("fail-behavior"));
+ cliArgs.setFailBehavior( ns.get( "fail-behavior" ) );
//Set Output format
- cliArgs.setFormat(Format.parse(ns.get("format")));
+ cliArgs.setFormat( Format.parse( ns.get( "format" ) ) );
- cliArgs.setDebugMode(ns.getBoolean("debug"));
+ cliArgs.setDebugMode( ns.getBoolean( "debug" ) );
- cliArgs.setNonInteractive(ns.getBoolean("force-non-interactive"));
+ cliArgs.setNonInteractive( ns.getBoolean( "force-non-interactive" ) );
- cliArgs.setWrap(ns.getBoolean("wrap"));
+ cliArgs.setWrap( ns.getBoolean( "wrap" ) );
- cliArgs.setNumSampleRows(ns.getInt("sample-rows"));
+ cliArgs.setNumSampleRows( ns.getInt( "sample-rows" ) );
- cliArgs.setVersion(ns.getBoolean("version"));
+ cliArgs.setVersion( ns.getBoolean( "version" ) );
- cliArgs.setDriverVersion(ns.getBoolean("driver-version"));
+ cliArgs.setDriverVersion( ns.getBoolean( "driver-version" ) );
return cliArgs;
}
- private static void parseUserInfo(URI uri, CliArgs cliArgs)
+ private static void parseUserInfo( URI uri, CliArgs cliArgs )
{
String userInfo = uri.getUserInfo();
String user = null;
String password = null;
- if (userInfo != null)
+ if ( userInfo != null )
{
String[] split = userInfo.split( ":" );
- if (split.length == 0)
+ if ( split.length == 0 )
{
user = userInfo;
- } else if (split.length == 2)
+ }
+ else if ( split.length == 2 )
{
user = split[0];
password = split[1];
- } else {
- throw new IllegalArgumentException("Cannot parse user and password from " + userInfo);
}
-
+ else
+ {
+ throw new IllegalArgumentException( "Cannot parse user and password from " + userInfo );
+ }
}
- cliArgs.setUsername(user, "");
- cliArgs.setPassword(password, "");
+ cliArgs.setUsername( user, "" );
+ cliArgs.setPassword( password, "" );
}
@Nullable
@@ -172,7 +199,7 @@ static URI parseURI( ArgumentParser parser, String address )
}
}
- private static ArgumentParser setupParser(ParameterMap parameterMap)
+ private static ArgumentParser setupParser( ParameterMap parameterMap )
{
ArgumentParser parser = ArgumentParsers.newArgumentParser( "cypher-shell" ).defaultHelp( true ).description(
format( "A command line shell where you can execute Cypher against an instance of Neo4j. " +
@@ -182,103 +209,111 @@ private static ArgumentParser setupParser(ParameterMap parameterMap)
"example of piping a file:%n" +
" cat some-cypher.txt | cypher-shell" ) );
- ArgumentGroup connGroup = parser.addArgumentGroup("connection arguments");
- connGroup.addArgument("-a", "--address")
- .help("address and port to connect to")
- .setDefault(String.format("%s://%s:%d", CliArgs.DEFAULT_SCHEME, CliArgs.DEFAULT_HOST, CliArgs.DEFAULT_PORT));
- connGroup.addArgument("-u", "--username")
- .setDefault("")
- .help("username to connect as. Can also be specified using environment variable " + ConnectionConfig.USERNAME_ENV_VAR);
- connGroup.addArgument("-p", "--password")
- .setDefault("")
- .help("password to connect with. Can also be specified using environment variable " + ConnectionConfig.PASSWORD_ENV_VAR);
- connGroup.addArgument("--encryption")
- .help("whether the connection to Neo4j should be encrypted. This must be consistent with Neo4j's " +
- "configuration. If choosing '" + Encryption.DEFAULT.name().toLowerCase() +
- "' the encryption setting is deduced from the specified address. " +
- "For example the 'neo4j+ssc' protocol would use encryption.")
- .choices(new CollectionArgumentChoice<>(
+ ArgumentGroup connGroup = parser.addArgumentGroup( "connection arguments" );
+ connGroup.addArgument( "-a", "--address" )
+ .help( "address and port to connect to" )
+ .setDefault( String.format( "%s://%s:%d", CliArgs.DEFAULT_SCHEME, CliArgs.DEFAULT_HOST, CliArgs.DEFAULT_PORT ) );
+ connGroup.addArgument( "-u", "--username" )
+ .setDefault( "" )
+ .help( "username to connect as. Can also be specified using environment variable " + ConnectionConfig.USERNAME_ENV_VAR );
+ connGroup.addArgument( "-p", "--password" )
+ .setDefault( "" )
+ .help( "password to connect with. Can also be specified using environment variable " + ConnectionConfig.PASSWORD_ENV_VAR );
+ connGroup.addArgument( "--encryption" )
+ .help( "whether the connection to Neo4j should be encrypted. This must be consistent with Neo4j's " +
+ "configuration. If choosing '" + Encryption.DEFAULT.name().toLowerCase() +
+ "' the encryption setting is deduced from the specified address. " +
+ "For example the 'neo4j+ssc' protocol would use encryption." )
+ .choices( new CollectionArgumentChoice<>(
Encryption.TRUE.name().toLowerCase(),
Encryption.FALSE.name().toLowerCase(),
- Encryption.DEFAULT.name().toLowerCase()))
- .setDefault(Encryption.DEFAULT.name().toLowerCase());
- connGroup.addArgument("-d", "--database")
- .help("database to connect to. Can also be specified using environment variable " + ConnectionConfig.DATABASE_ENV_VAR)
- .setDefault("");
+ Encryption.DEFAULT.name().toLowerCase() ) )
+ .setDefault( Encryption.DEFAULT.name().toLowerCase() );
+ connGroup.addArgument( "-d", "--database" )
+ .help( "database to connect to. Can also be specified using environment variable " + ConnectionConfig.DATABASE_ENV_VAR )
+ .setDefault( "" );
MutuallyExclusiveGroup failGroup = parser.addMutuallyExclusiveGroup();
- failGroup.addArgument("--fail-fast")
- .help("exit and report failure on first error when reading from file (this is the default behavior)")
- .dest("fail-behavior")
- .setConst(FAIL_FAST)
- .action(new StoreConstArgumentAction());
- failGroup.addArgument("--fail-at-end")
- .help("exit and report failures at end of input when reading from file")
- .dest("fail-behavior")
- .setConst(FAIL_AT_END)
- .action(new StoreConstArgumentAction());
- parser.setDefault("fail-behavior", FAIL_FAST);
-
- parser.addArgument("--format")
- .help("desired output format, verbose displays results in tabular format and prints statistics, " +
- "plain displays data with minimal formatting")
- .choices(new CollectionArgumentChoice<>(
- Format.AUTO.name().toLowerCase(),
- Format.VERBOSE.name().toLowerCase(),
- Format.PLAIN.name().toLowerCase()))
- .setDefault(Format.AUTO.name().toLowerCase());
+ failGroup.addArgument( "--fail-fast" )
+ .help( "exit and report failure on first error when reading from file (this is the default behavior)" )
+ .dest( "fail-behavior" )
+ .setConst( FAIL_FAST )
+ .action( new StoreConstArgumentAction() );
+ failGroup.addArgument( "--fail-at-end" )
+ .help( "exit and report failures at end of input when reading from file" )
+ .dest( "fail-behavior" )
+ .setConst( FAIL_AT_END )
+ .action( new StoreConstArgumentAction() );
+ parser.setDefault( "fail-behavior", FAIL_FAST );
+
+ parser.addArgument( "--format" )
+ .help( "desired output format, verbose displays results in tabular format and prints statistics, " +
+ "plain displays data with minimal formatting" )
+ .choices( new CollectionArgumentChoice<>(
+ Format.AUTO.name().toLowerCase(),
+ Format.VERBOSE.name().toLowerCase(),
+ Format.PLAIN.name().toLowerCase() ) )
+ .setDefault( Format.AUTO.name().toLowerCase() );
parser.addArgument( "-P", "--param" )
.help( "Add a parameter to this session. Example: `-P \"number => 3\"`. This argument can be specified multiple times." )
.action( new AddParamArgumentAction( parameterMap ) );
- parser.addArgument("--debug")
- .help("print additional debug information")
- .action(new StoreTrueArgumentAction());
-
- parser.addArgument("--non-interactive")
- .help("force non-interactive mode, only useful if auto-detection fails (like on Windows)")
- .dest("force-non-interactive")
- .action(new StoreTrueArgumentAction());
-
- parser.addArgument("--sample-rows")
- .help("number of rows sampled to compute table widths (only for format=VERBOSE)")
- .type(new PositiveIntegerType())
- .dest("sample-rows")
- .setDefault(CliArgs.DEFAULT_NUM_SAMPLE_ROWS);
-
- parser.addArgument("--wrap")
- .help("wrap table column values if column is too narrow (only for format=VERBOSE)")
- .type(new BooleanArgumentType())
- .setDefault(true);
-
- parser.addArgument("-v", "--version")
- .help("print version of cypher-shell and exit")
- .action(new StoreTrueArgumentAction());
-
- parser.addArgument("--driver-version")
- .help("print version of the Neo4j Driver used and exit")
- .dest("driver-version")
- .action(new StoreTrueArgumentAction());
-
- parser.addArgument("cypher")
- .nargs("?")
- .help("an optional string of cypher to execute and then exit");
- parser.addArgument("-f", "--file")
- .help("Pass a file with cypher statements to be executed. After the statements have been executed cypher-shell will be shutdown");
+ parser.addArgument( "--debug" )
+ .help( "print additional debug information" )
+ .action( new StoreTrueArgumentAction() );
+
+ parser.addArgument( "--non-interactive" )
+ .help( "force non-interactive mode, only useful if auto-detection fails (like on Windows)" )
+ .dest( "force-non-interactive" )
+ .action( new StoreTrueArgumentAction() );
+
+ parser.addArgument( "--sample-rows" )
+ .help( "number of rows sampled to compute table widths (only for format=VERBOSE)" )
+ .type( new PositiveIntegerType() )
+ .dest( "sample-rows" )
+ .setDefault( CliArgs.DEFAULT_NUM_SAMPLE_ROWS );
+
+ parser.addArgument( "--wrap" )
+ .help( "wrap table column values if column is too narrow (only for format=VERBOSE)" )
+ .type( new BooleanArgumentType() )
+ .setDefault( true );
+
+ parser.addArgument( "-v", "--version" )
+ .help( "print version of cypher-shell and exit" )
+ .action( new StoreTrueArgumentAction() );
+
+ parser.addArgument( "--driver-version" )
+ .help( "print version of the Neo4j Driver used and exit" )
+ .dest( "driver-version" )
+ .action( new StoreTrueArgumentAction() );
+
+ parser.addArgument( "cypher" )
+ .nargs( "?" )
+ .help( "an optional string of cypher to execute and then exit" );
+ parser.addArgument( "-f", "--file" )
+ .help( "Pass a file with cypher statements to be executed. After the statements have been executed cypher-shell will be shutdown" );
return parser;
}
- private static class PositiveIntegerType implements ArgumentType {
+ private static class PositiveIntegerType implements ArgumentType
+ {
@Override
- public Integer convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException {
- try {
- int result = Integer.parseInt(value);
- if (result < 1) throw new NumberFormatException(value);
+ public Integer convert( ArgumentParser parser, Argument arg, String value ) throws ArgumentParserException
+ {
+ try
+ {
+ int result = Integer.parseInt( value );
+ if ( result < 1 )
+ {
+ throw new NumberFormatException( value );
+ }
return result;
- } catch (NumberFormatException nfe) {
- throw new ArgumentParserException("Invalid value: "+value, parser);
+ }
+ catch ( NumberFormatException nfe )
+ {
+ throw new ArgumentParserException( "Invalid value: " + value, parser );
}
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgs.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgs.java
index fc5ecacd..bfcb2952 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgs.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/CliArgs.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import java.util.Optional;
@@ -9,7 +28,8 @@
import static org.neo4j.shell.DatabaseManager.ABSENT_DB_NAME;
-public class CliArgs {
+public class CliArgs
+{
static final String DEFAULT_SCHEME = "neo4j";
static final String DEFAULT_HOST = "localhost";
static final int DEFAULT_PORT = 7687;
@@ -27,201 +47,235 @@ public class CliArgs {
private Optional cypher = Optional.empty();
private Encryption encryption = Encryption.DEFAULT;
private boolean debugMode;
- private boolean nonInteractive = false;
- private boolean version = false;
- private boolean driverVersion = false;
+ private boolean nonInteractive;
+ private boolean version;
+ private boolean driverVersion;
private int numSampleRows = DEFAULT_NUM_SAMPLE_ROWS;
private boolean wrap = true;
- private String inputFilename = null;
+ private String inputFilename;
private ParameterMap parameters = new ShellParameterMap();
/**
* Set the scheme to the primary value, or if null, the fallback value.
*/
- public void setScheme(@Nullable String primary, @Nonnull String fallback) {
+ public void setScheme( @Nullable String primary, @Nonnull String fallback )
+ {
scheme = primary == null ? fallback : primary;
}
/**
* Set the host to the primary value, or if null, the fallback value.
*/
- void setHost(@Nullable String primary, @Nonnull String fallback) {
+ void setHost( @Nullable String primary, @Nonnull String fallback )
+ {
host = primary == null ? fallback : primary;
}
- /**
- * Set the port to the value.
- */
- public void setPort(int port) {
- this.port = port;
- }
-
/**
* Set the username to the primary value, or if null, the fallback value.
*/
- public void setUsername(@Nullable String primary, @Nonnull String fallback) {
+ public void setUsername( @Nullable String primary, @Nonnull String fallback )
+ {
username = primary == null ? fallback : primary;
}
/**
* Set the password to the primary value, or if null, the fallback value.
*/
- public void setPassword(@Nullable String primary, @Nonnull String fallback) {
+ public void setPassword( @Nullable String primary, @Nonnull String fallback )
+ {
password = primary == null ? fallback : primary;
}
- /**
- * Set the database to connect to.
- */
- public void setDatabase(@Nullable String databaseName) {
- this.databaseName = databaseName;
+ @Nonnull
+ public String getScheme()
+ {
+ return scheme;
}
- /**
- * Set the desired fail behavior
- */
- void setFailBehavior(@Nonnull FailBehavior failBehavior) {
- this.failBehavior = failBehavior;
+ @Nonnull
+ public String getHost()
+ {
+ return host;
}
- /**
- * Set the desired format
- */
- public void setFormat(@Nonnull Format format) {
- this.format = format;
+ public int getPort()
+ {
+ return port;
}
/**
- * Set the specified cypher string to execute
+ * Set the port to the value.
*/
- public void setCypher(@Nullable String cypher) {
- this.cypher = Optional.ofNullable(cypher);
+ public void setPort( int port )
+ {
+ this.port = port;
}
- /**
- * Set whether the connection should be encrypted
- */
- public void setEncryption(Encryption encryption) {
- this.encryption = encryption;
+ @Nonnull
+ public String getUsername()
+ {
+ return username;
}
- /**
- * Force the shell to use non-interactive mode. Only useful on systems where auto-detection fails, such as Windows.
- */
- public void setNonInteractive(boolean nonInteractive) {
- this.nonInteractive = nonInteractive;
+ @Nonnull
+ public String getPassword()
+ {
+ return password;
}
- /**
- * Sets a filename where to read Cypher statements from, much like piping statements from a file.
- */
- public void setInputFilename(String inputFilename)
+ @Nonnull
+ public String getDatabase()
{
- this.inputFilename = inputFilename;
+ return databaseName;
}
/**
- * Enable/disable debug mode
+ * Set the database to connect to.
*/
- void setDebugMode(boolean enabled) {
- this.debugMode = enabled;
- }
-
- @Nonnull
- public String getScheme() {
- return scheme;
+ public void setDatabase( @Nullable String databaseName )
+ {
+ this.databaseName = databaseName;
}
@Nonnull
- public String getHost() {
- return host;
+ public FailBehavior getFailBehavior()
+ {
+ return failBehavior;
}
- public int getPort() {
- return port;
+ /**
+ * Set the desired fail behavior
+ */
+ void setFailBehavior( @Nonnull FailBehavior failBehavior )
+ {
+ this.failBehavior = failBehavior;
}
@Nonnull
- public String getUsername() {
- return username;
+ public Optional getCypher()
+ {
+ return cypher;
}
- @Nonnull
- public String getPassword() {
- return password;
+ /**
+ * Set the specified cypher string to execute
+ */
+ public void setCypher( @Nullable String cypher )
+ {
+ this.cypher = Optional.ofNullable( cypher );
}
@Nonnull
- public String getDatabase() {
- return databaseName;
+ public Format getFormat()
+ {
+ return format;
}
- @Nonnull
- public FailBehavior getFailBehavior() {
- return failBehavior;
+ /**
+ * Set the desired format
+ */
+ public void setFormat( @Nonnull Format format )
+ {
+ this.format = format;
}
- @Nonnull
- public Optional getCypher() {
- return cypher;
+ public Encryption getEncryption()
+ {
+ return encryption;
}
- @Nonnull
- public Format getFormat() {
- return format;
+ /**
+ * Set whether the connection should be encrypted
+ */
+ public void setEncryption( Encryption encryption )
+ {
+ this.encryption = encryption;
}
- public Encryption getEncryption() {
- return encryption;
+ public boolean getDebugMode()
+ {
+ return debugMode;
}
- public boolean getDebugMode() {
- return debugMode;
+ /**
+ * Enable/disable debug mode
+ */
+ void setDebugMode( boolean enabled )
+ {
+ this.debugMode = enabled;
}
- public boolean getNonInteractive() {
+ public boolean getNonInteractive()
+ {
return nonInteractive;
}
+ /**
+ * Force the shell to use non-interactive mode. Only useful on systems where auto-detection fails, such as Windows.
+ */
+ public void setNonInteractive( boolean nonInteractive )
+ {
+ this.nonInteractive = nonInteractive;
+ }
+
public String getInputFilename()
{
return inputFilename;
}
- public boolean getVersion() {
+ /**
+ * Sets a filename where to read Cypher statements from, much like piping statements from a file.
+ */
+ public void setInputFilename( String inputFilename )
+ {
+ this.inputFilename = inputFilename;
+ }
+
+ public boolean getVersion()
+ {
return version;
}
- public void setVersion(boolean version) {
+ public void setVersion( boolean version )
+ {
this.version = version;
}
- public boolean getDriverVersion() {
+ public boolean getDriverVersion()
+ {
return driverVersion;
}
- public void setDriverVersion(boolean version) {
+ public void setDriverVersion( boolean version )
+ {
this.driverVersion = version;
}
- public boolean isStringShell() {
+ public boolean isStringShell()
+ {
return cypher.isPresent();
}
- public boolean getWrap() {
+ public boolean getWrap()
+ {
return wrap;
}
- public void setWrap(boolean wrap) {
+ public void setWrap( boolean wrap )
+ {
this.wrap = wrap;
}
- public int getNumSampleRows() {
+ public int getNumSampleRows()
+ {
return numSampleRows;
}
- public void setNumSampleRows(Integer numSampleRows) {
- if (numSampleRows != null && numSampleRows > 0) {
+ public void setNumSampleRows( Integer numSampleRows )
+ {
+ if ( numSampleRows != null && numSampleRows > 0 )
+ {
this.numSampleRows = numSampleRows;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/Encryption.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/Encryption.java
index 0e141f15..9eb24253 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/Encryption.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/Encryption.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import javax.annotation.Nonnull;
@@ -8,12 +27,18 @@ public enum Encryption
FALSE,
DEFAULT;
- public static Encryption parse( @Nonnull String format) {
- if (format.equalsIgnoreCase(TRUE.name())) {
+ public static Encryption parse( @Nonnull String format )
+ {
+ if ( format.equalsIgnoreCase( TRUE.name() ) )
+ {
return TRUE;
- } else if (format.equalsIgnoreCase( FALSE.name() )) {
+ }
+ else if ( format.equalsIgnoreCase( FALSE.name() ) )
+ {
return FALSE;
- } else {
+ }
+ else
+ {
return DEFAULT;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/FailBehavior.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/FailBehavior.java
index e15a4cc9..c4b7cbb4 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/FailBehavior.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/FailBehavior.java
@@ -1,6 +1,26 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
-public enum FailBehavior {
+public enum FailBehavior
+{
FAIL_FAST,
FAIL_AT_END
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/FileHistorian.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/FileHistorian.java
index a27800bd..0611b17f 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/FileHistorian.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/FileHistorian.java
@@ -1,89 +1,125 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import jline.console.ConsoleReader;
import jline.console.history.FileHistory;
import jline.console.history.MemoryHistory;
-import org.neo4j.shell.Historian;
-import org.neo4j.shell.log.Logger;
-import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.neo4j.shell.Historian;
+import org.neo4j.shell.log.Logger;
import static java.lang.System.getProperty;
/**
- * An historian which stores history in a file in the users home dir. The setup methods install a shutdown hook which
- * will flush the history on exit.
+ * An historian which stores history in a file in the users home dir. The setup methods install a shutdown hook which will flush the history on exit.
*/
-public class FileHistorian implements Historian {
+public class FileHistorian implements Historian
+{
private final MemoryHistory history;
- private FileHistorian(MemoryHistory history) {
+ private FileHistorian( MemoryHistory history )
+ {
this.history = history;
}
@Nonnull
- public static Historian setupHistory(@Nonnull final ConsoleReader reader,
- @Nonnull final Logger logger,
- @Nonnull final File historyFile) throws IOException {
- try {
+ public static Historian setupHistory( @Nonnull final ConsoleReader reader,
+ @Nonnull final Logger logger,
+ @Nonnull final File historyFile ) throws IOException
+ {
+ try
+ {
File dir = historyFile.getParentFile();
- if (!dir.isDirectory() && !dir.mkdir()) {
- throw new IOException("Failed to create directory for history: " + dir.getAbsolutePath());
+ if ( !dir.isDirectory() && !dir.mkdir() )
+ {
+ throw new IOException( "Failed to create directory for history: " + dir.getAbsolutePath() );
}
- final FileHistory history = new FileHistory(historyFile);
- reader.setHistory(history);
+ final FileHistory history = new FileHistory( historyFile );
+ reader.setHistory( history );
// Make sure we flush history on exit
- addShutdownHookToFlushHistory(logger, history);
+ addShutdownHookToFlushHistory( logger, history );
- return new FileHistorian(history);
- } catch (IOException e) {
- logger.printError("Could not load history file. Falling back to session-based history.\n"
- + e.getMessage());
+ return new FileHistorian( history );
+ }
+ catch ( IOException e )
+ {
+ logger.printError( "Could not load history file. Falling back to session-based history.\n"
+ + e.getMessage() );
MemoryHistory history = new MemoryHistory();
- reader.setHistory(history);
- return new FileHistorian(history);
+ reader.setHistory( history );
+ return new FileHistorian( history );
}
}
- private static void addShutdownHookToFlushHistory(@Nonnull final Logger logger, final FileHistory history) {
- Runtime.getRuntime().addShutdownHook(new Thread() {
+ private static void addShutdownHookToFlushHistory( @Nonnull final Logger logger, final FileHistory history )
+ {
+ Runtime.getRuntime().addShutdownHook( new Thread()
+ {
@Override
- public void run() {
- try {
+ public void run()
+ {
+ try
+ {
history.flush();
- } catch (IOException e) {
- logger.printError("Failed to save history:\n" + e.getMessage());
+ }
+ catch ( IOException e )
+ {
+ logger.printError( "Failed to save history:\n" + e.getMessage() );
}
}
- });
+ } );
}
@Nonnull
- public static File getDefaultHistoryFile() {
+ public static File getDefaultHistoryFile()
+ {
// Storing in same directory as driver uses
- File dir = new File(getProperty("user.home"), ".neo4j");
- return new File(dir, ".neo4j_history");
+ File dir = new File( getProperty( "user.home" ), ".neo4j" );
+ return new File( dir, ".neo4j_history" );
}
@Nonnull
@Override
- public List getHistory() {
- List result = new ArrayList<>();
+ public List getHistory()
+ {
+ List result = new ArrayList<>();
- history.forEach(entry -> result.add(String.valueOf(entry.value())));
+ history.forEach( entry -> result.add( String.valueOf( entry.value() ) ) );
return result;
}
@Override
- public void flushHistory() throws IOException {
- if (history instanceof FileHistory) {
+ public void flushHistory() throws IOException
+ {
+ if ( history instanceof FileHistory )
+ {
((FileHistory) history).flush();
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/Format.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/Format.java
index ac08cf31..2666eb7e 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/Format.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/Format.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import javax.annotation.Nonnull;
@@ -5,7 +24,8 @@
import static org.neo4j.shell.ShellRunner.isInputInteractive;
import static org.neo4j.shell.ShellRunner.isOutputInteractive;
-public enum Format {
+public enum Format
+{
// Will select depending based on STDOUT and STDIN redirection
AUTO,
// Intended for human consumption
@@ -14,12 +34,18 @@ public enum Format {
PLAIN;
// TODO JSON, strictly intended for machine consumption with data formatted in JSON
- public static Format parse(@Nonnull String format) {
- if (format.equalsIgnoreCase(PLAIN.name())) {
+ public static Format parse( @Nonnull String format )
+ {
+ if ( format.equalsIgnoreCase( PLAIN.name() ) )
+ {
return PLAIN;
- } else if (format.equalsIgnoreCase( VERBOSE.name() )) {
+ }
+ else if ( format.equalsIgnoreCase( VERBOSE.name() ) )
+ {
return VERBOSE;
- } else {
+ }
+ else
+ {
return isInputInteractive() && isOutputInteractive() ? VERBOSE : PLAIN;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/InteractiveShellRunner.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/InteractiveShellRunner.java
index 9aea56c9..dfc2135b 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/InteractiveShellRunner.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/InteractiveShellRunner.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import jline.console.ConsoleReader;
@@ -31,101 +50,124 @@
import static org.neo4j.shell.DatabaseManager.DATABASE_UNAVAILABLE_ERROR_CODE;
/**
- * A shell runner intended for interactive sessions where lines are input one by one and execution should happen
- * along the way.
+ * A shell runner intended for interactive sessions where lines are input one by one and execution should happen along the way.
*/
-public class InteractiveShellRunner implements ShellRunner, SignalHandler {
+public class InteractiveShellRunner implements ShellRunner, SignalHandler
+{
static final String INTERRUPT_SIGNAL = "INT";
- private final static String FRESH_PROMPT = "> ";
- private final static String TRANSACTION_PROMPT = "# ";
- private final static String USERNAME_DB_DELIMITER = "@";
- private final static int ONELINE_PROMPT_MAX_LENGTH = 50;
static final String UNRESOLVED_DEFAULT_DB_PROPMPT_TEXT = "";
static final String DATABASE_UNAVAILABLE_ERROR_PROMPT_TEXT = "[UNAVAILABLE]";
-
+ private static final String FRESH_PROMPT = "> ";
+ private static final String TRANSACTION_PROMPT = "# ";
+ private static final String USERNAME_DB_DELIMITER = "@";
+ private static final int ONELINE_PROMPT_MAX_LENGTH = 50;
// Need to know if we are currently executing when catch Ctrl-C, needs to be atomic due to
// being called from different thread
private final AtomicBoolean currentlyExecuting;
- @Nonnull private final Logger logger;
- @Nonnull private final ConsoleReader reader;
- @Nonnull private final Historian historian;
- @Nonnull private final StatementParser statementParser;
- @Nonnull private final TransactionHandler txHandler;
- @Nonnull private final DatabaseManager databaseManager;
- @Nonnull private final StatementExecuter executer;
- @Nonnull private final UserMessagesHandler userMessagesHandler;
- @Nonnull private final ConnectionConfig connectionConfig;
+ @Nonnull
+ private final Logger logger;
+ @Nonnull
+ private final ConsoleReader reader;
+ @Nonnull
+ private final Historian historian;
+ @Nonnull
+ private final StatementParser statementParser;
+ @Nonnull
+ private final TransactionHandler txHandler;
+ @Nonnull
+ private final DatabaseManager databaseManager;
+ @Nonnull
+ private final StatementExecuter executer;
+ @Nonnull
+ private final UserMessagesHandler userMessagesHandler;
+ @Nonnull
+ private final ConnectionConfig connectionConfig;
- private AnsiFormattedText continuationPrompt = null;
+ private AnsiFormattedText continuationPrompt;
- public InteractiveShellRunner(@Nonnull StatementExecuter executer,
- @Nonnull TransactionHandler txHandler,
- @Nonnull DatabaseManager databaseManager,
- @Nonnull Logger logger,
- @Nonnull StatementParser statementParser,
- @Nonnull InputStream inputStream,
- @Nonnull File historyFile,
- @Nonnull UserMessagesHandler userMessagesHandler,
- @Nonnull ConnectionConfig connectionConfig) throws IOException {
+ public InteractiveShellRunner( @Nonnull StatementExecuter executer,
+ @Nonnull TransactionHandler txHandler,
+ @Nonnull DatabaseManager databaseManager,
+ @Nonnull Logger logger,
+ @Nonnull StatementParser statementParser,
+ @Nonnull InputStream inputStream,
+ @Nonnull File historyFile,
+ @Nonnull UserMessagesHandler userMessagesHandler,
+ @Nonnull ConnectionConfig connectionConfig ) throws IOException
+ {
this.userMessagesHandler = userMessagesHandler;
- this.currentlyExecuting = new AtomicBoolean(false);
+ this.currentlyExecuting = new AtomicBoolean( false );
this.executer = executer;
this.txHandler = txHandler;
this.databaseManager = databaseManager;
this.logger = logger;
this.statementParser = statementParser;
- this.reader = setupConsoleReader(logger, inputStream);
- this.historian = FileHistorian.setupHistory(reader, logger, historyFile);
+ this.reader = setupConsoleReader( logger, inputStream );
+ this.historian = FileHistorian.setupHistory( reader, logger, historyFile );
this.connectionConfig = connectionConfig;
// Catch ctrl-c
- Signal.handle(new Signal(INTERRUPT_SIGNAL), this);
+ Signal.handle( new Signal( INTERRUPT_SIGNAL ), this );
}
- private ConsoleReader setupConsoleReader(@Nonnull Logger logger,
- @Nonnull InputStream inputStream) throws IOException {
- ConsoleReader reader = new ConsoleReader(inputStream, logger.getOutputStream());
+ private ConsoleReader setupConsoleReader( @Nonnull Logger logger,
+ @Nonnull InputStream inputStream ) throws IOException
+ {
+ ConsoleReader reader = new ConsoleReader( inputStream, logger.getOutputStream() );
// Disable expansion of bangs: !
- reader.setExpandEvents(false);
+ reader.setExpandEvents( false );
// Ensure Reader does not handle user input for ctrl+C behaviour
- reader.setHandleUserInterrupt(false);
+ reader.setHandleUserInterrupt( false );
return reader;
}
@Override
- public int runUntilEnd() {
+ public int runUntilEnd()
+ {
int exitCode = Main.EXIT_SUCCESS;
boolean running = true;
- logger.printIfVerbose(userMessagesHandler.getWelcomeMessage());
+ logger.printIfVerbose( userMessagesHandler.getWelcomeMessage() );
- while (running) {
- try {
- for (String statement : readUntilStatement()) {
- currentlyExecuting.set(true);
- executer.execute(statement);
- currentlyExecuting.set(false);
+ while ( running )
+ {
+ try
+ {
+ for ( String statement : readUntilStatement() )
+ {
+ currentlyExecuting.set( true );
+ executer.execute( statement );
+ currentlyExecuting.set( false );
}
- } catch (ExitException e) {
+ }
+ catch ( ExitException e )
+ {
exitCode = e.getCode();
running = false;
- } catch (NoMoreInputException e) {
+ }
+ catch ( NoMoreInputException e )
+ {
// User pressed Ctrl-D and wants to exit
running = false;
- } catch (Throwable e) {
- logger.printError(e);
- } finally {
- currentlyExecuting.set(false);
+ }
+ catch ( Throwable e )
+ {
+ logger.printError( e );
+ }
+ finally
+ {
+ currentlyExecuting.set( false );
}
}
- logger.printIfVerbose(userMessagesHandler.getExitMessage());
+ logger.printIfVerbose( userMessagesHandler.getExitMessage() );
return exitCode;
}
@Nonnull
@Override
- public Historian getHistorian() {
+ public Historian getHistorian()
+ {
return historian;
}
@@ -137,22 +179,27 @@ public Historian getHistorian() {
* @throws NoMoreInputException
*/
@Nonnull
- public List readUntilStatement() throws IOException, NoMoreInputException {
- while (true) {
- String line = reader.readLine(updateAndGetPrompt().renderedString());
- if (line == null) {
+ public List readUntilStatement() throws IOException, NoMoreInputException
+ {
+ while ( true )
+ {
+ String line = reader.readLine( updateAndGetPrompt().renderedString() );
+ if ( line == null )
+ {
// User hit CTRL-D, or file ended
throw new NoMoreInputException();
}
// Empty lines are ignored if nothing has been read yet
- if (line.trim().isEmpty() && !statementParser.containsText()) {
+ if ( line.trim().isEmpty() && !statementParser.containsText() )
+ {
continue;
}
- statementParser.parseMoreText(line + "\n");
+ statementParser.parseMoreText( line + "\n" );
- if (statementParser.hasStatements()) {
+ if ( statementParser.hasStatements() )
+ {
return statementParser.consumeStatements();
}
}
@@ -161,20 +208,23 @@ public List readUntilStatement() throws IOException, NoMoreInputExceptio
/**
* @return suitable prompt depending on current parsing state
*/
- AnsiFormattedText updateAndGetPrompt() {
- if (statementParser.containsText()) {
+ AnsiFormattedText updateAndGetPrompt()
+ {
+ if ( statementParser.containsText() )
+ {
return continuationPrompt;
}
String databaseName = databaseManager.getActualDatabaseAsReportedByServer();
- if (databaseName == null || ABSENT_DB_NAME.equals(databaseName)) {
+ if ( databaseName == null || ABSENT_DB_NAME.equals( databaseName ) )
+ {
// We have failed to get a successful response from the connection ping query
// Build the prompt from the db name as set by the user + a suffix indicating that we are in a disconnected state
String dbNameSetByUser = databaseManager.getActiveDatabaseAsSetByUser();
- databaseName = ABSENT_DB_NAME.equals(dbNameSetByUser)? UNRESOLVED_DEFAULT_DB_PROPMPT_TEXT : dbNameSetByUser;
+ databaseName = ABSENT_DB_NAME.equals( dbNameSetByUser ) ? UNRESOLVED_DEFAULT_DB_PROPMPT_TEXT : dbNameSetByUser;
}
- String errorSuffix = getErrorPrompt(executer.lastNeo4jErrorCode());
+ String errorSuffix = getErrorPrompt( executer.lastNeo4jErrorCode() );
int promptIndent = connectionConfig.username().length() +
USERNAME_DB_DELIMITER.length() +
@@ -183,21 +233,24 @@ AnsiFormattedText updateAndGetPrompt() {
FRESH_PROMPT.length();
AnsiFormattedText prePrompt = AnsiFormattedText.s().bold()
- .append(connectionConfig.username())
- .append("@")
- .append(databaseName);
+ .append( connectionConfig.username() )
+ .append( "@" )
+ .append( databaseName );
// If we encountered an error with the connection ping query we display it in the prompt in RED
- if (!errorSuffix.isEmpty()) {
- prePrompt.colorRed().append(errorSuffix).colorDefault();
+ if ( !errorSuffix.isEmpty() )
+ {
+ prePrompt.colorRed().append( errorSuffix ).colorDefault();
}
- if (promptIndent <= ONELINE_PROMPT_MAX_LENGTH) {
- continuationPrompt = AnsiFormattedText.s().bold().append(OutputFormatter.repeat(' ', promptIndent));
+ if ( promptIndent <= ONELINE_PROMPT_MAX_LENGTH )
+ {
+ continuationPrompt = AnsiFormattedText.s().bold().append( OutputFormatter.repeat( ' ', promptIndent ) );
return prePrompt
.append( txHandler.isTransactionOpen() ? TRANSACTION_PROMPT : FRESH_PROMPT );
-
- } else {
+ }
+ else
+ {
continuationPrompt = AnsiFormattedText.s().bold();
return prePrompt
.appendNewLine()
@@ -205,12 +258,16 @@ AnsiFormattedText updateAndGetPrompt() {
}
}
- private String getErrorPrompt(String errorCode) {
+ private String getErrorPrompt( String errorCode )
+ {
// NOTE: errorCode can be null
String errorPromptSuffix;
- if (DATABASE_UNAVAILABLE_ERROR_CODE.equals(errorCode)) {
+ if ( DATABASE_UNAVAILABLE_ERROR_CODE.equals( errorCode ) )
+ {
errorPromptSuffix = DATABASE_UNAVAILABLE_ERROR_PROMPT_TEXT;
- } else {
+ }
+ else
+ {
errorPromptSuffix = "";
}
return errorPromptSuffix;
@@ -222,20 +279,24 @@ private String getErrorPrompt(String errorCode) {
* @param signal to handle
*/
@Override
- public void handle(final Signal signal) {
+ public void handle( final Signal signal )
+ {
// Stop any running cypher statements
- if (currentlyExecuting.get()) {
+ if ( currentlyExecuting.get() )
+ {
executer.reset();
- } else {
+ }
+ else
+ {
// Print a literal newline here to get around us being in the middle of the prompt
logger.printError(
AnsiFormattedText.s().colorRed()
- .append("\nInterrupted (Note that Cypher queries must end with a ")
- .bold().append("semicolon. ").boldOff()
- .append("Type ")
- .bold().append(Exit.COMMAND_NAME).append(" ").boldOff()
- .append("to exit the shell.)")
- .formattedString());
+ .append( "\nInterrupted (Note that Cypher queries must end with a " )
+ .bold().append( "semicolon. " ).boldOff()
+ .append( "Type " )
+ .bold().append( Exit.COMMAND_NAME ).append( " " ).boldOff()
+ .append( "to exit the shell.)" )
+ .formattedString() );
// Clear any text which has been inputted
resetPrompt();
}
@@ -244,26 +305,32 @@ public void handle(final Signal signal) {
/**
* Clears the prompt of any text which has been inputted and redraws it.
*/
- private void resetPrompt() {
- try {
+ private void resetPrompt()
+ {
+ try
+ {
// Clear whatever text has currently been inputted
boolean more = true;
- while (more) {
+ while ( more )
+ {
more = reader.delete();
}
more = true;
- while (more) {
+ while ( more )
+ {
more = reader.backspace();
}
// Clear parser state
statementParser.reset();
// Redraw the prompt now because the error message has changed the terminal text
- reader.setPrompt(updateAndGetPrompt().renderedString());
+ reader.setPrompt( updateAndGetPrompt().renderedString() );
reader.redrawLine();
reader.flush();
- } catch (IOException e) {
- logger.printError(e);
+ }
+ catch ( IOException e )
+ {
+ logger.printError( e );
}
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/cli/NonInteractiveShellRunner.java b/cypher-shell/src/main/java/org/neo4j/shell/cli/NonInteractiveShellRunner.java
index 44f540cf..006d7772 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/cli/NonInteractiveShellRunner.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/cli/NonInteractiveShellRunner.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.cli;
import java.io.BufferedReader;
@@ -16,12 +35,12 @@
import static org.neo4j.shell.Main.EXIT_FAILURE;
import static org.neo4j.shell.Main.EXIT_SUCCESS;
-
/**
- * A shell runner which reads all of STDIN and executes commands until completion. In case of errors, the failBehavior
- * determines if the shell exits immediately, or if it should keep trying the next commands.
+ * A shell runner which reads all of STDIN and executes commands until completion. In case of errors, the failBehavior determines if the shell exits
+ * immediately, or if it should keep trying the next commands.
*/
-public class NonInteractiveShellRunner implements ShellRunner {
+public class NonInteractiveShellRunner implements ShellRunner
+{
private final FailBehavior failBehavior;
@Nonnull
@@ -30,11 +49,12 @@ public class NonInteractiveShellRunner implements ShellRunner {
private final StatementParser statementParser;
private final InputStream inputStream;
- public NonInteractiveShellRunner(@Nonnull FailBehavior failBehavior,
- @Nonnull StatementExecuter executer,
- @Nonnull Logger logger,
- @Nonnull StatementParser statementParser,
- @Nonnull InputStream inputStream) {
+ public NonInteractiveShellRunner( @Nonnull FailBehavior failBehavior,
+ @Nonnull StatementExecuter executer,
+ @Nonnull Logger logger,
+ @Nonnull StatementParser statementParser,
+ @Nonnull InputStream inputStream )
+ {
this.failBehavior = failBehavior;
this.executer = executer;
this.logger = logger;
@@ -43,29 +63,40 @@ public NonInteractiveShellRunner(@Nonnull FailBehavior failBehavior,
}
@Override
- public int runUntilEnd() {
+ public int runUntilEnd()
+ {
List statements;
- try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
+ try ( BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( inputStream ) ) )
+ {
bufferedReader
.lines()
- .forEach(line -> statementParser.parseMoreText(line + "\n"));
+ .forEach( line -> statementParser.parseMoreText( line + "\n" ) );
statements = statementParser.consumeStatements();
- } catch (Throwable e) {
- logger.printError(e);
+ }
+ catch ( Throwable e )
+ {
+ logger.printError( e );
return 1;
}
int exitCode = EXIT_SUCCESS;
- for (String statement : statements) {
- try {
- executer.execute(statement);
- } catch (ExitException e) {
+ for ( String statement : statements )
+ {
+ try
+ {
+ executer.execute( statement );
+ }
+ catch ( ExitException e )
+ {
// These exceptions are always fatal
return e.getCode();
- } catch (Throwable e) {
+ }
+ catch ( Throwable e )
+ {
exitCode = EXIT_FAILURE;
- logger.printError(e);
- if (FailBehavior.FAIL_AT_END != failBehavior) {
+ logger.printError( e );
+ if ( FailBehavior.FAIL_AT_END != failBehavior )
+ {
return exitCode;
}
}
@@ -75,7 +106,8 @@ public int runUntilEnd() {
@Nonnull
@Override
- public Historian getHistorian() {
+ public Historian getHistorian()
+ {
return Historian.empty;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Begin.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Begin.java
index b3a2ea40..e4e3e497 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Begin.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Begin.java
@@ -1,60 +1,87 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.TransactionHandler;
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.exception.ExitException;
-import javax.annotation.Nonnull;
-import java.util.Collections;
-import java.util.List;
-
import static org.neo4j.shell.commands.CommandHelper.simpleArgParse;
/**
* This command starts a transaction.
*/
-public class Begin implements Command {
+public class Begin implements Command
+{
private static final String COMMAND_NAME = ":begin";
private final TransactionHandler transactionHandler;
- public Begin(@Nonnull final TransactionHandler transactionHandler) {
+ public Begin( @Nonnull final TransactionHandler transactionHandler )
+ {
this.transactionHandler = transactionHandler;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Open a transaction";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "";
}
@Nonnull
@Override
- public String getHelp() {
- return String.format("Start a transaction which will remain open until %s or %s is called",
- Commit.COMMAND_NAME, Rollback.COMMAND_NAME);
+ public String getHelp()
+ {
+ return String.format( "Start a transaction which will remain open until %s or %s is called",
+ Commit.COMMAND_NAME, Rollback.COMMAND_NAME );
}
@Nonnull
@Override
- public List getAliases() {
+ public List getAliases()
+ {
return Collections.emptyList();
}
@Override
- public void execute(@Nonnull final String argString) throws ExitException, CommandException {
- simpleArgParse(argString, 0, COMMAND_NAME, getUsage());
+ public void execute( @Nonnull final String argString ) throws ExitException, CommandException
+ {
+ simpleArgParse( argString, 0, COMMAND_NAME, getUsage() );
transactionHandler.beginTransaction();
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Command.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Command.java
index 8ea201c3..527d8e52 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Command.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Command.java
@@ -1,15 +1,35 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
+import java.util.List;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.exception.ExitException;
-import javax.annotation.Nonnull;
-import java.util.List;
-
/**
* A shell command
*/
-public interface Command {
+public interface Command
+{
@Nonnull
String getName();
@@ -27,5 +47,5 @@ public interface Command {
@Nonnull
List getAliases();
- void execute(@Nonnull final String args) throws ExitException, CommandException;
+ void execute( @Nonnull String args ) throws ExitException, CommandException;
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandExecutable.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandExecutable.java
index b582a83a..1cb9f09c 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandExecutable.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandExecutable.java
@@ -1,9 +1,29 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.exception.ExitException;
@FunctionalInterface
-public interface CommandExecutable {
+public interface CommandExecutable
+{
void execute() throws CommandException, ExitException;
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandHelper.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandHelper.java
index b2972eb9..6b045f8c 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandHelper.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/CommandHelper.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import java.util.List;
@@ -17,51 +36,97 @@
/**
* Utility methods for dealing with commands
*/
-public class CommandHelper {
- private final TreeMap commands = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+public class CommandHelper
+{
+ private final TreeMap commands = new TreeMap<>( String.CASE_INSENSITIVE_ORDER );
- public CommandHelper(Logger logger, Historian historian, CypherShell cypherShell) {
- registerAllCommands(logger, historian, cypherShell);
+ public CommandHelper( Logger logger, Historian historian, CypherShell cypherShell )
+ {
+ registerAllCommands( logger, historian, cypherShell );
}
- private void registerAllCommands(Logger logger,
- Historian historian,
- CypherShell cypherShell) {
- registerCommand(new Exit(logger));
- registerCommand(new Help(logger, this));
- registerCommand(new History(logger, historian));
- registerCommand(new Use(cypherShell));
- registerCommand(new Begin(cypherShell));
- registerCommand(new Commit(cypherShell));
- registerCommand(new Rollback(cypherShell));
- registerCommand(new Param(cypherShell.getParameterMap()));
- registerCommand(new Params(logger, cypherShell.getParameterMap()));
- registerCommand(new Source(cypherShell, new ShellStatementParser() ));
+ /**
+ * Split an argument string on whitespace
+ */
+ @Nonnull
+ public static String[] simpleArgParse( @Nonnull final String argString, int expectedCount,
+ @Nonnull final String commandName, @Nonnull final String usage )
+ throws CommandException
+ {
+ return simpleArgParse( argString, expectedCount, expectedCount, commandName, usage );
}
- private void registerCommand(@Nonnull final Command command) throws DuplicateCommandException {
- if (commands.containsKey(command.getName())) {
- throw new DuplicateCommandException("This command name has already been registered: " + command.getName());
+ /**
+ * Split an argument string on whitespace
+ */
+ @Nonnull
+ public static String[] simpleArgParse( @Nonnull final String argString, int minCount, int maxCount,
+ @Nonnull final String commandName, @Nonnull final String usage )
+ throws CommandException
+ {
+ final String[] args;
+ if ( argString.trim().isEmpty() )
+ {
+ args = new String[] {};
+ }
+ else
+ {
+ args = argString.trim().split( "\\s+" );
}
- commands.put(command.getName(), command);
+ if ( args.length < minCount || args.length > maxCount )
+ {
+ throw new CommandException( AnsiFormattedText.from( "Incorrect number of arguments.\nusage: " )
+ .bold().append( commandName ).boldOff().append( " " ).append( usage ) );
+ }
- for (String alias: command.getAliases()) {
- if (commands.containsKey(alias)) {
- throw new DuplicateCommandException("This command alias has already been registered: " + alias);
- }
- commands.put(alias, command);
+ return args;
+ }
+
+ private void registerAllCommands( Logger logger,
+ Historian historian,
+ CypherShell cypherShell )
+ {
+ registerCommand( new Exit( logger ) );
+ registerCommand( new Help( logger, this ) );
+ registerCommand( new History( logger, historian ) );
+ registerCommand( new Use( cypherShell ) );
+ registerCommand( new Begin( cypherShell ) );
+ registerCommand( new Commit( cypherShell ) );
+ registerCommand( new Rollback( cypherShell ) );
+ registerCommand( new Param( cypherShell.getParameterMap() ) );
+ registerCommand( new Params( logger, cypherShell.getParameterMap() ) );
+ registerCommand( new Source( cypherShell, new ShellStatementParser() ) );
+ }
+
+ private void registerCommand( @Nonnull final Command command ) throws DuplicateCommandException
+ {
+ if ( commands.containsKey( command.getName() ) )
+ {
+ throw new DuplicateCommandException( "This command name has already been registered: " + command.getName() );
}
+ commands.put( command.getName(), command );
+
+ for ( String alias : command.getAliases() )
+ {
+ if ( commands.containsKey( alias ) )
+ {
+ throw new DuplicateCommandException( "This command alias has already been registered: " + alias );
+ }
+ commands.put( alias, command );
+ }
}
/**
* Get a command corresponding to the given name, or null if no such command has been registered.
*/
@Nullable
- public Command getCommand(@Nonnull final String name) {
- if (commands.containsKey(name)) {
- return commands.get(name);
+ public Command getCommand( @Nonnull final String name )
+ {
+ if ( commands.containsKey( name ) )
+ {
+ return commands.get( name );
}
return null;
}
@@ -70,39 +135,8 @@ public Command getCommand(@Nonnull final String name) {
* Get a list of all registered commands
*/
@Nonnull
- public List getAllCommands() {
- return commands.values().stream().distinct().collect(Collectors.toList());
- }
-
- /**
- * Split an argument string on whitespace
- */
- @Nonnull
- public static String[] simpleArgParse(@Nonnull final String argString, int expectedCount,
- @Nonnull final String commandName, @Nonnull final String usage)
- throws CommandException {
- return simpleArgParse(argString, expectedCount, expectedCount, commandName, usage);
- }
-
- /**
- * Split an argument string on whitespace
- */
- @Nonnull
- public static String[] simpleArgParse(@Nonnull final String argString, int minCount, int maxCount,
- @Nonnull final String commandName, @Nonnull final String usage)
- throws CommandException {
- final String[] args;
- if (argString.trim().isEmpty()) {
- args = new String[] {};
- } else {
- args = argString.trim().split("\\s+");
- }
-
- if (args.length < minCount || args.length > maxCount) {
- throw new CommandException(AnsiFormattedText.from("Incorrect number of arguments.\nusage: ")
- .bold().append(commandName).boldOff().append(" ").append(usage));
- }
-
- return args;
+ public List getAllCommands()
+ {
+ return commands.values().stream().distinct().collect( Collectors.toList() );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Commit.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Commit.java
index 6a035a42..ad84300d 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Commit.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Commit.java
@@ -1,59 +1,86 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.TransactionHandler;
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.exception.ExitException;
-import javax.annotation.Nonnull;
-import java.util.Collections;
-import java.util.List;
-
import static org.neo4j.shell.commands.CommandHelper.simpleArgParse;
/**
* This command marks a transaction as successful and closes it.
*/
-public class Commit implements Command {
+public class Commit implements Command
+{
public static final String COMMAND_NAME = ":commit";
private final TransactionHandler transactionHandler;
- public Commit(@Nonnull final TransactionHandler transactionHandler) {
+ public Commit( @Nonnull final TransactionHandler transactionHandler )
+ {
this.transactionHandler = transactionHandler;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Commit the currently open transaction";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "";
}
@Nonnull
@Override
- public String getHelp() {
+ public String getHelp()
+ {
return "Commit and close the currently open transaction";
}
@Nonnull
@Override
- public List getAliases() {
+ public List getAliases()
+ {
return Collections.emptyList();
}
@Override
- public void execute(@Nonnull final String argString) throws ExitException, CommandException {
- simpleArgParse(argString, 0, COMMAND_NAME, getUsage());
+ public void execute( @Nonnull final String argString ) throws ExitException, CommandException
+ {
+ simpleArgParse( argString, 0, COMMAND_NAME, getUsage() );
transactionHandler.commitTransaction();
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Exit.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Exit.java
index c4daa61b..9c21f7db 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Exit.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Exit.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import java.util.Arrays;
@@ -15,49 +34,57 @@
/**
* Command to exit the logger. Equivalent to hitting Ctrl-D.
*/
-public class Exit implements Command {
+public class Exit implements Command
+{
public static final String COMMAND_NAME = ":exit";
private final Logger logger;
- public Exit(@Nonnull final Logger logger) {
+ public Exit( @Nonnull final Logger logger )
+ {
this.logger = logger;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Exit the logger";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "";
}
@Nonnull
@Override
- public String getHelp() {
- return AnsiFormattedText.from("Exit the logger. Corresponds to entering ").bold().append("CTRL-D").boldOff()
- .append(".").formattedString();
+ public String getHelp()
+ {
+ return AnsiFormattedText.from( "Exit the logger. Corresponds to entering " ).bold().append( "CTRL-D" ).boldOff()
+ .append( "." ).formattedString();
}
@Nonnull
@Override
- public List getAliases() {
- return Arrays.asList(":quit");
+ public List getAliases()
+ {
+ return Arrays.asList( ":quit" );
}
@Override
- public void execute(@Nonnull final String argString) throws ExitException, CommandException {
- simpleArgParse(argString, 0, COMMAND_NAME, getUsage());
+ public void execute( @Nonnull final String argString ) throws ExitException, CommandException
+ {
+ simpleArgParse( argString, 0, COMMAND_NAME, getUsage() );
- throw new ExitException(EXIT_SUCCESS);
+ throw new ExitException( EXIT_SUCCESS );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Help.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Help.java
index 92cd58bb..cf57dece 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Help.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Help.java
@@ -1,121 +1,156 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
-import org.neo4j.shell.exception.CommandException;
-import org.neo4j.shell.log.Logger;
-import org.neo4j.shell.log.AnsiFormattedText;
-
-import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.neo4j.shell.exception.CommandException;
+import org.neo4j.shell.log.AnsiFormattedText;
+import org.neo4j.shell.log.Logger;
import static org.neo4j.shell.commands.CommandHelper.simpleArgParse;
/**
* Help command, which prints help documentation.
*/
-public class Help implements Command {
+public class Help implements Command
+{
public static final String COMMAND_NAME = ":help";
+ public static String CYPHER_REFCARD_LINK = "https://neo4j.com/docs/developer-manual/current/cypher/";
private final Logger logger;
private final CommandHelper commandHelper;
- public static String CYPHER_REFCARD_LINK = "https://neo4j.com/docs/developer-manual/current/cypher/";
- public Help(@Nonnull final Logger shell, @Nonnull final CommandHelper commandHelper) {
+ public Help( @Nonnull final Logger shell, @Nonnull final CommandHelper commandHelper )
+ {
this.logger = shell;
this.commandHelper = commandHelper;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Show this help message";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "[command]";
}
@Nonnull
@Override
- public String getHelp() {
+ public String getHelp()
+ {
return "Show the list of available commands or help for a specific command.";
}
@Nonnull
@Override
- public List getAliases() {
- return Arrays.asList(":man");
+ public List getAliases()
+ {
+ return Arrays.asList( ":man" );
}
@Override
- public void execute(@Nonnull final String argString) throws CommandException {
- String[] args = simpleArgParse(argString, 0, 1, COMMAND_NAME, getUsage());
- if (args.length == 0) {
+ public void execute( @Nonnull final String argString ) throws CommandException
+ {
+ String[] args = simpleArgParse( argString, 0, 1, COMMAND_NAME, getUsage() );
+ if ( args.length == 0 )
+ {
printGeneralHelp();
- } else {
- printHelpFor(args[0]);
+ }
+ else
+ {
+ printHelpFor( args[0] );
}
}
- private void printHelpFor(@Nonnull final String name) throws CommandException {
- Command cmd = commandHelper.getCommand(name);
- if (cmd == null && !name.startsWith(":")) {
+ private void printHelpFor( @Nonnull final String name ) throws CommandException
+ {
+ Command cmd = commandHelper.getCommand( name );
+ if ( cmd == null && !name.startsWith( ":" ) )
+ {
// Be friendly to users and don't force them to type colons for help if possible
- cmd = commandHelper.getCommand(":" + name);
+ cmd = commandHelper.getCommand( ":" + name );
}
- if (cmd == null) {
- throw new CommandException(AnsiFormattedText.from("No such command: ").bold().append(name));
+ if ( cmd == null )
+ {
+ throw new CommandException( AnsiFormattedText.from( "No such command: " ).bold().append( name ) );
}
- logger.printOut(AnsiFormattedText.from("\nusage: ")
- .bold().append(cmd.getName())
- .boldOff()
- .append(" ")
- .append(cmd.getUsage())
- .append("\n\n")
- .append(cmd.getHelp())
- .append("\n")
- .formattedString());
+ logger.printOut( AnsiFormattedText.from( "\nusage: " )
+ .bold().append( cmd.getName() )
+ .boldOff()
+ .append( " " )
+ .append( cmd.getUsage() )
+ .append( "\n\n" )
+ .append( cmd.getHelp() )
+ .append( "\n" )
+ .formattedString() );
}
- private void printGeneralHelp() {
- logger.printOut("\nAvailable commands:");
+ private void printGeneralHelp()
+ {
+ logger.printOut( "\nAvailable commands:" );
// Get longest command so we can align them nicely
List allCommands = commandHelper.getAllCommands();
- int leftColWidth = longestCmdLength(allCommands);
+ int leftColWidth = longestCmdLength( allCommands );
- allCommands.stream().forEach(cmd -> logger.printOut(
- AnsiFormattedText.from(" ")
- .bold().append(String.format("%-" + leftColWidth + "s", cmd.getName()))
- .boldOff().append(" " + cmd.getDescription())
- .formattedString()));
+ allCommands.stream().forEach( cmd -> logger.printOut(
+ AnsiFormattedText.from( " " )
+ .bold().append( String.format( "%-" + leftColWidth + "s", cmd.getName() ) )
+ .boldOff().append( " " + cmd.getDescription() )
+ .formattedString() ) );
- logger.printOut("\nFor help on a specific command type:");
- logger.printOut(AnsiFormattedText.from(" ")
- .append(COMMAND_NAME)
- .bold().append(" command")
- .boldOff().append("\n").formattedString());
+ logger.printOut( "\nFor help on a specific command type:" );
+ logger.printOut( AnsiFormattedText.from( " " )
+ .append( COMMAND_NAME )
+ .bold().append( " command" )
+ .boldOff().append( "\n" ).formattedString() );
- logger.printOut("\nFor help on cypher please visit:");
- logger.printOut(AnsiFormattedText.from(" ")
- .append(CYPHER_REFCARD_LINK)
- .append("\n").formattedString());
+ logger.printOut( "\nFor help on cypher please visit:" );
+ logger.printOut( AnsiFormattedText.from( " " )
+ .append( CYPHER_REFCARD_LINK )
+ .append( "\n" ).formattedString() );
}
- private int longestCmdLength(List allCommands) {
+ private int longestCmdLength( List allCommands )
+ {
String longestCommand = allCommands.stream()
- .map(Command::getName)
- .reduce("", (s1, s2) -> s1.length() > s2.length() ? s1 : s2);
+ .map( Command::getName )
+ .reduce( "", ( s1, s2 ) -> s1.length() > s2.length() ? s1 : s2 );
return longestCommand.length();
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/History.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/History.java
index 8dd7cf59..39018046 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/History.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/History.java
@@ -1,69 +1,96 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.Historian;
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.exception.ExitException;
import org.neo4j.shell.log.Logger;
-import javax.annotation.Nonnull;
-import java.util.Collections;
-import java.util.List;
-
import static org.neo4j.shell.commands.CommandHelper.simpleArgParse;
/**
* Show command history
*/
-public class History implements Command {
+public class History implements Command
+{
private static final String COMMAND_NAME = ":history";
private final Logger logger;
private final Historian historian;
private final List aliases = Collections.emptyList();
- public History(@Nonnull final Logger logger, @Nonnull final Historian historian) {
+ public History( @Nonnull final Logger logger, @Nonnull final Historian historian )
+ {
this.logger = logger;
this.historian = historian;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Print a list of the last commands executed";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "";
}
@Nonnull
@Override
- public String getHelp() {
+ public String getHelp()
+ {
return "Print a list of the last commands executed.";
}
@Nonnull
@Override
- public List getAliases() {
+ public List getAliases()
+ {
return aliases;
}
@Override
- public void execute(@Nonnull String argString) throws ExitException, CommandException {
- simpleArgParse(argString, 0, COMMAND_NAME, getUsage());
+ public void execute( @Nonnull String argString ) throws ExitException, CommandException
+ {
+ simpleArgParse( argString, 0, COMMAND_NAME, getUsage() );
// Calculate starting position
int lineCount = 16;
- logger.printOut(printHistory(historian.getHistory(), lineCount));
+ logger.printOut( printHistory( historian.getHistory(), lineCount ) );
}
/**
@@ -71,18 +98,20 @@ public void execute(@Nonnull String argString) throws ExitException, CommandExce
*
* @param lineCount number of entries to print
*/
- private String printHistory(@Nonnull final List history, final int lineCount) {
+ private String printHistory( @Nonnull final List history, final int lineCount )
+ {
// for alignment, check the string length of history size
- int colWidth = Integer.toString(history.size()).length();
+ int colWidth = Integer.toString( history.size() ).length();
String fmt = " %-" + colWidth + "d %s\n";
String result = "";
int count = 0;
- for (int i = history.size() - 1; i >= 0 && count < lineCount; i--, count++) {
- String line = history.get(i);
+ for ( int i = history.size() - 1; i >= 0 && count < lineCount; i--, count++ )
+ {
+ String line = history.get( i );
// Executing old commands with !N actually starts from 1, and not 0, hence increment index by one
- result = String.format(fmt, i + 1, line) + result;
+ result = String.format( fmt, i + 1, line ) + result;
}
return result;
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Param.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Param.java
index cdff2894..95c0988b 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Param.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Param.java
@@ -1,74 +1,96 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nonnull;
+
import org.neo4j.cypher.internal.evaluator.EvaluationException;
import org.neo4j.shell.ParameterMap;
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.log.AnsiFormattedText;
import org.neo4j.shell.util.ParameterSetter;
-import javax.annotation.Nonnull;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.BiPredicate;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
/**
* This command sets a variable to a name, for use as query parameter.
*/
-public class Param extends ParameterSetter implements Command {
- private final static String COMMAND_NAME = ":param";
+public class Param extends ParameterSetter implements Command
+{
+ private static final String COMMAND_NAME = ":param";
/**
* @param parameterMap the map to set parameters in
*/
- public Param(@Nonnull final ParameterMap parameterMap) {
- super(parameterMap);
+ public Param( @Nonnull final ParameterMap parameterMap )
+ {
+ super( parameterMap );
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Set the value of a query parameter";
}
@Nonnull
@Override
- public String getUsage() {
- return "name => value" ;
+ public String getUsage()
+ {
+ return "name => value";
}
@Nonnull
@Override
- public String getHelp() {
+ public String getHelp()
+ {
return "Set the specified query parameter to the value given";
}
@Nonnull
@Override
- public List getAliases() {
+ public List getAliases()
+ {
return Collections.emptyList();
}
@Override
protected void onWrongUsage() throws CommandException
{
- throw new CommandException(AnsiFormattedText.from("Incorrect usage.\nusage: ")
- .bold().append( COMMAND_NAME ).boldOff().append( " ").append( getUsage()));
+ throw new CommandException( AnsiFormattedText.from( "Incorrect usage.\nusage: " )
+ .bold().append( COMMAND_NAME ).boldOff().append( " " ).append( getUsage() ) );
}
@Override
protected void onWrongNumberOfArguments() throws CommandException
{
- throw new CommandException(AnsiFormattedText.from("Incorrect number of arguments.\nusage: ")
- .bold().append( COMMAND_NAME ).boldOff().append( " ").append( getUsage()));
+ throw new CommandException( AnsiFormattedText.from( "Incorrect number of arguments.\nusage: " )
+ .bold().append( COMMAND_NAME ).boldOff().append( " " ).append( getUsage() ) );
}
@Override
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 0db3daae..21ca5526 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
@@ -1,17 +1,36 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
-import org.neo4j.shell.ParameterMap;
-import org.neo4j.shell.exception.CommandException;
-import org.neo4j.shell.exception.ExitException;
-import org.neo4j.shell.log.Logger;
-import org.neo4j.shell.prettyprint.CypherVariablesFormatter;
-
-import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+
+import org.neo4j.shell.ParameterMap;
+import org.neo4j.shell.exception.CommandException;
+import org.neo4j.shell.exception.ExitException;
+import org.neo4j.shell.log.Logger;
+import org.neo4j.shell.prettyprint.CypherVariablesFormatter;
import static org.neo4j.shell.commands.CommandHelper.simpleArgParse;
import static org.neo4j.shell.prettyprint.CypherVariablesFormatter.escape;
@@ -19,80 +38,98 @@
/**
* This lists all query parameters which have been set
*/
-public class Params implements Command {
+public class Params implements Command
+{
public static final String COMMAND_NAME = ":params";
+ private static final Pattern backtickPattern = Pattern.compile( "^\\s*(?(`([^`])*`)+?)\\s*" );
private final Logger logger;
private final ParameterMap parameterMap;
- private static final Pattern backtickPattern = Pattern.compile("^\\s*(?(`([^`])*`)+?)\\s*");
- public Params(@Nonnull Logger logger, @Nonnull ParameterMap parameterMap) {
+ public Params( @Nonnull Logger logger, @Nonnull ParameterMap parameterMap )
+ {
this.logger = logger;
this.parameterMap = parameterMap;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Print all currently set query parameters and their values";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "[parameter]";
}
@Nonnull
@Override
- public String getHelp() {
+ public String getHelp()
+ {
return "Print a table of all currently set query parameters or the value for the given parameter";
}
@Nonnull
@Override
- public List getAliases() {
- return Arrays.asList(":parameters");
+ public List getAliases()
+ {
+ return Arrays.asList( ":parameters" );
}
@Override
- public void execute(@Nonnull final String argString) throws ExitException, CommandException {
+ public void execute( @Nonnull final String argString ) throws ExitException, CommandException
+ {
String trim = argString.trim();
- Matcher matcher = backtickPattern.matcher(trim);
- if (trim.startsWith("`") && matcher.matches()) {
- listParam(trim);
- } else {
- String[] args = simpleArgParse(argString, 0, 1, COMMAND_NAME, getUsage());
- if (args.length > 0) {
- listParam(args[0]);
- } else {
+ Matcher matcher = backtickPattern.matcher( trim );
+ if ( trim.startsWith( "`" ) && matcher.matches() )
+ {
+ listParam( trim );
+ }
+ else
+ {
+ String[] args = simpleArgParse( argString, 0, 1, COMMAND_NAME, getUsage() );
+ if ( args.length > 0 )
+ {
+ listParam( args[0] );
+ }
+ else
+ {
listAllParams();
}
}
}
- private void listParam(@Nonnull String name) throws CommandException {
- String parameterName = CypherVariablesFormatter.unescapedCypherVariable(name);
- if (!this.parameterMap.getAllAsUserInput().containsKey(parameterName)) {
- throw new CommandException("Unknown parameter: " + name);
+ private void listParam( @Nonnull String name ) throws CommandException
+ {
+ String parameterName = CypherVariablesFormatter.unescapedCypherVariable( name );
+ if ( !this.parameterMap.getAllAsUserInput().containsKey( parameterName ) )
+ {
+ throw new CommandException( "Unknown parameter: " + name );
}
- listParam(name.length(), name, this.parameterMap.getAllAsUserInput().get(parameterName).getValueAsString());
+ listParam( name.length(), name, this.parameterMap.getAllAsUserInput().get( parameterName ).getValueAsString() );
}
- private void listParam(int leftColWidth, @Nonnull String key, @Nonnull Object value) {
- logger.printOut(String.format(":param %-" + leftColWidth + "s => %s", key, value));
+ private void listParam( int leftColWidth, @Nonnull String key, @Nonnull Object value )
+ {
+ logger.printOut( String.format( ":param %-" + leftColWidth + "s => %s", key, value ) );
}
- private void listAllParams() {
- List keys = parameterMap.getAllAsUserInput().keySet().stream().sorted().collect(Collectors.toList());
+ private void listAllParams()
+ {
+ List keys = parameterMap.getAllAsUserInput().keySet().stream().sorted().collect( Collectors.toList() );
- int leftColWidth = keys.stream().map((s) -> escape(s).length()).reduce(0, Math::max);
+ int leftColWidth = keys.stream().map( s -> escape( s ).length() ).reduce( 0, Math::max );
- keys.forEach(key -> listParam(leftColWidth, escape(key), parameterMap.getAllAsUserInput().get(key).getValueAsString()));
+ keys.forEach( key -> listParam( leftColWidth, escape( key ), parameterMap.getAllAsUserInput().get( key ).getValueAsString() ) );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Rollback.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Rollback.java
index d2383923..a789ddac 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Rollback.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Rollback.java
@@ -1,59 +1,86 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.TransactionHandler;
import org.neo4j.shell.exception.CommandException;
import org.neo4j.shell.exception.ExitException;
-import javax.annotation.Nonnull;
-import java.util.Collections;
-import java.util.List;
-
import static org.neo4j.shell.commands.CommandHelper.simpleArgParse;
/**
* This command marks a transaction as failed and closes it.
*/
-public class Rollback implements Command {
+public class Rollback implements Command
+{
public static final String COMMAND_NAME = ":rollback";
private final TransactionHandler transactionHandler;
- public Rollback(@Nonnull final TransactionHandler transactionHandler) {
+ public Rollback( @Nonnull final TransactionHandler transactionHandler )
+ {
this.transactionHandler = transactionHandler;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Rollback the currently open transaction";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "";
}
@Nonnull
@Override
- public String getHelp() {
+ public String getHelp()
+ {
return "Roll back and closes the currently open transaction";
}
@Nonnull
@Override
- public List getAliases() {
+ public List getAliases()
+ {
return Collections.emptyList();
}
@Override
- public void execute(@Nonnull final String argString) throws ExitException, CommandException {
- simpleArgParse(argString, 0, COMMAND_NAME, getUsage());
+ public void execute( @Nonnull final String argString ) throws ExitException, CommandException
+ {
+ simpleArgParse( argString, 0, COMMAND_NAME, getUsage() );
transactionHandler.rollbackTransaction();
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Source.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Source.java
index 76153a44..2048fe73 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Source.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Source.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import java.io.BufferedReader;
@@ -20,53 +39,62 @@
/**
* This command reads a cypher file frome the filesystem and executes the statements therein.
*/
-public class Source implements Command {
+public class Source implements Command
+{
private static final String COMMAND_NAME = ":source";
private final CypherShell cypherShell;
private final StatementParser statementParser;
- public Source( CypherShell cypherShell, StatementParser statementParser ) {
+ public Source( CypherShell cypherShell, StatementParser statementParser )
+ {
this.cypherShell = cypherShell;
this.statementParser = statementParser;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Interactively executes cypher statements from a file";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "[filename]";
}
@Nonnull
@Override
- public String getHelp() {
+ public String getHelp()
+ {
return "Executes Cypher statements from a file";
}
@Nonnull
@Override
- public List getAliases() {
+ public List getAliases()
+ {
return Collections.emptyList();
}
@Override
- public void execute(@Nonnull final String argString) throws ExitException, CommandException {
- String filename = simpleArgParse(argString, 1, 1, COMMAND_NAME, getUsage())[0];
+ public void execute( @Nonnull final String argString ) throws ExitException, CommandException
+ {
+ String filename = simpleArgParse( argString, 1, 1, COMMAND_NAME, getUsage() )[0];
- try ( BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream( new File(filename) )))) {
+ try ( BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( new FileInputStream( new File( filename ) ) ) ) )
+ {
bufferedReader.lines()
- .forEach(line -> statementParser.parseMoreText(line + "\n"));
+ .forEach( line -> statementParser.parseMoreText( line + "\n" ) );
List statements = statementParser.consumeStatements();
for ( String statement : statements )
{
@@ -75,7 +103,7 @@ public void execute(@Nonnull final String argString) throws ExitException, Comma
}
catch ( IOException e )
{
- throw new CommandException( format("Cannot find file: '%s'", filename), e);
+ throw new CommandException( format( "Cannot find file: '%s'", filename ), e );
}
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/commands/Use.java b/cypher-shell/src/main/java/org/neo4j/shell/commands/Use.java
index bb66ffb9..449909c8 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/commands/Use.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/commands/Use.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.commands;
import java.util.Collections;
@@ -13,49 +32,59 @@
/**
* This command starts a transaction.
*/
-public class Use implements Command {
+public class Use implements Command
+{
private static final String COMMAND_NAME = ":use";
- @Nonnull private final DatabaseManager databaseManager;
- @Nonnull private String databaseName;
+ @Nonnull
+ private final DatabaseManager databaseManager;
+ @Nonnull
+ private String databaseName;
- public Use(@Nonnull final DatabaseManager databaseManager) {
+ public Use( @Nonnull final DatabaseManager databaseManager )
+ {
this.databaseManager = databaseManager;
}
@Nonnull
@Override
- public String getName() {
+ public String getName()
+ {
return COMMAND_NAME;
}
@Nonnull
@Override
- public String getDescription() {
+ public String getDescription()
+ {
return "Set the active database";
}
@Nonnull
@Override
- public String getUsage() {
+ public String getUsage()
+ {
return "database";
}
@Nonnull
@Override
- public String getHelp() {
- return String.format("Set the active database that transactions are executed on", Commit.COMMAND_NAME);
+ public String getHelp()
+ {
+ return String.format( "Set the active database that transactions are executed on", Commit.COMMAND_NAME );
}
@Nonnull
@Override
- public List getAliases() {
+ public List getAliases()
+ {
return Collections.emptyList();
}
@Override
- public void execute(@Nonnull final String argString) throws ExitException, CommandException {
- String[] args = simpleArgParse(argString, 0, 1, COMMAND_NAME, getUsage());
+ public void execute( @Nonnull final String argString ) throws ExitException, CommandException
+ {
+ String[] args = simpleArgParse( argString, 0, 1, COMMAND_NAME, getUsage() );
String databaseName = args.length == 0 ? DatabaseManager.ABSENT_DB_NAME : args[0];
- databaseManager.setActiveDatabase(databaseName);
+ databaseManager.setActiveDatabase( databaseName );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/exception/AnsiFormattedException.java b/cypher-shell/src/main/java/org/neo4j/shell/exception/AnsiFormattedException.java
index aa912c31..b8041326 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/exception/AnsiFormattedException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/exception/AnsiFormattedException.java
@@ -1,33 +1,57 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.exception;
-import org.neo4j.shell.log.AnsiFormattedText;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.neo4j.shell.log.AnsiFormattedText;
+
/**
* A type of exception where the message can formatted with Ansi codes.
*/
-public class AnsiFormattedException extends Exception {
+public class AnsiFormattedException extends Exception
+{
private final AnsiFormattedText message;
- public AnsiFormattedException(@Nullable String message) {
- super(message);
- this.message = AnsiFormattedText.from(message);
+ public AnsiFormattedException( @Nullable String message )
+ {
+ super( message );
+ this.message = AnsiFormattedText.from( message );
}
- public AnsiFormattedException(@Nullable String message, Throwable cause) {
- super(message, cause);
- this.message = AnsiFormattedText.from(message);
+ public AnsiFormattedException( @Nullable String message, Throwable cause )
+ {
+ super( message, cause );
+ this.message = AnsiFormattedText.from( message );
}
- public AnsiFormattedException(@Nonnull AnsiFormattedText message) {
- super(message.plainString());
+ public AnsiFormattedException( @Nonnull AnsiFormattedText message )
+ {
+ super( message.plainString() );
this.message = message;
}
@Nonnull
- public AnsiFormattedText getFormattedMessage() {
+ public AnsiFormattedText getFormattedMessage()
+ {
return message;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/exception/CommandException.java b/cypher-shell/src/main/java/org/neo4j/shell/exception/CommandException.java
index 45073616..613c4140 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/exception/CommandException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/exception/CommandException.java
@@ -1,23 +1,46 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.exception;
-import org.neo4j.shell.log.AnsiFormattedText;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.neo4j.shell.log.AnsiFormattedText;
+
/**
* And exception indicating that a command invocation failed.
*/
-public class CommandException extends AnsiFormattedException {
- public CommandException(@Nullable String msg) {
- super(msg);
+public class CommandException extends AnsiFormattedException
+{
+ public CommandException( @Nullable String msg )
+ {
+ super( msg );
}
- public CommandException(@Nullable String msg, Throwable cause) {
- super(msg, cause);
+ public CommandException( @Nullable String msg, Throwable cause )
+ {
+ super( msg, cause );
}
- public CommandException(@Nonnull AnsiFormattedText append) {
- super(append);
+ public CommandException( @Nonnull AnsiFormattedText append )
+ {
+ super( append );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/exception/DuplicateCommandException.java b/cypher-shell/src/main/java/org/neo4j/shell/exception/DuplicateCommandException.java
index 2b11c09e..557e2ce8 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/exception/DuplicateCommandException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/exception/DuplicateCommandException.java
@@ -1,7 +1,28 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.exception;
-public class DuplicateCommandException extends RuntimeException {
- public DuplicateCommandException(String s) {
- super(s);
+public class DuplicateCommandException extends RuntimeException
+{
+ public DuplicateCommandException( String s )
+ {
+ super( s );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/exception/ExitException.java b/cypher-shell/src/main/java/org/neo4j/shell/exception/ExitException.java
index 562b4ab9..6ebbc83d 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/exception/ExitException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/exception/ExitException.java
@@ -1,14 +1,36 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.exception;
-public class ExitException extends Error {
+public class ExitException extends Error
+{
private final int code;
- public ExitException(int code) {
+ public ExitException( int code )
+ {
super();
this.code = code;
}
- public int getCode() {
+ public int getCode()
+ {
return code;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/exception/IncompleteStatementException.java b/cypher-shell/src/main/java/org/neo4j/shell/exception/IncompleteStatementException.java
index 4f2edd55..6b0ac9d8 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/exception/IncompleteStatementException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/exception/IncompleteStatementException.java
@@ -1,4 +1,24 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.exception;
-public class IncompleteStatementException extends IllegalArgumentException {
+public class IncompleteStatementException extends IllegalArgumentException
+{
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/exception/NoMoreInputException.java b/cypher-shell/src/main/java/org/neo4j/shell/exception/NoMoreInputException.java
index 663ea688..9899ee41 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/exception/NoMoreInputException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/exception/NoMoreInputException.java
@@ -1,8 +1,27 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.exception;
/**
- * Signifies that the user hit CTRL-D, or we simply ran out of file.
- * Should many times exit gracefully.
+ * Signifies that the user hit CTRL-D, or we simply ran out of file. Should many times exit gracefully.
*/
-public class NoMoreInputException extends Exception {
+public class NoMoreInputException extends Exception
+{
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/exception/UnconsumedStatementException.java b/cypher-shell/src/main/java/org/neo4j/shell/exception/UnconsumedStatementException.java
index decd531c..270c41b6 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/exception/UnconsumedStatementException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/exception/UnconsumedStatementException.java
@@ -1,4 +1,24 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.exception;
-public class UnconsumedStatementException extends IllegalArgumentException {
+public class UnconsumedStatementException extends IllegalArgumentException
+{
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiFormattedText.java b/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiFormattedText.java
index b7a72d3a..f8a00bfe 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiFormattedText.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiFormattedText.java
@@ -1,19 +1,39 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.log;
import org.fusesource.jansi.Ansi;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
/**
* A piece of text which can be rendered with Ansi format codes.
*/
-public class AnsiFormattedText {
+public class AnsiFormattedText
+{
private static final String RED = "RED";
private static final String BOLD = "BOLD";
@@ -23,36 +43,38 @@ public class AnsiFormattedText {
// Each piece is formatted separately
private final LinkedList pieces = new LinkedList<>();
// can be defined, or undefined. null means undefined.
- private String color = null;
+ private String color;
/**
- * Return a new map which is a copy of the first map, with the keys/values from the second if they do not override
- * anything already defined in the first map.
+ * Return a new map which is a copy of the first map, with the keys/values from the second if they do not override anything already defined in the first
+ * map.
*/
- private static Map mergeMaps(Map primary, Map secondary) {
+ private static Map mergeMaps( Map primary, Map secondary )
+ {
Map result = new HashMap<>();
- result.putAll(primary);
- secondary.forEach(result::putIfAbsent);
+ result.putAll( primary );
+ secondary.forEach( result::putIfAbsent );
return result;
}
/**
- *
* @return a new empty instance
*/
- public static AnsiFormattedText s() {
+ public static AnsiFormattedText s()
+ {
return new AnsiFormattedText();
}
/**
- *
* @param string to start with, may be null in which case it is ignored
* @return a new instance containing the unformatted text in string, or empty if it was null
*/
- public static AnsiFormattedText from(@Nullable String string) {
+ public static AnsiFormattedText from( @Nullable String string )
+ {
AnsiFormattedText st = new AnsiFormattedText();
- if (string != null) {
- st.append(string);
+ if ( string != null )
+ {
+ st.append( string );
}
return st;
}
@@ -61,30 +83,36 @@ public static AnsiFormattedText from(@Nullable String string) {
* @return the text as a string including possible formatting, ready for ANSI formatting
*/
@Nonnull
- public String formattedString() {
+ public String formattedString()
+ {
StringBuilder sb = new StringBuilder();
- for (AnsiFormattedString s : pieces) {
+ for ( AnsiFormattedString s : pieces )
+ {
List codes = new ArrayList<>();
// color
- if (s.color != null && !DEFAULT_COLOR.equals(s.color)) {
- codes.add(s.color);
+ if ( s.color != null && !DEFAULT_COLOR.equals( s.color ) )
+ {
+ codes.add( s.color );
}
// attributes
- if (s.attributes.getOrDefault(BOLD, false)) {
- codes.add(BOLD);
+ if ( s.attributes.getOrDefault( BOLD, false ) )
+ {
+ codes.add( BOLD );
}
// Only do formatting if we actually have some formatting to apply
- if (!codes.isEmpty()) {
- sb.append("@|")
- .append(String.join(",", codes))
- .append(" ");
+ if ( !codes.isEmpty() )
+ {
+ sb.append( "@|" )
+ .append( String.join( ",", codes ) )
+ .append( " " );
}
// string
- sb.append(s.string);
+ sb.append( s.string );
// Only reset formatting if we actually did some formatting
- if (!codes.isEmpty()) {
- sb.append("|@");
+ if ( !codes.isEmpty() )
+ {
+ sb.append( "|@" );
}
}
return sb.toString();
@@ -94,30 +122,32 @@ public String formattedString() {
* @return the text as a string rendered with ANSI escape codes
*/
@Nonnull
- public String renderedString() {
- return Ansi.ansi().render(formattedString()).toString();
+ public String renderedString()
+ {
+ return Ansi.ansi().render( formattedString() ).toString();
}
/**
* @return the text as a plain string without any formatting
*/
@Nonnull
- public String plainString() {
+ public String plainString()
+ {
StringBuilder sb = new StringBuilder();
- pieces.forEach(sb::append);
+ pieces.forEach( sb::append );
return sb.toString();
}
/**
- * Append an already formatted string. If any formatting codes are defined, then they will be ignored in favor
- * of this instance's formatting.
+ * Append an already formatted string. If any formatting codes are defined, then they will be ignored in favor of this instance's formatting.
*
* @param existing text to append using this instance's formatting
* @return this
*/
- public AnsiFormattedText append(AnsiFormattedText existing) {
- existing.pieces.forEach(s -> pieces.add(new AnsiFormattedString(color != null ? color : s.color,
- mergeMaps(attributes, s.attributes), s.string)));
+ public AnsiFormattedText append( AnsiFormattedText existing )
+ {
+ existing.pieces.forEach( s -> pieces.add( new AnsiFormattedString( color != null ? color : s.color,
+ mergeMaps( attributes, s.attributes ), s.string ) ) );
return this;
}
@@ -127,17 +157,20 @@ public AnsiFormattedText append(AnsiFormattedText existing) {
* @param s string to append using this instance's formatting
* @return this
*/
- public AnsiFormattedText append(String s) {
- pieces.add(new AnsiFormattedString(color, attributes, s));
+ public AnsiFormattedText append( String s )
+ {
+ pieces.add( new AnsiFormattedString( color, attributes, s ) );
return this;
}
/**
* Append a new line
+ *
* @return this
*/
- public AnsiFormattedText appendNewLine() {
- pieces.add(new AnsiFormattedString(color, attributes, System.lineSeparator()));
+ public AnsiFormattedText appendNewLine()
+ {
+ pieces.add( new AnsiFormattedString( color, attributes, System.lineSeparator() ) );
return this;
}
@@ -146,8 +179,9 @@ public AnsiFormattedText appendNewLine() {
*
* @return this
*/
- public AnsiFormattedText bold() {
- attributes.put(BOLD, true);
+ public AnsiFormattedText bold()
+ {
+ attributes.put( BOLD, true );
return this;
}
@@ -156,8 +190,9 @@ public AnsiFormattedText bold() {
*
* @return this
*/
- public AnsiFormattedText boldOff() {
- attributes.put(BOLD, false);
+ public AnsiFormattedText boldOff()
+ {
+ attributes.put( BOLD, false );
return this;
}
@@ -166,7 +201,8 @@ public AnsiFormattedText boldOff() {
*
* @return this
*/
- public AnsiFormattedText colorRed() {
+ public AnsiFormattedText colorRed()
+ {
color = RED;
return this;
}
@@ -176,30 +212,33 @@ public AnsiFormattedText colorRed() {
*
* @return this
*/
- public AnsiFormattedText colorDefault() {
+ public AnsiFormattedText colorDefault()
+ {
color = DEFAULT_COLOR;
return this;
}
-
/**
* A formatted string
*/
- private static class AnsiFormattedString {
+ private static class AnsiFormattedString
+ {
// can be defined, or undefined. null means undefined.
final String color;
// same here, no mapping means undefined
final Map attributes = new HashMap<>();
final String string;
- AnsiFormattedString(String color, Map attributes, String s) {
+ AnsiFormattedString( String color, Map attributes, String s )
+ {
this.color = color;
- this.attributes.putAll(attributes);
+ this.attributes.putAll( attributes );
this.string = s;
}
@Override
- public String toString() {
+ public String toString()
+ {
return string;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiLogger.java b/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiLogger.java
index 69cc0dca..aa9f8f27 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiLogger.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/log/AnsiLogger.java
@@ -1,18 +1,38 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.log;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+import javax.annotation.Nonnull;
+
import org.neo4j.driver.exceptions.ClientException;
import org.neo4j.driver.exceptions.DiscoveryException;
import org.neo4j.driver.exceptions.ServiceUnavailableException;
import org.neo4j.shell.cli.Format;
import org.neo4j.shell.exception.AnsiFormattedException;
-import javax.annotation.Nonnull;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.nio.charset.StandardCharsets;
-
import static org.fusesource.jansi.internal.CLibrary.STDERR_FILENO;
import static org.fusesource.jansi.internal.CLibrary.STDOUT_FILENO;
import static org.fusesource.jansi.internal.CLibrary.isatty;
@@ -20,40 +40,51 @@
/**
* A basic logger which prints Ansi formatted text to STDOUT and STDERR
*/
-public class AnsiLogger implements Logger {
+public class AnsiLogger implements Logger
+{
private final PrintStream out;
private final PrintStream err;
private final boolean debug;
private Format format;
- public AnsiLogger(final boolean debug) {
- this(debug, Format.VERBOSE, System.out, System.err);
+ public AnsiLogger( final boolean debug )
+ {
+ this( debug, Format.VERBOSE, System.out, System.err );
}
- public AnsiLogger(final boolean debug, @Nonnull Format format,
- @Nonnull PrintStream out, @Nonnull PrintStream err) {
+ public AnsiLogger( final boolean debug, @Nonnull Format format,
+ @Nonnull PrintStream out, @Nonnull PrintStream err )
+ {
this.debug = debug;
this.format = format;
this.out = out;
this.err = err;
- try {
- if (isOutputInteractive()) {
- Ansi.setEnabled(true);
+ try
+ {
+ if ( isOutputInteractive() )
+ {
+ Ansi.setEnabled( true );
AnsiConsole.systemInstall();
- } else {
- Ansi.setEnabled(false);
}
- } catch (Throwable t) {
+ else
+ {
+ Ansi.setEnabled( false );
+ }
+ }
+ catch ( Throwable t )
+ {
// Not running on a distro with standard c library, disable Ansi.
- Ansi.setEnabled(false);
+ Ansi.setEnabled( false );
}
}
@Nonnull
- private static Throwable getRootCause(@Nonnull final Throwable th) {
+ private static Throwable getRootCause( @Nonnull final Throwable th )
+ {
Throwable cause = th;
- while (cause.getCause() != null) {
+ while ( cause.getCause() != null )
+ {
cause = cause.getCause();
}
return cause;
@@ -64,93 +95,117 @@ private static Throwable getRootCause(@Nonnull final Throwable th) {
* @throws UnsatisfiedLinkError maybe if standard c library can't be found
* @throws NoClassDefFoundError maybe if standard c library can't be found
*/
- private static boolean isOutputInteractive() {
- return 1 == isatty(STDOUT_FILENO) && 1 == isatty(STDERR_FILENO);
+ private static boolean isOutputInteractive()
+ {
+ return 1 == isatty( STDOUT_FILENO ) && 1 == isatty( STDERR_FILENO );
}
@Nonnull
@Override
- public PrintStream getOutputStream() {
+ public PrintStream getOutputStream()
+ {
return out;
}
@Nonnull
@Override
- public PrintStream getErrorStream() {
+ public PrintStream getErrorStream()
+ {
return err;
}
@Nonnull
@Override
- public Format getFormat() {
+ public Format getFormat()
+ {
return format;
}
@Override
- public void setFormat(@Nonnull Format format) {
+ public void setFormat( @Nonnull Format format )
+ {
this.format = format;
}
@Override
- public boolean isDebugEnabled() {
+ public boolean isDebugEnabled()
+ {
return debug;
}
@Override
- public void printError(@Nonnull Throwable throwable) {
- printError(getFormattedMessage(throwable));
+ public void printError( @Nonnull Throwable throwable )
+ {
+ printError( getFormattedMessage( throwable ) );
}
@Override
- public void printError(@Nonnull String s) {
- err.println(Ansi.ansi().render(s).toString());
+ public void printError( @Nonnull String s )
+ {
+ err.println( Ansi.ansi().render( s ).toString() );
}
@Override
- public void printOut(@Nonnull final String msg) {
- out.println(Ansi.ansi().render(msg).toString());
+ public void printOut( @Nonnull final String msg )
+ {
+ out.println( Ansi.ansi().render( msg ).toString() );
}
/**
* Formatting for Bolt exceptions.
*/
@Nonnull
- public String getFormattedMessage(@Nonnull final Throwable e) {
+ public String getFormattedMessage( @Nonnull final Throwable e )
+ {
AnsiFormattedText msg = AnsiFormattedText.s().colorRed();
- if (isDebugEnabled()) {
+ if ( isDebugEnabled() )
+ {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(baos);
- e.printStackTrace(ps);
- msg.append(new String(baos.toByteArray(), StandardCharsets.UTF_8));
- } else {
- if (e instanceof AnsiFormattedException) {
- msg = msg.append(((AnsiFormattedException) e).getFormattedMessage());
- } else if (e instanceof ClientException &&
- e.getMessage() != null && e.getMessage().contains("Missing username")) {
+ PrintStream ps = new PrintStream( baos );
+ e.printStackTrace( ps );
+ msg.append( new String( baos.toByteArray(), StandardCharsets.UTF_8 ) );
+ }
+ else
+ {
+ if ( e instanceof AnsiFormattedException )
+ {
+ msg = msg.append( ((AnsiFormattedException) e).getFormattedMessage() );
+ }
+ else if ( e instanceof ClientException &&
+ e.getMessage() != null && e.getMessage().contains( "Missing username" ) )
+ {
// Username and password was not specified
- msg = msg.append(e.getMessage())
- .append("\nPlease specify --username, and optionally --password, as argument(s)")
- .append("\nor as environment variable(s), NEO4J_USERNAME, and NEO4J_PASSWORD respectively.")
- .append("\nSee --help for more info.");
- } else {
+ msg = msg.append( e.getMessage() )
+ .append( "\nPlease specify --username, and optionally --password, as argument(s)" )
+ .append( "\nor as environment variable(s), NEO4J_USERNAME, and NEO4J_PASSWORD respectively." )
+ .append( "\nSee --help for more info." );
+ }
+ else
+ {
Throwable cause = e;
// Get the suppressed root cause of ServiceUnavailableExceptions
- if (e instanceof ServiceUnavailableException) {
+ if ( e instanceof ServiceUnavailableException )
+ {
Throwable[] suppressed = e.getSuppressed();
- for (Throwable s : suppressed) {
- if (s instanceof DiscoveryException ) {
- cause = getRootCause(s);
+ for ( Throwable s : suppressed )
+ {
+ if ( s instanceof DiscoveryException )
+ {
+ cause = getRootCause( s );
break;
}
}
}
- if (cause.getMessage() != null) {
- msg = msg.append(cause.getMessage());
- } else {
- msg = msg.append(cause.getClass().getSimpleName());
+ if ( cause.getMessage() != null )
+ {
+ msg = msg.append( cause.getMessage() );
+ }
+ else
+ {
+ msg = msg.append( cause.getClass().getSimpleName() );
}
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/log/Logger.java b/cypher-shell/src/main/java/org/neo4j/shell/log/Logger.java
index 5e319867..1f42a824 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/log/Logger.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/log/Logger.java
@@ -1,12 +1,32 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.log;
+import java.io.PrintStream;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.cli.Format;
import org.neo4j.shell.prettyprint.LinePrinter;
-import javax.annotation.Nonnull;
-import java.io.PrintStream;
-
-public interface Logger extends LinePrinter {
+public interface Logger extends LinePrinter
+{
/**
* @return the output stream
*/
@@ -20,19 +40,18 @@ public interface Logger extends LinePrinter {
PrintStream getErrorStream();
/**
- * Print a sanitized cause of the specified error.
- * If debug mode is enabled, a full stacktrace should be printed as well.
+ * Print a sanitized cause of the specified error. If debug mode is enabled, a full stacktrace should be printed as well.
*
* @param throwable to print to the error stream
*/
- void printError(@Nonnull Throwable throwable);
+ void printError( @Nonnull Throwable throwable );
/**
* Print the designated text to configured error stream.
*
* @param text to print to the error stream
*/
- void printError(@Nonnull String text);
+ void printError( @Nonnull String text );
/**
* @return the current format of the logger
@@ -45,7 +64,7 @@ public interface Logger extends LinePrinter {
*
* @param format to set
*/
- void setFormat(@Nonnull Format format);
+ void setFormat( @Nonnull Format format );
/**
* @return true if debug mode is enabled, false otherwise
@@ -57,33 +76,37 @@ public interface Logger extends LinePrinter {
*
* @param text to print to the output stream
*/
- default void printIfDebug(@Nonnull String text) {
- if (isDebugEnabled()) {
- printOut(text);
+ default void printIfDebug( @Nonnull String text )
+ {
+ if ( isDebugEnabled() )
+ {
+ printOut( text );
}
}
/**
- * Convenience method which only prints the given text to the output stream if the format set
- * is {@link Format#VERBOSE}.
+ * Convenience method which only prints the given text to the output stream if the format set is {@link Format#VERBOSE}.
*
* @param text to print to the output stream
*/
- default void printIfVerbose(@Nonnull String text) {
- if (Format.VERBOSE.equals(getFormat())) {
- printOut(text);
+ default void printIfVerbose( @Nonnull String text )
+ {
+ if ( Format.VERBOSE.equals( getFormat() ) )
+ {
+ printOut( text );
}
}
/**
- * Convenience method which only prints the given text to the output stream if the format set
- * is {@link Format#PLAIN}.
+ * Convenience method which only prints the given text to the output stream if the format set is {@link Format#PLAIN}.
*
* @param text to print to the output stream
*/
- default void printIfPlain(@Nonnull String text) {
- if (Format.PLAIN.equals(getFormat())) {
- printOut(text);
+ default void printIfPlain( @Nonnull String text )
+ {
+ if ( Format.PLAIN.equals( getFormat() ) )
+ {
+ printOut( text );
}
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogger.java b/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogger.java
index dc2201e3..4b5bd77a 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogger.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogger.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.log;
import org.neo4j.driver.Logger;
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogging.java b/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogging.java
index e012e81e..6c326cf5 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogging.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/log/NullLogging.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.log;
import org.neo4j.driver.Logger;
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/parser/ShellStatementParser.java b/cypher-shell/src/main/java/org/neo4j/shell/parser/ShellStatementParser.java
index 731c3def..c64db0e7 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/parser/ShellStatementParser.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/parser/ShellStatementParser.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.parser;
import java.util.ArrayList;
@@ -9,9 +28,10 @@
/**
* A cypher aware parser which can detect shell commands (:prefixed) or cypher.
*/
-public class ShellStatementParser implements StatementParser {
+public class ShellStatementParser implements StatementParser
+{
- private static final Pattern SHELL_CMD_PATTERN = Pattern.compile("^\\s*:.+\\s*$");
+ private static final Pattern SHELL_CMD_PATTERN = Pattern.compile( "^\\s*:.+\\s*$" );
private static final char SEMICOLON = ';';
private static final char BACKSLASH = '\\';
private static final String LINE_COMMENT_START = "//";
@@ -27,63 +47,71 @@ public class ShellStatementParser implements StatementParser {
private ArrayList parsedStatements;
private int commentStart = NO_COMMENT;
- public ShellStatementParser() {
+ public ShellStatementParser()
+ {
parsedStatements = new ArrayList<>();
statement = new StringBuilder();
awaitedRightDelimiter = Optional.empty();
}
/**
- * Parses text and adds to the list of parsed statements if a statement is found to be completed.
- * Note that it is expected that lines include newlines.
+ * Parses text and adds to the list of parsed statements if a statement is found to be completed. Note that it is expected that lines include newlines.
*
* @param line to parse (including ending newline)
*/
@Override
- public void parseMoreText(@Nonnull String line) {
+ public void parseMoreText( @Nonnull String line )
+ {
// See if it could possibly be a shell command, only valid if not in a current statement
- if ( statementNotStarted() && SHELL_CMD_PATTERN.matcher(line).find()) {
- parsedStatements.add(line);
+ if ( statementNotStarted() && SHELL_CMD_PATTERN.matcher( line ).find() )
+ {
+ parsedStatements.add( line );
return;
}
// We will guess it is cypher then
boolean skipNext = false;
char prev, current = (char) 0;
- for (char c : line.toCharArray()) {
+ for ( char c : line.toCharArray() )
+ {
// append current
- statement.append(c);
+ statement.append( c );
// last char shuffling
prev = current;
current = c;
- if (skipNext) {
+ if ( skipNext )
+ {
// This char is escaped so gets no special treatment
skipNext = false;
continue;
}
- if (handleComments(prev, current)) {
+ if ( handleComments( prev, current ) )
+ {
continue;
}
- if (current == BACKSLASH) {
+ if ( current == BACKSLASH )
+ {
// backslash can escape stuff outside of comments (but inside quotes too!)
skipNext = true;
continue;
}
- if (handleQuotes(prev, current)) {
+ if ( handleQuotes( prev, current ) )
+ {
continue;
}
// Not escaped, not in a quote, not in a comment
- if (handleSemicolon(current)) {
+ if ( handleSemicolon( current ) )
+ {
continue;
}
// If it's the start of a quote or comment
- awaitedRightDelimiter = getRightDelimiter(prev, current);
+ awaitedRightDelimiter = getRightDelimiter( prev, current );
}
}
@@ -91,10 +119,12 @@ public void parseMoreText(@Nonnull String line) {
* @param current character
* @return true if parsing should go immediately to the next character, false otherwise
*/
- private boolean handleSemicolon(char current) {
- if (current == SEMICOLON) {
+ private boolean handleSemicolon( char current )
+ {
+ if ( current == SEMICOLON )
+ {
// end current statement
- parsedStatements.add(statement.toString());
+ parsedStatements.add( statement.toString() );
// start a new statement
statement = new StringBuilder();
return true;
@@ -103,13 +133,16 @@ private boolean handleSemicolon(char current) {
}
/**
- * @param prev character
+ * @param prev character
* @param current character
* @return true if parsing should go immediately to the next character, false otherwise
*/
- private boolean handleQuotes(char prev, char current) {
- if (inQuote()) {
- if (isRightDelimiter(prev, current)) {
+ private boolean handleQuotes( char prev, char current )
+ {
+ if ( inQuote() )
+ {
+ if ( isRightDelimiter( prev, current ) )
+ {
// Then end it
awaitedRightDelimiter = Optional.empty();
return true;
@@ -121,18 +154,22 @@ private boolean handleQuotes(char prev, char current) {
}
/**
- * @param prev character
+ * @param prev character
* @param current character
* @return true if parsing should go immediately to the next character, false otherwise
*/
- private boolean handleComments(char prev, char current) {
- if (inComment()) {
- if ( commentStart == NO_COMMENT ) {
+ private boolean handleComments( char prev, char current )
+ {
+ if ( inComment() )
+ {
+ if ( commentStart == NO_COMMENT )
+ {
//find the position of //.. or /*...
//i.e. currentPos - 1 - 2
commentStart = statement.length() - 3;
}
- if (isRightDelimiter(prev, current)) {
+ if ( isRightDelimiter( prev, current ) )
+ {
// Then end it
awaitedRightDelimiter = Optional.empty();
statement.delete( commentStart, statement.length() );
@@ -148,7 +185,8 @@ private boolean handleComments(char prev, char current) {
/**
* @return true if inside a quote, false otherwise
*/
- private boolean inQuote() {
+ private boolean inQuote()
+ {
return awaitedRightDelimiter.isPresent() && !inComment();
}
@@ -157,84 +195,99 @@ private boolean inQuote() {
* @param last character
* @return true if the last two chars ends the current comment, false otherwise
*/
- private boolean isRightDelimiter(char first, char last) {
- if (!awaitedRightDelimiter.isPresent()) {
+ private boolean isRightDelimiter( char first, char last )
+ {
+ if ( !awaitedRightDelimiter.isPresent() )
+ {
return false;
}
final String expectedEnd = awaitedRightDelimiter.get();
- if (expectedEnd.length() == 1) {
- return expectedEnd.equals(String.valueOf(last));
- } else {
- return expectedEnd.equals(String.valueOf(first) + last);
+ if ( expectedEnd.length() == 1 )
+ {
+ return expectedEnd.equals( String.valueOf( last ) );
+ }
+ else
+ {
+ return expectedEnd.equals( String.valueOf( first ) + last );
}
}
/**
* @return true if we are currently inside a comment, false otherwise
*/
- private boolean inComment() {
+ private boolean inComment()
+ {
return awaitedRightDelimiter.isPresent() &&
- (awaitedRightDelimiter.get().equals(LINE_COMMENT_END) ||
- awaitedRightDelimiter.get().equals(BLOCK_COMMENT_END));
+ (awaitedRightDelimiter.get().equals( LINE_COMMENT_END ) ||
+ awaitedRightDelimiter.get().equals( BLOCK_COMMENT_END ));
}
/**
- * If the last characters start a quote or a comment, this returns the piece of text which will end said quote
- * or comment.
+ * If the last characters start a quote or a comment, this returns the piece of text which will end said quote or comment.
*
* @param first character
* @param last character
* @return the matching right delimiter or something empty if not the start of a quote/comment
*/
@Nonnull
- private Optional getRightDelimiter(char first, char last) {
+ private Optional getRightDelimiter( char first, char last )
+ {
// double characters
- final String lastTwoChars = String.valueOf(first) + last;
- switch (lastTwoChars) {
- case LINE_COMMENT_START:
- return Optional.of(LINE_COMMENT_END);
- case BLOCK_COMMENT_START:
- return Optional.of(BLOCK_COMMENT_END);
+ final String lastTwoChars = String.valueOf( first ) + last;
+ switch ( lastTwoChars )
+ {
+ case LINE_COMMENT_START:
+ return Optional.of( LINE_COMMENT_END );
+ case BLOCK_COMMENT_START:
+ return Optional.of( BLOCK_COMMENT_END );
+ default:
+ // Do nothing
}
// single characters
- switch (last) {
- case BACKTICK:
- case DOUBLE_QUOTE:
- case SINGLE_QUOTE:
- return Optional.of(String.valueOf(last));
+ switch ( last )
+ {
+ case BACKTICK:
+ case DOUBLE_QUOTE:
+ case SINGLE_QUOTE:
+ return Optional.of( String.valueOf( last ) );
+ default:
+ return Optional.empty();
}
-
- return Optional.empty();
}
/**
* @return false if a statement has not begun (non whitespace has been seen) else true
*/
- private boolean statementNotStarted() {
+ private boolean statementNotStarted()
+ {
return statement.toString().trim().isEmpty();
}
@Override
- public boolean hasStatements() {
+ public boolean hasStatements()
+ {
return !parsedStatements.isEmpty();
}
@Nonnull
@Override
- public List consumeStatements() {
+ public List consumeStatements()
+ {
ArrayList result = parsedStatements;
parsedStatements = new ArrayList<>();
return result;
}
@Override
- public boolean containsText() {
+ public boolean containsText()
+ {
return !statement.toString().trim().isEmpty();
}
@Override
- public void reset() {
+ public void reset()
+ {
statement = new StringBuilder();
parsedStatements.clear();
awaitedRightDelimiter = Optional.empty();
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/parser/StatementParser.java b/cypher-shell/src/main/java/org/neo4j/shell/parser/StatementParser.java
index 0ae3775c..fc215032 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/parser/StatementParser.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/parser/StatementParser.java
@@ -1,19 +1,39 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.parser;
-import javax.annotation.Nonnull;
import java.util.List;
+import javax.annotation.Nonnull;
/**
* An object capable of parsing a piece of text and returning a List statements contained within.
*/
-public interface StatementParser {
+public interface StatementParser
+{
/**
* Parse the next line of text
*
* @param line to parse
*/
- void parseMoreText(@Nonnull String line);
+ void parseMoreText( @Nonnull String line );
/**
* @return true if any statements have been parsed yet, false otherwise
@@ -21,8 +41,8 @@ public interface StatementParser {
boolean hasStatements();
/**
- * Once this method has been called, the method will return the empty list (unless more text is parsed).
- * If nothing has been parsed yet, then the empty list is returned.
+ * Once this method has been called, the method will return the empty list (unless more text is parsed). If nothing has been parsed yet, then the empty list
+ * is returned.
*
* @return statements which have been parsed so far and remove them from internal state
*/
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/CypherVariablesFormatter.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/CypherVariablesFormatter.java
index d080ca81..c80c2221 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/CypherVariablesFormatter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/CypherVariablesFormatter.java
@@ -1,30 +1,56 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
-import javax.annotation.Nonnull;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.annotation.Nonnull;
-public class CypherVariablesFormatter {
+public class CypherVariablesFormatter
+{
private static final String BACKTICK = "`";
- private static final Pattern ALPHA_NUMERIC = Pattern.compile("^[\\p{L}_][\\p{L}0-9_]*");
+ private static final Pattern ALPHA_NUMERIC = Pattern.compile( "^[\\p{L}_][\\p{L}0-9_]*" );
@Nonnull
- public static String escape(@Nonnull String string) {
- Matcher alphaNumericMatcher = ALPHA_NUMERIC.matcher(string);
- if (!alphaNumericMatcher.matches()) {
- String reEscapeBackTicks = string.replaceAll(BACKTICK, BACKTICK + BACKTICK);
+ public static String escape( @Nonnull String string )
+ {
+ Matcher alphaNumericMatcher = ALPHA_NUMERIC.matcher( string );
+ if ( !alphaNumericMatcher.matches() )
+ {
+ String reEscapeBackTicks = string.replaceAll( BACKTICK, BACKTICK + BACKTICK );
return BACKTICK + reEscapeBackTicks + BACKTICK;
}
return string;
}
@Nonnull
- public static String unescapedCypherVariable(@Nonnull String string) {
- Matcher alphaNumericMatcher = ALPHA_NUMERIC.matcher(string);
- if (!alphaNumericMatcher.matches()) {
- String substring = string.substring(1, string.length() - 1);
- return substring.replace(BACKTICK + BACKTICK, BACKTICK);
- } else {
+ public static String unescapedCypherVariable( @Nonnull String string )
+ {
+ Matcher alphaNumericMatcher = ALPHA_NUMERIC.matcher( string );
+ if ( !alphaNumericMatcher.matches() )
+ {
+ String substring = string.substring( 1, string.length() - 1 );
+ return substring.replace( BACKTICK + BACKTICK, BACKTICK );
+ }
+ else
+ {
return string;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/LinePrinter.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/LinePrinter.java
index 248176c0..84887181 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/LinePrinter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/LinePrinter.java
@@ -1,15 +1,35 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
/**
* Prints lines.
*/
@FunctionalInterface
-public interface LinePrinter {
+public interface LinePrinter
+{
/**
* Print the designated line to configured output stream.
*
* @param line to print to the output stream
*/
- void printOut(String line );
+ void printOut( String line );
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/OutputFormatter.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/OutputFormatter.java
index b0b642be..848d28d2 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/OutputFormatter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/OutputFormatter.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
import java.util.ArrayList;
@@ -25,203 +44,275 @@
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.neo4j.shell.prettyprint.CypherVariablesFormatter.escape;
-public interface OutputFormatter {
-
- enum Capabilities {INFO, PLAN, RESULT, FOOTER, STATISTICS}
+public interface OutputFormatter
+{
String COMMA_SEPARATOR = ", ";
String COLON_SEPARATOR = ": ";
String COLON = ":";
String SPACE = " ";
- String NEWLINE = System.getProperty("line.separator");
-
- int formatAndCount(@Nonnull BoltResult result, @Nonnull LinePrinter linePrinter);
-
- @Nonnull default String formatValue(final Value value) {
- if (value == null) return "";
- TypeRepresentation type = (TypeRepresentation) value.type();
- switch (type.constructor()) {
- case LIST:
- return listAsString(value.asList(this::formatValue));
- case MAP:
- return mapAsString(value.asMap(this::formatValue));
- case NODE:
- return nodeAsString(value.asNode());
- case RELATIONSHIP:
- return relationshipAsString(value.asRelationship());
- case PATH:
- return pathAsString(value.asPath());
- case POINT:
- return pointAsString(value.asPoint());
- case ANY:
- case BOOLEAN:
- case BYTES:
- case STRING:
- case NUMBER:
- case INTEGER:
- case FLOAT:
- case DATE:
- case TIME:
- case DATE_TIME:
- case LOCAL_TIME:
- case LOCAL_DATE_TIME:
- case DURATION:
- case NULL:
- default:
- return value.toString();
- }
- }
-
- @Nonnull
- default String pointAsString(Point point) {
- StringBuilder stringBuilder = new StringBuilder("point({");
- stringBuilder.append("srid:").append(point.srid()).append(",");
- stringBuilder.append(" x:").append(point.x()).append(",");
- stringBuilder.append(" y:").append(point.y());
- double z = point.z();
- if (!Double.isNaN(z)) {
- stringBuilder.append(", z:").append(z);
- }
- stringBuilder.append("})");
- return stringBuilder.toString();
- }
+ String NEWLINE = System.getProperty( "line.separator" );
+ List INFO_SUMMARY = asList( "Version", "Planner", "Runtime" );
@Nonnull
- default String pathAsString(@Nonnull Path path) {
- List list = new ArrayList<>(path.length());
- Node lastTraversed = path.start();
- if (lastTraversed != null) {
- list.add(nodeAsString(lastTraversed));
-
- for (Path.Segment segment : path) {
- Relationship relationship = segment.relationship();
- if (relationship.startNodeId() == lastTraversed.id()) {
- list.add("-" + relationshipAsString(relationship) + "->");
- } else {
- list.add("<-" + relationshipAsString(relationship) + "-");
- }
- list.add(nodeAsString(segment.end()));
- lastTraversed = segment.end();
- }
- }
-
- return String.join("", list);
- }
-
- @Nonnull default String relationshipAsString(@Nonnull Relationship relationship) {
- List relationshipAsString = new ArrayList<>();
- relationshipAsString.add(COLON + escape(relationship.type()));
- relationshipAsString.add(mapAsStringWithEmpty(relationship.asMap(this::formatValue)));
-
- return "[" + joinWithSpace(relationshipAsString) + "]";
- }
-
- @Nonnull default String nodeAsString(@Nonnull final Node node) {
- List nodeAsString = new ArrayList<>();
- nodeAsString.add(collectNodeLabels(node));
- nodeAsString.add(mapAsStringWithEmpty(node.asMap(this::formatValue)));
-
- return "(" + joinWithSpace(nodeAsString) + ")";
- }
-
- @Nonnull static String collectNodeLabels(@Nonnull Node node) {
+ static String collectNodeLabels( @Nonnull Node node )
+ {
StringBuilder sb = new StringBuilder();
- node.labels().forEach(label -> sb.append(COLON).append(escape(label)));
+ node.labels().forEach( label -> sb.append( COLON ).append( escape( label ) ) );
return sb.toString();
}
- @Nonnull static String listAsString(@Nonnull List list) {
- return list.stream().collect(Collectors.joining(COMMA_SEPARATOR,"[","]"));
+ @Nonnull
+ static String listAsString( @Nonnull List list )
+ {
+ return list.stream().collect( Collectors.joining( COMMA_SEPARATOR, "[", "]" ) );
}
- @Nonnull static String mapAsStringWithEmpty(@Nonnull Map map) {
- return map.isEmpty() ? "" : mapAsString(map);
+ @Nonnull
+ static String mapAsStringWithEmpty( @Nonnull Map map )
+ {
+ return map.isEmpty() ? "" : mapAsString( map );
}
- @Nonnull static String mapAsString(@Nonnull Map map) {
+ @Nonnull
+ static String mapAsString( @Nonnull Map map )
+ {
return map.entrySet().stream()
- .map(e -> escape(e.getKey()) + COLON_SEPARATOR + e.getValue())
- .collect(Collectors.joining(COMMA_SEPARATOR,"{","}"));
+ .map( e -> escape( e.getKey() ) + COLON_SEPARATOR + e.getValue() )
+ .collect( Collectors.joining( COMMA_SEPARATOR, "{", "}" ) );
}
- @Nonnull static String joinWithSpace(@Nonnull List strings) {
- return strings.stream().filter(OutputFormatter::isNotBlank).collect(Collectors.joining(SPACE));
+ @Nonnull
+ static String joinWithSpace( @Nonnull List strings )
+ {
+ return strings.stream().filter( OutputFormatter::isNotBlank ).collect( Collectors.joining( SPACE ) );
}
- @Nonnull static String joinNonBlanks(@Nonnull String delim, @Nonnull List strings) {
- return strings.stream().filter(OutputFormatter::isNotBlank).collect(Collectors.joining(delim));
+
+ @Nonnull
+ static String joinNonBlanks( @Nonnull String delim, @Nonnull List strings )
+ {
+ return strings.stream().filter( OutputFormatter::isNotBlank ).collect( Collectors.joining( delim ) );
}
- static boolean isNotBlank(String string) {
+ static boolean isNotBlank( String string )
+ {
return string != null && !string.trim().isEmpty();
}
- @Nonnull static String repeat(char c, int times) {
+ @Nonnull
+ static String repeat( char c, int times )
+ {
char[] chars = new char[times];
- Arrays.fill(chars, c);
- return String.valueOf(chars);
+ Arrays.fill( chars, c );
+ return String.valueOf( chars );
}
- @Nonnull static String repeat(@Nonnull String c, int times) {
- StringBuilder sb = new StringBuilder(times*c.length());
- for (int i=0;i width) {
- return str.substring(0, width);
- } else if (actualSize < width) {
- return str + repeat( c, width - actualSize);
- } else {
+ if ( actualSize > width )
+ {
+ return str.substring( 0, width );
+ }
+ else if ( actualSize < width )
+ {
+ return str + repeat( c, width - actualSize );
+ }
+ else
+ {
return str;
}
}
- @Nonnull default String formatPlan(@Nonnull ResultSummary summary) {
- return "";
- }
- @Nonnull default String formatInfo(@Nonnull ResultSummary summary) {
- return "";
- }
- @Nonnull default String formatFooter(@Nonnull BoltResult result, int numberOfRows) {
- return "";
- }
-
- Set capabilities();
-
- List INFO_SUMMARY = asList("Version", "Planner", "Runtime");
-
@Nonnull
- static Map info(@Nonnull ResultSummary summary) {
+ static Map info( @Nonnull ResultSummary summary )
+ {
Map result = new LinkedHashMap<>();
- if (!summary.hasPlan()) return result;
+ if ( !summary.hasPlan() )
+ {
+ return result;
+ }
Plan plan = summary.plan();
- result.put("Plan", Values.value(summary.hasProfile() ? "PROFILE" : "EXPLAIN"));
- result.put("Statement", Values.value(summary.queryType().name()));
+ result.put( "Plan", Values.value( summary.hasProfile() ? "PROFILE" : "EXPLAIN" ) );
+ result.put( "Statement", Values.value( summary.queryType().name() ) );
Map arguments = plan.arguments();
- Value emptyString = Values.value("");
- Value questionMark = Values.value("?");
+ Value emptyString = Values.value( "" );
+ Value questionMark = Values.value( "?" );
- for (String key : INFO_SUMMARY) {
- Value value = arguments.getOrDefault(key, arguments.getOrDefault(key.toLowerCase(), emptyString));
- result.put(key, value);
+ for ( String key : INFO_SUMMARY )
+ {
+ Value value = arguments.getOrDefault( key, arguments.getOrDefault( key.toLowerCase(), emptyString ) );
+ result.put( key, value );
+ }
+ result.put( "Time", Values.value( summary.resultAvailableAfter( MILLISECONDS ) + summary.resultConsumedAfter( MILLISECONDS ) ) );
+ if ( summary.hasProfile() )
+ {
+ result.put( "DbHits", Values.value( collectHits( summary.profile() ) ) );
+ }
+ if ( summary.hasProfile() )
+ {
+ result.put( "Rows", Values.value( summary.profile().records() ) );
+ }
+ if ( summary.hasProfile() )
+ {
+ result.put( "Memory (Bytes)", arguments.getOrDefault( "GlobalMemory", questionMark ) );
}
- result.put("Time", Values.value(summary.resultAvailableAfter(MILLISECONDS)+summary.resultConsumedAfter(MILLISECONDS)));
- if ( summary.hasProfile() ) result.put( "DbHits", Values.value( collectHits( summary.profile() ) ) );
- if (summary.hasProfile()) result.put("Rows", Values.value( summary.profile().records() ));
- if (summary.hasProfile()) result.put("Memory (Bytes)", arguments.getOrDefault("GlobalMemory", questionMark));
return result;
}
- static long collectHits(@Nonnull ProfiledPlan operator ) {
+ static long collectHits( @Nonnull ProfiledPlan operator )
+ {
long hits = operator.dbHits();
- hits = operator.children().stream().map( OutputFormatter::collectHits ).reduce(hits, Long::sum);
+ hits = operator.children().stream().map( OutputFormatter::collectHits ).reduce( hits, Long::sum );
return hits;
}
+ int formatAndCount( @Nonnull BoltResult result, @Nonnull LinePrinter linePrinter );
+
+ @Nonnull
+ default String formatValue( final Value value )
+ {
+ if ( value == null )
+ {
+ return "";
+ }
+ TypeRepresentation type = (TypeRepresentation) value.type();
+ switch ( type.constructor() )
+ {
+ case LIST:
+ return listAsString( value.asList( this::formatValue ) );
+ case MAP:
+ return mapAsString( value.asMap( this::formatValue ) );
+ case NODE:
+ return nodeAsString( value.asNode() );
+ case RELATIONSHIP:
+ return relationshipAsString( value.asRelationship() );
+ case PATH:
+ return pathAsString( value.asPath() );
+ case POINT:
+ return pointAsString( value.asPoint() );
+ case ANY:
+ case BOOLEAN:
+ case BYTES:
+ case STRING:
+ case NUMBER:
+ case INTEGER:
+ case FLOAT:
+ case DATE:
+ case TIME:
+ case DATE_TIME:
+ case LOCAL_TIME:
+ case LOCAL_DATE_TIME:
+ case DURATION:
+ case NULL:
+ default:
+ return value.toString();
+ }
+ }
+
+ @Nonnull
+ default String pointAsString( Point point )
+ {
+ StringBuilder stringBuilder = new StringBuilder( "point({" );
+ stringBuilder.append( "srid:" ).append( point.srid() ).append( "," );
+ stringBuilder.append( " x:" ).append( point.x() ).append( "," );
+ stringBuilder.append( " y:" ).append( point.y() );
+ double z = point.z();
+ if ( !Double.isNaN( z ) )
+ {
+ stringBuilder.append( ", z:" ).append( z );
+ }
+ stringBuilder.append( "})" );
+ return stringBuilder.toString();
+ }
+
+ @Nonnull
+ default String pathAsString( @Nonnull Path path )
+ {
+ List list = new ArrayList<>( path.length() );
+ Node lastTraversed = path.start();
+ if ( lastTraversed != null )
+ {
+ list.add( nodeAsString( lastTraversed ) );
+
+ for ( Path.Segment segment : path )
+ {
+ Relationship relationship = segment.relationship();
+ if ( relationship.startNodeId() == lastTraversed.id() )
+ {
+ list.add( "-" + relationshipAsString( relationship ) + "->" );
+ }
+ else
+ {
+ list.add( "<-" + relationshipAsString( relationship ) + "-" );
+ }
+ list.add( nodeAsString( segment.end() ) );
+ lastTraversed = segment.end();
+ }
+ }
+
+ return String.join( "", list );
+ }
+
+ @Nonnull
+ default String relationshipAsString( @Nonnull Relationship relationship )
+ {
+ List relationshipAsString = new ArrayList<>();
+ relationshipAsString.add( COLON + escape( relationship.type() ) );
+ relationshipAsString.add( mapAsStringWithEmpty( relationship.asMap( this::formatValue ) ) );
+
+ return "[" + joinWithSpace( relationshipAsString ) + "]";
+ }
+
+ @Nonnull
+ default String nodeAsString( @Nonnull final Node node )
+ {
+ List nodeAsString = new ArrayList<>();
+ nodeAsString.add( collectNodeLabels( node ) );
+ nodeAsString.add( mapAsStringWithEmpty( node.asMap( this::formatValue ) ) );
+
+ return "(" + joinWithSpace( nodeAsString ) + ")";
+ }
+
+ @Nonnull
+ default String formatPlan( @Nonnull ResultSummary summary )
+ {
+ return "";
+ }
+
+ @Nonnull
+ default String formatInfo( @Nonnull ResultSummary summary )
+ {
+ return "";
+ }
+
+ @Nonnull
+ default String formatFooter( @Nonnull BoltResult result, int numberOfRows )
+ {
+ return "";
+ }
+
+ Set capabilities();
+
+ enum Capabilities
+ { INFO, PLAN, RESULT, FOOTER, STATISTICS }
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyConfig.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyConfig.java
index b65f1ad8..15801d58 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyConfig.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyConfig.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
import org.neo4j.shell.cli.CliArgs;
@@ -6,28 +25,33 @@
/**
* Configuration of pretty printer.
*/
-public class PrettyConfig {
+public class PrettyConfig
+{
- public static final PrettyConfig DEFAULT = new PrettyConfig(new CliArgs());
+ public static final PrettyConfig DEFAULT = new PrettyConfig( new CliArgs() );
public final Format format;
public final boolean wrap;
public final int numSampleRows;
- public PrettyConfig(CliArgs cliArgs) {
- this(selectFormat(cliArgs), cliArgs.getWrap(), cliArgs.getNumSampleRows());
- }
-
- private static Format selectFormat(CliArgs cliArgs) {
- if (cliArgs.isStringShell() && Format.AUTO.equals(cliArgs.getFormat())) {
- return Format.PLAIN;
- }
- return cliArgs.getFormat();
+ public PrettyConfig( CliArgs cliArgs )
+ {
+ this( selectFormat( cliArgs ), cliArgs.getWrap(), cliArgs.getNumSampleRows() );
}
- public PrettyConfig(Format format, boolean wrap, int numSampleRows) {
+ public PrettyConfig( Format format, boolean wrap, int numSampleRows )
+ {
this.format = format;
this.wrap = wrap;
this.numSampleRows = numSampleRows;
}
+
+ private static Format selectFormat( CliArgs cliArgs )
+ {
+ if ( cliArgs.isStringShell() && Format.AUTO.equals( cliArgs.getFormat() ) )
+ {
+ return Format.PLAIN;
+ }
+ return cliArgs.getFormat();
+ }
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyPrinter.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyPrinter.java
index 794e173e..6ab1e8d1 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyPrinter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/PrettyPrinter.java
@@ -1,56 +1,108 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
+import java.util.Set;
+import javax.annotation.Nonnull;
+
import org.neo4j.shell.cli.Format;
import org.neo4j.shell.state.BoltResult;
-import javax.annotation.Nonnull;
-import java.util.Set;
-
-import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.*;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.FOOTER;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.INFO;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.PLAN;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.RESULT;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.STATISTICS;
/**
* Print the result from neo4j in a intelligible fashion.
*/
-public class PrettyPrinter {
+public class PrettyPrinter
+{
private final StatisticsCollector statisticsCollector;
private final OutputFormatter outputFormatter;
- public PrettyPrinter(@Nonnull PrettyConfig prettyConfig) {
- this.statisticsCollector = new StatisticsCollector(prettyConfig.format);
- this.outputFormatter = selectFormatter(prettyConfig);
+ public PrettyPrinter( @Nonnull PrettyConfig prettyConfig )
+ {
+ this.statisticsCollector = new StatisticsCollector( prettyConfig.format );
+ this.outputFormatter = selectFormatter( prettyConfig );
}
- public void format(@Nonnull final BoltResult result, LinePrinter linePrinter) {
+ public void format( @Nonnull final BoltResult result, LinePrinter linePrinter )
+ {
Set capabilities = outputFormatter.capabilities();
int numberOfRows = 0;
- if (capabilities.contains(RESULT)) {
- numberOfRows = outputFormatter.formatAndCount(result, linePrinter);
+ if ( capabilities.contains( RESULT ) )
+ {
+ numberOfRows = outputFormatter.formatAndCount( result, linePrinter );
}
- if (capabilities.contains(INFO)) printIfNotEmpty(outputFormatter.formatInfo(result.getSummary()), linePrinter);
- if (capabilities.contains(PLAN)) printIfNotEmpty(outputFormatter.formatPlan(result.getSummary()), linePrinter);
- if (capabilities.contains(FOOTER)) printIfNotEmpty(outputFormatter.formatFooter(result, numberOfRows), linePrinter);
- if (capabilities.contains(STATISTICS)) printIfNotEmpty(statisticsCollector.collect(result.getSummary()), linePrinter);
+ if ( capabilities.contains( INFO ) )
+ {
+ printIfNotEmpty( outputFormatter.formatInfo( result.getSummary() ), linePrinter );
+ }
+ if ( capabilities.contains( PLAN ) )
+ {
+ printIfNotEmpty( outputFormatter.formatPlan( result.getSummary() ), linePrinter );
+ }
+ if ( capabilities.contains( FOOTER ) )
+ {
+ printIfNotEmpty( outputFormatter.formatFooter( result, numberOfRows ), linePrinter );
+ }
+ if ( capabilities.contains( STATISTICS ) )
+ {
+ printIfNotEmpty( statisticsCollector.collect( result.getSummary() ), linePrinter );
+ }
}
// Helper for testing
- String format(@Nonnull final BoltResult result) {
+ String format( @Nonnull final BoltResult result )
+ {
StringBuilder sb = new StringBuilder();
- format(result, line -> {if (line!=null && !line.trim().isEmpty()) sb.append(line).append(OutputFormatter.NEWLINE);});
+ format( result, line ->
+ {
+ if ( line != null && !line.trim().isEmpty() )
+ {
+ sb.append( line ).append( OutputFormatter.NEWLINE );
+ }
+ } );
return sb.toString();
}
- private void printIfNotEmpty( String s, LinePrinter linePrinter ) {
- if (!s.isEmpty()) {
+ private void printIfNotEmpty( String s, LinePrinter linePrinter )
+ {
+ if ( !s.isEmpty() )
+ {
linePrinter.printOut( s );
}
}
- private OutputFormatter selectFormatter(PrettyConfig prettyConfig) {
- if (prettyConfig.format == Format.VERBOSE) {
- return new TableOutputFormatter(prettyConfig.wrap, prettyConfig.numSampleRows);
- } else {
+ private OutputFormatter selectFormatter( PrettyConfig prettyConfig )
+ {
+ if ( prettyConfig.format == Format.VERBOSE )
+ {
+ return new TableOutputFormatter( prettyConfig.wrap, prettyConfig.numSampleRows );
+ }
+ else
+ {
return new SimpleOutputFormatter();
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/SimpleOutputFormatter.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/SimpleOutputFormatter.java
index f16791a3..9ddaef3a 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/SimpleOutputFormatter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/SimpleOutputFormatter.java
@@ -1,32 +1,57 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
-import org.neo4j.driver.Record;
-import org.neo4j.driver.Value;
-import org.neo4j.driver.summary.ResultSummary;
-import org.neo4j.shell.state.BoltResult;
-
-import javax.annotation.Nonnull;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+
+import org.neo4j.driver.Record;
+import org.neo4j.driver.Value;
+import org.neo4j.driver.summary.ResultSummary;
+import org.neo4j.shell.state.BoltResult;
-import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.*;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.INFO;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.RESULT;
+import static org.neo4j.shell.prettyprint.OutputFormatter.Capabilities.STATISTICS;
-public class SimpleOutputFormatter implements OutputFormatter {
+public class SimpleOutputFormatter implements OutputFormatter
+{
@Override
- public int formatAndCount(@Nonnull BoltResult result, @Nonnull LinePrinter output) {
+ public int formatAndCount( @Nonnull BoltResult result, @Nonnull LinePrinter output )
+ {
Iterator records = result.iterate();
int numberOfRows = 0;
- if (records.hasNext()) {
+ if ( records.hasNext() )
+ {
Record firstRow = records.next();
- output.printOut(String.join(COMMA_SEPARATOR, firstRow.keys()));
- output.printOut(formatRecord(firstRow));
+ output.printOut( String.join( COMMA_SEPARATOR, firstRow.keys() ) );
+ output.printOut( formatRecord( firstRow ) );
numberOfRows++;
- while (records.hasNext()) {
- output.printOut(formatRecord(records.next()));
+ while ( records.hasNext() )
+ {
+ output.printOut( formatRecord( records.next() ) );
numberOfRows++;
}
}
@@ -34,23 +59,27 @@ public int formatAndCount(@Nonnull BoltResult result, @Nonnull LinePrinter outpu
}
@Nonnull
- private String formatRecord(@Nonnull final Record record) {
- return record.values().stream().map(this::formatValue).collect(Collectors.joining(COMMA_SEPARATOR));
+ private String formatRecord( @Nonnull final Record record )
+ {
+ return record.values().stream().map( this::formatValue ).collect( Collectors.joining( COMMA_SEPARATOR ) );
}
@Nonnull
@Override
- public String formatInfo(@Nonnull ResultSummary summary) {
- if (!summary.hasPlan()) {
+ public String formatInfo( @Nonnull ResultSummary summary )
+ {
+ if ( !summary.hasPlan() )
+ {
return "";
}
- Map info = OutputFormatter.info(summary);
+ Map info = OutputFormatter.info( summary );
return info.entrySet().stream()
- .map( e -> String.format("%s: %s",e.getKey(),e.getValue())).collect(Collectors.joining(NEWLINE));
+ .map( e -> String.format( "%s: %s", e.getKey(), e.getValue() ) ).collect( Collectors.joining( NEWLINE ) );
}
@Override
- public Set capabilities() {
- return EnumSet.of(INFO, STATISTICS, RESULT);
+ public Set capabilities()
+ {
+ return EnumSet.of( INFO, STATISTICS, RESULT );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/StatisticsCollector.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/StatisticsCollector.java
index 3f056eae..39bdcdc0 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/StatisticsCollector.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/StatisticsCollector.java
@@ -1,66 +1,106 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
-import org.neo4j.driver.summary.ResultSummary;
-import org.neo4j.driver.summary.SummaryCounters;
-import org.neo4j.shell.cli.Format;
-
-import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
-public class StatisticsCollector {
+import org.neo4j.driver.summary.ResultSummary;
+import org.neo4j.driver.summary.SummaryCounters;
+import org.neo4j.shell.cli.Format;
+
+public class StatisticsCollector
+{
private Format format;
- public StatisticsCollector(@Nonnull Format format) {
+ public StatisticsCollector( @Nonnull Format format )
+ {
this.format = format;
}
- public String collect(@Nonnull ResultSummary summary) {
- if (Format.VERBOSE == format) {
- return collectStatistics(summary);
- } else {
+ public String collect( @Nonnull ResultSummary summary )
+ {
+ if ( Format.VERBOSE == format )
+ {
+ return collectStatistics( summary );
+ }
+ else
+ {
return "";
}
}
- private String collectStatistics(@Nonnull ResultSummary summary) {
+ private String collectStatistics( @Nonnull ResultSummary summary )
+ {
List statistics = new ArrayList<>();
SummaryCounters counters = summary.counters();
- if (counters == null) return "";
- if (counters.nodesCreated() != 0) {
- statistics.add(String.format("Added %d nodes", counters.nodesCreated()));
+ if ( counters == null )
+ {
+ return "";
+ }
+ if ( counters.nodesCreated() != 0 )
+ {
+ statistics.add( String.format( "Added %d nodes", counters.nodesCreated() ) );
}
- if (counters.nodesDeleted() != 0) {
- statistics.add(String.format("Deleted %d nodes", counters.nodesDeleted()));
+ if ( counters.nodesDeleted() != 0 )
+ {
+ statistics.add( String.format( "Deleted %d nodes", counters.nodesDeleted() ) );
}
- if (counters.relationshipsCreated() != 0) {
- statistics.add(String.format("Created %d relationships", counters.relationshipsCreated()));
+ if ( counters.relationshipsCreated() != 0 )
+ {
+ statistics.add( String.format( "Created %d relationships", counters.relationshipsCreated() ) );
}
- if (counters.relationshipsDeleted() != 0) {
- statistics.add(String.format("Deleted %d relationships", counters.relationshipsDeleted()));
+ if ( counters.relationshipsDeleted() != 0 )
+ {
+ statistics.add( String.format( "Deleted %d relationships", counters.relationshipsDeleted() ) );
}
- if (counters.propertiesSet() != 0) {
- statistics.add(String.format("Set %d properties", counters.propertiesSet()));
+ if ( counters.propertiesSet() != 0 )
+ {
+ statistics.add( String.format( "Set %d properties", counters.propertiesSet() ) );
}
- if (counters.labelsAdded() != 0) {
- statistics.add(String.format("Added %d labels", counters.labelsAdded()));
+ if ( counters.labelsAdded() != 0 )
+ {
+ statistics.add( String.format( "Added %d labels", counters.labelsAdded() ) );
}
- if (counters.labelsRemoved() != 0) {
- statistics.add(String.format("Removed %d labels", counters.labelsRemoved()));
+ if ( counters.labelsRemoved() != 0 )
+ {
+ statistics.add( String.format( "Removed %d labels", counters.labelsRemoved() ) );
}
- if (counters.indexesAdded() != 0) {
- statistics.add(String.format("Added %d indexes", counters.indexesAdded()));
+ if ( counters.indexesAdded() != 0 )
+ {
+ statistics.add( String.format( "Added %d indexes", counters.indexesAdded() ) );
}
- if (counters.indexesRemoved() != 0) {
- statistics.add(String.format("Removed %d indexes", counters.indexesRemoved()));
+ if ( counters.indexesRemoved() != 0 )
+ {
+ statistics.add( String.format( "Removed %d indexes", counters.indexesRemoved() ) );
}
- if (counters.constraintsAdded() != 0) {
- statistics.add(String.format("Added %d constraints", counters.constraintsAdded()));
+ if ( counters.constraintsAdded() != 0 )
+ {
+ statistics.add( String.format( "Added %d constraints", counters.constraintsAdded() ) );
}
- if (counters.constraintsRemoved() != 0) {
- statistics.add(String.format("Removed %d constraints", counters.constraintsRemoved()));
+ if ( counters.constraintsRemoved() != 0 )
+ {
+ statistics.add( String.format( "Removed %d constraints", counters.constraintsRemoved() ) );
}
- return statistics.stream().collect(Collectors.joining(", "));
+ return statistics.stream().collect( Collectors.joining( ", " ) );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TableOutputFormatter.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TableOutputFormatter.java
index 3e0eb579..84661e4c 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TableOutputFormatter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TableOutputFormatter.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
import java.util.ArrayList;
@@ -10,95 +29,111 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import org.neo4j.driver.internal.InternalRecord;
-import org.neo4j.driver.internal.value.NumberValueAdapter;
import org.neo4j.driver.Record;
import org.neo4j.driver.Value;
+import org.neo4j.driver.internal.InternalRecord;
+import org.neo4j.driver.internal.value.NumberValueAdapter;
import org.neo4j.driver.summary.ResultSummary;
import org.neo4j.shell.state.BoltResult;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-public class TableOutputFormatter implements OutputFormatter {
+public class TableOutputFormatter implements OutputFormatter
+{
private final boolean wrap;
private final int numSampleRows;
- public TableOutputFormatter(boolean wrap, int numSampleRows) {
+ public TableOutputFormatter( boolean wrap, int numSampleRows )
+ {
this.wrap = wrap;
this.numSampleRows = numSampleRows;
}
@Override
- public int formatAndCount(@Nonnull BoltResult result, @Nonnull LinePrinter output) {
- String[] columns = result.getKeys().toArray(new String[0]);
- if (columns.length == 0) {
+ public int formatAndCount( @Nonnull BoltResult result, @Nonnull LinePrinter output )
+ {
+ String[] columns = result.getKeys().toArray( new String[0] );
+ if ( columns.length == 0 )
+ {
return 0;
}
Iterator records = result.iterate();
- return formatResultAndCountRows(columns, records, output);
+ return formatResultAndCountRows( columns, records, output );
}
- private List take(Iterator records, int count) {
- List topRecords = new ArrayList<>(count);
- while (records.hasNext() && topRecords.size() < count) {
- topRecords.add(records.next());
+ private List take( Iterator records, int count )
+ {
+ List topRecords = new ArrayList<>( count );
+ while ( records.hasNext() && topRecords.size() < count )
+ {
+ topRecords.add( records.next() );
}
return topRecords;
}
- private int formatResultAndCountRows(String[] columns,
- Iterator records,
- LinePrinter output) {
+ private int formatResultAndCountRows( String[] columns,
+ Iterator records,
+ LinePrinter output )
+ {
- List topRecords = take(records, numSampleRows);
- int[] columnSizes = calculateColumnSizes(columns, topRecords, records.hasNext());
+ List topRecords = take( records, numSampleRows );
+ int[] columnSizes = calculateColumnSizes( columns, topRecords, records.hasNext() );
int totalWidth = 1;
- for (int columnSize : columnSizes) {
+ for ( int columnSize : columnSizes )
+ {
totalWidth += columnSize + 3;
}
- StringBuilder builder = new StringBuilder(totalWidth);
- String headerLine = formatRow(builder, columnSizes, columns, new boolean[columnSizes.length]);
+ StringBuilder builder = new StringBuilder( totalWidth );
+ String headerLine = formatRow( builder, columnSizes, columns, new boolean[columnSizes.length] );
int lineWidth = totalWidth - 2;
- String dashes = "+" + OutputFormatter.repeat('-', lineWidth) + "+";
+ String dashes = "+" + OutputFormatter.repeat( '-', lineWidth ) + "+";
- output.printOut(dashes);
- output.printOut(headerLine);
- output.printOut(dashes);
+ output.printOut( dashes );
+ output.printOut( headerLine );
+ output.printOut( dashes );
int numberOfRows = 0;
- for (Record record : topRecords) {
- output.printOut(formatRecord(builder, columnSizes, record));
+ for ( Record record : topRecords )
+ {
+ output.printOut( formatRecord( builder, columnSizes, record ) );
numberOfRows++;
}
- while (records.hasNext()) {
- output.printOut(formatRecord(builder, columnSizes, records.next()));
+ while ( records.hasNext() )
+ {
+ output.printOut( formatRecord( builder, columnSizes, records.next() ) );
numberOfRows++;
}
- output.printOut(String.format("%s%n", dashes));
+ output.printOut( String.format( "%s%n", dashes ) );
return numberOfRows;
}
/**
* Calculate the size of the columns for table formatting
- * @param columns the column names
- * @param data (sample) data
+ *
+ * @param columns the column names
+ * @param data (sample) data
* @param moreDataAfterSamples if there is more data that should be written into the table after `data`
* @return the column sizes
*/
- private int[] calculateColumnSizes(@Nonnull String[] columns, @Nonnull List data, boolean moreDataAfterSamples) {
+ private int[] calculateColumnSizes( @Nonnull String[] columns, @Nonnull List data, boolean moreDataAfterSamples )
+ {
int[] columnSizes = new int[columns.length];
- for (int i = 0; i < columns.length; i++) {
+ for ( int i = 0; i < columns.length; i++ )
+ {
columnSizes[i] = columns[i].length();
}
- for (Record record : data) {
- for (int i = 0; i < columns.length; i++) {
- int len = columnLengthForValue(record.get(i), moreDataAfterSamples);
- if (columnSizes[i] < len) {
+ for ( Record record : data )
+ {
+ for ( int i = 0; i < columns.length; i++ )
+ {
+ int len = columnLengthForValue( record.get( i ), moreDataAfterSamples );
+ if ( columnSizes[i] < len )
+ {
columnSizes[i] = len;
}
}
@@ -109,27 +144,34 @@ private int[] calculateColumnSizes(@Nonnull String[] columns, @Nonnull List length) {
- if (wrap) {
- sb.append(txt, 0, length);
- row[i] = txt.substring(length);
+ if ( txt != null )
+ {
+ if ( txt.length() > length )
+ {
+ if ( wrap )
+ {
+ sb.append( txt, 0, length );
+ row[i] = txt.substring( length );
continuation[i] = true;
remainder = true;
- } else {
- sb.append(txt, 0, length - 1);
- sb.append("…");
}
- } else {
+ else
+ {
+ sb.append( txt, 0, length - 1 );
+ sb.append( "…" );
+ }
+ }
+ else
+ {
row[i] = null;
- sb.append(OutputFormatter.rightPad(txt, length));
+ sb.append( OutputFormatter.rightPad( txt, length ) );
}
- } else {
- sb.append(OutputFormatter.repeat(' ', length));
}
- if (i == row.length -1 || !continuation[i+1]) {
- sb.append(" |");
- } else {
- sb.append(" \\");
+ else
+ {
+ sb.append( OutputFormatter.repeat( ' ', length ) );
+ }
+ if ( i == row.length - 1 || !continuation[i + 1] )
+ {
+ sb.append( " |" );
+ }
+ else
+ {
+ sb.append( " \\" );
}
}
- if (wrap && remainder) {
- sb.append(OutputFormatter.NEWLINE);
- formatRow(sb, columnSizes, row, continuation);
+ if ( wrap && remainder )
+ {
+ sb.append( OutputFormatter.NEWLINE );
+ formatRow( sb, columnSizes, row, continuation );
}
return sb.toString();
}
@Override
@Nonnull
- public String formatFooter(@Nonnull BoltResult result, int numberOfRows) {
+ public String formatFooter( @Nonnull BoltResult result, int numberOfRows )
+ {
ResultSummary summary = result.getSummary();
- return String.format("%d row%s available after %d ms, " +
- "consumed after another %d ms", numberOfRows, numberOfRows != 1 ? "s" : "",
- summary.resultAvailableAfter(MILLISECONDS),
- summary.resultConsumedAfter(MILLISECONDS));
+ return String.format( "%d row%s available after %d ms, " +
+ "consumed after another %d ms", numberOfRows, numberOfRows != 1 ? "s" : "",
+ summary.resultAvailableAfter( MILLISECONDS ),
+ summary.resultConsumedAfter( MILLISECONDS ) );
}
@Override
@Nonnull
- public String formatInfo(@Nonnull ResultSummary summary) {
- Map info = OutputFormatter.info(summary);
- if (info.isEmpty()) {
+ public String formatInfo( @Nonnull ResultSummary summary )
+ {
+ Map info = OutputFormatter.info( summary );
+ if ( info.isEmpty() )
+ {
return "";
}
- String[] columns = info.keySet().toArray(new String[0]);
+ String[] columns = info.keySet().toArray( new String[0] );
StringBuilder sb = new StringBuilder();
- Record record = new InternalRecord(asList(columns), info.values().toArray(new Value[0]));
- formatResultAndCountRows(columns, Collections.singletonList(record).iterator(), line -> sb.append( line).append( OutputFormatter.NEWLINE) );
+ Record record = new InternalRecord( asList( columns ), info.values().toArray( new Value[0] ) );
+ formatResultAndCountRows( columns, Collections.singletonList( record ).iterator(), line -> sb.append( line ).append( OutputFormatter.NEWLINE ) );
return sb.toString();
}
@Override
@Nonnull
- public String formatPlan(@Nullable ResultSummary summary) {
- if (summary == null || !summary.hasPlan()) {
+ public String formatPlan( @Nullable ResultSummary summary )
+ {
+ if ( summary == null || !summary.hasPlan() )
+ {
return "";
}
- return new TablePlanFormatter().formatPlan(summary.plan());
+ return new TablePlanFormatter().formatPlan( summary.plan() );
}
@Override
- public Set capabilities() {
- return EnumSet.allOf(Capabilities.class);
+ public Set capabilities()
+ {
+ return EnumSet.allOf( Capabilities.class );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TablePlanFormatter.java b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TablePlanFormatter.java
index a1074378..ab1182f2 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TablePlanFormatter.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TablePlanFormatter.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.prettyprint;
import java.util.ArrayList;
@@ -26,10 +45,11 @@
import static org.neo4j.shell.prettyprint.OutputFormatter.NEWLINE;
import static org.neo4j.shell.prettyprint.OutputFormatter.repeat;
-public class TablePlanFormatter {
+public class TablePlanFormatter
+{
private static final String UNNAMED_PATTERN_STRING = " (UNNAMED|FRESHID|AGGREGATION|NODE|REL)(\\d+)";
- private static final Pattern UNNAMED_PATTERN = Pattern.compile(UNNAMED_PATTERN_STRING);
+ private static final Pattern UNNAMED_PATTERN = Pattern.compile( UNNAMED_PATTERN_STRING );
private static final String OPERATOR = "Operator";
private static final String ESTIMATED_ROWS = "Estimated Rows";
private static final String ROWS = "Rows";
@@ -42,324 +62,404 @@ public class TablePlanFormatter {
private static final String OTHER = "Other";
public static final String DETAILS = "Details";
private static final String SEPARATOR = ", ";
- private static final Pattern DEDUP_PATTERN = Pattern.compile("\\s*(\\S+)@\\d+");
+ private static final Pattern DEDUP_PATTERN = Pattern.compile( "\\s*(\\S+)@\\d+" );
public static final int MAX_DETAILS_COLUMN_WIDTH = 100;
- private static final List HEADERS = asList(OPERATOR, DETAILS, ESTIMATED_ROWS, ROWS, HITS, PAGE_CACHE, TIME, MEMORY, IDENTIFIERS, ORDER, OTHER);
+ private static final List HEADERS = asList( OPERATOR, DETAILS, ESTIMATED_ROWS, ROWS, HITS, PAGE_CACHE, TIME, MEMORY, IDENTIFIERS, ORDER, OTHER );
private static final Set IGNORED_ARGUMENTS = new LinkedHashSet<>(
asList( "Rows", "DbHits", "EstimatedRows", "planner", "planner-impl", "planner-version", "version", "runtime", "runtime-impl", "runtime-version",
"time", "source-code", "PageCacheMisses", "PageCacheHits", "PageCacheHitRatio", "Order", "Memory", "GlobalMemory", "Details" ) );
- public static final Value ZERO_VALUE = Values.value(0);
+ public static final Value ZERO_VALUE = Values.value( 0 );
- private int width(@Nonnull String header, @Nonnull Map columns) {
- return 2 + Math.max(header.length(), columns.get(header));
+ private int width( @Nonnull String header, @Nonnull Map columns )
+ {
+ return 2 + Math.max( header.length(), columns.get( header ) );
}
- private static void pad(int width, char chr, @Nonnull StringBuilder result) {
- result.append(OutputFormatter.repeat(chr, width));
+ private static void pad( int width, char chr, @Nonnull StringBuilder result )
+ {
+ result.append( OutputFormatter.repeat( chr, width ) );
}
-
- private void divider(@Nonnull List headers, @Nullable TableRow tableRow /*= null*/, @Nonnull StringBuilder result, @Nonnull Map columns) {
- for (String header : headers) {
- if (tableRow != null && header.equals(OPERATOR) && tableRow.connection.isPresent()) {
- result.append("|");
+ private void divider( @Nonnull List headers, @Nullable TableRow tableRow /*= null*/, @Nonnull StringBuilder result,
+ @Nonnull Map columns )
+ {
+ for ( String header : headers )
+ {
+ if ( tableRow != null && header.equals( OPERATOR ) && tableRow.connection.isPresent() )
+ {
+ result.append( "|" );
String connection = tableRow.connection.get();
- result.append(" ").append(connection);
- pad(width(header, columns) - connection.length() - 1, ' ', result);
- } else {
- result.append("+");
- pad(width(header, columns), '-', result);
+ result.append( " " ).append( connection );
+ pad( width( header, columns ) - connection.length() - 1, ' ', result );
+ }
+ else
+ {
+ result.append( "+" );
+ pad( width( header, columns ), '-', result );
}
}
- result.append("+").append(NEWLINE);
+ result.append( "+" ).append( NEWLINE );
}
@Nonnull
- String formatPlan(@Nonnull Plan plan) {
+ String formatPlan( @Nonnull Plan plan )
+ {
Map columns = new HashMap<>();
- List tableRows = accumulate(plan, new Root(), columns);
+ List tableRows = accumulate( plan, new Root(), columns );
// Remove Identifiers column if we have a Details column
- List headers = HEADERS.stream().filter(header -> columns.containsKey(header) && !(header.equals(IDENTIFIERS) && columns.containsKey(DETAILS))).collect(Collectors.toList());
+ List headers =
+ HEADERS.stream().filter( header -> columns.containsKey( header ) && !(header.equals( IDENTIFIERS ) && columns.containsKey( DETAILS )) )
+ .collect( Collectors.toList() );
- StringBuilder result = new StringBuilder((2 + NEWLINE.length() + headers.stream().mapToInt(h -> width(h, columns)).sum()) * (tableRows.size() * 2 + 3));
+ StringBuilder result =
+ new StringBuilder( (2 + NEWLINE.length() + headers.stream().mapToInt( h -> width( h, columns ) ).sum()) * (tableRows.size() * 2 + 3) );
List allTableRows = new ArrayList<>();
- Map headerMap = headers.stream().map(header -> Pair.of(header, new LeftJustifiedCell(header))).collect(toMap(p -> p._1, p -> p._2));
- allTableRows.add(new TableRow(OPERATOR, headerMap, Optional.empty()));
+ Map headerMap =
+ headers.stream().map( header -> Pair.of( header, new LeftJustifiedCell( header ) ) ).collect( toMap( p -> p._1, p -> p._2 ) );
+ allTableRows.add( new TableRow( OPERATOR, headerMap, Optional.empty() ) );
allTableRows.addAll( tableRows );
- for (int rowIndex = 0; rowIndex < allTableRows.size(); rowIndex++) {
- TableRow tableRow = allTableRows.get( rowIndex);
- divider(headers, tableRow, result, columns);
- for (int rowLineIndex = 0; rowLineIndex < tableRow.height; rowLineIndex++) {
- for (String header : headers) {
- Cell cell = tableRow.get(header);
+ for ( int rowIndex = 0; rowIndex < allTableRows.size(); rowIndex++ )
+ {
+ TableRow tableRow = allTableRows.get( rowIndex );
+ divider( headers, tableRow, result, columns );
+ for ( int rowLineIndex = 0; rowLineIndex < tableRow.height; rowLineIndex++ )
+ {
+ for ( String header : headers )
+ {
+ Cell cell = tableRow.get( header );
String defaultText = "";
- if (header.equals(OPERATOR) && rowIndex + 1 < allTableRows.size()) {
- defaultText = allTableRows.get(rowIndex + 1).connection.orElse("").replace('\\', ' ');
+ if ( header.equals( OPERATOR ) && rowIndex + 1 < allTableRows.size() )
+ {
+ defaultText = allTableRows.get( rowIndex + 1 ).connection.orElse( "" ).replace( '\\', ' ' );
}
result.append( "| " );
- int columnWidth = width(header, columns);
- cell.writePaddedLine(rowLineIndex, defaultText, columnWidth, result);
+ int columnWidth = width( header, columns );
+ cell.writePaddedLine( rowLineIndex, defaultText, columnWidth, result );
result.append( " " );
}
- result.append("|").append(NEWLINE);
+ result.append( "|" ).append( NEWLINE );
}
}
- divider(headers, null, result, columns);
+ divider( headers, null, result, columns );
return result.toString();
}
@Nonnull
- private String serialize(@Nonnull String key, @Nonnull Value v) {
- switch (key) {
- case "ColumnsLeft":
- return removeGeneratedNames(v.asString());
- case "LegacyExpression":
- return removeGeneratedNames(v.asString());
- case "Expression":
- return removeGeneratedNames(v.asString());
- case "UpdateActionName":
- return v.asString();
- case "LegacyIndex":
- return v.toString();
- case "version":
- return v.toString();
- case "planner":
- return v.toString();
- case "planner-impl":
- return v.toString();
- case "runtime":
- return v.toString();
- case "runtime-impl":
- return v.toString();
- case "MergePattern":
- return "MergePattern(" + v.toString() + ")";
- case "DbHits":
- return v.asNumber().toString();
- case "Rows":
- return v.asNumber().toString();
- case "Time":
- return v.asNumber().toString();
- case "EstimatedRows":
- return v.asNumber().toString();
- case "LabelName":
- return v.asString();
- case "KeyNames":
- return removeGeneratedNames(v.asString());
- case "KeyExpressions":
- return String.join(SEPARATOR, v.asList(Value::asString));
-
- case "ExpandExpression":
- return removeGeneratedNames(v.asString());
- case "Index":
- return v.asString();
- case "PrefixIndex":
- return v.asString();
- case "InequalityIndex":
- return v.asString();
- case "EntityByIdRhs":
- return v.asString();
- case "PageCacheMisses":
- return v.asNumber().toString();
- case "Details":
- return v.asString();
- default:
- return v.asObject().toString();
+ private String serialize( @Nonnull String key, @Nonnull Value v )
+ {
+ switch ( key )
+ {
+ case "ColumnsLeft":
+ return removeGeneratedNames( v.asString() );
+ case "LegacyExpression":
+ return removeGeneratedNames( v.asString() );
+ case "Expression":
+ return removeGeneratedNames( v.asString() );
+ case "UpdateActionName":
+ return v.asString();
+ case "LegacyIndex":
+ return v.toString();
+ case "version":
+ return v.toString();
+ case "planner":
+ return v.toString();
+ case "planner-impl":
+ return v.toString();
+ case "runtime":
+ return v.toString();
+ case "runtime-impl":
+ return v.toString();
+ case "MergePattern":
+ return "MergePattern(" + v.toString() + ")";
+ case "DbHits":
+ return v.asNumber().toString();
+ case "Rows":
+ return v.asNumber().toString();
+ case "Time":
+ return v.asNumber().toString();
+ case "EstimatedRows":
+ return v.asNumber().toString();
+ case "LabelName":
+ return v.asString();
+ case "KeyNames":
+ return removeGeneratedNames( v.asString() );
+ case "KeyExpressions":
+ return String.join( SEPARATOR, v.asList( Value::asString ) );
+
+ case "ExpandExpression":
+ return removeGeneratedNames( v.asString() );
+ case "Index":
+ return v.asString();
+ case "PrefixIndex":
+ return v.asString();
+ case "InequalityIndex":
+ return v.asString();
+ case "EntityByIdRhs":
+ return v.asString();
+ case "PageCacheMisses":
+ return v.asNumber().toString();
+ case "Details":
+ return v.asString();
+ default:
+ return v.asObject().toString();
}
}
- @Nonnull private Stream> children(@Nonnull Plan plan, Level level, @Nonnull Map columns) {
+ @Nonnull
+ private Stream> children( @Nonnull Plan plan, Level level, @Nonnull Map columns )
+ {
List extends Plan> c = plan.children();
- switch (c.size()) {
- case 0:
- return Stream.empty();
- case 1:
- return Stream.of(accumulate(c.get(0), level.child(), columns));
- case 2:
- return Stream.of(accumulate(c.get(1), level.fork(), columns), accumulate(c.get(0), level.child(), columns));
- }
- throw new IllegalStateException("Plan has more than 2 children " + c);
+ switch ( c.size() )
+ {
+ case 0:
+ return Stream.empty();
+ case 1:
+ return Stream.of( accumulate( c.get( 0 ), level.child(), columns ) );
+ case 2:
+ return Stream.of( accumulate( c.get( 1 ), level.fork(), columns ), accumulate( c.get( 0 ), level.child(), columns ) );
+ default:
+ throw new IllegalStateException( "Plan has more than 2 children " + c );
+ }
}
- @Nonnull private List accumulate(@Nonnull Plan plan, @Nonnull Level level, @Nonnull Map columns) {
+ @Nonnull
+ private List accumulate( @Nonnull Plan plan, @Nonnull Level level, @Nonnull Map columns )
+ {
String line = level.line() + plan.operatorType(); // wa plan.name
- mapping(OPERATOR, new LeftJustifiedCell(line), columns);
+ mapping( OPERATOR, new LeftJustifiedCell( line ), columns );
return Stream.concat(
- Stream.of(new TableRow(line, details(plan, columns), level.connector())),
- children(plan, level, columns).flatMap(Collection::stream))
- .collect(Collectors.toList());
+ Stream.of( new TableRow( line, details( plan, columns ), level.connector() ) ),
+ children( plan, level, columns ).flatMap( Collection::stream ) )
+ .collect( Collectors.toList() );
}
@Nonnull
- private Map details(@Nonnull Plan plan, @Nonnull Map columns) {
+ private Map details( @Nonnull Plan plan, @Nonnull Map columns )
+ {
Map args = plan.arguments();
- Stream>> formattedPlan = args.entrySet().stream().map(e -> {
- Value value = e.getValue();
- switch (e.getKey()) {
- case "EstimatedRows":
- return mapping(ESTIMATED_ROWS, new RightJustifiedCell(format(value.asDouble())), columns);
- case "Rows":
- return mapping(ROWS, new RightJustifiedCell(value.asNumber().toString()), columns);
- case "DbHits":
- return mapping(HITS, new RightJustifiedCell(value.asNumber().toString()), columns);
- case "PageCacheHits":
- return mapping(PAGE_CACHE, new RightJustifiedCell(String.format("%s/%s", value.asNumber(), args.getOrDefault("PageCacheMisses", ZERO_VALUE).asNumber())), columns);
- case "Time":
- return mapping(TIME, new RightJustifiedCell(String.format("%.3f", value.asLong() / 1000000.0d)), columns);
- case "Order":
- return mapping(ORDER, new LeftJustifiedCell(String.format("%s", value.asString())), columns);
- case "Details":
- return mapping(DETAILS, new LeftJustifiedCell(splitDetails(value.asString())), columns);
- case "Memory":
- return mapping(MEMORY, new RightJustifiedCell(String.format("%s", value.asNumber().toString())), columns);
- default:
- return Optional.empty();
- }
- });
+ Stream>> formattedPlan = args.entrySet().stream()
+ .map( e ->
+ {
+ Value value = e.getValue();
+ switch ( e.getKey() )
+ {
+ case "EstimatedRows":
+ return mapping( ESTIMATED_ROWS, new RightJustifiedCell(
+ format( value.asDouble() ) ), columns );
+ case "Rows":
+ return mapping( ROWS, new RightJustifiedCell(
+ value.asNumber().toString() ), columns );
+ case "DbHits":
+ return mapping( HITS, new RightJustifiedCell(
+ value.asNumber().toString() ), columns );
+ case "PageCacheHits":
+ return mapping( PAGE_CACHE, new RightJustifiedCell(
+ String.format( "%s/%s", value.asNumber(),
+ args.getOrDefault( "PageCacheMisses",
+ ZERO_VALUE )
+ .asNumber() ) ), columns );
+ case "Time":
+ return mapping( TIME, new RightJustifiedCell(
+ String.format( "%.3f",
+ value.asLong() / 1000000.0d ) ),
+ columns );
+ case "Order":
+ return mapping( ORDER, new LeftJustifiedCell(
+ String.format( "%s", value.asString() ) ), columns );
+ case "Details":
+ return mapping( DETAILS, new LeftJustifiedCell(
+ splitDetails( value.asString() ) ), columns );
+ case "Memory":
+ return mapping( MEMORY, new RightJustifiedCell(
+ String.format( "%s", value.asNumber().toString() ) ),
+ columns );
+ default:
+ return Optional.empty();
+ }
+ } );
return Stream.concat(
formattedPlan,
Stream.of(
- Optional.of(Pair.of(IDENTIFIERS, new LeftJustifiedCell(identifiers(plan, columns)))),
- Optional.of(Pair.of(OTHER, new LeftJustifiedCell(other(plan, columns))))))
- .filter(Optional::isPresent)
- .collect(toMap(o -> o.get()._1, o -> o.get()._2));
+ Optional.of( Pair.of( IDENTIFIERS, new LeftJustifiedCell( identifiers( plan, columns ) ) ) ),
+ Optional.of( Pair.of( OTHER, new LeftJustifiedCell( other( plan, columns ) ) ) ) ) )
+ .filter( Optional::isPresent )
+ .collect( toMap( o -> o.get()._1, o -> o.get()._2 ) );
}
@Nonnull
- private Optional> mapping(@Nonnull String key, @Nonnull Cell value, @Nonnull Map columns) {
- update(columns, key, value.length);
- return Optional.of(Pair.of(key, value));
+ private Optional> mapping( @Nonnull String key, @Nonnull Cell value, @Nonnull Map columns )
+ {
+ update( columns, key, value.length );
+ return Optional.of( Pair.of( key, value ) );
}
@Nonnull
- private String replaceAllIn(@Nonnull Pattern pattern, @Nonnull String s, @Nonnull Function mapper) {
+ private String replaceAllIn( @Nonnull Pattern pattern, @Nonnull String s, @Nonnull Function mapper )
+ {
StringBuffer sb = new StringBuffer();
- Matcher matcher = pattern.matcher(s);
- while (matcher.find()) {
- matcher.appendReplacement(sb, mapper.apply(matcher));
+ Matcher matcher = pattern.matcher( s );
+ while ( matcher.find() )
+ {
+ matcher.appendReplacement( sb, mapper.apply( matcher ) );
}
- matcher.appendTail(sb);
+ matcher.appendTail( sb );
return sb.toString();
}
@Nonnull
- private String removeGeneratedNames(@Nonnull String s) {
- String named = replaceAllIn(UNNAMED_PATTERN, s, m -> "anon[" + m.group(2) + "]");
- return replaceAllIn(DEDUP_PATTERN, named, m -> m.group(1));
+ private String removeGeneratedNames( @Nonnull String s )
+ {
+ String named = replaceAllIn( UNNAMED_PATTERN, s, m -> "anon[" + m.group( 2 ) + "]" );
+ return replaceAllIn( DEDUP_PATTERN, named, m -> m.group( 1 ) );
}
- private void update(@Nonnull Map columns, @Nonnull String key, int length) {
- columns.put(key, Math.max(columns.getOrDefault(key, 0), length));
+ private void update( @Nonnull Map columns, @Nonnull String key, int length )
+ {
+ columns.put( key, Math.max( columns.getOrDefault( key, 0 ), length ) );
}
@Nonnull
- private String identifiers(@Nonnull Plan description, @Nonnull Map columns) {
- String result = description.identifiers().stream().map(this::removeGeneratedNames).collect(joining(", "));
- if (!result.isEmpty()) {
- update(columns, IDENTIFIERS, result.length());
+ private String identifiers( @Nonnull Plan description, @Nonnull Map columns )
+ {
+ String result = description.identifiers().stream().map( this::removeGeneratedNames ).collect( joining( ", " ) );
+ if ( !result.isEmpty() )
+ {
+ update( columns, IDENTIFIERS, result.length() );
}
return result;
}
@Nonnull
- private String other(@Nonnull Plan description, @Nonnull Map columns) {
- String result = description.arguments().entrySet().stream().map(e -> {
- if (!IGNORED_ARGUMENTS.contains(e.getKey())) return serialize(e.getKey(), e.getValue());
- return "";
- }).filter(OutputFormatter::isNotBlank).collect(Collectors.joining("; ")).replaceAll(UNNAMED_PATTERN_STRING, "");
-
- if (!result.isEmpty()) {
- update(columns, OTHER, result.length());
+ private String other( @Nonnull Plan description, @Nonnull Map columns )
+ {
+ String result = description.arguments().entrySet().stream().map( e ->
+ {
+ if ( !IGNORED_ARGUMENTS.contains( e.getKey() ) )
+ {
+ return serialize( e.getKey(), e.getValue() );
+ }
+ return "";
+ } ).filter( OutputFormatter::isNotBlank ).collect( Collectors.joining( "; " ) )
+ .replaceAll( UNNAMED_PATTERN_STRING, "" );
+
+ if ( !result.isEmpty() )
+ {
+ update( columns, OTHER, result.length() );
}
return result;
}
@Nonnull
- private String format(@Nonnull Double v) {
- if (v.isNaN()) return v.toString();
- return String.valueOf(Math.round(v));
+ private String format( @Nonnull Double v )
+ {
+ if ( v.isNaN() )
+ {
+ return v.toString();
+ }
+ return String.valueOf( Math.round( v ) );
}
- static class TableRow {
+ static class TableRow
+ {
private final String tree;
- private final Map cells;
+ private final Map cells;
private final Optional connection;
private final int height;
- TableRow(String tree, Map cells, Optional connection) {
+ TableRow( String tree, Map cells, Optional connection )
+ {
this.tree = tree;
this.cells = cells;
this.connection = connection == null ? Optional.empty() : connection;
- this.height = cells.values().stream().mapToInt(v -> v.lines.length).max().orElse(0);
+ this.height = cells.values().stream().mapToInt( v -> v.lines.length ).max().orElse( 0 );
}
- Cell get(String key) {
- if (key.equals(TablePlanFormatter.OPERATOR))
- return new LeftJustifiedCell(tree);
+ Cell get( String key )
+ {
+ if ( key.equals( TablePlanFormatter.OPERATOR ) )
+ {
+ return new LeftJustifiedCell( tree );
+ }
else
- return cells.getOrDefault(key, new LeftJustifiedCell(""));
+ {
+ return cells.getOrDefault( key, new LeftJustifiedCell( "" ) );
+ }
}
}
- static abstract class Cell {
+ abstract static class Cell
+ {
final int length;
final String[] lines;
- Cell(String[] lines) {
- this.length = Stream.of(lines).mapToInt(String::length).max().orElse(0);
+ Cell( String[] lines )
+ {
+ this.length = Stream.of( lines ).mapToInt( String::length ).max().orElse( 0 );
this.lines = lines;
}
- abstract void writePaddedLine(int lineIndex, String orElseValue, int columnWidth, StringBuilder result);
+ abstract void writePaddedLine( int lineIndex, String orElseValue, int columnWidth, StringBuilder result );
- protected int paddingWidth(int columnWidth, String line) {
+ protected int paddingWidth( int columnWidth, String line )
+ {
return columnWidth - line.length() - 2;
}
- protected String getLineOrElse(int lineIndex, String orElseValue) {
- if (lineIndex < lines.length)
+ protected String getLineOrElse( int lineIndex, String orElseValue )
+ {
+ if ( lineIndex < lines.length )
+ {
return lines[lineIndex];
+ }
else
+ {
return orElseValue;
+ }
}
}
static class LeftJustifiedCell extends Cell
{
- LeftJustifiedCell(String... lines) {
- super(lines);
+ LeftJustifiedCell( String... lines )
+ {
+ super( lines );
}
@Override
- void writePaddedLine(int lineIndex, String orElseValue, int columnWidth, StringBuilder result) {
- String line = getLineOrElse(lineIndex, orElseValue);
- result.append(line);
- pad(paddingWidth(columnWidth, line), ' ', result);
+ void writePaddedLine( int lineIndex, String orElseValue, int columnWidth, StringBuilder result )
+ {
+ String line = getLineOrElse( lineIndex, orElseValue );
+ result.append( line );
+ pad( paddingWidth( columnWidth, line ), ' ', result );
}
}
- static class RightJustifiedCell extends Cell {
- RightJustifiedCell(String... lines) {
- super(lines);
+ static class RightJustifiedCell extends Cell
+ {
+ RightJustifiedCell( String... lines )
+ {
+ super( lines );
}
@Override
- void writePaddedLine(int lineIndex, String orElseValue, int columnWidth, StringBuilder result)
+ void writePaddedLine( int lineIndex, String orElseValue, int columnWidth, StringBuilder result )
{
- String line = getLineOrElse(lineIndex, orElseValue);
- pad(paddingWidth(columnWidth, line), ' ', result);
- result.append(line);
+ String line = getLineOrElse( lineIndex, orElseValue );
+ pad( paddingWidth( columnWidth, line ), ' ', result );
+ result.append( line );
}
}
- static abstract class Level {
+ abstract static class Level
+ {
abstract Level child();
abstract Level fork();
@@ -369,125 +469,154 @@ static abstract class Level {
abstract Optional connector();
}
- static class Root extends Level {
+ static class Root extends Level
+ {
@Override
- Level child() {
- return new Child(1);
+ Level child()
+ {
+ return new Child( 1 );
}
@Override
- Level fork() {
- return new Fork(2);
+ Level fork()
+ {
+ return new Fork( 2 );
}
@Override
- String line() {
+ String line()
+ {
return "+";
}
@Override
- Optional connector() {
+ Optional connector()
+ {
return Optional.empty();
}
-
}
- static class Child extends Level {
+ static class Child extends Level
+ {
private final int level;
- Child(int level) {
+ Child( int level )
+ {
this.level = level;
}
@Override
- Level child() {
- return new Child(level);
+ Level child()
+ {
+ return new Child( level );
}
@Override
- Level fork() {
- return new Fork(level + 1);
+ Level fork()
+ {
+ return new Fork( level + 1 );
}
@Override
- String line() {
- return repeat("| ", (level - 1)) + "+";
+ String line()
+ {
+ return repeat( "| ", level - 1 ) + "+";
}
@Override
- Optional connector() {
- return Optional.of(repeat("| ", level));
+ Optional connector()
+ {
+ return Optional.of( repeat( "| ", level ) );
}
}
- static class Fork extends Level {
+ static class Fork extends Level
+ {
private final int level;
- Fork(int level) {
+ Fork( int level )
+ {
this.level = level;
}
@Override
- Level child() {
- return new Child(level);
+ Level child()
+ {
+ return new Child( level );
}
@Override
- Level fork() {
- return new Fork(level + 1);
+ Level fork()
+ {
+ return new Fork( level + 1 );
}
@Override
- String line() {
- return repeat("| ", level - 1) + "+";
+ String line()
+ {
+ return repeat( "| ", level - 1 ) + "+";
}
@Override
- Optional connector() {
- return Optional.of(repeat("| ", level - 2) + "|\\");
+ Optional connector()
+ {
+ return Optional.of( repeat( "| ", level - 2 ) + "|\\" );
}
}
- static final class Pair {
+ static final class Pair
+ {
final T1 _1;
final T2 _2;
- private Pair(T1 _1, T2 _2) {
+ private Pair( T1 _1, T2 _2 )
+ {
this._1 = _1;
this._2 = _2;
}
@Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
Pair, ?> pair = (Pair, ?>) o;
- return _1.equals(pair._1) && _2.equals(pair._2);
+ return _1.equals( pair._1 ) && _2.equals( pair._2 );
}
@Override
- public int hashCode() {
+ public int hashCode()
+ {
return 31 * _1.hashCode() + _2.hashCode();
}
- public static Pair of(T1 _1, T2 _2) {
- return new Pair<>(_1, _2);
+ public static Pair of( T1 _1, T2 _2 )
+ {
+ return new Pair<>( _1, _2 );
}
}
- private String[] splitDetails(String original) {
+ private String[] splitDetails( String original )
+ {
List detailsList = new ArrayList<>();
int currentPos = 0;
- while(currentPos < original.length()){
- int newPos = Math.min(original.length(), currentPos + MAX_DETAILS_COLUMN_WIDTH);
- detailsList.add(original.substring( currentPos, newPos));
+ while ( currentPos < original.length() )
+ {
+ int newPos = Math.min( original.length(), currentPos + MAX_DETAILS_COLUMN_WIDTH );
+ detailsList.add( original.substring( currentPos, newPos ) );
currentPos = newPos;
}
- return detailsList.toArray(new String[0]);
+ return detailsList.toArray( new String[0] );
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/state/BoltResult.java b/cypher-shell/src/main/java/org/neo4j/shell/state/BoltResult.java
index 8f8aa720..adfc543f 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/state/BoltResult.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/state/BoltResult.java
@@ -1,16 +1,36 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.state;
-import org.neo4j.driver.Record;
-import org.neo4j.driver.summary.ResultSummary;
-
-import javax.annotation.Nonnull;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.neo4j.driver.Record;
+import org.neo4j.driver.summary.ResultSummary;
/**
* The result of executing some Cypher over bolt.
*/
-public interface BoltResult {
+public interface BoltResult
+{
@Nonnull
List getKeys();
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java b/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java
index 95c76c9b..e2f52d21 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/state/BoltStateHandler.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.state;
import java.util.HashMap;
@@ -45,51 +64,61 @@
/**
* Handles interactions with the driver
*/
-public class BoltStateHandler implements TransactionHandler, Connector, DatabaseManager {
- private final TriFunction driverProvider;
+public class BoltStateHandler implements TransactionHandler, Connector, DatabaseManager
+{
private static final String USER_AGENT = "neo4j-cypher-shell/v" + Build.version();
+ private final TriFunction driverProvider;
+ private final boolean isInteractive;
+ private final Map bookmarks = new HashMap<>();
protected Driver driver;
Session session;
private String version;
private String activeDatabaseNameAsSetByUser;
private String actualDatabaseNameAsReportedByServer;
- private final boolean isInteractive;
- private final Map bookmarks = new HashMap<>();
- private Transaction tx = null;
+ private Transaction tx;
- public BoltStateHandler(boolean isInteractive) {
- this(GraphDatabase::driver, isInteractive);
+ public BoltStateHandler( boolean isInteractive )
+ {
+ this( GraphDatabase::driver, isInteractive );
}
- BoltStateHandler(TriFunction driverProvider,
- boolean isInteractive) {
+ BoltStateHandler( TriFunction driverProvider,
+ boolean isInteractive )
+ {
this.driverProvider = driverProvider;
activeDatabaseNameAsSetByUser = ABSENT_DB_NAME;
this.isInteractive = isInteractive;
}
@Override
- public void setActiveDatabase(String databaseName) throws CommandException
+ public void setActiveDatabase( String databaseName ) throws CommandException
{
- if (isTransactionOpen()) {
- throw new CommandException("There is an open transaction. You need to close it before you can switch database.");
+ if ( isTransactionOpen() )
+ {
+ throw new CommandException( "There is an open transaction. You need to close it before you can switch database." );
}
String previousDatabaseName = activeDatabaseNameAsSetByUser;
activeDatabaseNameAsSetByUser = databaseName;
- try {
- if (isConnected()) {
- reconnect(databaseName, previousDatabaseName);
+ try
+ {
+ if ( isConnected() )
+ {
+ reconnect( databaseName, previousDatabaseName );
}
}
- catch (ClientException e) {
- if (isInteractive) {
+ catch ( ClientException e )
+ {
+ if ( isInteractive )
+ {
// We want to try to connect to the previous database
activeDatabaseNameAsSetByUser = previousDatabaseName;
- try {
- reconnect(previousDatabaseName, previousDatabaseName);
+ try
+ {
+ reconnect( previousDatabaseName, previousDatabaseName );
}
- catch (Exception e2) {
- e.addSuppressed(e2);
+ catch ( Exception e2 )
+ {
+ e.addSuppressed( e2 );
}
}
throw e;
@@ -109,23 +138,29 @@ public String getActualDatabaseAsReportedByServer()
}
@Override
- public void beginTransaction() throws CommandException {
- if (!isConnected()) {
- throw new CommandException("Not connected to Neo4j");
+ public void beginTransaction() throws CommandException
+ {
+ if ( !isConnected() )
+ {
+ throw new CommandException( "Not connected to Neo4j" );
}
- if (isTransactionOpen()) {
- throw new CommandException("There is already an open transaction");
+ if ( isTransactionOpen() )
+ {
+ throw new CommandException( "There is already an open transaction" );
}
tx = session.beginTransaction();
}
@Override
- public void commitTransaction() throws CommandException {
- if (!isConnected()) {
- throw new CommandException("Not connected to Neo4j");
+ public void commitTransaction() throws CommandException
+ {
+ if ( !isConnected() )
+ {
+ throw new CommandException( "Not connected to Neo4j" );
}
- if (!isTransactionOpen()) {
- throw new CommandException("There is no open transaction to commit");
+ if ( !isTransactionOpen() )
+ {
+ throw new CommandException( "There is no open transaction to commit" );
}
tx.commit();
tx.close();
@@ -133,12 +168,15 @@ public void commitTransaction() throws CommandException {
}
@Override
- public void rollbackTransaction() throws CommandException {
- if (!isConnected()) {
- throw new CommandException("Not connected to Neo4j");
+ public void rollbackTransaction() throws CommandException
+ {
+ if ( !isConnected() )
+ {
+ throw new CommandException( "Not connected to Neo4j" );
}
- if (!isTransactionOpen()) {
- throw new CommandException("There is no open transaction to rollback");
+ if ( !isTransactionOpen() )
+ {
+ throw new CommandException( "There is no open transaction to rollback" );
}
tx.rollback();
tx.close();
@@ -146,9 +184,8 @@ public void rollbackTransaction() throws CommandException {
}
/**
- * Handle an exception while getting or consuming the result.
- * If not in TX, return the given exception.
- * If in a TX, terminate the TX and return a more verbose error message.
+ * Handle an exception while getting or consuming the result. If not in TX, return the given exception. If in a TX, terminate the TX and return a more
+ * verbose error message.
*
* @param e the thrown exception.
* @return a suitable exception to rethrow.
@@ -169,28 +206,36 @@ public Neo4jException handleException( Neo4jException e )
}
@Override
- public boolean isTransactionOpen() {
+ public boolean isTransactionOpen()
+ {
return tx != null;
}
@Override
- public boolean isConnected() {
+ public boolean isConnected()
+ {
return session != null && session.isOpen();
}
@Override
- public void connect( @Nonnull ConnectionConfig connectionConfig, ThrowingAction command) throws CommandException {
- if (isConnected()) {
- throw new CommandException("Already connected");
+ public void connect( @Nonnull ConnectionConfig connectionConfig, ThrowingAction command ) throws CommandException
+ {
+ if ( isConnected() )
+ {
+ throw new CommandException( "Already connected" );
}
- final AuthToken authToken = AuthTokens.basic(connectionConfig.username(), connectionConfig.password());
- try {
+ final AuthToken authToken = AuthTokens.basic( connectionConfig.username(), connectionConfig.password() );
+ try
+ {
String previousDatabaseName = activeDatabaseNameAsSetByUser;
- try {
+ try
+ {
activeDatabaseNameAsSetByUser = connectionConfig.database();
- driver = getDriver(connectionConfig, authToken);
- reconnect(activeDatabaseNameAsSetByUser, previousDatabaseName, command);
- } catch (org.neo4j.driver.exceptions.ServiceUnavailableException e) {
+ driver = getDriver( connectionConfig, authToken );
+ reconnect( activeDatabaseNameAsSetByUser, previousDatabaseName, command );
+ }
+ catch ( org.neo4j.driver.exceptions.ServiceUnavailableException e )
+ {
String scheme = connectionConfig.scheme();
String fallbackScheme;
switch ( scheme )
@@ -208,33 +253,40 @@ public void connect( @Nonnull ConnectionConfig connectionConfig, ThrowingAction<
throw e;
}
connectionConfig = new ConnectionConfig(
- fallbackScheme,
- connectionConfig.host(),
- connectionConfig.port(),
- connectionConfig.username(),
- connectionConfig.password(),
- connectionConfig.encryption(),
- connectionConfig.database());
- driver = getDriver(connectionConfig, authToken);
- reconnect(activeDatabaseNameAsSetByUser, previousDatabaseName, command);
+ fallbackScheme,
+ connectionConfig.host(),
+ connectionConfig.port(),
+ connectionConfig.username(),
+ connectionConfig.password(),
+ connectionConfig.encryption(),
+ connectionConfig.database() );
+ driver = getDriver( connectionConfig, authToken );
+ reconnect( activeDatabaseNameAsSetByUser, previousDatabaseName, command );
}
- } catch (Throwable t) {
- try {
+ }
+ catch ( Throwable t )
+ {
+ try
+ {
silentDisconnect();
- } catch (Exception e) {
- t.addSuppressed(e);
+ }
+ catch ( Exception e )
+ {
+ t.addSuppressed( e );
}
throw t;
}
}
- private void reconnect(String databaseToConnectTo, String previousDatabase) throws CommandException {
- reconnect(databaseToConnectTo, previousDatabase, null);
+ private void reconnect( String databaseToConnectTo, String previousDatabase ) throws CommandException
+ {
+ reconnect( databaseToConnectTo, previousDatabase, null );
}
private void reconnect( String databaseToConnectTo,
String previousDatabase,
- ThrowingAction command ) throws CommandException {
+ ThrowingAction command ) throws CommandException
+ {
SessionConfig.Builder builder = SessionConfig.builder();
builder.withDefaultAccessMode( AccessMode.WRITE );
if ( !ABSENT_DB_NAME.equals( databaseToConnectTo ) )
@@ -251,12 +303,12 @@ private void reconnect( String databaseToConnectTo,
session = driver.session( builder.build() );
resetActualDbName(); // Set this to null first in case run throws an exception
- connect(command);
+ connect( command );
}
/**
- * Closes the session, if there is any.
- * Saves a bookmark for the database currently connected to.
+ * Closes the session, if there is any. Saves a bookmark for the database currently connected to.
+ *
* @param databaseName the name of the database currently connected to
*/
private void closeSession( String databaseName )
@@ -266,11 +318,11 @@ private void closeSession( String databaseName )
// Save the last bookmark and close the session
final Bookmark bookmarkForPreviousDB = session.lastBookmark();
session.close();
- bookmarks.put(databaseName, bookmarkForPreviousDB);
+ bookmarks.put( databaseName, bookmarkForPreviousDB );
}
}
- private void connect( ThrowingAction command) throws CommandException
+ private void connect( ThrowingAction command ) throws CommandException
{
ThrowingAction toCall = command == null ? getPing() : () ->
{
@@ -282,7 +334,7 @@ private void connect( ThrowingAction command) throws CommandEx
{
//If we need to update password we need to call the apply
//to set the server version and such.
- if (isPasswordChangeRequiredException( e ))
+ if ( isPasswordChangeRequiredException( e ) )
{
getPing().apply();
}
@@ -294,42 +346,57 @@ private void connect( ThrowingAction command) throws CommandEx
toCall.apply();
}
- private ThrowingAction getPing() {
+ private ThrowingAction getPing()
+ {
- return () -> {
+ return () ->
+ {
ResultSummary summary = null;
- Result run = session.run( "CALL db.ping()");
- try {
+ Result run = session.run( "CALL db.ping()" );
+ try
+ {
summary = run.consume();
- } catch (ClientException e) {
+ }
+ catch ( ClientException e )
+ {
//In older versions there is no db.ping procedure, use legacy method.
- if ( procedureNotFound( e ) ) {
- run = session.run(isSystemDb() ? "CALL db.indexes()" : "RETURN 1" );
- } else {
+ if ( procedureNotFound( e ) )
+ {
+ run = session.run( isSystemDb() ? "CALL db.indexes()" : "RETURN 1" );
+ }
+ else
+ {
throw e;
}
- } finally {
+ }
+ finally
+ {
// Since run.consume() can throw the first time we have to go through this extra hoop to get the summary
- if (summary == null) {
+ if ( summary == null )
+ {
summary = run.consume();
}
BoltStateHandler.this.version = summary.server().version();
- updateActualDbName(summary);
+ updateActualDbName( summary );
}
};
}
@Nonnull
@Override
- public String getServerVersion() {
- if (isConnected()) {
- if (version == null) {
+ public String getServerVersion()
+ {
+ if ( isConnected() )
+ {
+ if ( version == null )
+ {
// On versions before 3.1.0-M09
version = "";
}
- if (version.startsWith("Neo4j/")) {
+ if ( version.startsWith( "Neo4j/" ) )
+ {
// Want to return '3.1.0' and not 'Neo4j/3.1.0'
- version = version.substring(6);
+ version = version.substring( 6 );
}
return version;
}
@@ -337,81 +404,104 @@ public String getServerVersion() {
}
@Nonnull
- public Optional runCypher(@Nonnull String cypher,
- @Nonnull Map queryParams) throws CommandException {
- if (!isConnected()) {
- throw new CommandException("Not connected to Neo4j");
+ public Optional runCypher( @Nonnull String cypher,
+ @Nonnull Map queryParams ) throws CommandException
+ {
+ if ( !isConnected() )
+ {
+ throw new CommandException( "Not connected to Neo4j" );
}
- if (isTransactionOpen()) {
+ if ( isTransactionOpen() )
+ {
// If this fails, don't try any funny business - just let it die
- return getBoltResult(cypher, queryParams);
- } else {
- try {
+ return getBoltResult( cypher, queryParams );
+ }
+ else
+ {
+ try
+ {
// Note that PERIODIC COMMIT can't execute in a transaction, so if the user has not typed BEGIN, then
// the statement should NOT be executed in a transaction.
- return getBoltResult(cypher, queryParams);
- } catch (SessionExpiredException e) {
+ return getBoltResult( cypher, queryParams );
+ }
+ catch ( SessionExpiredException e )
+ {
// Server is no longer accepting writes, reconnect and try again.
// If it still fails, leave it up to the user
- reconnect(activeDatabaseNameAsSetByUser, activeDatabaseNameAsSetByUser);
- return getBoltResult(cypher, queryParams);
+ reconnect( activeDatabaseNameAsSetByUser, activeDatabaseNameAsSetByUser );
+ return getBoltResult( cypher, queryParams );
}
}
}
- public void updateActualDbName(@Nonnull ResultSummary resultSummary) {
- actualDatabaseNameAsReportedByServer = getActualDbName(resultSummary);
+ public void updateActualDbName( @Nonnull ResultSummary resultSummary )
+ {
+ actualDatabaseNameAsReportedByServer = getActualDbName( resultSummary );
}
public void changePassword( @Nonnull ConnectionConfig connectionConfig )
{
- if (!connectionConfig.passwordChangeRequired()) {
+ if ( !connectionConfig.passwordChangeRequired() )
+ {
return;
}
- if (isConnected()) {
+ if ( isConnected() )
+ {
silentDisconnect();
}
- final AuthToken authToken = AuthTokens.basic(connectionConfig.username(), connectionConfig.password());
+ final AuthToken authToken = AuthTokens.basic( connectionConfig.username(), connectionConfig.password() );
- try {
- driver = getDriver(connectionConfig, authToken);
+ try
+ {
+ driver = getDriver( connectionConfig, authToken );
activeDatabaseNameAsSetByUser = SYSTEM_DB_NAME;
// Supply empty command, so that we do not run ping.
- reconnect( SYSTEM_DB_NAME, SYSTEM_DB_NAME, () -> {} );
+ reconnect( SYSTEM_DB_NAME, SYSTEM_DB_NAME, () ->
+ {
+ } );
String command;
Value parameters;
- if (majorVersion(getServerVersion()) >= 4) {
+ if ( majorVersion( getServerVersion() ) >= 4 )
+ {
command = "ALTER CURRENT USER SET PASSWORD FROM $o TO $n";
- parameters = Values.parameters("o", connectionConfig.password(), "n", connectionConfig.newPassword());
- } else {
+ parameters = Values.parameters( "o", connectionConfig.password(), "n", connectionConfig.newPassword() );
+ }
+ else
+ {
command = "CALL dbms.security.changePassword($n)";
- parameters = Values.parameters("n", connectionConfig.newPassword());
+ parameters = Values.parameters( "n", connectionConfig.newPassword() );
}
- Result run = session.run(command, parameters);
+ Result run = session.run( command, parameters );
run.consume();
// If successful, use the new password when reconnecting
- connectionConfig.setPassword(connectionConfig.newPassword());
- connectionConfig.setNewPassword(null);
+ connectionConfig.setPassword( connectionConfig.newPassword() );
+ connectionConfig.setNewPassword( null );
silentDisconnect();
- } catch (Throwable t) {
- try {
+ }
+ catch ( Throwable t )
+ {
+ try
+ {
silentDisconnect();
- } catch (Exception e) {
- t.addSuppressed(e);
}
- if (t instanceof RuntimeException) {
+ catch ( Exception e )
+ {
+ t.addSuppressed( e );
+ }
+ if ( t instanceof RuntimeException )
+ {
throw (RuntimeException) t;
}
// The only checked exception is CommandException and we know that
// we cannot get that since we supply an empty command.
- throw new RuntimeException(t);
+ throw new RuntimeException( t );
}
}
@@ -419,42 +509,53 @@ public void changePassword( @Nonnull ConnectionConfig connectionConfig )
* @throws SessionExpiredException when server no longer serves writes anymore
*/
@Nonnull
- private Optional getBoltResult(@Nonnull String cypher, @Nonnull Map queryParams) throws SessionExpiredException {
+ private Optional getBoltResult( @Nonnull String cypher, @Nonnull Map queryParams ) throws SessionExpiredException
+ {
Result statementResult;
- if (isTransactionOpen()){
- statementResult = tx.run(new Query(cypher, queryParams));
- } else {
- statementResult = session.run(new Query(cypher, queryParams));
+ if ( isTransactionOpen() )
+ {
+ statementResult = tx.run( new Query( cypher, queryParams ) );
+ }
+ else
+ {
+ statementResult = session.run( new Query( cypher, queryParams ) );
}
- if (statementResult == null) {
+ if ( statementResult == null )
+ {
return Optional.empty();
}
- return Optional.of(new StatementBoltResult(statementResult));
+ return Optional.of( new StatementBoltResult( statementResult ) );
}
- private String getActualDbName(@Nonnull ResultSummary resultSummary) {
+ private String getActualDbName( @Nonnull ResultSummary resultSummary )
+ {
DatabaseInfo dbInfo = resultSummary.database();
return dbInfo.name() == null ? ABSENT_DB_NAME : dbInfo.name();
}
- private void resetActualDbName() {
+ private void resetActualDbName()
+ {
actualDatabaseNameAsReportedByServer = null;
}
/**
- * Disconnect from Neo4j, clearing up any session resources, but don't give any output.
- * Intended only to be used if connect fails.
+ * Disconnect from Neo4j, clearing up any session resources, but don't give any output. Intended only to be used if connect fails.
*/
- void silentDisconnect() {
- try {
+ void silentDisconnect()
+ {
+ try
+ {
closeSession( activeDatabaseNameAsSetByUser );
- if (driver != null) {
+ if ( driver != null )
+ {
driver.close();
}
- } finally {
+ }
+ finally
+ {
session = null;
driver = null;
resetActualDbName();
@@ -464,12 +565,15 @@ void silentDisconnect() {
/**
* Reset the current session. This rolls back any open transactions.
*/
- public void reset() {
- if (isConnected()) {
+ public void reset()
+ {
+ if ( isConnected() )
+ {
session.reset();
// Clear current state
- if (isTransactionOpen()) {
+ if ( isTransactionOpen() )
+ {
// Bolt has already rolled back the transaction but it doesn't close it properly
tx.rollback();
tx.close();
@@ -481,17 +585,19 @@ public void reset() {
/**
* Used for testing purposes
*/
- public void disconnect() {
- reset();
- silentDisconnect();
- version = null;
+ public void disconnect()
+ {
+ reset();
+ silentDisconnect();
+ version = null;
}
- private Driver getDriver(@Nonnull ConnectionConfig connectionConfig, @Nullable AuthToken authToken) {
+ private Driver getDriver( @Nonnull ConnectionConfig connectionConfig, @Nullable AuthToken authToken )
+ {
Config.ConfigBuilder configBuilder = Config.builder()
- .withLogging(NullLogging.NULL_LOGGING)
+ .withLogging( NullLogging.NULL_LOGGING )
.withUserAgent( USER_AGENT );
- switch(connectionConfig.encryption())
+ switch ( connectionConfig.encryption() )
{
case TRUE:
configBuilder = configBuilder.withEncryption();
@@ -499,25 +605,27 @@ private Driver getDriver(@Nonnull ConnectionConfig connectionConfig, @Nullable A
case FALSE:
configBuilder = configBuilder.withoutEncryption();
break;
+ default:
+ // Do nothing
}
- return driverProvider.apply(connectionConfig.driverUrl(), authToken, configBuilder.build());
+ return driverProvider.apply( connectionConfig.driverUrl(), authToken, configBuilder.build() );
}
- private List executeWithRetry(List transactionStatements, BiFunction biFunction) {
- return session.writeTransaction(tx ->
- transactionStatements.stream()
- .map(transactionStatement -> biFunction.apply(transactionStatement, tx))
- .collect(Collectors.toList()));
-
+ private List executeWithRetry( List transactionStatements, BiFunction biFunction )
+ {
+ return session.writeTransaction( tx ->
+ transactionStatements.stream()
+ .map( transactionStatement -> biFunction.apply( transactionStatement, tx ) )
+ .collect( Collectors.toList() ) );
}
private boolean isSystemDb()
{
- return activeDatabaseNameAsSetByUser.compareToIgnoreCase(SYSTEM_DB_NAME) == 0;
+ return activeDatabaseNameAsSetByUser.compareToIgnoreCase( SYSTEM_DB_NAME ) == 0;
}
private boolean procedureNotFound( ClientException e )
{
- return e.code().compareToIgnoreCase("Neo.ClientError.Procedure.ProcedureNotFound") == 0;
+ return e.code().compareToIgnoreCase( "Neo.ClientError.Procedure.ProcedureNotFound" ) == 0;
}
}
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/state/ErrorWhileInTransactionException.java b/cypher-shell/src/main/java/org/neo4j/shell/state/ErrorWhileInTransactionException.java
index 286228f7..007c46d4 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/state/ErrorWhileInTransactionException.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/state/ErrorWhileInTransactionException.java
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.state;
import org.neo4j.driver.exceptions.Neo4jException;
diff --git a/cypher-shell/src/main/java/org/neo4j/shell/state/ListBoltResult.java b/cypher-shell/src/main/java/org/neo4j/shell/state/ListBoltResult.java
index 13f96853..ac625100 100644
--- a/cypher-shell/src/main/java/org/neo4j/shell/state/ListBoltResult.java
+++ b/cypher-shell/src/main/java/org/neo4j/shell/state/ListBoltResult.java
@@ -1,27 +1,49 @@
+/*
+ * Copyright (c) 2002-2020 "Neo4j,"
+ * Neo4j Sweden AB [http://neo4j.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
package org.neo4j.shell.state;
-import org.neo4j.driver.Record;
-import org.neo4j.driver.summary.ResultSummary;
-
-import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.neo4j.driver.Record;
+import org.neo4j.driver.summary.ResultSummary;
/**
* A fully materialized Cypher result.
*/
-public class ListBoltResult implements BoltResult {
+public class ListBoltResult implements BoltResult
+{
private final List keys;
private final List records;
private final ResultSummary summary;
- public ListBoltResult(@Nonnull List records, @Nonnull ResultSummary summary) {
- this(records, summary, records.isEmpty() ? Collections.emptyList() : records.get(0).keys());
+ public ListBoltResult( @Nonnull List records, @Nonnull ResultSummary summary )
+ {
+ this( records, summary, records.isEmpty() ? Collections.emptyList() : records.get( 0 ).keys() );
}
- public ListBoltResult(@Nonnull List records, @Nonnull ResultSummary summary, @Nonnull List