Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions driver/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -818,4 +818,10 @@
<method>org.neo4j.driver.Logging systemLogging()</method>
</difference>

<difference>
<className>org/neo4j/driver/types/TypeSystem</className>
<differenceType>7012</differenceType>
<method>org.neo4j.driver.types.Type VECTOR()</method>
</difference>

</differences>
109 changes: 108 additions & 1 deletion driver/src/main/java/org/neo4j/driver/Values.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@
import org.neo4j.driver.exceptions.ClientException;
import org.neo4j.driver.internal.AsValue;
import org.neo4j.driver.internal.GqlStatusError;
import org.neo4j.driver.internal.InternalByteVector;
import org.neo4j.driver.internal.InternalDoubleVector;
import org.neo4j.driver.internal.InternalFloatVector;
import org.neo4j.driver.internal.InternalIntVector;
import org.neo4j.driver.internal.InternalIsoDuration;
import org.neo4j.driver.internal.InternalLongVector;
import org.neo4j.driver.internal.InternalPoint2D;
import org.neo4j.driver.internal.InternalPoint3D;
import org.neo4j.driver.internal.InternalShortVector;
import org.neo4j.driver.internal.value.BooleanValue;
import org.neo4j.driver.internal.value.BytesValue;
import org.neo4j.driver.internal.value.DateTimeValue;
Expand All @@ -60,6 +66,7 @@
import org.neo4j.driver.internal.value.PointValue;
import org.neo4j.driver.internal.value.StringValue;
import org.neo4j.driver.internal.value.TimeValue;
import org.neo4j.driver.internal.value.VectorValue;
import org.neo4j.driver.mapping.Property;
import org.neo4j.driver.types.Entity;
import org.neo4j.driver.types.IsoDuration;
Expand All @@ -69,6 +76,7 @@
import org.neo4j.driver.types.Point;
import org.neo4j.driver.types.Relationship;
import org.neo4j.driver.types.TypeSystem;
import org.neo4j.driver.types.Vector;
import org.neo4j.driver.util.Preview;

/**
Expand Down Expand Up @@ -170,6 +178,9 @@ public static Value value(Object value) {
if (value instanceof Point) {
return value((Point) value);
}
if (value instanceof Vector vector) {
return value(vector);
}

if (value instanceof List<?>) {
return value((List<Object>) value);
Expand Down Expand Up @@ -469,10 +480,11 @@ public static Value value(java.lang.Record record) {
for (var recordComponent : recordComponents) {
var propertyAnnotation = recordComponent.getAnnotation(Property.class);
var property = propertyAnnotation != null ? propertyAnnotation.value() : recordComponent.getName();
var isVector = recordComponent.getAnnotation(org.neo4j.driver.mapping.Vector.class) != null;
Value value;
try {
var objectValue = recordComponent.getAccessor().invoke(record);
value = (objectValue != null) ? value(objectValue) : null;
value = (objectValue != null) ? isVector ? vector(objectValue) : value(objectValue) : null;
} catch (Throwable throwable) {
var message = "Failed to map '%s' property to value during mapping '%s' to map value"
.formatted(property, record.getClass().getCanonicalName());
Expand Down Expand Up @@ -996,4 +1008,99 @@ public static Function<Value, List<Object>> ofList() {
public static <T> Function<Value, List<T>> ofList(final Function<Value, T> innerMap) {
return value -> value.asList(innerMap);
}

/**
* Returns Neo4j Vector that holds a sequence of {@code byte} values.
*
* @param elements the vector elements
* @return the vector value
* @since 6.0.0
*/
@Preview(name = "Neo4j Vector")
public static Value vector(byte[] elements) {
return value(new InternalByteVector(elements));
}

/**
* Returns Neo4j Vector that holds a sequence of {@code short} values.
*
* @param elements the vector elements
* @return the vector value
* @since 6.0.0
*/
@Preview(name = "Neo4j Vector")
public static Value vector(short[] elements) {
return value(new InternalShortVector(elements));
}

/**
* Returns Neo4j Vector that holds a sequence of {@code int} values.
*
* @param elements the vector elements
* @return the vector value
* @since 6.0.0
*/
@Preview(name = "Neo4j Vector")
public static Value vector(int[] elements) {
return value(new InternalIntVector(elements));
}

