org.neo4j.jdbc.values.Value Maven / Gradle / Ivy
/*
* Copyright (c) 2023-2024 "Neo4j,"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.neo4j.jdbc.values;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* A unit of data that adheres to the Neo4j type system.
*
* This interface describes a number of isType
methods along with
* typeValue
methods. The first set of these correlate with types from the
* Neo4j Type System and are used to determine which Neo4j type is represented. The second
* set of methods perform coercions to Java types (wherever possible). For example, a
* common String value should be tested for using isString
and extracted
* using stringValue
.
*
*
Navigating a tree structure
*
* Because Neo4j often handles dynamic structures, this interface is designed to help you
* handle such structures in Java. Specifically, {@link Value} lets you navigate arbitrary
* tree structures without having to resort to type casting.
*
* Given a tree structure like:
*
*
* {@code
* {
* users : [
* { name : "Anders" },
* { name : "John" }
* ]
* }
* }
*
*
* You can retrieve the name of the second user, John, like so:
*
* {@code
* String username = value.get("users").get(1).get("name").asString();
* }
*
*
* You can also easily iterate over the users:
*
* {@code
* List names = new LinkedList<>();
* for(Value user : value.get("users").values() )
* {
* names.add(user.get("name").asString());
* }
* }
*
*
* @author Neo4j Drivers Team
* @since 6.0.0
*/
public interface Value extends MapAccessorWithDefaultValue {
/**
* If the underlying value is a collection type, return the number of values in the
* collection.
*
* For {@link Type#LIST list} values, this will return the size of the list.
*
* For {@link Type#MAP map} values, this will return the number of entries in the map.
*
* For {@link Type#NODE node} and {@link Type#RELATIONSHIP} relationship} values, this
* will return the number of properties.
*
* For {@link Type#PATH path} values, this returns the length (number of
* relationships) in the path.
* @return the number of values in an underlying collection
*/
int size();
/**
* If this value represents a list or map, test if the collection is empty.
* @return {@code true} if size() is 0, otherwise {@code false}
*/
boolean isEmpty();
/**
* If the underlying value supports {@link #get(String) key-based indexing}, return an
* iterable of the keys in the map, this applies to {@link Type#MAP map},
* {@link #asNode() node} and {@link Type#RELATIONSHIP relationship} values.
* @return the keys in the value
*/
@Override
Iterable keys();
/**
* Retrieve the value at the given index.
* @param index the index of the value
* @return the value or a {@link NullValue} if the index is out of bounds
* @throws ValueException if record has not been initialized
*/
Value get(int index);
/**
* Returns the type.
* @return the type of this value as defined in the Neo4j type system
*/
Type type();
/**
* Test if this value is a value of the given type.
* @param type the given type
* @return type.isTypeOf(this)
*/
boolean hasType(Type type);
/**
* Returns {@code true} if the value is a Boolean value and has the value True.
* @return {@code true} if the value is a Boolean value and has the value True.
*/
boolean isTrue();
/**
* Returns {@code true} if the value is a Boolean value and has the value False.
* @return {@code true} if the value is a Boolean value and has the value False.
*/
boolean isFalse();
/**
* Returns {@code true} if the value is a Null, otherwise {@code false}.
* @return {@code true} if the value is a Null, otherwise {@code false}
*/
boolean isNull();
/**
* This returns a java standard library representation of the underlying value, using
* a java type that is "sensible" given the underlying type. The mapping for common
* types is as follows:
*
*
* - {@link Type#NULL} - {@code null}
* - {@link Type#LIST} - {@link List}
* - {@link Type#MAP} - {@link Map}
* - {@link Type#BOOLEAN} - {@link Boolean}
* - {@link Type#INTEGER} - {@link Long}
* - {@link Type#FLOAT} - {@link Double}
* - {@link Type#STRING} - {@link String}
* - {@link Type#BYTES} - {@literal byte[]}
* - {@link Type#DATE} - {@link LocalDate}
* - {@link Type#TIME} - {@link OffsetTime}
* - {@link Type#LOCAL_TIME} - {@link LocalTime}
* - {@link Type#DATE_TIME} - {@link ZonedDateTime}
* - {@link Type#LOCAL_DATE_TIME} - {@link LocalDateTime}
* - {@link Type#DURATION} - {@link IsoDuration}
* - {@link Type#POINT} - {@link Point}
* - {@link Type#NODE} - {@link Node}
* - {@link Type#RELATIONSHIP} - {@link Relationship}
* - {@link Type#PATH} - {@link Path}
*
*
* Note that the types refer to the Neo4j type system where {@link Type#INTEGER} and
* {@link Type#FLOAT} are both 64-bit precision. This is why these types return java
* {@link Long} and {@link Double}, respectively.
* @return the value as a Java Object.
* @throws DateTimeException if zone information supplied by server is not supported
* by driver runtime. Applicable to datetime values only.
*/
Object asObject();
/**
* 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}.
* @param mapper the mapping function defines how to map a {@link Value} to T.
* @param defaultValue the value to return if the value is a {@link NullValue}
* @param the return type
* @return the value after applying the given mapping function or the default value if
* the value is {@link NullValue}.
*/
T computeOrDefault(Function mapper, T defaultValue);
/**
* Returns value as boolean if possible.
* @return the value as a Java boolean, if possible.
* @throws UncoercibleException if value types are incompatible.
*/
boolean asBoolean();
/**
* Returns value as boolean if possible or the default value otherwise.
* @param defaultValue return this value if the value is a {@link NullValue}.
* @return the value as a Java boolean, if possible.
* @throws UncoercibleException if value types are incompatible.
*/
boolean asBoolean(boolean defaultValue);
/**
* Returns value as byte array if possible.
* @return the value as a Java byte array, if possible.
* @throws UncoercibleException if value types are incompatible.
*/
byte[] asByteArray();
/**
* Returns value as byte array if possible or the default value otherwise.
* @param defaultValue default to this value if the original value is a
* {@link NullValue}
* @return the value as a Java byte array, if possible.
* @throws UncoercibleException if value types are incompatible.
*/
byte[] asByteArray(byte[] defaultValue);
/**
* Returns value as string if possible.
* @return the value as a Java String, if possible.
* @throws UncoercibleException if value types are incompatible.
*/
String asString();
/**
* Returns value as string if possible or the default value otherwise.
* @param defaultValue return this value if the value is null.
* @return the value as a Java String, if possible
* @throws UncoercibleException if value types are incompatible.
*/
String asString(String defaultValue);
/**
* Returns value as number if possible.
* @return the value as a Java Number, if possible.
* @throws UncoercibleException if value types are incompatible.
*/
Number asNumber();
/**
* Returns a Java long if no precision is lost in the conversion. Returns a Java long
* if no precision is lost in the conversion.
* @return the value as a Java long.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
long asLong();
/**
* Returns a Java long if no precision is lost in the conversion.
* @param defaultValue return this default value if the value is a {@link NullValue}.
* @return the value as a Java long.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
long asLong(long defaultValue);
/**
* Returns a Java int if no precision is lost in the conversion.
* @return the value as a Java int.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
int asInt();
/**
* Returns a Java int if no precision is lost in the conversion.
* @param defaultValue return this default value if the value is a {@link NullValue}.
* @return the value as a Java int.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
int asInt(int defaultValue);
/**
* Returns a Java double if no precision is lost in the conversion.
* @return the value as a Java double.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
double asDouble();
/**
* Returns a Java double if no precision is lost in the conversion.
* @param defaultValue default to this value if the value is a {@link NullValue}.
* @return the value as a Java double.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
double asDouble(double defaultValue);
/**
* Returns a Java float if no precision is lost in the conversion.
* @return the value as a Java float.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
float asFloat();
/**
* Returns a Java float if no precision is lost in the conversion.
* @param defaultValue default to this value if the value is a {@link NullValue}
* @return the value as a Java float.
* @throws LossyCoercion if it is not possible to convert the value without loosing
* precision.
* @throws UncoercibleException if value types are incompatible.
*/
float asFloat(float defaultValue);
/**
* If the underlying type can be viewed as a list, returns a java list of values,
* where each value has been converted using {@link #asObject()}.
* @return the value as a Java list of values, if possible
* @see #asObject()
*/
List