Skip to content

Commit

Permalink
Adding Temporal Array types.
Browse files Browse the repository at this point in the history
Refactoring all ArrayValue classes to not have single implementation
"Direct", but be concrete themselves.

Create class NonPrimitiveArray to capture common behavior of PointArrays,
Date/Time-Arrays and DurationArrays.
  • Loading branch information
sherfert committed Feb 2, 2018
1 parent e812bcc commit 9ab8a36
Show file tree
Hide file tree
Showing 33 changed files with 1,641 additions and 556 deletions.
Expand Up @@ -19,8 +19,7 @@
*/
package org.neo4j.cypher.internal.runtime.interpreted

import java.time.temporal.{Temporal, TemporalAmount}
import java.time.{ZoneId, ZoneOffset}
import java.time._

import org.neo4j.cypher.internal.util.v3_4.CypherTypeException
import org.neo4j.graphdb.spatial.Point
Expand Down Expand Up @@ -141,17 +140,17 @@ object CastSupport {
case _: Point => Converter(
transform(new ArrayConverterWriter(classOf[Point], a => Values.pointArray(a.asInstanceOf[Array[Point]]))))
case _: DurationValue => Converter(
transform(new ArrayConverterWriter(classOf[DurationValue], a => Values.durationArray(a.asInstanceOf[Array[TemporalAmount]]))))
transform(new ArrayConverterWriter(classOf[DurationValue], a => Values.durationArray(a.asInstanceOf[Array[DurationValue]]))))
case _: DateTimeValue => Converter(
transform(new ArrayConverterWriter(classOf[ZonedDateTime], a => Values.dateTimeArray(a.asInstanceOf[Array[ZonedDateTime]]))))
case _: DateValue => Converter(
transform(new ArrayConverterWriter(classOf[DateValue], a => Values.temporalArray(a.asInstanceOf[Array[Temporal]]))))
transform(new ArrayConverterWriter(classOf[LocalDate], a => Values.dateArray(a.asInstanceOf[Array[LocalDate]]))))
case _: LocalTimeValue => Converter(
transform(new ArrayConverterWriter(classOf[LocalTimeValue], a => Values.temporalArray(a.asInstanceOf[Array[Temporal]]))))
transform(new ArrayConverterWriter(classOf[LocalTime], a => Values.localTimeArray(a.asInstanceOf[Array[LocalTime]]))))
case _: TimeValue => Converter(
transform(new ArrayConverterWriter(classOf[TimeValue], a => Values.temporalArray(a.asInstanceOf[Array[Temporal]]))))
transform(new ArrayConverterWriter(classOf[OffsetTime], a => Values.timeArray(a.asInstanceOf[Array[OffsetTime]]))))
case _: LocalDateTimeValue => Converter(
transform(new ArrayConverterWriter(classOf[LocalDateTimeValue], a => Values.temporalArray(a.asInstanceOf[Array[Temporal]]))))
case _: DateTimeValue => Converter(
transform(new ArrayConverterWriter(classOf[DateTimeValue], a => Values.temporalArray(a.asInstanceOf[Array[Temporal]]))))
transform(new ArrayConverterWriter(classOf[LocalDateTime], a => Values.localDateTimeArray(a.asInstanceOf[Array[LocalDateTime]]))))
case _ => throw new CypherTypeException("Property values can only be of primitive types or arrays thereof")
}

Expand Down
Expand Up @@ -21,6 +21,10 @@ package org.neo4j.cypher.internal.runtime.interpreted

import org.neo4j.cypher.internal.util.v3_4.CypherTypeException
import org.neo4j.cypher.internal.util.v3_4.test_helpers.CypherFunSuite
import org.neo4j.values.storable.DurationValue.duration
import org.neo4j.values.storable.LocalTimeValue.localTime
import org.neo4j.values.storable._
import org.neo4j.values.virtual.VirtualValues

