Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ElementID for Nodes & Relationships #591

Merged
merged 31 commits into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0e42da3
elementid
thelonelyvulpes Feb 23, 2022
1a26bc0
Merge branch '5.0' into feature/elementid
thelonelyvulpes Feb 25, 2022
a76a9b0
implement element id
thelonelyvulpes Feb 28, 2022
e2c3586
move relationships elementid reading
thelonelyvulpes Feb 28, 2022
38836fc
dedupe some code
thelonelyvulpes Feb 28, 2022
e09a46b
split out entity tests
thelonelyvulpes Feb 28, 2022
929fb14
fix path tests
thelonelyvulpes Feb 28, 2022
e1eeecd
5.0 handshake for tk back end
thelonelyvulpes Feb 28, 2022
1bae742
tidying
thelonelyvulpes Feb 28, 2022
2c945d8
tidy up strings
thelonelyvulpes Feb 28, 2022
75ae9d2
optimise handshake
thelonelyvulpes Feb 28, 2022
25d6b63
remove unused constant
thelonelyvulpes Feb 28, 2022
8897e89
name the constant
thelonelyvulpes Feb 28, 2022
dd6f190
rejig the code again a bit
thelonelyvulpes Mar 1, 2022
599cf6b
fix a unit tests
thelonelyvulpes Mar 1, 2022
4997962
fix backwards logic
thelonelyvulpes Mar 1, 2022
52bbd62
implement cypher relationship mapping
thelonelyvulpes Mar 1, 2022
5433119
restore feature
thelonelyvulpes Mar 2, 2022
0b45029
send path back
thelonelyvulpes Mar 3, 2022
bd05e37
Merge branch '5.0' into feature/elementid
thelonelyvulpes Mar 3, 2022
fe9e898
add more unit tests
thelonelyvulpes Mar 4, 2022
83ade24
unit tests
thelonelyvulpes Mar 4, 2022
2ae6118
add deprecation text
thelonelyvulpes Mar 4, 2022
03807ba
Merge branch '5.0' into feature/elementid
thelonelyvulpes Mar 4, 2022
6f422f7
Merge branch '5.0' into feature/elementid
thelonelyvulpes Mar 7, 2022
6106762
trigger build against handshake testkit
thelonelyvulpes Mar 8, 2022
4334976
add elementid feature toggle
thelonelyvulpes Mar 8, 2022
c03b3e6
remove feature flag
thelonelyvulpes Mar 9, 2022
d4daeac
fix some white space for a build
thelonelyvulpes Mar 11, 2022
01241c0
swap spaces, build against new 5.0
thelonelyvulpes Mar 11, 2022
3791101
blacklist summary test while 5.0 server responds 4.4
thelonelyvulpes Mar 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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),
});
}
}
}