Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Query infrastructure with Hazelcast SQL #147

Open
pivovarit opened this issue Dec 17, 2020 · 0 comments
Open

Replace Query infrastructure with Hazelcast SQL #147

pivovarit opened this issue Dec 17, 2020 · 0 comments
Assignees

Comments

@pivovarit
Copy link
Contributor

pivovarit commented Dec 17, 2020

Once SQL support is production-ready, we should remove our custom querying infrastructure and reuse what's already in Hazelcast

case ENDING_WITH:
case LIKE:
case NOT_LIKE:
return fromLikeVariant(type, ignoreCase, property, iterator);
case TRUE:
case FALSE:
return fromBooleanVariant(type, property);
case SIMPLE_PROPERTY:
case NEGATING_SIMPLE_PROPERTY:
return fromEqualityVariant(type, ignoreCase, property, iterator);
case REGEX:
return Predicates.regex(property, iterator.next().toString());
case IS_EMPTY:
case IS_NOT_EMPTY:
return fromEmptyVariant(type, property);
/* case EXISTS:*/
case NEAR:
case WITHIN:
return fromGeoVariant(type, property, iterator);
default:
throw new InvalidDataAccessApiUsageException(String.format("Unsupported type '%s'", type));
}
}
private Predicate<?, ?> fromBooleanVariant(Type type, String property) {
switch (type) {
case TRUE:
return Predicates.equal(property, true);
case FALSE:
return Predicates.equal(property, false);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromCollectionVariant(Type type, String property, Iterator<Comparable<?>> iterator) {
switch (type) {
case IN:
return Predicates.in(property, collectToArray(type, iterator));
case NOT_IN:
return Predicates.not(Predicates.in(property, collectToArray(type, iterator)));
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromInequalityVariant(Type type, String property, Iterator<Comparable<?>> iterator) {
switch (type) {
case AFTER:
case GREATER_THAN:
return Predicates.greaterThan(property, iterator.next());
case GREATER_THAN_EQUAL:
return Predicates.greaterEqual(property, iterator.next());
case BEFORE:
case LESS_THAN:
return Predicates.lessThan(property, iterator.next());
case LESS_THAN_EQUAL:
return Predicates.lessEqual(property, iterator.next());
case BETWEEN:
Comparable<?> first = iterator.next();
Comparable<?> second = iterator.next();
return Predicates.between(property, first, second);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromNullVariant(Type type, String property) {
switch (type) {
case IS_NULL:
return Predicates.equal(property, null);
case IS_NOT_NULL:
return Predicates.notEqual(property, null);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromEqualityVariant(Type type, boolean ignoreCase, String property,
Iterator<Comparable<?>> iterator) {
switch (type) {
case SIMPLE_PROPERTY:
if (ignoreCase) {
return Predicates.ilike(property, iterator.next().toString());
} else {
return Predicates.equal(property, iterator.next());
}
case NEGATING_SIMPLE_PROPERTY:
if (ignoreCase) {
return Predicates.not(Predicates.ilike(property, iterator.next().toString()));
} else {
return Predicates.notEqual(property, iterator.next());
}
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromLikeVariant(Type type, boolean ignoreCase, String property, Iterator<Comparable<?>> iterator) {
String likeExpression = iterator.next().toString();
switch (type) {
case CONTAINING:
case NOT_CONTAINING:
likeExpression = String.join("", "%", likeExpression, "%");
break;
case STARTING_WITH:
likeExpression = String.join("", likeExpression, "%");
break;
case ENDING_WITH:
likeExpression = String.join("", "%", likeExpression);
break;
case LIKE:
case NOT_LIKE:
break;
default:
throw new InvalidDataAccessApiUsageException(String.format("'%s' is not supported for LIKE style query", type));
}
Predicate likePredicate = ignoreCase ? Predicates.ilike(property, likeExpression) : Predicates
.like(property, likeExpression);
return type.equals(NOT_LIKE) || type.equals(NOT_CONTAINING) ? Predicates.not(likePredicate) : likePredicate;
}
private boolean ifIgnoreCase(Part part) {
switch (part.shouldIgnoreCase()) {
case ALWAYS:
Assert.state(canUpperCase(part.getProperty()),
String.format("Unable to ignore case of %s types, the property '%s' must reference a String",
part.getProperty().getType().getName(), part.getProperty().getSegment()));
return true;
case WHEN_POSSIBLE:
return canUpperCase(part.getProperty());
case NEVER:
default:
return false;
}
}
private boolean canUpperCase(PropertyPath path) {
return String.class.equals(path.getType());
}
private boolean isCollection(Object item) {
return Collection.class.isAssignableFrom(item.getClass());
}
private Comparable<?>[] collectToArray(Type type, Iterator<Comparable<?>> iterator) {
Object item = iterator.next();
Assert.state(isCollection(item), String.format("%s requires collection of values", type));
Collection<Comparable<?>> itemcol = (Collection<Comparable<?>>) item;
return itemcol.toArray(new Comparable<?>[0]);
}
private Predicate<?, ?> fromEmptyVariant(Type type, String property) {
switch (type) {
case IS_EMPTY:
return Predicates.equal(property, "");
case IS_NOT_EMPTY:
return Predicates.notEqual(property, "");
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}
private Predicate<?, ?> fromGeoVariant(Type type, String property, Iterator<Comparable<?>> iterator) {
final Object item = iterator.next();
Point point;
Distance distance;
if (item instanceof Point) {
point = (Point) item;
if (!iterator.hasNext()) {
throw new InvalidDataAccessApiUsageException(
"Expected to find distance value for geo query. Are you missing a parameter?");
}
Object distObject = iterator.next();
if (distObject instanceof Distance) {
distance = (Distance) distObject;
} else if (distObject instanceof Number) {
distance = new Distance(((Number) distObject).doubleValue(), Metrics.KILOMETERS);
} else {
throw new InvalidDataAccessApiUsageException(String
.format("Expected to find Distance or Numeric value for geo query but was %s.",
distObject.getClass()));
}
} else if (item instanceof Circle) {
point = ((Circle) item).getCenter();
distance = ((Circle) item).getRadius();
} else {
throw new InvalidDataAccessApiUsageException(
String.format("Expected to find a Circle or Point/Distance for geo query but was %s.", item.getClass()));
}
switch (type) {
case WITHIN:
case NEAR:
return new GeoPredicate<>(property, point, distance);
default:
throw new InvalidDataAccessApiUsageException(String.format("Logic error for '%s' in query", type));
}
}

@pivovarit pivovarit self-assigned this Dec 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant