Skip to content

Commit

Permalink
Refactor range predicates to share base class
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Mar 13, 2018
1 parent 9d73157 commit a6d5269
Show file tree
Hide file tree
Showing 22 changed files with 286 additions and 414 deletions.
Expand Up @@ -25,14 +25,16 @@
import org.apache.commons.lang3.builder.ToStringStyle;

import org.neo4j.values.storable.CoordinateReferenceSystem;
import org.neo4j.values.storable.LongValue;
import org.neo4j.values.storable.NumberValue;
import org.neo4j.values.storable.PointValue;
import org.neo4j.values.storable.TextValue;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup;
import org.neo4j.values.storable.ValueTuple;
import org.neo4j.values.storable.Values;

import static org.neo4j.values.storable.Values.NO_VALUE;

public abstract class IndexQuery
{
/**
Expand Down Expand Up @@ -68,10 +70,12 @@ public static ExactPredicate exact( int propertyKeyId, Object value )
* @param toInclusive the upper bound is inclusive if true.
* @return an {@link IndexQuery} instance to be used for querying an index.
*/
public static NumberRangePredicate range( int propertyKeyId, Number from, boolean fromInclusive, Number to,
boolean toInclusive )
public static RangePredicate range( int propertyKeyId, Number from, boolean fromInclusive,
Number to, boolean toInclusive )
{
return new NumberRangePredicate( propertyKeyId, from, fromInclusive, to, toInclusive );
return new NumberRangePredicate( propertyKeyId,
from == null ? null : Values.numberValue( from ), fromInclusive,
to == null ? null : Values.numberValue( to ), toInclusive );
}

/**
Expand All @@ -84,8 +88,8 @@ public static NumberRangePredicate range( int propertyKeyId, Number from, boolea
* @param toInclusive the upper bound is inclusive if true.
* @return an {@link IndexQuery} instance to be used for querying an index.
*/
public static GeometryRangePredicate range( int propertyKeyId, PointValue from, boolean fromInclusive, PointValue to,
boolean toInclusive )
public static RangePredicate range( int propertyKeyId, PointValue from, boolean fromInclusive,
PointValue to, boolean toInclusive )
{
return new GeometryRangePredicate( propertyKeyId, from, fromInclusive, to, toInclusive );
}
Expand All @@ -100,10 +104,12 @@ public static GeometryRangePredicate range( int propertyKeyId, PointValue from,
* @param toInclusive the upper bound is inclusive if true.
* @return an {@link IndexQuery} instance to be used for querying an index.
*/
public static StringRangePredicate range( int propertyKeyId, String from, boolean fromInclusive, String to,
boolean toInclusive )
public static RangePredicate range( int propertyKeyId, String from, boolean fromInclusive,
String to, boolean toInclusive )
{
return new StringRangePredicate( propertyKeyId, from, fromInclusive, to, toInclusive );
return new TextRangePredicate( propertyKeyId,
from == null ? null : Values.stringValue( from ), fromInclusive,
to == null ? null : Values.stringValue( to ), toInclusive );
}

/**
Expand Down Expand Up @@ -204,9 +210,7 @@ public enum IndexQueryType
{
exists,
exact,
rangeString,
rangeNumeric,
rangeGeometric,
range,
stringPrefix,
stringSuffix,
stringContains
Expand All @@ -228,7 +232,7 @@ public IndexQueryType type()
@Override
public boolean acceptsValue( Value value )
{
return value != null && value != Values.NO_VALUE;
return value != null && value != NO_VALUE;
}

@Override
Expand Down Expand Up @@ -278,46 +282,50 @@ public Value value()
}
}

public static final class NumberRangePredicate extends IndexQuery
public static class RangePredicate<T extends Value> extends IndexQuery
{
private final Value from;
private final boolean fromInclusive;
private final Value to;
private final boolean toInclusive;
protected final T from;
protected final boolean fromInclusive;
protected final T to;
protected final boolean toInclusive;
protected final ValueGroup valueGroup;

NumberRangePredicate( int propertyKeyId, Number from, boolean fromInclusive, Number to, boolean toInclusive )
RangePredicate( int propertyKeyId, ValueGroup valueGroup,
T from, boolean fromInclusive,
T to, boolean toInclusive )
{
super( propertyKeyId );
this.from = Values.numberValue( from );
this.valueGroup = valueGroup;
this.from = from;
this.fromInclusive = fromInclusive;
this.to = Values.numberValue( to );
this.to = to;
this.toInclusive = toInclusive;
}

@Override
public IndexQueryType type()
{
return IndexQueryType.rangeNumeric;
return IndexQueryType.range;
}

@Override
public boolean acceptsValue( Value value )
{
if ( value == null )
if ( value == null || value == NO_VALUE )
{
return false;
}
if ( Values.isNumberValue( value ) )
if ( value.valueGroup() == valueGroup )
{
if ( from != Values.NO_VALUE )
if ( from != NO_VALUE )
{
int compare = Values.COMPARATOR.compare( value, from );
if ( compare < 0 || !fromInclusive && compare == 0 )
{
return false;
}
}
if ( to != Values.NO_VALUE )
if ( to != NO_VALUE )
{
int compare = Values.COMPARATOR.compare( value, to );
if ( compare > 0 || !toInclusive && compare == 0 )
Expand All @@ -333,27 +341,17 @@ public boolean acceptsValue( Value value )
@Override
public ValueGroup valueGroup()
{
return ValueGroup.NUMBER;
return valueGroup;
}

public Number from()
public Value fromValue()
{
return (Number)from.asObject();
}

public Number to()
{
return (Number)to.asObject();
}

public Value fromAsValue()
{
return from;
return from == null ? NO_VALUE : from;
}

public Value toAsValue()
public Value toValue()
{
return to;
return to == null ? NO_VALUE : to;
}

public boolean fromInclusive()
Expand All @@ -367,42 +365,27 @@ public boolean toInclusive()
}
}

public static final class GeometryRangePredicate extends IndexQuery
public static final class GeometryRangePredicate extends RangePredicate<PointValue>
{
private final PointValue from;
private final boolean fromInclusive;
private final PointValue to;
private final boolean toInclusive;
private final CoordinateReferenceSystem crs;

GeometryRangePredicate( int propertyKeyId, PointValue from, boolean fromInclusive, PointValue to, boolean toInclusive )
{
super( propertyKeyId );
super( propertyKeyId, ValueGroup.GEOMETRY, from, fromInclusive, to, toInclusive );
if ( from == null && to == null )
{
throw new IllegalArgumentException( "Cannot create GeometryRangePredicate without at least one bound" );
}
this.from = from;
this.fromInclusive = fromInclusive;
this.to = to;
this.toInclusive = toInclusive;
this.crs = from != null ? from.getCoordinateReferenceSystem() : to.getCoordinateReferenceSystem();
}

@Override
public IndexQueryType type()
{
return IndexQueryType.rangeGeometric;
}

@Override
public boolean acceptsValue( Value value )
{
if ( value == null )
{
return false;
}
//TODO Deal with other Geometries
if ( value instanceof PointValue )
{
PointValue point = (PointValue) value;
Expand All @@ -411,10 +394,9 @@ public boolean acceptsValue( Value value )
return false;
}

@Override
public ValueGroup valueGroup()
public CoordinateReferenceSystem crs()
{
return ValueGroup.GEOMETRY;
return crs;
}

public PointValue from()
Expand All @@ -426,117 +408,57 @@ public PointValue to()
{
return to;
}

public CoordinateReferenceSystem crs()
{
return crs;
}

public boolean fromInclusive()
{
return fromInclusive;
}

public boolean toInclusive()
{
return toInclusive;
}
}

public abstract static class StringPredicate extends IndexQuery
public static final class NumberRangePredicate extends RangePredicate<NumberValue>
{
StringPredicate( int propertyKeyId )
{
super( propertyKeyId );
}

@Override
public ValueGroup valueGroup()
NumberRangePredicate( int propertyKeyId, NumberValue from, boolean fromInclusive, NumberValue to,
boolean toInclusive )
{
return ValueGroup.TEXT;
super( propertyKeyId, ValueGroup.NUMBER, from, fromInclusive, to, toInclusive );
}
}

public static final class StringRangePredicate extends StringPredicate
{
private final Value from;
private final boolean fromInclusive;
private final Value to;
private final boolean toInclusive;

StringRangePredicate( int propertyKeyId, String from, boolean fromInclusive, String to, boolean toInclusive )
public Number from()
{
super( propertyKeyId );
this.from = Values.stringOrNoValue( from );
this.fromInclusive = fromInclusive;
this.to = Values.stringOrNoValue( to );
this.toInclusive = toInclusive;
return from == null ? null : from.asObject();
}

@Override
public IndexQueryType type()
public Number to()
{
return IndexQueryType.rangeString;
return to == null ? null : to.asObject();
}
}

@Override
public boolean acceptsValue( Value value )
public static final class TextRangePredicate extends RangePredicate<TextValue>
{
TextRangePredicate( int propertyKeyId, TextValue from, boolean fromInclusive, TextValue to,
boolean toInclusive )
{
if ( value == null )
{
return false;
}
if ( !Values.isTextValue( value ) )
{
return false;
}
if ( from != Values.NO_VALUE )
{
int compare = Values.COMPARATOR.compare( value, from );
if ( compare < 0 || !fromInclusive && compare == 0 )
{
return false;
}
}
if ( to != Values.NO_VALUE )
{
int compare = Values.COMPARATOR.compare( value, to );
if ( compare > 0 || !toInclusive && compare == 0 )
{
return false;
}
}
return true;
super( propertyKeyId, ValueGroup.TEXT, from, fromInclusive, to, toInclusive );
}

public String from()
{
return (String)from.asObject();
}

public Value fromAsValue()
{
return from;
}

public boolean fromInclusive()
{
return fromInclusive;
return from == null ? null : from.stringValue();
}

public String to()
{
return (String)to.asObject();
return to == null ? null : to.stringValue();
}
}

public Value toAsValue()
public abstract static class StringPredicate extends IndexQuery
{
StringPredicate( int propertyKeyId )
{
return to;
super( propertyKeyId );
}

public boolean toInclusive()
@Override
public ValueGroup valueGroup()
{
return toInclusive;
return ValueGroup.TEXT;
}
}

Expand Down

0 comments on commit a6d5269

Please sign in to comment.