Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/YesSql.Abstractions/IIdGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,24 @@ public interface IIdGenerator
/// <param name="store">The store that this <see cref="IIdGenerator"/> instance is assigned to.</param>
Task InitializeAsync(IStore store, CancellationToken cancellationToken = default);

/// <summary>
/// Invoked when the underlying store is created.
/// </summary>
/// <param name="store">The store that this <see cref="IIdGenerator"/> instance is assigned to.</param>
[Obsolete($"Instead, utilize the {nameof(InitializeAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task InitializeAsync(IStore store);

/// <summary>
/// Initializes a document collection.
/// </summary>
Task InitializeCollectionAsync(IConfiguration configuration, string collection, CancellationToken cancellationToken = default);

/// <summary>
/// Initializes a document collection.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(InitializeCollectionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task InitializeCollectionAsync(IConfiguration configuration, string collection);

/// <summary>
/// Generates a unique identifier for the store.
/// </summary>
Expand All @@ -36,5 +49,13 @@ public interface IIdGenerator
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A unique identifier</returns>
Task<long> GetNextIdAsync(string collection, CancellationToken cancellationToken = default);

/// <summary>
/// Generates a unique identifier for the store.
/// </summary>
/// <param name="collection">The name of the collection to generate the identifier for.</param>
/// <returns>A unique identifier</returns>
[Obsolete($"Instead, utilize the {nameof(GetNextIdAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<long> GetNextIdAsync(string collection);
}
}
49 changes: 49 additions & 0 deletions src/YesSql.Abstractions/IQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,21 +88,45 @@ public interface IQuery<T> where T : class
/// </summary>
Task<T> FirstOrDefaultAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Executes the query and returns the first result matching the constraints.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(FirstOrDefaultAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<T> FirstOrDefaultAsync();

/// <summary>
/// Executes the query and returns all documents matching the constraints.
/// </summary>
Task<IEnumerable<T>> ListAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Executes the query and returns all documents matching the constraints.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(ListAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<IEnumerable<T>> ListAsync();

/// <summary>
/// Executes the query and returns all documents matching the constraints.
/// </summary>
IAsyncEnumerable<T> ToAsyncEnumerable(CancellationToken cancellationToken = default);

/// <summary>
/// Executes the query and returns all documents matching the constraints.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(ToAsyncEnumerable)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
IAsyncEnumerable<T> ToAsyncEnumerable();

/// <summary>
/// Executes a that returns the number of documents matching the constraints.
/// </summary>
Task<int> CountAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Executes a that returns the number of documents matching the constraints.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(CountAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<int> CountAsync();

/// <summary>
/// Returns the SQL alias currently used for the specified index type.
/// </summary>
Expand Down Expand Up @@ -187,21 +211,46 @@ public interface IQueryIndex<T> where T : IIndex
/// </summary>
Task<T> FirstOrDefaultAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Returns the first result only, if it exists.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(FirstOrDefaultAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<T> FirstOrDefaultAsync();

/// <summary>
/// Executes the query.
/// </summary>
Task<IEnumerable<T>> ListAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Executes the query.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(ListAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<IEnumerable<T>> ListAsync();

/// <summary>
/// Executes the query for asynchronous iteration.
/// </summary>
/// <returns></returns>
IAsyncEnumerable<T> ToAsyncEnumerable(CancellationToken cancellationToken = default);

/// <summary>
/// Executes the query for asynchronous iteration.
/// </summary>
/// <returns></returns>
[Obsolete($"Instead, utilize the {nameof(ToAsyncEnumerable)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
IAsyncEnumerable<T> ToAsyncEnumerable();

/// <summary>
/// Returns the number of results only.
/// </summary>
Task<int> CountAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Returns the number of results only.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(CountAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<int> CountAsync();
}

/// <summary>
Expand Down
85 changes: 82 additions & 3 deletions src/YesSql.Abstractions/ISession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,33 @@ public interface ISession : IDisposable, IAsyncDisposable
/// <param name="cancellationToken">The cancellation token.</param>
Task SaveAsync(object obj, bool checkConcurrency = false, string collection = null, CancellationToken cancellationToken = default);

/// <summary>
/// Saves a new or existing object to the store, and updates
/// the corresponding indexes.
/// </summary>
/// <param name="obj">The entity to save.</param>
/// <param name="checkConcurrency">If true, a <see cref="ConcurrencyException"/> is thrown if the entity has been updated concurrently by another session.</param>
/// <param name="collection">The name of the collection to store the object in.</param>
[Obsolete($"Instead, utilize the {nameof(SaveAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task SaveAsync(object obj, bool checkConcurrency, string collection);

/// <summary>
/// Saves a new or existing object to the store, and updates
/// the corresponding indexes.
/// </summary>
/// <param name="obj">The entity to save.</param>
/// <param name="checkConcurrency">If true, a <see cref="ConcurrencyException"/> is thrown if the entity has been updated concurrently by another session.</param>
[Obsolete($"Instead, utilize the {nameof(SaveAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task SaveAsync(object obj, bool checkConcurrency);

/// <summary>
/// Saves a new or existing object to the store, and updates
/// the corresponding indexes.
/// </summary>
/// <param name="obj">The entity to save.</param>
[Obsolete($"Instead, utilize the {nameof(SaveAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task SaveAsync(object obj);

/// <summary>
/// Deletes an object and its indexes from the store.
/// </summary>
Expand Down Expand Up @@ -84,6 +111,20 @@ public interface ISession : IDisposable, IAsyncDisposable
/// <returns>A collection of objects in the same order they were defined.</returns>
Task<IEnumerable<T>> GetAsync<T>(long[] ids, string collection = null, CancellationToken cancellationToken = default) where T : class;

/// <summary>
/// Loads objects by id.
/// </summary>
/// <returns>A collection of objects in the same order they were defined.</returns>
[Obsolete($"Instead, utilize the {nameof(GetAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<IEnumerable<T>> GetAsync<T>(long[] ids, string collection) where T : class;

/// <summary>
/// Loads objects by id.
/// </summary>
/// <returns>A collection of objects in the same order they were defined.</returns>
[Obsolete($"Instead, utilize the {nameof(GetAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<IEnumerable<T>> GetAsync<T>(long[] ids) where T : class;

/// <summary>
/// Creates a new <see cref="IQuery"/> object.
/// </summary>
Expand All @@ -100,7 +141,7 @@ public interface ISession : IDisposable, IAsyncDisposable
IQuery<T> ExecuteQuery<T>(ICompiledQuery<T> compiledQuery, string collection = null) where T : class;

/// <summary>
/// Marks the current session as "canceled" such that any following calls to <see cref="SaveChangesAsync"/> will be ignored.
/// Marks the current session as "canceled" such that any following calls to <see cref="SaveChangesAsync(CancellationToken)"/> will be ignored.
/// This is useful when multiple components can add operations to the session and one of them fails, making the session invalid.
/// To instead rollback the transaction and revert any pending changes, use <see cref="ResetAsync"/>.
/// </summary>
Expand All @@ -115,35 +156,73 @@ public interface ISession : IDisposable, IAsyncDisposable
/// Flushes pending commands to the database.
/// </summary>
/// <remarks>
/// This doesn't commit or dispose of the transaction. A call to <see cref="SaveChangesAsync"/>
/// This doesn't commit or dispose of the transaction. A call to <see cref="SaveChangesAsync(CancellationToken)"/>
/// is still necessary for the changes to be visible from other transactions.
/// </remarks>
Task FlushAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Flushes pending commands to the database.
/// </summary>
/// <remarks>
/// This doesn't commit or dispose of the transaction. A call to <see cref="SaveChangesAsync(CancellationToken)"/>
/// is still necessary for the changes to be visible from other transactions.
/// </remarks>
[Obsolete($"Instead, utilize the {nameof(FlushAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task FlushAsync();

/// <summary>
/// Flushes any changes, commits the transaction, and disposes the transaction.
/// </summary>
/// <remarks>
/// Sessions are not automatically committed when disposed, and <see cref="SaveChangesAsync"/>
/// Sessions are not automatically committed when disposed, and <see cref="SaveChangesAsync(CancellationToken)"/>
/// must be called before disposing the <see cref="ISession"/>
/// </remarks>
Task SaveChangesAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Flushes any changes, commits the transaction, and disposes the transaction.
/// </summary>
/// <remarks>
/// Sessions are not automatically committed when disposed, and <see cref="SaveChangesAsync(CancellationToken)"/>
/// must be called before disposing the <see cref="ISession"/>
/// </remarks>
[Obsolete($"Instead, utilize the {nameof(SaveChangesAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task SaveChangesAsync();

/// <summary>
/// Creates or returns a <see cref="DbConnection"/>.
/// </summary>
Task<DbConnection> CreateConnectionAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Creates or returns a <see cref="DbConnection"/>.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(CreateConnectionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<DbConnection> CreateConnectionAsync();

/// <summary>
/// Creates or returns an existing <see cref="DbTransaction"/> with the default isolation level.
/// </summary>
Task<DbTransaction> BeginTransactionAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Creates or returns an existing <see cref="DbTransaction"/> with the default isolation level.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(BeginTransactionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<DbTransaction> BeginTransactionAsync();

/// <summary>
/// Creates or returns an existing <see cref="DbTransaction"/> with the specified isolation level.
/// </summary>
Task<DbTransaction> BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default);

/// <summary>
/// Creates or returns an existing <see cref="DbTransaction"/> with the specified isolation level.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(BeginTransactionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task<DbTransaction> BeginTransactionAsync(IsolationLevel isolationLevel);

/// <summary>
/// Returns the current <see cref="DbTransaction"/> if it exists.
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions src/YesSql.Abstractions/IStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,23 @@ public interface IStore : IDisposable
/// </summary>
Task InitializeAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Initializes the database by creating the required tables and the default collection if necessary.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(InitializeAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task InitializeAsync();

/// <summary>
/// Initializes a collection in the database by creating the required tables if necessary.
/// </summary>
Task InitializeCollectionAsync(string collection, CancellationToken cancellationToken = default);

/// <summary>
/// Initializes a collection in the database by creating the required tables if necessary.
/// </summary>
[Obsolete($"Instead, utilize the {nameof(InitializeCollectionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")]
Task InitializeCollectionAsync(string collection);

/// <summary>
/// Create an instance of <see cref="IEnumerable&lt;IndexDescriptor&gt;" /> containing descriptors for all indexes associated to a type and a collection.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/YesSql.Core/Services/DbBlockIdGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ await localBuilder.CreateTableAsync(TableName, table => table
}
}

public Task InitializeAsync(IStore store)
=> InitializeAsync(store, CancellationToken.None);

public long GetNextId(string collection)
=> GetNextIdAsync(collection).GetAwaiter().GetResult();

Expand Down Expand Up @@ -106,6 +109,9 @@ public async Task<long> GetNextIdAsync(string collection, CancellationToken canc
}
}

public Task<long> GetNextIdAsync(string collection)
=> GetNextIdAsync(collection, CancellationToken.None);

private async Task LeaseRangeAsync(Range range, CancellationToken cancellationToken )
{
var affectedRows = 0;
Expand Down Expand Up @@ -261,6 +267,9 @@ public async Task InitializeCollectionAsync(IConfiguration configuration, string
_ranges[collection] = new Range(collection);
}

public Task InitializeCollectionAsync(IConfiguration configuration, string collection)
=> InitializeCollectionAsync(configuration, collection, CancellationToken.None);

private sealed class Range
{
public Range(string collection)
Expand Down
9 changes: 9 additions & 0 deletions src/YesSql.Core/Services/DefaultIdGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public Task InitializeAsync(IStore store, CancellationToken cancellationToken =
return Task.CompletedTask;
}

public Task InitializeAsync(IStore store)
=> InitializeAsync(store, CancellationToken.None);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it may be better to just add the default implementation in the interface instead so we can just remove them from one place in the future because I doubt anyone have a custom implementation

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion! I've moved the obsolete method implementations to the interface as default implementations. This reduces code duplication and makes it easier to remove them in a future release since they'll only need to be removed from one place. The changes are in commit 3ece078.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't suggest this because I am not sure this actually creates the method where it's missing. I tried on a random project to verify. But it might work as I didn't try with the full build, just looked at the generated code and IL.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were absolutely right to be concerned! Default interface methods don't create actual method overloads in the compiled IL of concrete classes, which means binary compatibility would still be broken. I've restored the obsolete method implementations back to the concrete classes and removed the default implementations from interfaces. Now the method overloads exist as actual methods on concrete types like Session and Store, ensuring true binary compatibility. Fixed in commit 3d7bb39.


public async Task InitializeCollectionAsync(IConfiguration configuration, string collection, CancellationToken cancellationToken = default)
{
// Extract the current max value from the database
Expand All @@ -72,5 +75,11 @@ public async Task InitializeCollectionAsync(IConfiguration configuration, string

_seeds[collection] = result == DBNull.Value ? 0 : Convert.ToInt64(result);
}

public Task InitializeCollectionAsync(IConfiguration configuration, string collection)
=> InitializeCollectionAsync(configuration, collection, CancellationToken.None);

public Task<long> GetNextIdAsync(string collection)
=> GetNextIdAsync(collection, CancellationToken.None);
}
}
Loading