Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public override async Task Process()
}
catch (TimeZoneNotFoundException tz)
{
var message = tz.Message + " This can happen if the server is set to a timezone that is not recognized by .NET";
throw new DriverExceptionWrapper(tz);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ public static CypherToNativeObject ExtractParameterFromProperty(JObject paramete
};
}

if (parameter["name"].Value<string>() == "CypherVector")
{
return new CypherToNativeObject()
{
name = parameter["name"].Value<string>(),
data = parameter["data"].ToObject<VectorParameterValue>()
};
}

return new CypherToNativeObject
{
name = parameter["name"].Value<string>(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Neo4j.Driver.Tests.TestBackend.Protocol.JsonConverters;
Expand All @@ -38,15 +39,26 @@ public override async Task Process()
data.TransactionConfig)
.ConfigureAwait(false);

var result = ProtocolObjectFactory.CreateObject<Result.Result>();
result.ResultCursor = cursor;
Result.Result result = null;
try
{
result = ProtocolObjectFactory.CreateObject<Result.Result>();
result.ResultCursor = cursor;
}
catch(Exception ex)
{
throw;
}

ResultId = result.uniqueId;
}

public override string Respond()
{
return ((Result.Result)ObjManager.GetObject(ResultId)).Respond();
var protocolObject = (Result.Result)ObjManager.GetObject(ResultId);
var type = protocolObject.GetType();
var response = protocolObject.Respond();
return response;
}

[JsonConverter(typeof(SessionTypeJsonConverter))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ static SupportedFeatures()
"Feature:API:SSLSchemes",
"Feature:API:Summary:GqlStatusObjects",
"Feature:API:Type.Temporal",
"Feature:API:Type.Vector",
"Feature:Auth:Bearer",
"Feature:Auth:Custom",
"Feature:Auth:Kerberos",
Expand All @@ -68,6 +69,7 @@ static SupportedFeatures()
"Feature:Bolt:5.6",
"Feature:Bolt:5.7",
"Feature:Bolt:5.8",
"Feature:Bolt:6.0",
"Feature:Bolt:Patch:UTC",
"Feature:Bolt:HandshakeManifestV1",
"Feature:Impersonation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Neo4j.Driver.Internal.Util;
using Neo4j.Driver.Tests.TestBackend.Protocol.Session;
using Newtonsoft.Json.Linq;

Expand Down Expand Up @@ -66,6 +67,12 @@ public class DateTimeParameterValue
public string timezone_id { get; set; }
}

public class VectorParameterValue
{
public string? dtype { get; set; }
public string? data { get; set; }
}

public class DurationParameterValue
{
public long? months { get; set; }
Expand Down Expand Up @@ -95,6 +102,7 @@ internal class CypherToNative
{ "CypherLocalDateTime", typeof(LocalDateTime) },
{ "CypherDuration", typeof(Duration) },
{ "CypherPoint", typeof(Point) },
{ "CypherVector", typeof(Vector) },

{ "CypherNode", typeof(INode) },
{ "CypherRelationship", typeof(IRelationship) },
Expand All @@ -120,6 +128,7 @@ internal class CypherToNative
{ typeof(LocalDateTime), CypherDateTime },
{ typeof(Duration), CypherDuration },
{ typeof(Point), CypherTODO },
{ typeof(Vector), CypherVector },

{ typeof(INode), CypherTODO },
{ typeof(IRelationship), CypherTODO },
Expand All @@ -143,7 +152,7 @@ public static object Convert(CypherToNativeObject sourceObject)
catch
{
throw new IOException(
$"Attempting to convert an unsuported object type to a CypherType: {sourceObject.GetType()}");
$"Attempting to convert an unsupported object type to a CypherType: {sourceObject.GetType()}");
}
}

Expand Down Expand Up @@ -241,6 +250,43 @@ private static object CypherDateTime(Type objectType, CypherToNativeObject obj)
dataTimeParam.nanosecond.Value);
}

private static object CypherVector(Type objectType, CypherToNativeObject obj)
{
var data = (VectorParameterValue)obj.data;
var byteArray = ConvertStringToBytes(data.data);
var vectorType = SupportedTypeNames[data.dtype!];
var typedArray = BytesToTypedArrayHelper.ConvertBytesToTypedArray(byteArray, vectorType);
return Vector.CreateDynamic(typedArray, byteArray);
}

private static byte[] ConvertStringToBytes(string hexString)
{
if (string.IsNullOrEmpty(hexString))
{
return Array.Empty<byte>();
}

// string looks like "7f c0 23 3a" etc.
var hexValues = hexString.Split(' ', StringSplitOptions.RemoveEmptyEntries);
var byteArray = new byte[hexValues.Length];
for (var i = 0; i < hexValues.Length; i++)
{
byteArray[i] = System.Convert.ToByte(hexValues[i], 16);
}

return byteArray;
}

internal static readonly Dictionary<string, Type> SupportedTypeNames = new()
{
["i8"] = typeof(sbyte),
["i16"] = typeof(short),
["i32"] = typeof(int),
["i64"] = typeof(long),
["f32"] = typeof(float),
["f64"] = typeof(double)
};

private static object CypherDuration(Type objectType, CypherToNativeObject obj)
{
var duration = obj.data as DurationParameterValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Neo4j.Driver.Internal.IO.ValueSerializers.VectorSerializers;
using Neo4j.Driver.Tests.TestBackend.Protocol.Result;

#pragma warning disable CS0618 // Type or member is obsolete - but still needs to be handled

Expand All @@ -40,6 +42,7 @@ internal static class NativeToCypher
{
{ typeof(List<object>), CypherList },
{ typeof(Dictionary<string, object>), CypherMap },
{ typeof(IVector), CypherVector },

{ typeof(bool), CypherSimple },
{ typeof(long), CypherSimple },
Expand Down Expand Up @@ -67,12 +70,17 @@ public static object Convert(object sourceObject)
return new NativeToCypherObject { name = "CypherNull" };
}

if (sourceObject as List<object> != null)
if(sourceObject is IVector)
{
return FunctionMap[typeof(IVector)]("CypherVector", sourceObject);
}

if (sourceObject is List<object>)
{
return FunctionMap[typeof(List<object>)]("CypherList", sourceObject);
}

if (sourceObject as Dictionary<string, object> != null)
if (sourceObject is Dictionary<string, object>)
{
return FunctionMap[typeof(Dictionary<string, object>)]("CypherMap", sourceObject);
}
Expand Down Expand Up @@ -187,6 +195,37 @@ public static NativeToCypherObject CypherList(string cypherType, object obj)
{ name = cypherType, data = new NativeToCypherObject.DataType { value = result } };
}

internal static readonly Dictionary<Type, string> VectorTypeMap = new()
{
[typeof(sbyte)] = "i8",
[typeof(short)] = "i16",
[typeof(int)] = "i32",
[typeof(long)] = "i64",
[typeof(float)] = "f32",
[typeof(double)] = "f64"
};

public static NativeToCypherObject CypherVector(string cypherType, object obj)
{
var vector = (IVector)obj;
Dictionary<string, object> result = new()
{
["dtype"] = VectorTypeMap[vector.ElementType],
["data"] = ByteStreamToHexString(VectorSerializer.GetByteStream(vector))
};

return new NativeToCypherObject()
{
data = result,
name = cypherType
};
}

private static string ByteStreamToHexString(byte[] byteStream)
{
return string.Join(" ", byteStream.Select(b => b.ToString("x2")));
}

public static NativeToCypherObject CypherTODO(string name, object obj)
{
throw new NotImplementedException($"NativeToCypher : {name} conversion is not implemented yet");
Expand Down
Loading