class CastSupportTest extends CypherFunSuite {

Expand Down Expand Up @@ -58,4 +62,36 @@ class CastSupportTest extends CypherFunSuite {
val given: Any = Seq(1)
intercept[CypherTypeException](CastSupport.castOrFail[Int](given))
}

test("should convert string lists to arrays") {
val valueObj = Values.stringValue("test")
val list = VirtualValues.list(valueObj)
val array = CastSupport.getConverter(valueObj).arrayConverter(list)
array shouldBe a[StringArray]
array.asInstanceOf[StringArray].asObjectCopy()(0) should equal(valueObj.asObjectCopy())
}

test("should convert point lists to arrays") {
val valueObj = Values.pointValue(CoordinateReferenceSystem.Cartesian, 0.0, 1.0)
val list = VirtualValues.list(valueObj)
val array = CastSupport.getConverter(valueObj).arrayConverter(list)
array shouldBe a[PointArray]
array.asInstanceOf[PointArray].asObjectCopy()(0) should equal(valueObj)
}

test("should convert local time lists to arrays") {
val valueObj = localTime(3, 20, 45, 0)
val list = VirtualValues.list(valueObj)
val array = CastSupport.getConverter(valueObj).arrayConverter(list)
array shouldBe a[LocalTimeArray]
array.asInstanceOf[LocalTimeArray].asObjectCopy()(0) should equal(valueObj.asObjectCopy())
}

test("should convert duration lists to arrays") {
val valueObj = duration(3, 20, 45, 0)
val list = VirtualValues.list(valueObj)
val array = CastSupport.getConverter(valueObj).arrayConverter(list)
array shouldBe a[DurationArray]
array.asInstanceOf[DurationArray].asObjectCopy()(0) should equal(valueObj.asObjectCopy())
}
}
36 changes: 36 additions & 0 deletions community/values/src/main/java/org/neo4j/values/ValueMapper.java
Expand Up @@ -37,10 +37,13 @@
import org.neo4j.values.storable.ByteValue;
import org.neo4j.values.storable.CharArray;
import org.neo4j.values.storable.CharValue;
import org.neo4j.values.storable.DateArray;
import org.neo4j.values.storable.DateTimeArray;
import org.neo4j.values.storable.DateTimeValue;
import org.neo4j.values.storable.DateValue;
import org.neo4j.values.storable.DoubleArray;
import org.neo4j.values.storable.DoubleValue;
import org.neo4j.values.storable.DurationArray;
import org.neo4j.values.storable.DurationValue;
import org.neo4j.values.storable.FloatArray;
import org.neo4j.values.storable.FloatValue;
Expand All @@ -50,7 +53,9 @@
import org.neo4j.values.storable.IntValue;
import org.neo4j.values.storable.IntegralArray;
import org.neo4j.values.storable.IntegralValue;
import org.neo4j.values.storable.LocalDateTimeArray;
import org.neo4j.values.storable.LocalDateTimeValue;
import org.neo4j.values.storable.LocalTimeArray;
import org.neo4j.values.storable.LocalTimeValue;
import org.neo4j.values.storable.LongArray;
import org.neo4j.values.storable.LongValue;
Expand All @@ -64,6 +69,7 @@
import org.neo4j.values.storable.StringValue;
import org.neo4j.values.storable.TextArray;
import org.neo4j.values.storable.TextValue;
import org.neo4j.values.storable.TimeArray;
import org.neo4j.values.storable.TimeValue;
import org.neo4j.values.virtual.MapValue;
import org.neo4j.values.virtual.PathValue;
Expand Down Expand Up @@ -228,6 +234,36 @@ default Base mapPointArray( PointArray value )
return mapSequence( value );
}

default Base mapDateTimeArray( DateTimeArray value )
{
return mapSequence( value );
}

default Base mapLocalDateTimeArray( LocalDateTimeArray value )
{
return mapSequence( value );
}

default Base mapLocalTimeArray( LocalTimeArray value )
{
return mapSequence( value );
}

default Base mapTimeArray( TimeArray value )
{
return mapSequence( value );
}

