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

Commit 3563309

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 174e8cf commit 3563309

File tree

2 files changed

+120
-24
lines changed

2 files changed

+120
-24
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.Record;
516
import org.neo4j.driver.Value;
617
import org.neo4j.driver.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: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ public void prettyPrintPlanInformationWithNewlines() {
105105

106106
// THEN
107107
assertThat(actual, startsWith(String.join(NEWLINE,
108-
"+--------------------------------------------------------------------+",
109-
"| Plan | Statement | Version | Planner | Runtime | Time |",
110-
"+--------------------------------------------------------------------+",
111-
"| \"EXPLAIN\" | \"READ_ONLY\" | \"3.1\" | \"COST\" | \"INTERPRETED\" | 12 |",
112-
"+--------------------------------------------------------------------+",
108+
"+-----------------------------------------------------------------------------------+",
109+
"| Plan | Statement | Version | Planner | Runtime | Time |",
110+
"+-----------------------------------------------------------------------------------+",
111+
"| \"EXPLAIN\" | \"READ_ONLY\" | \"3.1\" | \"COST\" | \"INTERPRETED\" | 12 |",
112+
"+-----------------------------------------------------------------------------------+",
113113
NEWLINE)));
114114
}
115115

@@ -303,8 +303,8 @@ public void basicTable() {
303303
// WHEN
304304
String table = formatResult(result);
305305
// THEN
306-
assertThat(table, containsString("| c1 | c2 |"));
307-
assertThat(table, containsString("| \"a\" | 42 |"));
306+
assertThat(table, containsString("| c1 | c2 |"));
307+
assertThat(table, containsString("| \"a\" | 42 |"));
308308
}
309309

310310
@Test
@@ -314,12 +314,12 @@ public void twoRows() {
314314
// WHEN
315315
String table = formatResult(result);
316316
// THEN
317-
assertThat(table, containsString("| \"a\" | 42 |"));
318-
assertThat(table, containsString("| \"b\" | 43 |"));
317+
assertThat(table, containsString("| \"a\" | 42 |"));
318+
assertThat(table, containsString("| \"b\" | 43 |"));
319319
}
320320

321321
@Test
322-
public void wrapContent()
322+
public void wrapStringContent()
323323
{
324324
// GIVEN
325325
Result result = mockResult( asList( "c1"), "a", "bb","ccc","dddd","eeeee" );
@@ -335,15 +335,75 @@ public void wrapContent()
335335
"| \"a\" |",
336336
"| \"bb\" |",
337337
"| \"ccc |",
338-
"| \" |",
338+
"\\ \" |",
339339
"| \"ddd |",
340-
"| d\" |",
340+
"\\ d\" |",
341341
"| \"eee |",
342-
"| ee\" |",
342+
"\\ ee\" |",
343343
"+------+",
344344
NEWLINE)));
345345
}
346346

347+
@Test
348+
public void wrapStringContentWithTwoColumns()
349+
{
350+
// GIVEN
351+
Result 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.consume()), 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+
Result result = mockResult( asList( "c1"), 345, 12, 978623, 132456798, 9223372036854775807L );
388+
result = mockResult( asList( "c1"), 345, 12, 978623, 132456798, 9223372036854775807L );
389+
// WHEN
390+
ToStringLinePrinter printer = new ToStringLinePrinter();
391+
new TableOutputFormatter(true, 2).formatAndCount(new ListBoltResult(result.list(), result.consume()), printer);
392+
String table = printer.result();
393+
// THEN
394+
assertThat(table, is(String.join(NEWLINE,
395+
"+---------------------+",
396+
"| c1 |",
397+
"+---------------------+",
398+
"| 345 |",
399+
"| 12 |",
400+
"| 978623 |",
401+
"| 132456798 |",
402+
"| 9223372036854775807 |",
403+
"+---------------------+",
404+
NEWLINE)));
405+
}
406+
347407
@Test
348408
public void truncateContent()
349409
{

0 commit comments

Comments
 (0)