Skip to content

Commit

Permalink
Import tool help/usage message should provide usage example
Browse files Browse the repository at this point in the history
Update import tool help message to be printed out when no input parameters were provided.
Text updated to include usage example.
  • Loading branch information
MishaDemianenko committed Sep 15, 2015
1 parent 56a0b13 commit 3c72ee0
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 24 deletions.
Expand Up @@ -29,6 +29,7 @@
import org.neo4j.graphdb.factory.GraphDatabaseFactory; import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.helpers.Args; import org.neo4j.helpers.Args;
import org.neo4j.helpers.Strings;
import org.neo4j.helpers.collection.MapUtil; import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.helpers.progress.ProgressMonitorFactory; import org.neo4j.helpers.progress.ProgressMonitorFactory;
import org.neo4j.io.fs.DefaultFileSystemAbstraction; import org.neo4j.io.fs.DefaultFileSystemAbstraction;
Expand Down Expand Up @@ -124,7 +125,7 @@ private void attemptRecoveryOrCheckStateOfLogicalLogs( Args arguments, File stor
{ {
if ( new RecoveryRequiredChecker( fs, pageCache ).isRecoveryRequiredAt( storeDir ) ) if ( new RecoveryRequiredChecker( fs, pageCache ).isRecoveryRequiredAt( storeDir ) )
{ {
systemError.print( lines( systemError.print( Strings.joinAsLines(
"Active logical log detected, this might be a source of inconsistencies.", "Active logical log detected, this might be a source of inconsistencies.",
"Consider allowing the database to recover before running the consistency check.", "Consider allowing the database to recover before running the consistency check.",
"Consistency checking will continue, abort if you wish to perform recovery first.", "Consistency checking will continue, abort if you wish to perform recovery first.",
Expand All @@ -150,7 +151,8 @@ private File determineStoreDirectory( Args arguments ) throws ToolFailureExcepti
File storeDir = new File( unprefixedArguments.get( 0 ) ); File storeDir = new File( unprefixedArguments.get( 0 ) );
if ( !storeDir.isDirectory() ) if ( !storeDir.isDirectory() )
{ {
throw new ToolFailureException( lines( String.format( "'%s' is not a directory", storeDir ) ) + usage() ); throw new ToolFailureException(
Strings.joinAsLines( String.format( "'%s' is not a directory", storeDir ) ) + usage() );
} }
return storeDir; return storeDir;
} }
Expand Down Expand Up @@ -178,7 +180,7 @@ private Config readTuningConfiguration( Args arguments ) throws ToolFailureExcep


private String usage() private String usage()
{ {
return lines( return Strings.joinAsLines(
Args.jarUsage( getClass(), "[-propowner] [-recovery] [-config <neo4j.properties>] <storedir>" ), Args.jarUsage( getClass(), "[-propowner] [-recovery] [-config <neo4j.properties>] <storedir>" ),
"WHERE: <storedir> is the path to the store to check", "WHERE: <storedir> is the path to the store to check",
" -recovery to perform recovery on the store before checking", " -recovery to perform recovery on the store before checking",
Expand All @@ -187,16 +189,6 @@ private String usage()
); );
} }


private static String lines( String... content )
{
StringBuilder result = new StringBuilder();
for ( String line : content )
{
result.append( line ).append( System.lineSeparator() );
}
return result.toString();
}

class ToolFailureException extends Exception class ToolFailureException extends Exception
{ {
ToolFailureException( String message ) ToolFailureException( String message )
Expand Down
Expand Up @@ -33,6 +33,8 @@
import org.neo4j.function.Function; import org.neo4j.function.Function;
import org.neo4j.helpers.Args; import org.neo4j.helpers.Args;
import org.neo4j.helpers.Args.Option; import org.neo4j.helpers.Args.Option;
import org.neo4j.helpers.ArrayUtil;
import org.neo4j.helpers.Strings;
import org.neo4j.helpers.collection.IterableWrapper; import org.neo4j.helpers.collection.IterableWrapper;
import org.neo4j.helpers.collection.Iterables; import org.neo4j.helpers.collection.Iterables;
import org.neo4j.io.fs.DefaultFileSystemAbstraction; import org.neo4j.io.fs.DefaultFileSystemAbstraction;
Expand Down Expand Up @@ -64,6 +66,7 @@


import static org.neo4j.helpers.Exceptions.launderedException; import static org.neo4j.helpers.Exceptions.launderedException;
import static org.neo4j.helpers.Format.bytes; import static org.neo4j.helpers.Format.bytes;
import static org.neo4j.helpers.Strings.TAB;
import static org.neo4j.kernel.impl.util.Converters.withDefault; import static org.neo4j.kernel.impl.util.Converters.withDefault;
import static org.neo4j.unsafe.impl.batchimport.Configuration.BAD_FILE_NAME; import static org.neo4j.unsafe.impl.batchimport.Configuration.BAD_FILE_NAME;
import static org.neo4j.unsafe.impl.batchimport.cache.AvailableMemoryCalculator.RUNTIME; import static org.neo4j.unsafe.impl.batchimport.cache.AvailableMemoryCalculator.RUNTIME;
Expand Down Expand Up @@ -259,7 +262,7 @@ public static void main( String[] incomingArguments ) throws IOException
public static void main( String[] incomingArguments, boolean defaultSettingsSuitableForTests ) throws IOException public static void main( String[] incomingArguments, boolean defaultSettingsSuitableForTests ) throws IOException
{ {
Args args = Args.parse( incomingArguments ); Args args = Args.parse( incomingArguments );
if ( asksForUsage( args ) ) if ( ArrayUtil.isEmpty( incomingArguments ) || asksForUsage( args ) )
{ {
printUsage( System.out ); printUsage( System.out );
return; return;
Expand Down Expand Up @@ -533,6 +536,13 @@ private static void printUsage( PrintStream out )
{ {
option.printUsage( out ); option.printUsage( out );
} }

out.println( "Example:");
out.print( Strings.joinAsLines(
TAB + "bin/neo4j-import --into retail.db --id-type string --nodes:Customer customers.csv ",
TAB + "--nodes products.csv --nodes orders_header.csv,orders1.csv,orders2.csv ",
TAB + "--relationships:CONTAINS order_details.csv ",
TAB + "--relationships:ORDERED customer_orders_header.csv,orders1.csv,orders2.csv" ) );
} }


private static boolean asksForUsage( Args args ) private static boolean asksForUsage( Args args )
Expand Down
Expand Up @@ -96,6 +96,24 @@ public class ImportToolTest
public final SuppressOutput suppressOutput = SuppressOutput.suppress( SuppressOutput.System.values() ); public final SuppressOutput suppressOutput = SuppressOutput.suppress( SuppressOutput.System.values() );
private int dataIndex; private int dataIndex;


@Test
public void usageMessageIncludeExample() throws Exception
{
SuppressOutput.Voice outputVoice = suppressOutput.getOutputVoice();
importTool( "?" );
assertTrue( "Usage message should include example section, but was:" + outputVoice,
outputVoice.containsMessage( "Example:" ) );
}

@Test
public void usageMessagePrintedOnEmptyInputParameters() throws Exception
{
SuppressOutput.Voice outputVoice = suppressOutput.getOutputVoice();
importTool();
assertTrue( "Output should include usage section, but was:" + outputVoice,
outputVoice.containsMessage( "Example:" ) );
}

@Test @Test
public void shouldImportWithAsManyDefaultsAsAvailable() throws Exception public void shouldImportWithAsManyDefaultsAsAvailable() throws Exception
{ {
Expand Down Expand Up @@ -637,7 +655,7 @@ public void shouldDisallowMultilineFieldsByDefault() throws Exception
@Test @Test
public void shouldPrintReferenceLinkOnDataImportErrors() throws Exception public void shouldPrintReferenceLinkOnDataImportErrors() throws Exception
{ {
shouldPrintReferenceLinkAsPartOfErrorMessage(nodeIds(), shouldPrintReferenceLinkAsPartOfErrorMessage( nodeIds(),
IteratorUtil.iterator( new RelationshipDataLine( "1", "", "type", "name" ) ), IteratorUtil.iterator( new RelationshipDataLine( "1", "", "type", "name" ) ),
"Relationship missing mandatory field 'END_ID', read more about relationship " + "Relationship missing mandatory field 'END_ID', read more about relationship " +
"format in the manual: http://neo4j.com/docs/" + Version.getKernelVersion() + "format in the manual: http://neo4j.com/docs/" + Version.getKernelVersion() +
Expand Down Expand Up @@ -952,7 +970,7 @@ private String randomLabels( char arrayDelimiter )


private String randomName() private String randomName()
{ {
int length = random.nextInt( 10 )+5; int length = random.nextInt( 10 ) + 5;
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for ( int i = 0; i < length; i++ ) for ( int i = 0; i < length; i++ )
{ {
Expand All @@ -962,13 +980,13 @@ private String randomName()
} }


private File relationshipData( boolean includeHeader, Configuration config, List<String> nodeIds, private File relationshipData( boolean includeHeader, Configuration config, List<String> nodeIds,
IntPredicate linePredicate, boolean specifyType ) throws Exception IntPredicate linePredicate, boolean specifyType ) throws Exception
{ {
return relationshipData( includeHeader, config, nodeIds, linePredicate, specifyType, Charset.defaultCharset() ); return relationshipData( includeHeader, config, nodeIds, linePredicate, specifyType, Charset.defaultCharset() );
} }


private File relationshipData( boolean includeHeader, Configuration config, List<String> nodeIds, private File relationshipData( boolean includeHeader, Configuration config, List<String> nodeIds,
IntPredicate linePredicate, boolean specifyType, Charset encoding ) throws Exception IntPredicate linePredicate, boolean specifyType, Charset encoding ) throws Exception
{ {
return relationshipData( includeHeader, config, randomRelationships( nodeIds ), linePredicate, return relationshipData( includeHeader, config, randomRelationships( nodeIds ), linePredicate,
specifyType, encoding ); specifyType, encoding );
Expand Down Expand Up @@ -1065,7 +1083,7 @@ private static class RelationshipDataLine
public String toString() public String toString()
{ {
return "RelationshipDataLine [startNodeId=" + startNodeId + ", endNodeId=" + endNodeId + ", type=" + type return "RelationshipDataLine [startNodeId=" + startNodeId + ", endNodeId=" + endNodeId + ", type=" + type
+ ", name=" + name + "]"; + ", name=" + name + "]";
} }
} }


Expand Down Expand Up @@ -1093,11 +1111,11 @@ private void writeRelationshipData( PrintStream writer, Configuration config,
if ( linePredicate.test( i ) ) if ( linePredicate.test( i ) )
{ {
writer.println( entry.startNodeId + writer.println( entry.startNodeId +
delimiter + entry.endNodeId + delimiter + entry.endNodeId +
(specifyType ? (delimiter + entry.type) : "") + (specifyType ? (delimiter + entry.type) : "") +
delimiter + currentTimeMillis() + delimiter + currentTimeMillis() +
delimiter + (entry.name != null ? entry.name : "") delimiter + (entry.name != null ? entry.name : "")
); );
} }
} }
} }
Expand Down
10 changes: 10 additions & 0 deletions community/kernel/src/main/java/org/neo4j/helpers/ArrayUtil.java
Expand Up @@ -372,6 +372,16 @@ public static <T> T[] union( T[] first, T[] other )
return union; return union;
} }


/**
* Check if provided array is empty
* @param array - array to check
* @return true if array is null or empty
*/
public static boolean isEmpty( Object[] array )
{
return (array == null) || (array.length == 0);
}

/** /**
* Convert an array to a String using a custom delimiter. * Convert an array to a String using a custom delimiter.
* *
Expand Down
16 changes: 16 additions & 0 deletions community/kernel/src/main/java/org/neo4j/helpers/Strings.java
Expand Up @@ -148,6 +148,22 @@ public static String escape( String arg )
return builder.toString(); return builder.toString();
} }


/**
* Joining independent lines from provided elements into one line with {@link java.lang.System#lineSeparator} after
* each element
* @param elements - lines to join
* @return joined line
*/
public static String joinAsLines( String... elements )
{
StringBuilder result = new StringBuilder();
for ( String line : elements )
{
result.append( line ).append( System.lineSeparator() );
}
return result.toString();
}

public static void escape( Appendable output, String arg ) throws IOException public static void escape( Appendable output, String arg ) throws IOException
{ {
int len = arg.length(); int len = arg.length();
Expand Down
Expand Up @@ -81,6 +81,14 @@ public void shouldCheckNullSafeEqual() throws Exception
assertTrue( ArrayUtil.nullSafeEquals( "1", "1" ) ); assertTrue( ArrayUtil.nullSafeEquals( "1", "1" ) );
} }


@Test
public void emptyArray()
{
assertTrue( ArrayUtil.isEmpty( null ) );
assertTrue( ArrayUtil.isEmpty( new String[] {} ) );
assertFalse( ArrayUtil.isEmpty( new Long[] { 1L } ) );
}

@Test @Test
public void shouldConcatOneAndMany() throws Exception public void shouldConcatOneAndMany() throws Exception
{ {
Expand Down
Expand Up @@ -79,4 +79,11 @@ public void testEscape()
assertEquals( "a\\bbc", Strings.escape( "a\bbc" ) ); assertEquals( "a\\bbc", Strings.escape( "a\bbc" ) );
assertEquals( "a\\fbc", Strings.escape( "a\fbc" ) ); assertEquals( "a\\fbc", Strings.escape( "a\fbc" ) );
} }

@Test
public void testJoiningLines()
{
assertEquals( "a" + System.lineSeparator() + "b" + System.lineSeparator() + "c" + System.lineSeparator(),
Strings.joinAsLines( "a", "b", "c" ) );
}
} }
Expand Up @@ -249,6 +249,12 @@ public boolean containsMessage( String message )
return voiceStream.toString().contains( message ); return voiceStream.toString().contains( message );
} }


@Override
public String toString()
{
return voiceStream.toString();
}

abstract void restore( boolean failure ) throws IOException; abstract void restore( boolean failure ) throws IOException;
} }


Expand Down

0 comments on commit 3c72ee0

Please sign in to comment.