8000 #80 allow collections from queries · aburmeis/spring-data@746bf11 · GitHub
[go: up one dir, main page]

Skip to content

Commit 746bf11

Browse files
committed
arangodb#80 allow collections from queries
1 parent 994030e commit 746bf11

File tree

6 files changed

+89
-40
lines changed

6 files changed

+89
-40
lines changed

src/main/java/com/arangodb/springframework/repository/ArangoRepositoryFactory.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.lang.reflect.Method;
2424
import java.util.Optional;
2525

26+
import com.arangodb.springframework.repository.query.QueryTransactionBridge;
2627
import org.springframework.context.ApplicationContext;
2728
import org.springframework.data.mapping.context.MappingContext;
2829
import org.springframework.data.projection.ProjectionFactory;
@@ -58,11 +59,13 @@
5859
public class ArangoRepositoryFactory extends RepositoryFactorySupport {
5960

6061
private final ArangoOperations arangoOperations;
62+
private final QueryTransactionBridge transactionBridge;
6163
private final ApplicationContext applicationContext;
6264
private final MappingContext<? extends ArangoPersistentEntity<?>, ArangoPersistentProperty> context;
6365

64-
public ArangoRepositoryFactory(final ArangoOperations arangoOperations, final ApplicationContext applicationContext) {
66+
public ArangoRepositoryFactory(final ArangoOperations arangoOperations, final QueryTransactionBridge transactionBridge, final ApplicationContext applicationContext) {
6567
this.arangoOperations = arangoOperations;
68+
this.transactionBridge = transactionBridge;
6669
this.applicationContext = applicationContext;
6770
this.context = arangoOperations.getConverter().getMappingContext();
6871
}
@@ -101,7 +104,7 @@ protected Optional<QueryLookupStrategy> getQueryLookupStrategy(
101104
QueryLookupStrategy strategy = null;
102105
switch (key) {
103106
case CREATE_IF_NOT_FOUND:
104-
strategy = new DefaultArangoQueryLookupStrategy(arangoOperations, applicationContext);
107+
strategy = new DefaultArangoQueryLookupStrategy(arangoOperations, transactionBridge, applicationContext);
105108
break;
106109
case CREATE:
107110
break;
@@ -115,11 +118,13 @@ static class DefaultArangoQueryLookupStrategy implements QueryLookupStrategy {
115118

116119
private final ArangoOperations operations;
117120
private final ApplicationContext applicationContext;
121+
private final QueryTransactionBridge transactionBridge;
118122

119123
public DefaultArangoQueryLookupStrategy(final ArangoOperations operations,
120-
final ApplicationContext applicationContext) {
124+
final QueryTransactionBridge transactionBridge, final ApplicationContext applicationContext) {
121125
this.operations = operations;
122126
this.applicationContext = applicationContext;
127+
this.transactionBridge = transactionBridge;
123128
}
124129

125130
@Override
@@ -134,11 +139,11 @@ public RepositoryQuery resolveQuery(
134139

135140
if (namedQueries.hasQuery(namedQueryName)) {
136141
final String namedQuery = namedQueries.getQuery(namedQueryName);
137-
return new StringBasedArangoQuery(namedQuery, queryMethod, operations, applicationContext);
142+
return new StringBasedArangoQuery(namedQuery, queryMethod, operations, transactionBridge, applicationContext);
138143
} else if (queryMethod.hasAnnotatedQuery()) {
139-
return new StringBasedArangoQuery(queryMethod, operations, applicationContext);
144+
return new StringBasedArangoQuery(queryMethod, operations, transactionBridge, applicationContext);
140145
} else {
141-
return new DerivedArangoQuery(queryMethod, operations);
146+
return new DerivedArangoQuery(queryMethod, operations, transactionBridge);
142147
}
143148
}
144149

src/main/java/com/arangodb/springframework/repository/ArangoRepositoryFactoryBean.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.arangodb.springframework.repository;
2222

23+
import com.arangodb.springframework.repository.query.QueryTransactionBridge;
2324
import org.springframework.beans.BeansException;
2425
import org.springframework.beans.factory.annotation.Autowired;
2526
import org.springframework.context.ApplicationContext;
@@ -38,6 +39,7 @@ public class ArangoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID>
3839
extends RepositoryFactoryBeanSupport<T, S, ID> implements ApplicationContextAware {
3940

4041
private ArangoOperations arangoOperations;
42+
private QueryTransactionBridge transactionBridge;
4143
private ApplicationContext applicationContext;
4244

4345
@Autowired
@@ -50,10 +52,15 @@ public void setArangoOperations(final ArangoOperations arangoOperations) {
5052
this.arangoOperations = arangoOperations;
5153
}
5254

55+
@Autowired
56+
public void setArangoOperations(final QueryTransactionBridge transactionBridge) {
57+
this.transactionBridge = transactionBridge;
58+
}
59+
5360
@Override
5461
protected RepositoryFactorySupport createRepositoryFactory() {
5562
Assert.notNull(arangoOperations, "arangoOperations not configured");
56-
return new ArangoRepositoryFactory(arangoOperations, applicationContext);
63+
return new ArangoRepositoryFactory(arangoOperations, transactionBridge, applicationContext);
5764
}
5865

5966
@Override

src/main/java/com/arangodb/springframework/repository/query/AbstractArangoQuery.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.slf4j.LoggerFactory;
2929
import org.springframework.data.repository.query.RepositoryQuery;
3030
import org.springframework.data.repository.query.ResultProcessor;
31+
import org.springframework.data.util.Pair;
3132
import org.springframework.util.Assert;
3233

3334
import com.arangodb.ArangoCursor;
@@ -49,13 +50,17 @@ public abstract class AbstractArangoQuery implements RepositoryQuery {
4950
protected final ArangoQueryMethod method;
5051
protected final ArangoOperations operations;
5152
protected final Class<?> domainClass;
53+
private final QueryTransactionBridge transactionBridge;
5254

53-
public AbstractArangoQuery(final ArangoQueryMethod method, final ArangoOperations operations) {
55+
public AbstractArangoQuery(final ArangoQueryMethod method, final ArangoOperations operations,
56+
final QueryTransactionBridge transactionBridge) {
5457
Assert.notNull(method, "ArangoQueryMethod must not be null!");
5558
Assert.notNull(operations, "ArangoOperations must not be null!");
59+
Assert.notNull(transactionBridge, "QueryTransactionBridge must not be null!");
5660
this.method = method;
5761
this.operations = operations;
5862
this.domainClass = method.getEntityInformation().getJavaType();
63+
this.transactionBridge = transactionBridge;
5964
}
6065

6166
@Override
@@ -72,12 +77,16 @@ public Object execute(final Object[] parameters) {
7277
options.fullCount(true);
7378
}
7479

75-
final String query = createQuery(accessor, bindVars, options);
80+
final Pair<String, ? extends Collection<String>> queryAndCollection = createQuery(accessor, bindVars);
81+
if (options.getStreamTransactionId() == null) {
82+
options.streamTransactionId(transactionBridge.beginCurrentTransaction(queryAndCollection.getSecond()));
83+
}
84+
7685

7786
final ResultProcessor processor = method.getResultProcessor().withDynamicProjection(accessor);
7887
final Class<?> typeToRead = getTypeToRead(processor);
7988

80-
final ArangoCursor<?> result = operations.query(query, bindVars, options, typeToRead);
89+
final ArangoCursor<?> result = operations.query(queryAndCollection.getFirst(), bindVars, options, typeToRead);
8190
logWarningsIfNecessary(result);
8291
return processor.processResult(convertResult(result, accessor));
8392
}
@@ -102,14 +111,11 @@ public ArangoQueryMethod getQueryMethod() {
102111
* provides access to the actual arguments
103112
* @param bindVars
104113
* the binding parameter map
105-
* @param options
106-
* contains the merged {@link com.arangodb.model.AqlQueryOptions}
107-
* @return the created AQL query
114+
* @return a pair of the created AQL query and all collection names
108115
*/
109-
protected abstract String createQuery(
110-
ArangoParameterAccessor accessor,
111-
Map<String, Object> bindVars,
112-
AqlQueryOptions options);
116+
protected abstract Pair<String, ? extends Collection<String>> createQuery(
117+
ArangoParameterAccessor accessor,
118+
Map<String, Object> bindVars);
113119

114120
protected abstract boolean isCountQuery();
115121

@@ -161,6 +167,10 @@ protected AqlQueryOptions mergeQueryOptions(final AqlQueryOptions oldStatic, fin
161167
if (rules != null) {
162168
oldStatic.rules(rules);
163169
}
170+
final String streamTransactionId = newDynamic.getStreamTransactionId();
171+
if (streamTransactionId != null) {
172+
oldStatic.streamTransactionId(streamTransactionId);
173+
}
164174
return oldStatic;
165175
}
166176

src/main/java/com/arangodb/springframework/repository/query/DerivedArangoQuery.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.arangodb.springframework.repository.query;
2222

23+
import java.util.Collection;
2324
import java.util.LinkedList;
2425
import java.util.List;
2526
import java.util.Map;
@@ -29,12 +30,12 @@
2930

3031
import com.arangodb.entity.IndexEntity;
3132
import com.arangodb.entity.IndexType;
32-
import com.arangodb.model.AqlQueryOptions;
3333
import com.arangodb.springframework.core.ArangoOperations;
3434
import com.arangodb.springframework.core.mapping.ArangoPersistentEntity;
3535
import com.arangodb.springframework.core.mapping.ArangoPersistentProperty;
3636
import com.arangodb.springframework.repository.query.derived.BindParameterBinding;
3737
import com.arangodb.springframework.repository.query.derived.DerivedQueryCreator;
38+
import org.springframework.data.util.Pair;
3839

3940
/**
4041
*
@@ -49,18 +50,18 @@ public class DerivedArangoQuery extends AbstractArangoQuery {
4950
private final MappingContext<? extends ArangoPersistentEntity<?>, ArangoPersistentProperty> context;
5051
private final List<String> geoFields;
5152

52-
public DerivedArangoQuery(final ArangoQueryMethod method, final ArangoOperations operations) {
53-
super(method, operations);
53+
public DerivedArangoQuery(final ArangoQueryMethod method, final ArangoOperations operations,
54+
final QueryTransactionBridge transactionBridge) {
55+
super(method, operations, transactionBridge);
5456
tree = new PartTree(method.getName(), domainClass);
5557
< F438 span class=pl-s1>context = operations.getConverter().getMappingContext();
5658
geoFields = getGeoFields();
5759
}
5860

5961
@Override
60-
protected String createQuery(
61-
final ArangoParameterAccessor accessor,
62-
final Map<String, Object> bindVars,
63-
final AqlQueryOptions options) {
62+
protected Pair<String, ? extends Collection<String>> createQuery(
63+
final ArangoParameterAccessor accessor,
64+
final Map<String, Object> bindVars) {
6465

6566
return new DerivedQueryCreator(context, domainClass, tree, accessor, new BindParameterBinding(bindVars),
6667
geoFields).createQuery();

src/main/java/com/arangodb/springframework/repository/query/StringBasedArangoQuery.java

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,23 @@
2020

2121
package com.arangodb.springframework.repository.query;
2222

23-
import java.util.HashSet;
24-
import java.util.Map;
25-
import java.util.Set;
23+
import java.util.*;
2624
import java.util.regex.Matcher;
2725
import java.util.regex.Pattern;
2826

27+
import com.arangodb.springframework.annotation.Document;
28+
import com.arangodb.springframework.annotation.Edge;
2929
import org.springframework.context.ApplicationContext;
3030
import org.springframework.context.expression.BeanFactoryAccessor;
3131
import org.springframework.context.expression.BeanFactoryResolver;
32+
import org.springframework.core.annotation.AnnotationUtils;
33+
import org.springframework.data.util.Pair;
3234
import org.springframework.expression.Expression;
3335
import org.springframework.expression.ParserContext;
3436
import org.springframework.expression.spel.standard.SpelExpressionParser;
3537
import org.springframework.expression.spel.support.StandardEvaluationContext;
3638
import org.springframework.util.Assert;
3739

38-
import com.arangodb.model.AqlQueryOptions;
3940
import com.arangodb.springframework.core.ArangoOperations;
4041
import com.arangodb.springframework.core.util.AqlUtils;
4142
import com.arangodb.springframework.repository.query.ArangoParameters.ArangoParameter;
@@ -70,13 +71,14 @@ public class StringBasedArangoQuery extends AbstractArangoQuery {
7071
private final Set<String> queryBindParams;
7172

7273
public StringBasedArangoQuery(final ArangoQueryMethod method, final ArangoOperations operations,
73-
final ApplicationContext applicationContext) {
74-
this(method.getAnnotatedQuery(), method, operations, applicationContext);
74+
final QueryTransactionBridge transactionBridge, final ApplicationContext applicationContext) {
75+
this(method.getAnnotatedQuery(), method, operations, transactionBridge, applicationContext);
7576
}
7677

7778
public StringBasedArangoQuery(final String query, final ArangoQueryMethod method,
78-
final ArangoOperations operations, final ApplicationContext applicationContext) {
79-
super(method, operations);
79+
final ArangoOperations operations, final QueryTransactionBridge transactionBridge,
80+
final ApplicationContext applicationContext) {
81+
super(method, operations, transactionBridge);
8082
Assert.notNull(query, "Query must not be null!");
8183

8284
this.query = query;
@@ -96,14 +98,37 @@ public StringBasedArangoQuery(final String query, final ArangoQueryMethod method
9698
}
9799

98100
@Override
99-
protected String createQuery(
100-
final ArangoParameterAccessor accessor,
101-
final Map<String, Object> bindVars,
102-
final AqlQueryOptions options) {
101+
protected Pair<String, ? extends Collection<String>> createQuery(
102+
final ArangoParameterAccessor accessor,
103+
final Map<String, Object> bindVars) {
103104

104105
extractBindVars(accessor, bindVars);
105106

106-
return prepareQuery(accessor);
107+
return Pair.of(prepareQuery(accessor), allCollectionNames(collectionName, bindVars));
108+
}
109+
110+
private Collection<String> allCollectionNames(String collectionName, Map<String, Object> bindVars) {
111+
HashSet<String> allCollections = new HashSet<>();
112+
allCollections.add(collectionName);
113+
bindVars.entrySet().stream()
114+
.filter(entry -> entry.getKey().startsWith("@"))
115+
.map(Map.Entry::getValue)
116+
.map(value -> value instanceof Class ? getCollectionName((Class<?>) value): value.toString())
117+
.filter(Objects::nonNull)
118+
.forEach(allCollections::add);
119+
return allCollections;
120+
}
121+
122+
private String getCollectionName(Class<?> value) {
123+
Document document = AnnotationUtils.findAnnotation(value, Document.class);
124+
if (document != null) {
125+
return document.value();
126+
}
127+
Edge edge = AnnotationUtils.findAnnotation(value, Edge.class);
128+
if (edge != null) {
129+
return edge.value();
130+
}
131+
return null;
107132
}
108133

109134
@Override

src/main/java/com/arangodb/springframework/repository/query/derived/DerivedQueryCreator.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
4141
import org.springframework.data.repository.query.parser.Part;
4242
import org.springframework.data.repository.query.parser.PartTree;
43+
import org.springframework.data.util.Pair;
4344
import org.springframework.util.Assert;
4445

4546
import com.arangodb.springframework.annotation.Relations;
@@ -52,7 +53,7 @@
5253
/**
5354
* Creates a full AQL query from a PartTree and ArangoParameterAccessor
5455
*/
55-
public class DerivedQueryCreator extends AbstractQueryCreator<String, Criteria> {
56+
public class DerivedQueryCreator extends AbstractQueryCreator<Pair<String, ? extends Collection<String>>, Criteria> {
5657

5758
private static final Logger LOGGER = LoggerFactory.getLogger(DerivedQueryCreator.class);
5859
private static final Set<Part.Type> UNSUPPORTED_IGNORE_CASE = new HashSet<>();
@@ -120,7 +121,7 @@ protected Criteria or(final Criteria base, final Criteria criteria) {
120121
* @return
121122
*/
122123
@Override
123-
protected String complete(final Criteria criteria, final Sort sort) {
124+
protected Pair<String, ? extends Collection<String>> complete(final Criteria criteria, final Sort sort) {
124125
if (tree.isDistinct() && !tree.isCountProjection()) {
125126
LOGGER.debug("Use of 'Distinct' is meaningful only in count queries");
126127
}
@@ -191,7 +192,7 @@ protected String complete(final Criteria criteria, final Sort sort) {
191192
}
192193
}
193194
}
194-
return query.toString();
195+
return Pair.of(query.toString(), withCollections);
195196
}
196197

197198
public double[] getUniquePoint() {

0 commit comments

Comments
 (0)
0