-
Couldn't load subscription status.
- Fork 69
5.X Change Log
- Default mapper could fail when creating custom mapping strategies (#821)
- GQL-compliant notifications and status objects (see https://www.gqlstandards.org/)
- Erroneous release.
- No changes.
- Delegate and blueprint mapping added to object mapping functionality (#810)
- Add SCHEMA notification type (#813)
- Bolt 5.6& 5.5 introduced
- GQL-compliant notifications and status objects (see https://www.gqlstandards.org/)
- No changes.
- No changes.
- Object mapping moved out of preview (#784)
- Default object mapper made stricter in order to avoid unpredictable or unexpected results (#792, #796)
- Reclassification of transient error when opening SSL Connection (#788)
- Add session auth to executableQuery config (#774)
- Invariant capable records (#780)
- Change DictAsRecord to have non-surprising case sensitivity (#782)
- Fix race condition for parallel queries in a transaction (#785)
- support .NET 8 (#770)
- fix cancellation token being ignored for ExecuteQuery (#771)
- Protect default memory pool for bolt (#758)
- Update array pool config, allow driver to request a max sized array (#764)
- Reduce memory allocations when creating a record object (#767)
- Refactoring of internal code to remove warnings and tidy the code base
- Constructor mapping added to object mapping feature (#751)
- The legal header at the top of each source file has been updated (#752)
- Reauth moved from preview to general availability. (#744)
- Introduction of
SecurityandTopologynotification categories. (#738) - Introduction of Bolt 5.4 (Introduced to Neo4j in server version 5.13) and TELEMETRY message. (#735
- The driver can opt out of telemetry collection using
ConfigBuilder.WithTelemetryDisabled(). - Telemetry is only collected when connecting to aura and is limited to which APIs were used to create a transaction.
- The driver can opt out of telemetry collection using
- All cursors belonging to a transaction are now invalidated if an error invalidates any of the transaction's queries. (#737)
- If the initial exception was ignored, this could result in undefined behavior, but now will result in a
TransactionTerminatedException; Any further interaction with any constituent results from the transaction will throw this error.
- If the initial exception was ignored, this could result in undefined behavior, but now will result in a
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.
Invokes the mapping functionality and returns an instance of T mapped from the record. T must have a parameterless constructor.
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").
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").
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").
The same group of methods as IRecord.GetXXXX, but for an entity.
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");- ExecutableQuery performance enhancement: Remove a server round-trip for
IDriver.ExecutableQueryAPI Docs.
- Changes to the re-auth functionality allow for catering to a wider range of use cases including simple password rotation.
- All re-auth-related namespaces have been moved to preview - previously some did not have this, although the classes therein would not have been usable.
- The
OnTokenExpiredAsyncmethod in theIAuthTokenManagerinterface was removed, and a newHandleSecurityExceptionAsyncmethod was added in its place. - The
ExpirationBasedmethod inAuthTokenManagerswas renamed to Bearer, and a new Basic method was added to cater for password rotation.
- Fixes for ZonedDateTime.
- Introduce
Ambiguousboolproperty, CreatingZonedDateTimewith out a datetime kind, or using a datetime kind local with a named Zone:Zone.of(string), meant we could create an ambiguous date time. - Introduce
ZonedDateTime.AmbiguityReasonenum flags type. - Introduce
ReasonAmbiguityReasonproperty forZonedDateTimes, to allow users to see why a value is considered ambiguous. - Introduce
UtcSecondslongproperty which is the understood monotonic timestamp from unix epoch in UTC. - Fix ZonedDateTime lazily parsing when returned from a query, now it is parsed immediately.
- Fix ZonedDateTime not supporting values outside of range of BCL Date Types
- Add
TicksProperty, and constructor which can be used for easy interop with nodatime's Instant - Deprecated 2 constructors that do not include DateTimeKind(API Doc, deprecated constructor, API Doc, deprecated constructor)
- Introduce
-
TransactionConfigBuilder'sWithTimeouthas been updated to respect neo4j transaction timeouts using whole milliseconds.- The
WithTimeoutmethod checks that the number of ticks represented by the timeout represents an exact number of milliseconds. - If not, then it round the timeout up to the next whole millisecond, for example, 0.1ms is rounded to 1ms, and 1.8ms is rounded to 2ms.
- If using
TimeSpan.MaxValuethen no rounding will be performed since rounding up to a whole number of milliseconds would result in a value greater thanTimeSpan.MaxValue.
- The
No changes.
- Support for bolt protocol 5.3 which adds
bolt_agentmetadata so that the server knows which driver is connecting (#706). - Re-authentication (in preview) (#689)
Allows for handling expiring authentication (backwards compatible) as well as session scoped authentication (requires neo4j server version 5.6+).
We are actively looking for feedback: https://github.com/neo4j/neo4j-dotnet-driver/discussions/705
Mention performance impact of notification filtering (#703).
- The ExecuteQuery API has now been moved out of preview. This provides a much simpler way to execute queries directly at the driver level, with sessions, transactions and bookmarks handled automatically.
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();- the
Neo4j.Driver.Experimentalnamespace has been renamed toNeo4j.Driver.Preview. This will be a compile-time breaking change for any code using this namespace. No functionality has been changed.
- Introduce
IDriver.TryVerifyConnectivityAsync#693 #See issue - Notifications Updates #691 Introduce better notifications, and configuration(Docs).
Introduce NotificationSeverity enum represents to represent a notification's severity level.
WarningInformationUnknown
Introduce NotificationCategory enum represents to represent a notification's category.
HintUnrecognizedUnsupportedPerformanceDeprecationGenericUnknown
The INotification interface extended with 4 new properties:
NotificationSeverity SeverityLevelstring RawSeverityLevelNotificationCategory Categorystring 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.WithNotificationsDisabled5.7 API Doc -
ConfigBuilder.WithNotifications5.7 API Doc -
SessionConfigBuilder.WithNotificationsDisabled5.7 API Doc -
SessionConfigBuilder.WithNotifications5.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.
No changes.
- The
IsRetriableproperty on exceptions is now public
- The
ExecutableQueryAPI has been added to theExperimentalnamespace (see here for more information)
- Add documentation for SessionConfigBuilder.WithDatabase and SessionConfig.Database
- Exclude test code in snyk code analysis
- TestKit backend: exclude txMeta from Cypher types
- Add new exception types and change to explicitly identifying fast fail errors
- Remove database notions from bookmark manager.
- Fix Bookmark manager references outside of Neo4j.Driver.Experimental namespace.
- When replacing LastBookmark with LastBookmarks we accidentally removed the old property, not following the planned deprecation policy. It is now restored and marked as obsolete, and due for removal in 6.0 of the driver.
- Simplify creation of bookmark manager with default config.
- Fixed an issue bookmark manager experimental classes: correctly exposing
WithBookmarkManagerto use bookmark managers on session configuration(#654).
No changes.
No changes.
final tidying for major release.
- Introduce Experimental Bookmark Manager. (Not recommended for production use currently.) (#632)
- Using
Neo4j.Driver.Experimental.GraphDatabase.BookmarkManagerFactoryusers can create anIBookmarkManager. -
IBookmarkManagercan be passed toSessionConfigBuilderwhen creating a creating a session by using theNeo4j.Driver.Experimental.ExperimentalExtensionsto addWithBookmarkManagertoSessionConfigBuilder. - The Experimental methods will be finalized as:
-
Neo4j.Driver.Experimental.GraphDatabase.BookmarkManagerFactory->Neo4j.Driver.GraphDatabase.BookmarkManagerFactory -
Neo4j.Driver.Experimental.ExperimentalExtensions->Neo4j.Driver.SessionConfigBuilder.
-
- Using
- Transaction lifetimes. (#640)
⚠️ remaining managed transactions have been deprecated and replaced, removing the ability to commit or rollback transactions inside the unit of work scope.-
ISession.ReadTransaction->ISession.ExecuteRead -
ISession.WriteTransaction->ISession.ExecuteWrite -
IRxSession.ReadTransaction->IRxSession.ExecuteRead -
IRxSession.WriteTransaction->IRxSession.ExecuteWrite
-
- Removal of 4.X Deprecations
- Removal of
IServerInfo.Version(#638)
- Removal of
This release introduces full support for Neo4j 5.0 Servers.
We now release for .NET 6.0 and .NET Standard 2.0.
- Support for Bolt protocol version
5.0 - SSL Configuration(#585)
- SSL certificate trust rules can be set on driver initialization using
ConfigBuilder.WithCertificateTrustRule-
CertificateTrustRule.TrustSystem- Will verify certificates against the system's Certificate Authority store.
-
CertificateTrustRule.TrustList- Users can specify a collection of X509Certificate2 or paths to load as trusted certificates.
-
CertificateTrustRule.TrustAny- Will trust any SSL Cert.
-
⚠️ Users can not use bothConfigBuilder.WithCertificateTrustRuleand+s/+sscin the url scheme at the same time.
- SSL certificate trust rules can be set on driver initialization using
- Added
Driver.GetServerInfoAsync. (#605)- Will verify connectivity and return a
IServerInfodetailing server summary.
- Will verify connectivity and return a
- Added
CanBeRetriedtoException. (#613)- All errors from driver that can be resolved by retrying an operation will return true.
- Add
IsOpento Result cursors. (#610)-
IsOpenwill return if the underlying cursor is open to read records; Attempting to read from a closed cursor will throw aResultConsumedException.
-
- Connection Acquisition Timeout (#588)
-
ConfigBuilder.WithConnectionAcquisitionTimeoutallows users to set maximum wait time to get a connection from the pool or create a new connection on driver initialization. ⚠️ default: 60 seconds
-
- Transaction lifetimes. (#612)
⚠️ Async managed transactions have been deprecated and replaced, removing the ability to commit or rollback transactions inside the unit of work scope.-
IAsyncSession.ReadTransactionAsync->IAsyncSession.ExecuteReadAsync -
IAsyncSession.WriteTransactionAsync->IAsyncSession.ExecuteWriteAsync
-
- Attempting close a transaction after it has been closed will now throw a
TransactionClosedException.
- Rename Bookmark to Bookmarks. (#609)
⚠️ Due to a mix of languageBookmarkand all references to bookmarks have been pluralized as it allows for multiple values.-
Bookmark->Bookmarks -
Session.LastBookmark->Session.LastBookmarks -
SessionConfigBuilder.WithBookmarks(Bookmark[])->SessionConfigBuilder.WithBookmarks(Bookmarks[])
- Transaction timeout (#574)
-
TransactionConfigBuilder.WithTimeoutnow acceptsNullable<TimeSpan>for timeout.⚠️ nullwill use the server's default transaction timeout.⚠️ TimeSpan.Zerowill remove timeout from transaction.
-
- No longer throwing when using APOC procedures in a profiled query. (#633)
- Discovery exceptions. (#594)
- Error message handling. (#592)
Full Changelog: https://github.com/neo4j/neo4j-dotnet-driver/compare/4.4.0...5.0.0-beta01