Skip to content

Commit de6e948

Browse files
author
Zhen Li
committed
Add Value#asXXX(defalutValue) for primary types
Add Value#computeOrDefault(Function<Value, T> mapper, T defaultValue) for other types Add Value#computeOrNull(Function<Value, T> mapper) for shortcuts to call Value#computeOrDefault(Function<Value, T> mapper, T defaultValue=null)
1 parent bee069a commit de6e948

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

driver/src/main/java/org/neo4j/driver/internal/value/ValueAdapter.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,42 @@ public String asString()
9090
throw new Uncoercible( type().name(), "Java String" );
9191
}
9292

93+
@Override
94+
public boolean asBoolean( boolean defaultValue )
95+
{
96+
return computeOrDefault( Value:: asBoolean, defaultValue );
97+
}
98+
99+
@Override
100+
public String asString( String defaultValue )
101+
{
102+
return computeOrDefault( (Value::asString), defaultValue );
103+
}
104+
105+
@Override
106+
public long asLong( long defaultValue )
107+
{
108+
return computeOrDefault( Value::asLong, defaultValue );
109+
}
110+
111+
@Override
112+
public int asInt( int defaultValue )
113+
{
114+
return computeOrDefault( Value::asInt, defaultValue );
115+
}
116+
117+
@Override
118+
public double asDouble( double defaultValue )
119+
{
120+
return computeOrDefault( Value::asDouble, defaultValue );
121+
}
122+
123+
@Override
124+
public float asFloat( float defaultValue )
125+
{
126+
return computeOrDefault( Value::asFloat, defaultValue );
127+
}
128+
93129
@Override
94130
public long asLong()
95131
{
@@ -150,6 +186,22 @@ public Object asObject()
150186
throw new Uncoercible( type().name(), "Java Object" );
151187
}
152188