default Base mapDateArray( DateArray value )
{
return mapSequence( value );
}

default Base mapDurationArray( DurationArray value )
{
return mapSequence( value );
}

abstract class JavaMapper implements ValueMapper<Object>
{
@Override
Expand Down
Expand Up @@ -65,6 +65,21 @@ public AnyValue next()
};
}

@Override
public final boolean eq( Object other )
{
if ( other == null )
{
return false;
}

if ( other instanceof SequenceValue )
{
return this.equals( (SequenceValue) other );
}
return other instanceof Value && equals( (Value) other );
}

@Override
public boolean equals( boolean x )
{
Expand Down
Expand Up @@ -19,34 +19,44 @@
*/
package org.neo4j.values.storable;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.Arrays;

import org.neo4j.graphdb.spatial.Geometry;
import org.neo4j.values.AnyValue;
import org.neo4j.values.SequenceValue;
import org.neo4j.values.ValueMapper;

import static java.lang.String.format;

public abstract class BooleanArray extends ArrayValue
public class BooleanArray extends ArrayValue
{
abstract boolean[] value();
private final boolean[] value;

BooleanArray( boolean[] value )
{
assert value != null;
this.value = value;
}

@Override
public int length()
{
return value().length;
return value.length;
}

public boolean booleanValue( int offset )
{
return value()[offset];
return value[offset];
}

@Override
public boolean equals( Value other )
{
return other.equals( this.value() );
return other.equals( this.value );
}

@Override
Expand Down Expand Up @@ -88,7 +98,7 @@ public boolean equals( double[] x )
@Override
public boolean equals( boolean[] x )
{
return Arrays.equals( value(), x );
return Arrays.equals( value, x );
}

@Override
Expand All @@ -109,10 +119,46 @@ public boolean equals( Geometry[] x )
return false;
}

@Override
public boolean equals( ZonedDateTime[] x )
{
return false;
}

@Override
public boolean equals( LocalDate[] x )
{
return false;
}

@Override
public boolean equals( DurationValue[] x )
{
return false;
}

@Override
public boolean equals( LocalDateTime[] x )
{
return false;
}

@Override
public boolean equals( LocalTime[] x )
{
return false;
}

@Override
public boolean equals( OffsetTime[] x )
{
return false;
}

@Override
public int computeHash()
{
return NumberValues.hash( value() );
return NumberValues.hash( value );
}

@Override
Expand All @@ -124,20 +170,20 @@ public <T> T map( ValueMapper<T> mapper )
@Override
public <E extends Exception> void writeTo( ValueWriter<E> writer ) throws E
{
PrimitiveArrayWriting.writeTo( writer, value() );
PrimitiveArrayWriting.writeTo( writer, value );
}

@Override
public boolean[] asObjectCopy()
{
return value().clone();
return value.clone();
}

@Override
@Deprecated
public boolean[] asObject()
{
return value();
return value;
}

public int compareTo( BooleanArray other )
Expand All @@ -160,22 +206,7 @@ public NumberType numberType()
@Override
public String prettyPrint()
{
return Arrays.toString( value() );
}

@Override
public final boolean eq( Object other )
{
if ( other == null )
{
return false;
}

if ( other instanceof SequenceValue )
{
return this.equals( (SequenceValue) other );
}
return other instanceof Value && equals( (Value) other );
return Arrays.toString( value );
}

@Override
Expand All @@ -184,26 +215,9 @@ public AnyValue value( int position )
return Values.booleanValue( booleanValue( position ) );
}

static final class Direct extends BooleanArray
@Override
public String toString()
{
private final boolean[] value;

Direct( boolean[] value )
{
assert value != null;
this.value = value;
}

@Override
boolean[] value()
{
return value;
}

@Override
public String toString()
{
return format( "BooleanArray%s", Arrays.toString( value() ) );
}
return format( "BooleanArray%s", Arrays.toString( value ) );
}
}

0 comments on commit 9ab8a36

Please sign in to comment.