Skip to content

Releases: geldata/gel-net

v1.1.0

07 Mar 18:35
Compare
Choose a tag to compare

This release fixes oversights and bugs with the new temporal datatypes as well as dynamic query results.

Added

  • Added PreferSystemTemporalTypes to EdgeDBConfig and EdgeDBClientPoolConfig. This option determines whether or not to prefer using .NETs system temporal types when deserializing EdgeDB's temporal types using non-concrete query result definitions. This setting does not override property-defined types, for example:

    public class ExampleModel
    {
        public EdgeDB.DataTypes.DateTime EDBDateTime { get; set; }
    }

    would be deserialized as EdgeDB.DataTypes.DateTime regardless of this option. Where this option does apply is when using
    dynamic or object as the generic in one of the Query* methods, e.g.:

    var result = client.QueryAsync<object>(...);

Fixed

  • Fixed an issue where dynamic results couldn't decide on which type to pick for complex codecs.
  • Fixed an issue where dynamic results couldn't build compliable codecs.

v1.0.5

24 Feb 21:17
Compare
Choose a tag to compare

This release adds more logging, fixes bugs, Adds new temporal types in EdgeDB.Datatypes, and introduces a new exception: QueryTimeoutException, which is thrown in favor for OperationCancelledException.

Added

  • Added QueryTimeoutException which is thrown when the EdgeDBConfig.MessageTimeout is exceeded. Ontop of this, a warning log was added when a query takes >=75% of the message timeout to complete, and a error log was added when the timeout is exceeded.
  • Added EdgeDB.DataTypes.DateDuration, EdgeDB.DataTypes.DateTime, EdgeDB.DataTypes.Duration, EdgeDB.DataTypes.LocalDate, EdgeDB.DataTypes.LocalDateTime, EdgeDB.DataTypes.LocalTime, and EdgeDB.DataTypes.RelativeDuration *

Fixed

  • Fixed EdgeDB.DataTypes.Memory failing to be deserialized.
  • Fixed idle timeout warning causing exceptions instead of implicitly reconnecting.
  • Fixed incorrect error messages for parsing connection parameters in DSN strings.
  • Fixed ExecuteAsync not specifying IOFormat.None to the server.
  • Fixed transactions with no return result throwing transaction exceptions even if the transaction completed successfully #31.
  • Fixed . being used as decimal character regardless of language/CultureInfo #31.

Misc

  • Bumped default message timeout from 5 seconds to 15 seconds.

* Temporal changes

Temporal behavior in the .NET binding has changed as per #27. With this, there are new date/time types added into the EdgeDB.DataTypes namespace which reflect the EdgeDB standard library date/time types. The motivation for this was to ensure precision between bindings and EdgeDB.

.NETs date/time types are implicitly converted to a corresponding EdgeDB.DataTypes.* type with rounding precision to keep backwards compatibility with <=1.0.4. It's recommended to always use the corresponding EdgeDB.DataTypes.* temporal type where possible to control the precision.

v1.0.4

26 Dec 16:30
Compare
Choose a tag to compare

This release fixes bugs within the internals of EdgeDB.Net, as well as adds .NET 7 as a build target, improving performance overall

Added

  • Added .NET 7 target for driver.

Fixed

  • Fixed PacketWriter not unpinning the internal buffer, causing a memory leak.
  • Fixed HTTP client not resolving state mismatched on execute step, if the codecs were cached the state would not be updated.
  • Fixed connection issues when server doesn't prompt for SASL.

Misc

  • Removed byte[] downcast from packet writer, memory owner becomes the receiver of the Memory<T> from any consumer of packet writer, improving memory usage overall.

v1.0.3

22 Dec 17:47
Compare
Choose a tag to compare

This release fixes bugs related to memory usage and nullable types

Fixes

  • Fixed cancellation token sources not being disposed.
  • Fixed Nullable value types not being deserialized.

v1.0.2

16 Dec 05:37
Compare
Choose a tag to compare

This release improves performance of client server IO as well as fixes bugs related to type deserialization.

Added

  • Added ErrorCode property to EdgeDBErrorException.
  • Added HTTP binary client, available by specifying the ClientType in the EdgeDBClientPoolConfig.

Fixed

  • Fixed EdgeDBClient.ServerConfig not being populated.
  • Fixed cfg::Memory not being deserializable.
  • Fixed converter types not validating the target type.

Full Changelog: 1.0.1...1.0.2

v1.0.1

02 Nov 21:42
Compare
Choose a tag to compare

This release fixes a bug that throws TaskCancelledException when receiving large amounts of data, as well as adds a way to globally define type converters.

v1.0.0

01 Nov 18:14
Compare
Choose a tag to compare

Official Dotnet Driver Release

V1.0.0 marks the dotnet driver as becoming an official client library for EdgeDB. With this milestone, they're have been some breaking changes to the api to meet the standards of other client libraries.

Breaking changes

πŸ”₯ EdgeDB v2 State πŸ”₯

The state/session/config api has changed for the dotnet client to meet the same standard as other client libraries.

Old state

client.DefaultSession.WithGlobals(new Dictionary<string, object?>
{
    {"current_user_id", Guid.NewGuid() }
});

