
org.jnosql.diana.arangodb.document.QueryAQLConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of arangodb-driver Show documentation
Show all versions of arangodb-driver Show documentation
The Eclipse JNoSQL communication layer, Diana, to AranboDB
/*
* Copyright (c) 2017 Otávio Santana and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
*
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
*
* Otavio Santana
*/
package org.jnosql.diana.arangodb.document;
import org.jnosql.diana.api.Sort;
import org.jnosql.diana.api.TypeReference;
import org.jnosql.diana.api.document.Document;
import org.jnosql.diana.api.document.DocumentCondition;
import org.jnosql.diana.api.document.DocumentDeleteQuery;
import org.jnosql.diana.api.document.DocumentQuery;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
final class QueryAQLConverter {
private static final String FILTER = " FILTER ";
private static final String LIMIT = " LIMIT ";
private static final String IN = " IN ";
private static final String SORT = " SORT ";
private static final String REMOVE = " REMOVE ";
private static final String RETURN = " RETURN ";
private static final String SEPARATOR = " ";
private static final String AND = " AND ";
private static final String OR = " OR ";
private static final String EQUALS = " == ";
private static final String GREATER_EQUALS_THAN = " >= ";
private static final String GREATER_THAN = " > ";
private static final String LESSER_THAN = " < ";
private static final String LESSER_EQUALS_THAN = " <= ";
private static final String LIKE = " LIKE ";
private static final String NOT = " NOT ";
private static final char PARAM_APPENDER = '@';
private QueryAQLConverter() {
}
public static AQLQueryResult delete(DocumentDeleteQuery query) throws NullPointerException {
return convert(query.getDocumentCollection(),
query.getCondition(),
Collections.emptyList(),
0L,
0L,
REMOVE, true);
}
public static AQLQueryResult select(DocumentQuery query) throws NullPointerException {
return convert(query.getDocumentCollection(),
query.getCondition(),
query.getSorts(),
query.getSkip(),
query.getLimit(),
RETURN, false);
}
private static AQLQueryResult convert(String documentCollection,
Optional documentCondition,
List sorts,
long firstResult,
long maxResult,
String conclusion, boolean delete) {
StringBuilder aql = new StringBuilder();
Map params = new HashMap<>();
char entity = Character.toLowerCase(documentCollection.charAt(0));
aql.append("FOR ").append(entity).append(IN).append(documentCollection);
documentCondition.ifPresent(condition -> {
aql.append(FILTER);
definesCondition(condition, aql, params, entity, 0);
});
if (!sorts.isEmpty()) {
sort(sorts, aql, entity);
}
if (firstResult > 0 && maxResult > 0) {
aql.append(LIMIT).append(firstResult)
.append(", ").append(maxResult);
} else if (maxResult > 0) {
aql.append(LIMIT).append(maxResult);
}
aql.append(conclusion).append(entity);
if (delete) {
aql.append(IN).append(documentCollection);
}
return new AQLQueryResult(aql.toString(), params);
}
private static void sort(List sorts, StringBuilder aql, char entity) {
aql.append(SORT);
String separator = SEPARATOR;
for (Sort sort : sorts) {
aql.append(separator)
.append(entity).append('.')
.append(sort.getName())
.append(SEPARATOR).append(sort.getType());
separator = " , ";
}
}
private static void definesCondition(DocumentCondition condition,
StringBuilder aql,
Map params,
char entity, int counter) {
Document document = condition.getDocument();
switch (condition.getCondition()) {
case IN:
appendCondition(aql, params, entity, document, IN);
return;
case EQUALS:
appendCondition(aql, params, entity, document, EQUALS);
return;
case GREATER_EQUALS_THAN:
appendCondition(aql, params, entity, document, GREATER_EQUALS_THAN);
return;
case GREATER_THAN:
appendCondition(aql, params, entity, document, GREATER_THAN);
return;
case LESSER_THAN:
appendCondition(aql, params, entity, document, LESSER_THAN);
return;
case LESSER_EQUALS_THAN:
appendCondition(aql, params, entity, document, LESSER_EQUALS_THAN);
return;
case LIKE:
appendCondition(aql, params, entity, document, LIKE);
return;
case AND:
for (DocumentCondition dc : document.get(new TypeReference>() {
})) {
if (isFirstCondition(aql, counter)) {
aql.append(AND);
}
definesCondition(dc, aql, params, entity, ++counter);
}
return;
case OR:
for (DocumentCondition dc : document.get(new TypeReference>() {
})) {
if (isFirstCondition(aql, counter)) {
aql.append(OR);
}
definesCondition(dc, aql, params, entity, ++counter);
}
return;
case NOT:
DocumentCondition documentCondition = document.get(DocumentCondition.class);
aql.append(NOT);
definesCondition(documentCondition, aql, params, entity, ++counter);
return;
default:
throw new IllegalArgumentException("The condition does not support in AQL: " + condition.getCondition());
}
}
private static boolean isFirstCondition(StringBuilder aql, int count) {
return count > 0 && !FILTER.equals(aql.substring(aql.length() - 8));
}
private static void appendCondition(StringBuilder aql, Map params,
char entity, Document document, String condition) {
String nameParam = getNameParam(document.getName(), params);
aql.append(SEPARATOR).append(entity).append('.').append(document.getName())
.append(condition).append(PARAM_APPENDER).append(nameParam);
params.put(nameParam, document.get());
}
private static String getNameParam(String name, Map params) {
String parameter = getNameParam(name);
String paramName = parameter;
int counter = 1;
while (params.containsKey(paramName)) {
paramName = parameter + '_' + counter;
}
return paramName;
}
private static String getNameParam(String name) {
if ('_' == name.charAt(0)) {
return name.substring(1);
}
return name;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy