Skip to content

Commit

Permalink
Implement ElementID for Nodes & Relationships (#591)
Browse files Browse the repository at this point in the history
- Implement string ElementId for Nodes and Relationships.
- Deprecate Id
- 5.0 Handshake
  • Loading branch information
thelonelyvulpes committed Mar 14, 2022
1 parent 7926708 commit 28741e2
Show file tree
Hide file tree
Showing 29 changed files with 1,084 additions and 263 deletions.
4 changes: 2 additions & 2 deletions Neo4j.Driver/Neo4j.Driver.Tests.TestBackend/IO/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ public void Close()
}

public void Dispose()
{
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

protected virtual void Dispose(bool disposing)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static SupportedFeatures()
"Feature:Bolt:4.2",
"Feature:Bolt:4.3",
"Feature:Bolt:4.4",
"Feature:Bolt:5.0",
"Feature:Impersonation",
//"Feature:TLS:1.1",
"Feature:TLS:1.2",
Expand Down
3 changes: 2 additions & 1 deletion Neo4j.Driver/Neo4j.Driver.Tests.TestBackend/TestBlackList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ static class TestBlackList
"Backend does not yet support serializing paths"),

("stub.tx_lifetime.test_tx_lifetime.TestTxLifetime.test_managed_tx_raises_tx_managed_exec",
"Driver (still) allows explicit managing of managed transaction")
"Driver (still) allows explicit managing of managed transaction"),

("test_summary.TestSummary.test_protocol_version_information", "Server not responding with 5.0")
};

public static bool FindTest(string testName, out string reason)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,45 @@

namespace Neo4j.Driver.Tests.TestBackend
{
internal class TransactionWrapper
{
public IAsyncTransaction Transaction { get; private set; }
private Func<IResultCursor, Task<string>> ResultHandler;

public TransactionWrapper(IAsyncTransaction transaction, Func<IResultCursor, Task<string>>resultHandler)
{
Transaction = transaction;
ResultHandler = resultHandler;
}

public async Task<string> ProcessResults(IResultCursor cursor)
{
return await ResultHandler(cursor);
}

}


internal class TransactionManager
{
private Dictionary<string, TransactionWrapper> Transactions { get; set; } = new Dictionary<string, TransactionWrapper>();

public string AddTransaction(TransactionWrapper transation)
{
var key = ProtocolObjectManager.GenerateUniqueIdString();
Transactions.Add(key, transation);
return key;
}

public void RemoveTransaction(string key)
{
Transactions.Remove(key);
}

public TransactionWrapper FindTransaction(string key)
{
return Transactions[key];
}

}
internal class TransactionWrapper
{
public IAsyncTransaction Transaction { get; private set; }
private Func<IResultCursor, Task<string>> ResultHandler;

public TransactionWrapper(IAsyncTransaction transaction, Func<IResultCursor, Task<string>>resultHandler)
{
Transaction = transaction;
ResultHandler = resultHandler;
}

public async Task<string> ProcessResults(IResultCursor cursor)
{
return await ResultHandler(cursor);
}

}


internal class TransactionManager
{
private Dictionary<string, TransactionWrapper> Transactions { get; set; } = new Dictionary<string, TransactionWrapper>();

public string AddTransaction(TransactionWrapper transation)
{
var key = ProtocolObjectManager.GenerateUniqueIdString();
Transactions.Add(key, transation);
return key;
}

public void RemoveTransaction(string key)
{
Transactions.Remove(key);
}

public TransactionWrapper FindTransaction(string key)
{
return Transactions[key];
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Neo4j.Driver.Tests.TestBackend
{
Expand Down Expand Up @@ -38,17 +39,15 @@ internal static class NativeToCypher
{ typeof(Duration), CypherTODO },
{ typeof(Point), CypherTODO },

{ typeof(INode), CypherNode },
{ typeof(IRelationship), CypherTODO },
{ typeof(IPath), CypherTODO }
{ typeof(INode), CypherNode },
{ typeof(IRelationship), CypherRelationship },
{ typeof(IPath), CypherPath }
};

public static object Convert(object sourceObject)
{
if (sourceObject is null)
{
return new NativeToCypherObject { name = "CypherNull", data = { } };
}

if (sourceObject as List<object> != null)
return FunctionMap[typeof(List<object>)]("CypherList", sourceObject);
Expand Down Expand Up @@ -146,12 +145,43 @@ public static NativeToCypherObject CypherNode(string cypherType, object obj)
var cypherNode = new Dictionary<string, object>
{
["id"] = Convert(node.Id),
["elementId"] = Convert(node.ElementId),
["labels"] = Convert(new List<object>(node.Labels)),
["props"] = Convert(new Dictionary<string, object>(node.Properties))
};

return new NativeToCypherObject() { name = "Node", data = cypherNode };
}

public static NativeToCypherObject CypherRelationship(string cypherType, object obj)
{
var rel = (IRelationship)obj;
var cypherRel = new Dictionary<string, object>
{
["id"] = Convert(rel.Id),
["startNodeId"] = Convert(rel.StartNodeId),
["type"] = Convert(rel.Type),
["endNodeId"] = Convert(rel.EndNodeId),
["props"] = Convert(new Dictionary<string, object>(rel.Properties)),
["elementId"] = Convert(rel.ElementId),
["startNodeElementId"] = Convert(rel.StartNodeElementId),
["endNodeElementId"] = Convert(rel.EndNodeElementId),
};

return new NativeToCypherObject() { name = "Relationship", data = cypherRel };
}

public static NativeToCypherObject CypherPath(string cypherType, object obj)
{
var path = (IPath)obj;
var cypherPath = new Dictionary<string, object>
{
["nodes"] = Convert(path.Nodes.OfType<object>().ToList()),
["relationships"] = Convert(path.Relationships.OfType<object>().ToList())
};

return new NativeToCypherObject() { name = "Path", data = cypherPath };
}
}
}

Expand Down
104 changes: 0 additions & 104 deletions Neo4j.Driver/Neo4j.Driver.Tests/EntityTests.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (c) 2002-2022 "Neo4j,"
// Neo4j Sweden AB [http://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
//
// 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.

using System.Collections.Generic;
using FluentAssertions;
using Neo4j.Driver.Internal.Types;
using Xunit;

namespace Neo4j.Driver.Internal.IO.ValueSerializers
{
public class ElementNodeSerializerTests : PackStreamSerializerTests
{
internal override IPackStreamSerializer SerializerUnderTest => new ElementNodeSerializer();

[Fact]
public void ShouldDeserialize()
{
var writerMachine = CreateWriterMachine();
var writer = writerMachine.Writer();

writer.WriteStructHeader(3, ElementNodeSerializer.Node);
writer.Write(1);
writer.Write(new List<string> { "Label1", "Label2" });
writer.Write(new Dictionary<string, object>
{
{"prop1", "something"},
{"prop2", 15},
{"prop3", true}
});
writer.Write("1");

var readerMachine = CreateReaderMachine(writerMachine.GetOutput());
var value = readerMachine.Reader().Read();

value.Should().NotBeNull();
value.Should().BeOfType<Node>().Which.Id.Should().Be(1L);
value.Should().BeOfType<Node>().Which.Labels.Should().Equal(new[] { "Label1", "Label2" });
value.Should().BeOfType<Node>().Which.Properties.Should().HaveCount(3).And.Contain(new[]
{
new KeyValuePair<string, object>("prop1", "something"),
new KeyValuePair<string, object>("prop2", 15L),
new KeyValuePair<string, object>("prop3", true),
});
value.Should().BeOfType<Node>().Which.ElementId.Should().Be("1");
}

[Fact]
public void ShouldDeserializeWithNulls()
{
var writerMachine = CreateWriterMachine();
var writer = writerMachine.Writer();

writer.WriteStructHeader(3, ElementNodeSerializer.Node);
writer.WriteNull();
writer.Write(new List<string> { "Label1", "Label2" });
writer.Write(new Dictionary<string, object>
{
{"prop1", "something"},
{"prop2", 15},
{"prop3", true}
});
writer.Write("1");

var readerMachine = CreateReaderMachine(writerMachine.GetOutput());
var value = readerMachine.Reader().Read();

value.Should().NotBeNull();
value.Should().BeOfType<Node>();
var node = value.As<Node>();

node.ElementId.Should().Be("1");
node.Id.Should().Be(-1L);

node.Labels.Should().Equal(new[] { "Label1", "Label2" });
node.Properties.Should().HaveCount(3).And.Contain(new[]
{
new KeyValuePair<string, object>("prop1", "something"),
new KeyValuePair<string, object>("prop2", 15L),
new KeyValuePair<string, object>("prop3", true),
});
}
}
}

0 comments on commit 28741e2

Please sign in to comment.