189+
@Override
190+
public <T> T computeOrDefault( Function<Value,T> mapper, T defaultValue )
191+
{
192+
if ( isNull() )
193+
{
194+
return defaultValue;
195+
}
196+
return mapper.apply( this );
197+
}
198+
199+
@Override
200+
public <T> T computeOrNull( Function<Value,T> mapper )
201+
{
202+
return computeOrDefault( mapper, null );
203+
}
204+
153205
@Override
154206
public byte[] asByteArray()
155207
{

driver/src/main/java/org/neo4j/driver/v1/Value.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.List;
2727
import java.util.Map;
2828

29+
import org.neo4j.driver.internal.value.NullValue;
2930
import org.neo4j.driver.v1.exceptions.ClientException;
3031
import org.neo4j.driver.v1.exceptions.value.LossyCoercion;
3132
import org.neo4j.driver.v1.exceptions.value.Uncoercible;
@@ -194,12 +195,36 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue
194195
*/
195196
Object asObject();
196197

198+
/**
199+
* Apply the mapping function on the value if the value is not a {@link NullValue}, or the default value if the value is a {@link NullValue}.
200+
* @param mapper The mapping function defines how to map a {@link Value} to T.
201+
* @param defaultValue the value to return if the value is a {@link NullValue}
202+
* @param <T> The return type
203+
* @return The value after applying the given mapping function or the default value if the value is {@link NullValue}.
204+
*/
205+
<T>T computeOrDefault( Function<Value, T> mapper, T defaultValue );
206+
207+
/**
208+
* Apply the mapping function on the value if the value is not a {@link NullValue}, or null if the value is a {@link NullValue}.
209+
* @param mapper The mapping function defines how to map a {@link Value} to T.
210+
* @param <T> The return type
211+
* @return The value after applying the given mapping function or null if the value is {@link NullValue}.
212+
*/
213+
<T>T computeOrNull( Function<Value, T> mapper );
214+
197215
/**
198216
* @return the value as a Java boolean, if possible.
199217
* @throws Uncoercible if value types are incompatible.
200218
*/
201219
boolean asBoolean();
202220

221+
/**
222+
* @param defaultValue return this value if the value is a {@link NullValue}.
223+
* @return the value as a Java boolean, if possible.
224+
* @throws Uncoercible if value types are incompatible.
225+
*/
226+
boolean asBoolean( boolean defaultValue );
227+
203228
/**
204229
* @return the value as a Java byte array, if possible.
205230
* @throws Uncoercible if value types are incompatible.
@@ -212,6 +237,12 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue
212237
*/
213238
String asString();
214239

240+
/**
241+
* @param defaultValue return this value if the value is null.
242+
* @return the value as a Java String, if possible
243+
*/
244+
String asString( String defaultValue );
245+
215246
/**
216247
* @return the value as a Java Number, if possible.
217248
* @throws Uncoercible if value types are incompatible.
@@ -227,6 +258,15 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue
227258
*/
228259
long asLong();
229260

261+
/**
262+
* Returns a Java long if no precision is lost in the conversion.
263+
* @param defaultValue return this default value if the value is a {@link NullValue}.
264+
* @return the value as a Java long.
265+
* @throws LossyCoercion if it is not possible to convert the value without loosing precision.
266+
* @throws Uncoercible if value types are incompatible.
267+
*/
268+
long asLong( long defaultValue );
269+
230270
/**
231271
* Returns a Java int if no precision is lost in the conversion.
232272
*
@@ -236,6 +276,15 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue
236276
*/
237277
int asInt();
238278

279+
/**
280+
* Returns a Java int if no precision is lost in the conversion.
281+
* @param defaultValue return this default value if the value is a {@link NullValue}.
282+
* @return the value as a Java int.
283+
* @throws LossyCoercion if it is not possible to convert the value without loosing precision.
284+
* @throws Uncoercible if value types are incompatible.
285+
*/
286+
int asInt( int defaultValue );
287+
239288
/**
240289
* Returns a Java double if no precision is lost in the conversion.
241290
*
@@ -245,6 +294,16 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue
245294
*/
246295
double asDouble();
247296

297+
/**
298+
* Returns a Java double if no precision is lost in the conversion.
299+
* @param defaultValue default to this value if the value is a {@link NullValue}.
300+
* @return the value as a Java double.
301+
* @throws LossyCoercion if it is not possible to convert the value without loosing precision.
302+
* @throws Uncoercible if value types are incompatible.
303+
304+
*/
305+
double asDouble( double defaultValue );
306+
248307
/**
249308
* Returns a Java float if no precision is lost in the conversion.
250309
*
@@ -254,6 +313,16 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue
254313
*/
255314
float asFloat();
256315

316+
/**
317+
* Returns a Java float if no precision is lost in the conversion.
318+
* @param defaultValue default to this value if the value is a {@link NullValue}
319+
* @return the value as a Java float.
320+
* @throws LossyCoercion if it is not possible to convert the value without loosing precision.
321+
* @throws Uncoercible if value types are incompatible.
322+
323+
*/
324+
float asFloat( float defaultValue );
325+
257326
/**
258327
* If the underlying type can be viewed as a list, returns a java list of
259328
* values, where each value has been converted using {@link #asObject()}.

driver/src/test/java/org/neo4j/driver/internal/value/NullValueTest.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,23 @@
2020

2121
import org.junit.Test;
2222

23+
import java.time.LocalDate;
24+
import java.time.LocalDateTime;
25+
import java.time.LocalTime;
26+
import java.time.OffsetTime;
27+
import java.time.ZonedDateTime;
28+
import java.util.Collections;
29+
2330
import org.neo4j.driver.internal.types.TypeConstructor;
31+
import org.neo4j.driver.v1.Value;
32+
import org.neo4j.driver.v1.Values;
33+
import org.neo4j.driver.v1.util.Function;
2434

2535
import static org.hamcrest.MatcherAssert.assertThat;
2636
import static org.hamcrest.Matchers.equalTo;
37+
import static org.hamcrest.Matchers.nullValue;
2738
import static org.junit.Assert.assertTrue;
39+
import static org.neo4j.driver.v1.Values.point;
2840

2941
public class NullValueTest
3042
{
@@ -45,4 +57,78 @@ public void shouldTypeAsNull()
4557
{
4658
assertThat( ((InternalValue) NullValue.NULL).typeConstructor(), equalTo( TypeConstructor.NULL ) );
4759
}
60+
61+
@Test
62+
public void shouldReturnNativeTypesAsDefaultValue() throws Throwable
63+
{
64+
Value value = NullValue.NULL;
65+
assertThat( value.asBoolean( false ), equalTo( false ) );
66+
assertThat( value.asBoolean( true ), equalTo( true ) );
67+
assertThat( value.asString( "string value" ), equalTo( "string value" ) );
68+
assertThat( value.asInt( 10 ), equalTo( 10 ) );
69+
assertThat( value.asLong( 100L ), equalTo( 100L ) );
70+
assertThat( value.asFloat( 10.4f ), equalTo( 10.4f ) );
71+
assertThat( value.asDouble( 10.10 ), equalTo( 10.10 ) );
72+
}
73+
74+
@Test
75+
public void shouldReturnAsNull() throws Throwable
76+
{
77+
Value value = NullValue.NULL;
78+
79+
assertThat( value.computeOrNull( Value::asObject ), nullValue() );
80+
assertThat( value.computeOrNull( Value::asNumber ), nullValue() );
81+
assertThat( value.computeOrNull( Value::asByteArray ), nullValue() );
82+
83+
assertThat( value.computeOrNull( Value::asEntity ), nullValue() );
84+
assertThat( value.computeOrNull( Value::asNode ), nullValue() );
85+
assertThat( value.computeOrNull( Value::asRelationship ), nullValue() );
86+
assertThat( value.computeOrNull( Value::asPath ), nullValue() );
87+
88+
assertThat( value.computeOrNull( Value::asPoint ), nullValue() );
89+
90+
assertThat( value.computeOrNull( Value::asLocalDate ), nullValue() );
91+
assertThat( value.computeOrNull( Value::asOffsetTime ), nullValue() );
92+
assertThat( value.computeOrNull( Value::asLocalTime ), nullValue() );
93+
assertThat( value.computeOrNull( Value::asLocalDateTime ), nullValue() );
94+
assertThat( value.computeOrNull( Value::asZonedDateTime ), nullValue() );
95+
assertThat( value.computeOrNull( Value::asIsoDuration ), nullValue() );
96+
97+
assertThat( value.computeOrNull( Value::asList ), nullValue() );
98+
assertThat( value.computeOrNull( Value::asMap ), nullValue() );
99+
}
100+
101+
@Test
102+
public void shouldReturnAsDefaultValue() throws Throwable
103+
{
104+
Value value = NullValue.NULL;
105+
106+
assertThat( value.computeOrDefault( Value::asObject, "null" ), equalTo( "null" ) );
107+
assertThat( value.computeOrDefault( Value::asNumber, 10 ), equalTo( 10 ) );
108+
assertThat( value.computeOrDefault( Value::asByteArray, new byte[0] ), equalTo( new byte[0] ) );
109+
110+
assertThat( value.computeOrDefault( Value::asEntity, null ), nullValue() );
111+
assertThat( value.computeOrDefault( Value::asNode, null ), nullValue() );
112+
assertThat( value.computeOrDefault( Value::asRelationship, null ), nullValue() );
113+
assertThat( value.computeOrDefault( Value::asPath, null ), nullValue() );
114+
115+
assertComputeOrDefaultReturnsDefaultValue( Value::asPoint, point( 1234, 1, 2 ) );
116+
117+
assertComputeOrDefaultReturnsDefaultValue( Value::asLocalDate, LocalDate.now() );
118+
assertComputeOrDefaultReturnsDefaultValue( Value::asOffsetTime, OffsetTime.now() );
119+
assertComputeOrDefaultReturnsDefaultValue( Value::asLocalTime, LocalTime.now() );
120+
assertComputeOrDefaultReturnsDefaultValue( Value::asLocalDateTime, LocalDateTime.now() );
121+
assertComputeOrDefaultReturnsDefaultValue( Value::asZonedDateTime, ZonedDateTime.now() );
122+
assertComputeOrDefaultReturnsDefaultValue( Value::asIsoDuration, Values.isoDuration( 1, 2, 3, 4 ) );
123+
124+
assertThat( value.computeOrDefault( Value::asList, Collections.emptyList() ), equalTo( Collections.emptyList() ) );
125+
assertThat( value.computeOrDefault( Value::asMap, Collections.emptyMap() ), equalTo( Collections.emptyMap() ) );
126+
}
127+
128+
private <T> void assertComputeOrDefaultReturnsDefaultValue( Function<Value, T> f, T defaultAndExpectedValue )
129+
{
130+
Value value = NullValue.NULL;
131+
T returned = value.computeOrDefault( f, defaultAndExpectedValue );
132+
assertThat( returned, equalTo( defaultAndExpectedValue ) );
133+
}
48134
}

0 commit comments

Comments
 (0)