await using var clientInstance = await client.GetOrCreateClientAsync(state =>
{
    state.WithGlobals(new Dictionary<string, object?>
    {
        {"current_user_id", Guid.NewGuid() }
    });
});

New state

var newClient = client.WithConfig(config => config.DDLPolicy = DDLPolicy.AlwaysAllow);

EdgeDBClient has new With* methods for describing state, each of these methods returns a new client instance which shares the same client pool and predefined state. but has you specified state changes applied.

🌲 Client Abstractions 🌲

Client abstractions (BaseEdgeDBClient, EdgeDBHttpClient, EdgeDBTCPClient, etc) have been hidden to provide the simplest DX possible without overstimulating you with all of these classes/abstractions without losing potency of the driver. Methods to create single client instances have been removed, since the use-case for this is minuscule when the client pool can be split into 'sections' with different states1.

πŸ—οΈ Type Building πŸ—οΈ

The type building system has drastically changed for the better, objects are no longer compiled to an intermediate representation and instead now directly build from the ObjectEnumerator type.

When adding your own TypeDeserializerFactory, you are given a ref ObjectEnumerator which directly reads from the raw data received from EdgeDB. This type acts like a standard IEnumerator<T> but with some changes to better reflect type building.

Example usage

TypeBuilder.AddOrUpdateTypeFactory<IPerson>((ref ObjectEnumerator enumerator) =>
{
    // turn the enumerator into a flat dictionary
    var data = (IDictionary<string, object?>)enumerator.ToDynamic()!;

    // return a instance of a 'IPerson'
    return new PersonImpl
    {
        Email = (string)data["email"]!,
        Name = (string)data["name"]!
    };
});

Normally, you would avoid the ToDynamic() method where possible to achieve maximum performance, but for this example we don't need to. With the new type deserialization system, performance was improved by up to 11x for deserializing types.

The old type builder is still compatible with the old deserialization system which under the hood gets converted like the above example to a dynamic dictionary.

πŸ“” Examples πŸ“”

The example app was split into EdgeDB.Examples.CSharp and EdgeDB.Examples.FSharp, more we're added and changed to meet the new standard. Please refresh yourself with the examples!

πŸ› οΈ Type Converters πŸ› οΈ

Custom client-side type converters are now available, what are they? Type converters allow you to use non-supported dotnet types with a serializer to serialize them to EdgeDB types. One use-case for this is to allow the use of Snowflake Identifiers, represented as ulong in dotnet and str in EgeDB. C# example of type converters for snowflake identifiers.

✍🏻 Naming Strategies ✍🏻

The type builder would convert property names from snake_case to CamelCase by default, this behaviour has been changed to be opt-in for clients. Now the default is to keep the case as is.

Opting in to a naming strategy

var client = new EdgeDBClient(new EdgeDBClientPoolConfig()
{
    SchemaNamingStrategy = INamingStrategy.SnakeCaseNamingStrategy
})

Note
Naming strategies are schema-based, the naming strategy of your dotnet property names have no effect on type building.

⚑ Performance ⚑

A lot of the internals have been reworked to bring the lightest, thinnest, fastest possible binding for dotnet!

  • Changed packet reading/writing to use Span<T> and Memory<T>.
  • Using shared memory instead of raw alloc's where possible.
  • Cut out intermediate objects while deserializing to directly deserialize as T.
  • Lots of caching where appropriate.

Changelog

Added

  • Added WithConfig, WithModule, WithAliases, and WithGlobals to EdgeDBClient.
  • Added ObjectEnumerator in favor for dynamic when deserializing.
  • Added EdgeDBTypeConverter attribute.
  • Added EdgeDBTypeConverter<TSource, TDest>.
  • Added EdgeDBErrorException formatting when using .ToString().
  • Added EnsureConnectedAsync to EdgeDBClient.
  • Added support for F# ValueOption<T>.
  • Added support for F# option<T>.
  • Added support for F# union types.

Fixed

  • Fixed a bug with clients not being able to reconnect after disconnecting.
  • Fixed a bug with EdgeDB named tuples not being able to be deserialized to dotnet tuples.
  • Fixed some F# types not being deserialized properly.
  • Fixed endianness being flipped on big-endian architecture when communicating over the EdgeDB binary protocol.
  • Fixed session-based Config having incorrect default values.
  • Fixed type builder trying to instantiate an abstract type.
  • Fixed errors on query parsing not being thrown correctly.
  • Fixed objects in objects not deserializing correctly

Misc

  • Made Session non-public.
  • Made BaseEdgeDBClient, EdgeDBHttpClient, and EdgeDBTCPClient non-public.
  • Removed the ability to create a 'raw' client instance in EdgeDBClient (GetOrCreateClient()).
  • Changed WithAliases and WithGobals to take IDictionary instead of Dictionary

  1. When you construct a new EdgeDBClient, you're creating a new connection pool with x amount of clients, this pool is exclusive to this client and any proxy-clients created from this pool. When making state changes (WithConfig(...), etc), the underlying connection pool is used to create a proxy client with the reflected state changes. ↩