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

Commit c9cb5a8

Browse files
committed
Change formatting ResultTables with long values
* For numbers, always reserve 19 digits (length of Long.Max) * For other types, change the borders of the table when values overflow into the next row.
1 parent ca1dd2a commit c9cb5a8

File tree

2 files changed

+144
-29
lines changed

2 files changed

+144
-29
lines changed

cypher-shell/src/main/java/org/neo4j/shell/prettyprint/TableOutputFormatter.java

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
package org.neo4j.shell.prettyprint;
22

3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.EnumSet;
6+
import java.util.Iterator;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Set;
10+
import javax.annotation.Nonnull;
11+
import javax.annotation.Nullable;
12+
313
import org.neo4j.driver.internal.InternalRecord;
14+
import org.neo4j.driver.internal.value.NumberValueAdapter;
415
import org.neo4j.driver.v1.Record;
516
import org.neo4j.driver.v1.Value;
617
import org.neo4j.driver.v1.summary.ResultSummary;
718
import org.neo4j.shell.state.BoltResult;
819

9-
import javax.annotation.Nonnull;
10-
import javax.annotation.Nullable;
11-
import java.util.*;
12-
1320
import static java.util.Arrays.asList;
1421
import static java.util.concurrent.TimeUnit.MILLISECONDS;
1522

@@ -55,7 +62,7 @@ private int formatResultAndCountRows(String[] columns,
5562
}
5663

5764
StringBuilder builder = new StringBuilder(totalWidth);
58-
String headerLine = formatRow(builder, columnSizes, columns);
65+
String headerLine = formatRow(builder, columnSizes, columns, new boolean[columnSizes.length]);
5966
int lineWidth = totalWidth - 2;
6067
String dashes = "+" + OutputFormatter.repeat('-', lineWidth) + "+";
6168

