Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ This release also includes changes from <<release-3-7-XXX, 3.7.XXX>>.
* Renamed `MergeElementStep` to `MergeElementStep` as it is a base class to `mergeV()` and `mergeE()`.
* Renamed `MergeStep` of `merge()` to `MergeElementStep` for consistency.
* Modified `RepeatUnrollStrategy` to use a more conservative approach, only unrolling repeat loops containing safe navigation and filtering steps.
* Added `splitByElement()` in `gremlin-test` for parsing nested list and set

== TinkerPop 3.7.0 (Gremfir Master of the Pan Flute)

Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do other GLVs need a similar change? For example the parsing logic for lists and sets in feature-steps.js and feature_steps.py.

Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public final class StepDefinition {
private List<Pair<Pattern, Function<String,Object>>> objectMatcherConverters = new ArrayList<Pair<Pattern, Function<String,Object>>>() {{
// expects json so that should port to the Gremlin script form - replace curly json braces with square ones
// for Gremlin sake.
add(Pair.with(Pattern.compile("m\\[(.*)\\]"), s -> {
add(Pair.with(Pattern.compile("^m\\[(.*)\\]$"), s -> {
try {
// read tree from JSON - can't parse right to Map as each m[] level needs to be managed individually
return convertToObject(mapper.readTree(s));
Expand All @@ -193,16 +193,14 @@ public final class StepDefinition {
}
}));

add(Pair.with(Pattern.compile("l\\[\\]"), s -> Collections.emptyList()));
add(Pair.with(Pattern.compile("l\\[(.*)\\]"), s -> {
final String[] items = s.split(",");
return Stream.of(items).map(String::trim).map(x -> convertToObject(x)).collect(Collectors.toList());
add(Pair.with(Pattern.compile("^l\\[\\]$"), s -> Collections.emptyList()));
add(Pair.with(Pattern.compile("^l\\[(.*)\\]$"), s -> {
return splitByElement(s).stream().map(x -> convertToObject(x)).collect(Collectors.toList());
}));

add(Pair.with(Pattern.compile("s\\[\\]"), s -> Collections.emptySet()));
add(Pair.with(Pattern.compile("s\\[(.*)\\]"), s -> {
final String[] items = s.split(",");
return Stream.of(items).map(String::trim).map(x -> convertToObject(x)).collect(Collectors.toSet());
add(Pair.with(Pattern.compile("^s\\[\\]$"), s -> Collections.emptySet()));
add(Pair.with(Pattern.compile("^s\\[(.*)\\]$"), s -> {
return splitByElement(s).stream().map(x -> convertToObject(x)).collect(Collectors.toSet());
}));

// return the string values as is, used to wrap results that may contain other regex patterns
Expand Down Expand Up @@ -642,6 +640,27 @@ private String convertToString(final String pkey, final String pvalue) {
return String.format("\"%s\"", pvalue);
}

private List<String> splitByElement(String s) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add a scenario to a feature test would would execute this new logic. Perhaps adding a scenario to the Fold.feature which does something like g.V().fold().fold() which will result in a list of lists?

if (s.trim().isEmpty()) return Collections.emptyList();

List<String> items = new ArrayList<>();
int depth = 0, start = 0;

for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '[' || c == '{') depth++;
else if (c == ']' || c == '}') depth--;
else if (c == ',' && depth == 0) {
String item = s.substring(start, i).trim();
if (!item.isEmpty()) items.add(item);
start = i + 1;
}
}
String lastItem = s.substring(start).trim();
if (!lastItem.isEmpty()) items.add(lastItem);
return items;
}

private Object convertToObject(final Object pvalue) {
final Object v;
// we may get some json stuff if it's a m[]
Expand Down