/**
* Returns Neo4j Vector that holds a sequence of {@code long} values.
*
* @param elements the vector elements
* @return the vector value
* @since 6.0.0
*/
@Preview(name = "Neo4j Vector")
public static Value vector(long[] elements) {
return value(new InternalLongVector(elements));
}

/**
* Returns Neo4j Vector that holds a sequence of {@code float} values.
*
* @param elements the vector elements
* @return the vector value
* @since 6.0.0
*/
@Preview(name = "Neo4j Vector")
public static Value vector(float[] elements) {
return value(new InternalFloatVector(elements));
}

/**
* Returns Neo4j Vector that holds a sequence of {@code double} values.
*
* @param elements the vector elements
* @return the vector value
* @since 6.0.0
*/
@Preview(name = "Neo4j Vector")
public static Value vector(double[] elements) {
return value(new InternalDoubleVector(elements));
}

private static Value value(Vector vector) {
return new VectorValue(vector);
}

private static Value vector(Object array) {
if (array instanceof byte[] elements) {
return value(Values.vector(elements));
} else if (array instanceof short[] elements) {
return value(Values.vector(elements));
} else if (array instanceof int[] elements) {
return value(Values.vector(elements));
} else if (array instanceof long[] elements) {
return value(Values.vector(elements));
} else if (array instanceof float[] elements) {
return value(Values.vector(elements));
} else if (array instanceof double[] elements) {
return value(Values.vector(elements));
} else {
throw new IllegalArgumentException(
"Unsupported vector element type: " + array.getClass().getName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* 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
*
* http://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.driver.internal;

import java.lang.reflect.Array;
import java.util.Objects;
import org.neo4j.bolt.connection.values.Vector;

public abstract class AbstractArrayVector<T> implements Vector {
private final Class<?> elementType;
private final int length;
protected final T elements;

AbstractArrayVector(T elements) {
this.elementType = elements.getClass().getComponentType();
this.length = Array.getLength(elements);
this.elements = arraycopy(elements);
}

public Class<?> elementType() {
return elementType;
}

public int length() {
return length;
}

public T toArray() {
return arraycopy(elements);
}

@Override
public Object elements() {
return elements;
}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
var that = (AbstractArrayVector<?>) o;
return length == that.length
&& Objects.equals(elementType, that.elementType)
&& Objects.equals(elements, that.elements);
}

@Override
public int hashCode() {
return Objects.hash(elementType, length, elements);
}

@Override
public String toString() {
return "AbstractArrayVector{" + "elementType="
+ elementType + ", length="
+ length + ", elements="
+ elements + '}';
}

@SuppressWarnings({"unchecked", "SuspiciousSystemArraycopy"})
private T arraycopy(T elements) {
var result = (T) Array.newInstance(elementType, length);
System.arraycopy(elements, 0, result, 0, length);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* 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
*
* http://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.driver.internal;

import org.neo4j.driver.types.ByteVector;

public final class InternalByteVector extends AbstractArrayVector<byte[]> implements ByteVector {
public InternalByteVector(byte[] elements) {
super(elements);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* 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
*
* http://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.driver.internal;

import org.neo4j.driver.types.DoubleVector;

public final class InternalDoubleVector extends AbstractArrayVector<double[]> implements DoubleVector {
public InternalDoubleVector(double[] elements) {
super(elements);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* 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
*
* http://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.driver.internal;

import org.neo4j.driver.types.FloatVector;

public final class InternalFloatVector extends AbstractArrayVector<float[]> implements FloatVector {
public InternalFloatVector(float[] elements) {
super(elements);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* 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
*
* http://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.driver.internal;

import org.neo4j.driver.types.IntVector;

public final class InternalIntVector extends AbstractArrayVector<int[]> implements IntVector {
public InternalIntVector(int[] elements) {
super(elements);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* 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
*
* http://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.driver.internal;

import org.neo4j.driver.types.LongVector;

public final class InternalLongVector extends AbstractArrayVector<long[]> implements LongVector {
public InternalLongVector(long[] elements) {
super(elements);
}
}
Loading