Bot releases are visible (Hide)
No new changes
Published by RichardIrons-neo4j 5 months ago
No changes.
Published by thelonelyvulpes 7 months ago
Published by thelonelyvulpes 8 months ago
Full Changelog: https://github.com/neo4j/neo4j-dotnet-driver/compare/5.17.0...5.18.0
Published by RichardIrons-neo4j 9 months ago
Published by thelonelyvulpes 9 months ago
Security
and Topology
notification categories. (#738)ConfigBuilder.WithTelemetryDisabled()
.TransactionTerminatedException
; Any further interaction with any constituent results from the transaction will throw this error.Full Changelog: https://github.com/neo4j/neo4j-dotnet-driver/compare/5.13.0...5.14.0
Published by RichardIrons-neo4j about 1 year ago
This new feature allows records to be mapped to objects simply and without endless boilerplate. Please see this discussion for full details and instructions.
The following extension methods have been added in order to make code that deals with the IRecord
and IEntity
(implemented by both INode
and IRelationship
) interfaces more readable - for example, when writing custom mapping code. The Neo4j.Driver.Preview.Mapping
namespace must be referenced to use these methods.
IRecord.AsObject<T>()
Invokes the mapping functionality and returns an instance of T
mapped from the record. T
must have a parameterless constructor.
IRecord.GetValue<T>(string key)
Gets the value of the given key from the record, converting it to the given type. For example, the code record["name"].As<string>()
becomes record.GetValue<string>("name")
.
IRecord.GetXXXX(string key)
This is a group of extension methods for the most commonly used primitive types: GetString
, GetInt
, GetLong
, GetDouble
, GetFloat
and GetBool
. These just call GetValue<T>
for the type named in the method name, so record["name"].As<string>()
becomes record.GetString("name")
.
IEntity.GetValue<T>(string key)
Gets the value of the given key from the entity, converting it to the given type. For example, the code entity["name"].As<string>()
becomes entity.GetValue<string>("name")
.
IEntity.GetXXXX(string key)
The same group of methods as IRecord.GetXXXX
, but for an entity.
IRecord.GetEntity(string key)
Gets the IEntity
identified by the given key from the record. When combined with the other methods, this can lead to more readable code that gets values from entities within records, so for example this code:
var name = record["person"].As<IEntity>().Properties["name"].As<string>();
becomes:
var name = record.GetEntity("person").GetString("name");
Published by RichardIrons-neo4j about 1 year ago
IDriver.ExecutableQuery
API Docs.OnTokenExpiredAsync
method in the IAuthTokenManager
interface was removed, and a new HandleSecurityExceptionAsync
method was added in its place.ExpirationBased
method in AuthTokenManagers
was renamed to Bearer, and a new Basic method was added to cater for password rotation.Published by thelonelyvulpes about 1 year ago
Published by RichardIrons-neo4j over 1 year ago
No changes.
Published by thelonelyvulpes over 1 year ago
bolt_agent
metadata so that the server knows which driver is connecting (#706).Mention performance impact of notification filtering (#703).
Published by RichardIrons-neo4j over 1 year ago
var queryOp = await driver
.ExecutableQuery("MATCH (person:Person) RETURN person")
.ExecuteAsync();
The result of executing a query in the way shown above is an EagerResult<T>
, where T
is the type of data returned from the query. In the simplest case, this will be an IReadOnlyList<IRecord>
, which is a fully materialized list of the records returned by the query. Other types of results can be used by using the fluent API exposed by the IExecutableQuery
type, for example:
var queryOp = await driver
.ExecutableQuery("MATCH (person:Person) RETURN person")
.WithMap(r => r["person"].As<INode>()["name"].As<string>())
.WithFilter(s => s.StartsWith("A"))
.ExecuteAsync();
With this method, the return type will be EagerResult<IReadonlyList<string>>
. Multiple .WithMap
and .WithFilter
calls may be chained together. Note that filtering is performed locally here so it should not be used in place of doing filtering on the server.
There is also a .WithReduce
method, to be used as follows:
var queryOp = await driver
.ExecutableQuery("MATCH (person:Person) RETURN person")
.WithMap(r => r["person"].As<INode>()["age"].As<int>())
.WithReduce(() => 0, (r, n) => r + n)
.ExecuteAsync();
This will result in an EagerResult<int>
, with the Result
property containing the sum of all the ages.
Custom processing of the record stream can be done by using the .WithStreamProcessor
method:
var queryOp = await driver
.ExecutableQuery("MATCH (person:Person) RETURN person")
.WithStreamProcessor(
async stream =>
{
double total = 0;
int count = 0;
await foreach(var record in stream)
{
var age = record["person"].As<INode>()["age"].As<double>();
total += age;
count++;
}
return total / count;
})
.ExecuteAsync();
Here we simply supply a delegate, which will be called, passing a parameter of type IAsyncEnumerable<IRecord>
. The value returned from this delegate will be an EagerResult<double>
, with the Result
property containing the average age.
Parameters can also be specified using the fluent interface, as follows.
var paramQuery = await driver
.ExecutableQuery("MATCH (p:Person) WHERE p.name = $name RETURN p")
.WithParameters(new { name = "Tom Hanks" })
.WithMap(r => r["p"].As<INode>()["name"].As<string>())
.ExecuteAsync();
Published by RichardIrons-neo4j over 1 year ago
Neo4j.Driver.Experimental
namespace has been renamed to Neo4j.Driver.Preview
. This will be a compile-time breaking change for any code using this namespace. No functionality has been changed.IDriver.TryVerifyConnectivityAsync
Introduce better notifications, and configuration(Docs).
Introduce NotificationSeverity
enum represents to represent a notification's severity level.
Warning
Information
Unknown
Introduce NotificationCategory
enum represents to represent a notification's category.
Hint
Unrecognized
Unsupported
Performance
Deprecation
Generic
Unknown
The INotification
interface extended with 4 new properties:
NotificationSeverity SeverityLevel
string RawSeverityLevel
NotificationCategory Category
string RawCategory
The Raw
prefixed properties return an unparsed string
representation returned by the server.
In case of an unrecognised values, both SeverityLevel
and Category
will be Unknown
.
This may happen if a new value is introduced in a future server version and a previous driver version does not support it.
Additionally, Unknown
may be returned when driver communicates with a server version that does not supply these values.
The Severity
property has been deprecated in favour of the RawSeverityLevel
property.
Introduce INotificationConfig
type has been introduced to allow notification preferences management.
By default, the server determines what notifications are provided to the driver.
However, user can set a minimum severity level and/or a set of disabled notification categories to manage its expectations.
This feature is only supported on Bolt protocol version 5.2(Introduced in server 5.7) and above.
Both the Config
and the SessionConfig
support this new configuration, configured with builders:
ConfigBuilder.WithNotificationsDisabled
5.7 API Doc
ConfigBuilder.WithNotifications
5.7 API Doc
SessionConfigBuilder.WithNotificationsDisabled
5.7 API Doc
SessionConfigBuilder.WithNotifications
5.7 API Doc
Introduce Severity
(API Docs) & Category
(API Docs) enums for configuration.
Servers will assess which notifications to emit based on a hierarchy, using the most recently declared values.
using var driver = GraphDatabase.Driver(Neo4jUrl, AuthToken, cb => cb.WithNotificationsDisabled());
using var session = driver.AsyncSession();
...
var summary = await cursor.ConsumeAsync();
// No notifications should be emitted.
// This is useful for helping the server optimize operations as the server doesn't need to assess for any notifications.
// Notifications are not sent over the wire too meaning less data!
Debug.Assert(summary.Notifications.Count() == 0);
Severity configuration sets the minimum level of a notification, while category confugration is used to disable a category.
using var driver = GraphDatabase.Driver(Neo4jUrl, AuthToken, cb => cb.WithNotifications(Severity.Warning, null));
using var session = driver.AsyncSession(scb => scb.WithNotifications(null, new []{Category.Performance}));
...
var summary = await cursor.ConsumeAsync();
// no Information or performance notifications emitted.
Debug.Assert(summary.Notifications.Count(x =>
x.NotificationCategory == NotificationCategory.Performance ||
x.NotificationSeverity == NotificationSeverity.Information) == 0);
if you require to enable a previously disabled categories for a session you can emit it from disabledCategories
parameter.
using var driver = GraphDatabase.Driver(Neo4jUrl, AuthToken, cb => cb.WithNotifications(null, new []{Category.Performance}));
using var session = driver.AsyncSession(scb => scb.WithNotifications(null, new Category[]{}));
...
var summary = await cursor.ConsumeAsync();
// Notifications can contain anything again!
This update includes support for both 5.1 and 5.2 versions. The latter is required for the full support of the new notification updates.
Published by RichardIrons-neo4j over 1 year ago
No changes.
Published by RichardIrons-neo4j almost 2 years ago