@@ -83,7 +90,7 @@ private int[] calculateColumnSizes(@Nonnull String[] columns, @Nonnull List<Reco
8390
}
8491
for (Record record : data) {
8592
for (int i = 0; i < columns.length; i++) {
86-
int len = formatValue(record.get(i)).length();
93+
int len = columnLengthForValue(record.get(i));
8794
if (columnSizes[i] < len) {
8895
columnSizes[i] = len;
8996
}
@@ -92,9 +99,20 @@ private int[] calculateColumnSizes(@Nonnull String[] columns, @Nonnull List<Reco
9299
return columnSizes;
93100
}
94101

102+
/**
103+
* The length of a column, where Numbers are always getting enough space to fit the highest number possible.
104+
*/
105+
private int columnLengthForValue(Value value) {
106+
if (value instanceof NumberValueAdapter ) {
107+
return 19; // The number of digits of Long.Max
108+
} else {
109+
return formatValue(value).length();
110+
}
111+
}
112+
95113
private String formatRecord(StringBuilder sb, int[] columnSizes, Record record) {
96114
sb.setLength(0);
97-
return formatRow(sb, columnSizes, formatValues(record));
115+
return formatRow(sb, columnSizes, formatValues(record), new boolean[columnSizes.length]);
98116
}
99117

100118
private String[] formatValues(Record record) {
@@ -105,8 +123,21 @@ private String[] formatValues(Record record) {
105123
return row;
106124
}
107125

108-
private String formatRow(StringBuilder sb, int[] columnSizes, String[] row) {
109-
sb.append("|");
126+
/**
127+
* Format one row of data.
128+
*
129+
* @param sb the StringBuilder to use
130+
* @param columnSizes the size of all columns
131+
* @param row the data
132+
* @param continuation for each column whether it holds the remainder of data that did not fit in the column
133+
* @return the String result
134+
*/
135+
private String formatRow(StringBuilder sb, int[] columnSizes, String[] row, boolean[] continuation) {
136+
if (!continuation[0]) {
137+
sb.append("|");
138+
} else {
139+
sb.append("\\");
140+
}
110141
boolean remainder = false;
111142
for (int i = 0; i < row.length; i++) {
112143
sb.append(" ");
@@ -117,6 +148,7 @@ private String formatRow(StringBuilder sb, int[] columnSizes, String[] row) {
117148
if (wrap) {
118149
sb.append(txt, 0, length);
119150
row[i] = txt.substring(length);
151+
continuation[i] = true;
120152
remainder = true;
121153
} else {
122154
sb.append(txt, 0, length - 1);
@@ -129,11 +161,15 @@ private String formatRow(StringBuilder sb, int[] columnSizes, String[] row) {
129161
} else {
130162
sb.append(OutputFormatter.repeat(' ', length));
131163
}
132-
sb.append(" |");
164+
if (i == row.length -1 || !continuation[i+1]) {
165+
sb.append(" |");
166+
} else {
167+
sb.append(" \\");
168+
}
133169
}
134170
if (wrap && remainder) {
135171
sb.append(OutputFormatter.NEWLINE);
136-
formatRow(sb, columnSizes, row);
172+
formatRow(sb, columnSizes, row, continuation);
137173
}
138174
return sb.toString();
139175
}

cypher-shell/src/test/java/org/neo4j/shell/prettyprint/TableOutputFormatterTest.java

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,31 @@
22

33
import org.hamcrest.CoreMatchers;
44
import org.junit.Test;
5-
import org.neo4j.driver.internal.*;
6-
import org.neo4j.driver.internal.value.*;
7-
import org.neo4j.driver.v1.*;
5+
6+
import java.util.ArrayList;
7+
import java.util.Collections;
8+
import java.util.HashMap;
9+
import java.util.LinkedHashMap;
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
import org.neo4j.driver.internal.InternalIsoDuration;
14+
import org.neo4j.driver.internal.InternalNode;
15+
import org.neo4j.driver.internal.InternalPath;
16+
import org.neo4j.driver.internal.InternalPoint2D;
17+
import org.neo4j.driver.internal.InternalPoint3D;
18+
import org.neo4j.driver.internal.InternalRecord;
19+
import org.neo4j.driver.internal.InternalRelationship;
20+
import org.neo4j.driver.internal.value.DurationValue;
21+
import org.neo4j.driver.internal.value.NodeValue;
22+
import org.neo4j.driver.internal.value.PathValue;
23+
import org.neo4j.driver.internal.value.PointValue;
24+
import org.neo4j.driver.internal.value.RelationshipValue;
25+
import org.neo4j.driver.v1.Record;
26+
import org.neo4j.driver.v1.Statement;
27+
import org.neo4j.driver.v1.StatementResult;
28+
import org.neo4j.driver.v1.Value;
29+
import org.neo4j.driver.v1.Values;
830
import org.neo4j.driver.v1.summary.ProfiledPlan;
931
import org.neo4j.driver.v1.summary.ResultSummary;
1032
import org.neo4j.driver.v1.summary.StatementType;
@@ -15,8 +37,6 @@
1537
import org.neo4j.shell.state.BoltResult;
1638
import org.neo4j.shell.state.ListBoltResult;
1739

18-
import java.util.*;
19-
2040
import static java.util.Arrays.asList;
2141
import static java.util.Collections.singletonMap;
2242
import static org.hamcrest.CoreMatchers.is;
@@ -85,11 +105,11 @@ public void prettyPrintPlanInformationWithNewlines() {
85105

86106
// THEN
87107
assertThat(actual, startsWith(String.join(NEWLINE,
88-
"+--------------------------------------------------------------------+",
89-
"| Plan | Statement | Version | Planner | Runtime | Time |",
90-
"+--------------------------------------------------------------------+",
91-
"| \"EXPLAIN\" | \"READ_ONLY\" | \"3.1\" | \"COST\" | \"INTERPRETED\" | 12 |",
92-
"+--------------------------------------------------------------------+",
108+
"+-----------------------------------------------------------------------------------+",
109+
"| Plan | Statement | Version | Planner | Runtime | Time |",
110+
"+-----------------------------------------------------------------------------------+",
111+
"| \"EXPLAIN\" | \"READ_ONLY\" | \"3.1\" | \"COST\" | \"INTERPRETED\" | 12 |",
112+
"+-----------------------------------------------------------------------------------+",
93113
NEWLINE)));
94114
}
95115

@@ -283,8 +303,8 @@ public void basicTable() {
283303
// WHEN
284304
String table = formatResult(result);
285305
// THEN
286-
assertThat(table, containsString("| c1 | c2 |"));
287-
assertThat(table, containsString("| \"a\" | 42 |"));
306+
assertThat(table, containsString("| c1 | c2 |"));
307+
assertThat(table, containsString("| \"a\" | 42 |"));
288308
}
289309

290310
@Test
@@ -294,12 +314,12 @@ public void twoRows() {
294314
// WHEN
295315
String table = formatResult(result);
296316
// THEN
297-
assertThat(table, containsString("| \"a\" | 42 |"));
298-
assertThat(table, containsString("| \"b\" | 43 |"));
317+
assertThat(table, containsString("| \"a\" | 42 |"));
318+
assertThat(table, containsString("| \"b\" | 43 |"));
299319
}
300320

301321
@Test
302-
public void wrapContent()
322+
public void wrapStringContent()
303323
{
304324
// GIVEN
305325
StatementResult result = mockResult( asList( "c1"), "a", "bb","ccc","dddd","eeeee" );
@@ -315,15 +335,74 @@ public void wrapContent()
315335
"| \"a\" |",
316336
"| \"bb\" |",
317337
"| \"ccc |",
318-
"| \" |",
338+
"\\ \" |",
319339
"| \"ddd |",
320-
"| d\" |",
340+
"\\ d\" |",
321341
"| \"eee |",
322-
"| ee\" |",
342+
"\\ ee\" |",
323343
"+------+",
324344
NEWLINE)));
325345
}
326346

347+
@Test
348+
public void wrapStringContentWithTwoColumns()
349+
{
350+
// GIVEN
351+
StatementResult result = mockResult( asList( "c1", "c2" ), "a", "b",
352+
"aa", "bb",
353+
"aaa", "b",
354+
"a", "bbb",
355+
"aaaa", "bb",
356+
"aa", "bbbb",
357+
"aaaaa", "bbbbb" );
358+
// WHEN
359+
ToStringLinePrinter printer = new ToStringLinePrinter();
360+
new TableOutputFormatter(true, 2).formatAndCount(new ListBoltResult(result.list(), result.summary()), printer);
361+
String table = printer.result();
362+
// THEN
363+
assertThat(table, is(String.join(NEWLINE,
364+
"+-------------+",
365+
"| c1 | c2 |",
366+
"+-------------+",
367+
"| \"a\" | \"b\" |",
368+
"| \"aa\" | \"bb\" |",
369+
"| \"aaa | \"b\" |",
370+
"\\ \" | |",
371+
"| \"a\" | \"bbb |",
372+
"| \\ \" |",
373+
"| \"aaa | \"bb\" |",
374+
"\\ a\" | |",
375+
"| \"aa\" | \"bbb |",
376+
"| \\ b\" |",
377+
"| \"aaa | \"bbb |",
378+
"\\ aa\" \\ bb\" |",
379+
"+-------------+",
380+
NEWLINE)));
381+
}
382+
383+
@Test
384+
public void wrapNumberContentWithLongSize()
385+
{
386+
// GIVEN
387+
StatementResult result = mockResult( asList( "c1"), 345, 12, 978623, 132456798, 9223372036854775807L );
388+
// WHEN
389+
ToStringLinePrinter printer = new ToStringLinePrinter();
390+
new TableOutputFormatter(true, 2).formatAndCount(new ListBoltResult(result.list(), result.summary()), printer);
391+
String table = printer.result();
392+
// THEN
393+
assertThat(table, is(String.join(NEWLINE,
394+
"+---------------------+",
395+
"| c1 |",
396+
"+---------------------+",
397+
"| 345 |",
398+
"| 12 |",
399+
"| 978623 |",
400+
"| 132456798 |",
401+
"| 9223372036854775807 |",
402+
"+---------------------+",
403+
NEWLINE)));
404+
}
405+
327406
@Test
328407
public void truncateContent()
329408
{

0 commit comments

Comments
 (0)