Skip to content

Commit cad24fb

Browse files
authored
[DE-241] fix WITH clause generation in ArangoDB 3.10 (#247)
* fixed WITH clause generation in ArangoDB 3.10 * upd docker images
1 parent 9d97636 commit cad24fb

File tree

8 files changed

+70
-41
lines changed

8 files changed

+70
-41
lines changed

.github/workflows/maven.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ jobs:
2323
fail-fast: false
2424
matrix:
2525
docker-img:
26-
- docker.io/arangodb/arangodb:3.7.16
27-
- docker.io/arangodb/arangodb:3.8.4
28-
- docker.io/arangodb/arangodb-preview:3.9.0-rc.1
26+
- docker.io/arangodb/arangodb:3.7.18
27+
- docker.io/arangodb/arangodb:3.8.7
28+
- docker.io/arangodb/arangodb:3.9.2
29+
- docker.io/arangodb/arangodb-preview:3.10.0-alpha.1
2930
topology:
3031
- single
3132
- cluster

src/main/java/com/arangodb/springframework/core/convert/DefaultArangoConverter.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,9 @@ private <A extends Annotation> Optional<Object> readRelation(
375375
final Optional<RelationResolver<Annotation>> resolver = resolverFactory.getRelationResolver(annotation,
376376
collectionType);
377377

378+
// FIXME: discover intermediate types, in case annotation is Relations and maxDepth > 1
379+
List<TypeInformation<?>> traversedTypes = Collections.singletonList(entity.getTypeInformation());
380+
378381
if (!resolver.isPresent()) {
379382
return Optional.empty();
380383
}
@@ -383,15 +386,15 @@ else if (property.isCollectionLike()) {
383386
if (parentId == null) {
384387
return Optional.empty();
385388
}
386-
return resolver.map(res -> res.resolveMultiple(parentId, property.getTypeInformation(), annotation));
389+
return resolver.map(res -> res.resolveMultiple(parentId, property.getTypeInformation(), traversedTypes, annotation));
387390
}
388391

389392
else if (source.isString()) {
390-
return resolver.map(res -> res.resolveOne(source.getAsString(), property.getTypeInformation(), annotation));
393+
return resolver.map(res -> res.resolveOne(source.getAsString(), property.getTypeInformation(), traversedTypes, annotation));
391394
}
392395

393396
else {
394-
return resolver.map(res -> res.resolveOne(parentId, property.getTypeInformation(), annotation));
397+
return resolver.map(res -> res.resolveOne(parentId, property.getTypeInformation(), traversedTypes, annotation));
395398
}
396399

397400
}

src/main/java/com/arangodb/springframework/core/convert/resolver/DocumentFromResolver.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.arangodb.springframework.core.ArangoOperations;
2929
import com.arangodb.util.MapBuilder;
3030

31+
import java.util.Collection;
32+
3133
/**
3234
* @author Mark Vollmary
3335
* @author Christian Lechner
@@ -43,7 +45,7 @@ public DocumentFromResolver(final ArangoOperations template) {
4345
}
4446

4547
@Override
46-
public Object resolveOne(final String id, final TypeInformation<?> type, final From annotation) {
48+
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
4749
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t))
4850
: _resolveOne(id, type);
4951
}
@@ -53,7 +55,7 @@ private Object _resolveOne(final String id, final TypeInformation<?> type) {
5355
}
5456

5557
@Override
56-
public Object resolveMultiple(final String id, final TypeInformation<?> type, final From annotation) {
58+
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
5759
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveMultiple(i, t))
5860
: _resolveMultiple(id, type);
5961
}

src/main/java/com/arangodb/springframework/core/convert/resolver/DocumentToResolver.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.arangodb.springframework.core.ArangoOperations;
2929
import com.arangodb.util.MapBuilder;
3030

31+
import java.util.Collection;
32+
3133
/**
3234
* @author Mark Vollmary
3335
* @author Christian Lechner
@@ -43,7 +45,7 @@ public DocumentToResolver(final ArangoOperations template) {
4345
}
4446

4547
@Override
46-
public Object resolveOne(final String id, final TypeInformation<?> type, final To annotation) {
48+
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final To annotation) {
4749
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t)) : _resolveOne(id, type);
4850
}
4951

@@ -52,7 +54,7 @@ private Object _resolveOne(final String id, final TypeInformation<?> type) {
5254
}
5355

5456
@Override
55-
public Object resolveMultiple(final String id, final TypeInformation<?> type, final To annotation) {
57+
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final To annotation) {
5658
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveMultiple(i, t))
5759
: _resolveMultiple(id, type);
5860
}

src/main/java/com/arangodb/springframework/core/convert/resolver/EdgeFromResolver.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import com.arangodb.springframework.annotation.From;
2626
import com.arangodb.springframework.core.ArangoOperations;
2727

28+
import java.util.Collection;
29+
2830
/**
2931
* @author Mark Vollmary
3032
*
@@ -39,7 +41,7 @@ public EdgeFromResolver(final ArangoOperations template) {
3941
}
4042

4143
@Override
42-
public Object resolveOne(final String id, final TypeInformation<?> type, final From annotation) {
44+
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
4345
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t)) : _resolveOne(id, type);
4446
}
4547

@@ -48,7 +50,7 @@ private Object _resolveOne(final String id, final TypeInformation<?> type) {
4850
}
4951

5052
@Override
51-
public Object resolveMultiple(final String id, final TypeInformation<?> type, final From annotation) {
53+
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
5254
throw new UnsupportedOperationException("Edges with multiple 'from' values are not supported.");
5355
}
5456

src/main/java/com/arangodb/springframework/core/convert/resolver/EdgeToResolver.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import com.arangodb.springframework.annotation.To;
2626
import com.arangodb.springframework.core.ArangoOperations;
2727

28+
import java.util.Collection;
29+
2830
/**
2931
* @author Mark Vollmary
3032
*
@@ -39,7 +41,7 @@ public EdgeToResolver(final ArangoOperations template) {
3941
}
4042

4143
@Override
42-
public Object resolveOne(final String id, final TypeInformation<?> type, final To annotation) {
44+
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final To annotation) {
4345
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t)) : _resolveOne(id, type);
4446
}
4547

@@ -48,7 +50,7 @@ private Object _resolveOne(final String id, final TypeInformation<?> type) {
4850
}
4951

5052
@Override
51-
public Object resolveMultiple(final String id, final TypeInformation<?> type, final To annotation) {
53+
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final To annotation) {
5254
throw new UnsupportedOperationException("Edges with multiple 'to' values are not supported.");
5355
}
5456

src/main/java/com/arangodb/springframework/core/convert/resolver/RelationResolver.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
package com.arangodb.springframework.core.convert.resolver;
2222

2323
import java.lang.annotation.Annotation;
24+
import java.util.Collection;
2425

2526
import org.springframework.data.util.TypeInformation;
2627

@@ -30,8 +31,8 @@
3031
*/
3132
public interface RelationResolver<A extends Annotation> {
3233

33-
Object resolveOne(String id, TypeInformation<?> type, A annotation);
34+
Object resolveOne(String id, TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, A annotation);
3435

35-
Object resolveMultiple(String id, TypeInformation<?> type, A annotation);
36+
Object resolveMultiple(String id, TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, A annotation);
3637

3738
}

src/main/java/com/arangodb/springframework/core/convert/resolver/RelationsResolver.java

+41-25
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020

2121
package com.arangodb.springframework.core.convert.resolver;
2222

23-
import java.util.Arrays;
24-
import java.util.Map;
23+
import java.util.*;
2524
import java.util.stream.Collectors;
2625

2726
import org.springframework.data.util.TypeInformation;
@@ -46,48 +45,65 @@ public RelationsResolver(final ArangoOperations template) {
4645
}
4746

4847
@Override
49-
public Object resolveOne(final String id, final TypeInformation<?> type, final Relations annotation) {
50-
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t, a))
51-
: _resolveOne(id, type, annotation);
48+
public Object resolveOne(final String id, final TypeInformation<?> type, final Collection<TypeInformation<?>> traversedTypes, final Relations annotation) {
49+
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t, traversedTypes, a))
50+
: _resolveOne(id, type, traversedTypes, annotation);
5251
}
5352

5453
@Override
55-
public Object resolveMultiple(final String id, final TypeInformation<?> type, final Relations annotation) {
56-
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveMultiple(i, t, a))
57-
: _resolveMultiple(id, type, annotation);
54+
public Object resolveMultiple(final String id, final TypeInformation<?> type, final Collection<TypeInformation<?>> traversedTypes, final Relations annotation) {
55+
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveMultiple(i, t, traversedTypes, a))
56+
: _resolveMultiple(id, type, traversedTypes, annotation);
5857
}
5958

60-
private Object _resolveOne(final String id, final TypeInformation<?> type, final Relations annotation) {
61-
return _resolve(id, type.getType(), annotation, true).first();
59+
private Object _resolveOne(final String id, final TypeInformation<?> type, final Collection<TypeInformation<?>> traversedTypes, final Relations annotation) {
60+
Collection<Class<?>> rawTypes = new ArrayList<>();
61+
for (TypeInformation<?> it : traversedTypes) {
62+
rawTypes.add(it.getType());
63+
}
64+
return _resolve(id, type.getType(), rawTypes, annotation, true).first();
6265
}
6366

64-
private Object _resolveMultiple(final String id, final TypeInformation<?> type, final Relations annotation) {
65-
return _resolve(id, getNonNullComponentType(type).getType(), annotation, false).asListRemaining();
67+
private Object _resolveMultiple(final String id, final TypeInformation<?> type, final Collection<TypeInformation<?>> traversedTypes, final Relations annotation) {
68+
Collection<Class<?>> rawTypes = new ArrayList<>();
69+
for (TypeInformation<?> it : traversedTypes) {
70+
rawTypes.add(it.getType());
71+
}
72+
return _resolve(id, getNonNullComponentType(type).getType(), rawTypes, annotation, false).asListRemaining();
6673
}
6774

6875
private ArangoCursor<?> _resolve(
6976
final String id,
7077
final Class<?> type,
78+
final Collection<Class<?>> traversedTypes,
7179
final Relations annotation,
7280
final boolean limit) {
7381

7482
final String edges = Arrays.stream(annotation.edges()).map(e -> template.collection(e).name())
7583
.collect(Collectors.joining(","));
7684

85+
List<Class<?>> allTraversedTypes = new ArrayList<>();
86+
allTraversedTypes.add(type);
87+
allTraversedTypes.addAll(traversedTypes);
88+
89+
MapBuilder bindVars = new MapBuilder().put("start", id);
90+
StringBuilder withClause = new StringBuilder("WITH ");
91+
for (int i = 0; i < allTraversedTypes.size(); i++) {
92+
bindVars.put("@with" + i, allTraversedTypes.get(i));
93+
if (i > 0) withClause.append(", ");
94+
withClause.append("@@with").append(i);
95+
}
96+
7797
final String query = String.format(
78-
"WITH @@vertex FOR v IN %d .. %d %s @start %s OPTIONS {bfs: true, uniqueVertices: \"global\"} %s RETURN v", //
79-
Math.max(1, annotation.minDepth()), //
80-
Math.max(1, annotation.maxDepth()), //
81-
annotation.direction(), //
82-
edges, //
83-
limit ? "LIMIT 1" : "");
84-
85-
final Map<String, Object> bindVars = new MapBuilder()//
86-
.put("start", id) //
87-
.put("@vertex", type) //
88-
.get();
89-
90-
return template.query(query, bindVars, type);
98+
"%s FOR v IN %d .. %d %s @start %s OPTIONS {bfs: true, uniqueVertices: \"global\"} %s RETURN v", //
99+
withClause, //
100+
Math.max(1, annotation.minDepth()), //
101+
Math.max(1, annotation.maxDepth()), //
102+
annotation.direction(), //
103+
edges, //
104+
limit ? "LIMIT 1" : "");
105+
106+
return template.query(query, bindVars.get(), type);
91107
}
92108

93109
}

0 commit comments

Comments
 (0)