diff --git a/src/YesSql.Abstractions/IIdGenerator.cs b/src/YesSql.Abstractions/IIdGenerator.cs index 283e10840..b3d2c6cf2 100644 --- a/src/YesSql.Abstractions/IIdGenerator.cs +++ b/src/YesSql.Abstractions/IIdGenerator.cs @@ -16,11 +16,24 @@ public interface IIdGenerator /// The store that this instance is assigned to. Task InitializeAsync(IStore store, CancellationToken cancellationToken = default); + /// + /// Invoked when the underlying store is created. + /// + /// The store that this instance is assigned to. + [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); + /// /// Initializes a document collection. /// Task InitializeCollectionAsync(IConfiguration configuration, string collection, CancellationToken cancellationToken = default); + /// + /// Initializes a document collection. + /// + [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); + /// /// Generates a unique identifier for the store. /// @@ -36,5 +49,13 @@ public interface IIdGenerator /// The cancellation token. /// A unique identifier Task GetNextIdAsync(string collection, CancellationToken cancellationToken = default); + + /// + /// Generates a unique identifier for the store. + /// + /// The name of the collection to generate the identifier for. + /// A unique identifier + [Obsolete($"Instead, utilize the {nameof(GetNextIdAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task GetNextIdAsync(string collection); } } diff --git a/src/YesSql.Abstractions/IQuery.cs b/src/YesSql.Abstractions/IQuery.cs index 5e1eac360..054f87cdc 100644 --- a/src/YesSql.Abstractions/IQuery.cs +++ b/src/YesSql.Abstractions/IQuery.cs @@ -88,21 +88,45 @@ public interface IQuery where T : class /// Task FirstOrDefaultAsync(CancellationToken cancellationToken = default); + /// + /// Executes the query and returns the first result matching the constraints. + /// + [Obsolete($"Instead, utilize the {nameof(FirstOrDefaultAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task FirstOrDefaultAsync(); + /// /// Executes the query and returns all documents matching the constraints. /// Task> ListAsync(CancellationToken cancellationToken = default); + /// + /// Executes the query and returns all documents matching the constraints. + /// + [Obsolete($"Instead, utilize the {nameof(ListAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task> ListAsync(); + /// /// Executes the query and returns all documents matching the constraints. /// IAsyncEnumerable ToAsyncEnumerable(CancellationToken cancellationToken = default); + /// + /// Executes the query and returns all documents matching the constraints. + /// + [Obsolete($"Instead, utilize the {nameof(ToAsyncEnumerable)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + IAsyncEnumerable ToAsyncEnumerable(); + /// /// Executes a that returns the number of documents matching the constraints. /// Task CountAsync(CancellationToken cancellationToken = default); + /// + /// Executes a that returns the number of documents matching the constraints. + /// + [Obsolete($"Instead, utilize the {nameof(CountAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task CountAsync(); + /// /// Returns the SQL alias currently used for the specified index type. /// @@ -187,21 +211,46 @@ public interface IQueryIndex where T : IIndex /// Task FirstOrDefaultAsync(CancellationToken cancellationToken = default); + /// + /// Returns the first result only, if it exists. + /// + [Obsolete($"Instead, utilize the {nameof(FirstOrDefaultAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task FirstOrDefaultAsync(); + /// /// Executes the query. /// Task> ListAsync(CancellationToken cancellationToken = default); + /// + /// Executes the query. + /// + [Obsolete($"Instead, utilize the {nameof(ListAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task> ListAsync(); + /// /// Executes the query for asynchronous iteration. /// /// IAsyncEnumerable ToAsyncEnumerable(CancellationToken cancellationToken = default); + /// + /// Executes the query for asynchronous iteration. + /// + /// + [Obsolete($"Instead, utilize the {nameof(ToAsyncEnumerable)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + IAsyncEnumerable ToAsyncEnumerable(); + /// /// Returns the number of results only. /// Task CountAsync(CancellationToken cancellationToken = default); + + /// + /// Returns the number of results only. + /// + [Obsolete($"Instead, utilize the {nameof(CountAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task CountAsync(); } /// diff --git a/src/YesSql.Abstractions/ISession.cs b/src/YesSql.Abstractions/ISession.cs index e1e4fa97d..27b91aebd 100644 --- a/src/YesSql.Abstractions/ISession.cs +++ b/src/YesSql.Abstractions/ISession.cs @@ -34,6 +34,33 @@ public interface ISession : IDisposable, IAsyncDisposable /// The cancellation token. Task SaveAsync(object obj, bool checkConcurrency = false, string collection = null, CancellationToken cancellationToken = default); + /// + /// Saves a new or existing object to the store, and updates + /// the corresponding indexes. + /// + /// The entity to save. + /// If true, a is thrown if the entity has been updated concurrently by another session. + /// The name of the collection to store the object in. + [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); + + /// + /// Saves a new or existing object to the store, and updates + /// the corresponding indexes. + /// + /// The entity to save. + /// If true, a is thrown if the entity has been updated concurrently by another session. + [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); + + /// + /// Saves a new or existing object to the store, and updates + /// the corresponding indexes. + /// + /// The entity to save. + [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); + /// /// Deletes an object and its indexes from the store. /// @@ -84,6 +111,20 @@ public interface ISession : IDisposable, IAsyncDisposable /// A collection of objects in the same order they were defined. Task> GetAsync(long[] ids, string collection = null, CancellationToken cancellationToken = default) where T : class; + /// + /// Loads objects by id. + /// + /// A collection of objects in the same order they were defined. + [Obsolete($"Instead, utilize the {nameof(GetAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task> GetAsync(long[] ids, string collection) where T : class; + + /// + /// Loads objects by id. + /// + /// A collection of objects in the same order they were defined. + [Obsolete($"Instead, utilize the {nameof(GetAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task> GetAsync(long[] ids) where T : class; + /// /// Creates a new object. /// @@ -100,7 +141,7 @@ public interface ISession : IDisposable, IAsyncDisposable IQuery ExecuteQuery(ICompiledQuery compiledQuery, string collection = null) where T : class; /// - /// Marks the current session as "canceled" such that any following calls to will be ignored. + /// Marks the current session as "canceled" such that any following calls to 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 . /// @@ -115,35 +156,73 @@ public interface ISession : IDisposable, IAsyncDisposable /// Flushes pending commands to the database. /// /// - /// This doesn't commit or dispose of the transaction. A call to + /// This doesn't commit or dispose of the transaction. A call to /// is still necessary for the changes to be visible from other transactions. /// Task FlushAsync(CancellationToken cancellationToken = default); + /// + /// Flushes pending commands to the database. + /// + /// + /// This doesn't commit or dispose of the transaction. A call to + /// is still necessary for the changes to be visible from other transactions. + /// + [Obsolete($"Instead, utilize the {nameof(FlushAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task FlushAsync(); + /// /// Flushes any changes, commits the transaction, and disposes the transaction. /// /// - /// Sessions are not automatically committed when disposed, and + /// Sessions are not automatically committed when disposed, and /// must be called before disposing the /// Task SaveChangesAsync(CancellationToken cancellationToken = default); + /// + /// Flushes any changes, commits the transaction, and disposes the transaction. + /// + /// + /// Sessions are not automatically committed when disposed, and + /// must be called before disposing the + /// + [Obsolete($"Instead, utilize the {nameof(SaveChangesAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task SaveChangesAsync(); + /// /// Creates or returns a . /// Task CreateConnectionAsync(CancellationToken cancellationToken = default); + /// + /// Creates or returns a . + /// + [Obsolete($"Instead, utilize the {nameof(CreateConnectionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task CreateConnectionAsync(); + /// /// Creates or returns an existing with the default isolation level. /// Task BeginTransactionAsync(CancellationToken cancellationToken = default); + /// + /// Creates or returns an existing with the default isolation level. + /// + [Obsolete($"Instead, utilize the {nameof(BeginTransactionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task BeginTransactionAsync(); + /// /// Creates or returns an existing with the specified isolation level. /// Task BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default); + /// + /// Creates or returns an existing with the specified isolation level. + /// + [Obsolete($"Instead, utilize the {nameof(BeginTransactionAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task BeginTransactionAsync(IsolationLevel isolationLevel); + /// /// Returns the current if it exists. /// diff --git a/src/YesSql.Abstractions/IStore.cs b/src/YesSql.Abstractions/IStore.cs index fda78c2f5..d89565df5 100644 --- a/src/YesSql.Abstractions/IStore.cs +++ b/src/YesSql.Abstractions/IStore.cs @@ -31,11 +31,23 @@ public interface IStore : IDisposable /// Task InitializeAsync(CancellationToken cancellationToken = default); + /// + /// Initializes the database by creating the required tables and the default collection if necessary. + /// + [Obsolete($"Instead, utilize the {nameof(InitializeAsync)} method with a CancellationToken parameter. This current method is slated for removal in upcoming releases.")] + Task InitializeAsync(); + /// /// Initializes a collection in the database by creating the required tables if necessary. /// Task InitializeCollectionAsync(string collection, CancellationToken cancellationToken = default); + /// + /// Initializes a collection in the database by creating the required tables if necessary. + /// + [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); + /// /// Create an instance of containing descriptors for all indexes associated to a type and a collection. /// diff --git a/src/YesSql.Core/Services/DbBlockIdGenerator.cs b/src/YesSql.Core/Services/DbBlockIdGenerator.cs index c90cd3cf5..19c085e6d 100644 --- a/src/YesSql.Core/Services/DbBlockIdGenerator.cs +++ b/src/YesSql.Core/Services/DbBlockIdGenerator.cs @@ -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(); @@ -106,6 +109,9 @@ public async Task GetNextIdAsync(string collection, CancellationToken canc } } + public Task GetNextIdAsync(string collection) + => GetNextIdAsync(collection, CancellationToken.None); + private async Task LeaseRangeAsync(Range range, CancellationToken cancellationToken ) { var affectedRows = 0; @@ -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) diff --git a/src/YesSql.Core/Services/DefaultIdGenerator.cs b/src/YesSql.Core/Services/DefaultIdGenerator.cs index a6fb71b4b..c39e6d689 100644 --- a/src/YesSql.Core/Services/DefaultIdGenerator.cs +++ b/src/YesSql.Core/Services/DefaultIdGenerator.cs @@ -46,6 +46,9 @@ public Task InitializeAsync(IStore store, CancellationToken cancellationToken = return Task.CompletedTask; } + public Task InitializeAsync(IStore store) + => InitializeAsync(store, CancellationToken.None); + public async Task InitializeCollectionAsync(IConfiguration configuration, string collection, CancellationToken cancellationToken = default) { // Extract the current max value from the database @@ -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 GetNextIdAsync(string collection) + => GetNextIdAsync(collection, CancellationToken.None); } } diff --git a/src/YesSql.Core/Services/DefaultQuery.cs b/src/YesSql.Core/Services/DefaultQuery.cs index 8c9816e28..9247ab35c 100644 --- a/src/YesSql.Core/Services/DefaultQuery.cs +++ b/src/YesSql.Core/Services/DefaultQuery.cs @@ -1170,6 +1170,9 @@ public async Task CountAsync(CancellationToken cancellationToken = default) } } + public Task CountAsync() + => CountAsync(CancellationToken.None); + IQuery IQuery.For(bool filterType) { _queryState.GetBindings().Clear(); @@ -1308,11 +1311,17 @@ protected async Task FirstOrDefaultImpl(CancellationToken cancellationToken = } } + public Task FirstOrDefaultAsync() + => FirstOrDefaultAsync(CancellationToken.None); + Task> IQuery.ListAsync(CancellationToken cancellationToken) { return ListImpl(cancellationToken); } + Task> IQuery.ListAsync() + => ((IQuery)this).ListAsync(CancellationToken.None); + #pragma warning disable CS8425 // Async-iterator member has one or more parameters of type 'CancellationToken' but none of them is decorated with the 'EnumeratorCancellation' attribute, so the cancellation token parameter from the generated 'IAsyncEnumerable<>.GetAsyncEnumerator' will be unconsumed async IAsyncEnumerable IQuery.ToAsyncEnumerable(CancellationToken cancellationToken) #pragma warning restore CS8425 // Async-iterator member has one or more parameters of type 'CancellationToken' but none of them is decorated with the 'EnumeratorCancellation' attribute, so the cancellation token parameter from the generated 'IAsyncEnumerable<>.GetAsyncEnumerator' will be unconsumed @@ -1324,6 +1333,9 @@ async IAsyncEnumerable IQuery.ToAsyncEnumerable(CancellationToken cancella } } + IAsyncEnumerable IQuery.ToAsyncEnumerable() + => ((IQuery)this).ToAsyncEnumerable(CancellationToken.None); + internal async Task> ListImpl(CancellationToken cancellationToken) { // TODO: [IAsyncEnumerable] Once Dapper supports IAsyncEnumerable we can return it by default, and buffer it in ListAsync instead @@ -1494,6 +1506,9 @@ Task IQuery.CountAsync(CancellationToken cancellationToken) return _query.CountAsync(cancellationToken); } + Task IQuery.CountAsync() + => ((IQuery)this).CountAsync(CancellationToken.None); + IQuery IQuery.Any(params Func, IQuery>[] predicates) { // Scope the currentPredicate so multiple calls will not act on the new predicate. @@ -1620,11 +1635,17 @@ Task IQueryIndex.FirstOrDefaultAsync(CancellationToken cancellationToken) return FirstOrDefaultImpl(cancellationToken); } + Task IQueryIndex.FirstOrDefaultAsync() + => ((IQueryIndex)this).FirstOrDefaultAsync(CancellationToken.None); + Task> IQueryIndex.ListAsync(CancellationToken cancellationToken) { return ListImpl(cancellationToken); } + Task> IQueryIndex.ListAsync() + => ((IQueryIndex)this).ListAsync(CancellationToken.None); + #pragma warning disable CS8425 // Async-iterator member has one or more parameters of type 'CancellationToken' but none of them is decorated with the 'EnumeratorCancellation' attribute, so the cancellation token parameter from the generated 'IAsyncEnumerable<>.GetAsyncEnumerator' will be unconsumed async IAsyncEnumerable IQueryIndex.ToAsyncEnumerable(CancellationToken cancellationToken) #pragma warning restore CS8425 // Async-iterator member has one or more parameters of type 'CancellationToken' but none of them is decorated with the 'EnumeratorCancellation' attribute, so the cancellation token parameter from the generated 'IAsyncEnumerable<>.GetAsyncEnumerator' will be unconsumed @@ -1636,6 +1657,9 @@ async IAsyncEnumerable IQueryIndex.ToAsyncEnumerable(CancellationToken can } } + IAsyncEnumerable IQueryIndex.ToAsyncEnumerable() + => ((IQueryIndex)this).ToAsyncEnumerable(CancellationToken.None); + IQueryIndex IQueryIndex.Skip(int count) { if (count > 0) @@ -1669,6 +1693,9 @@ async Task IQueryIndex.CountAsync(CancellationToken cancellationToken) return await _query.CountAsync(cancellationToken); } + Task IQueryIndex.CountAsync() + => ((IQueryIndex)this).CountAsync(CancellationToken.None); + IQueryIndex IQueryIndex.With() { _query.Bind(); diff --git a/src/YesSql.Core/Session.cs b/src/YesSql.Core/Session.cs index 898ca29b3..2f61b3ca4 100644 --- a/src/YesSql.Core/Session.cs +++ b/src/YesSql.Core/Session.cs @@ -160,6 +160,15 @@ public async Task SaveAsync(object entity, bool checkConcurrency = false, string state.Saved.Add(entity); } + public Task SaveAsync(object entity, bool checkConcurrency, string collection) + => SaveAsync(entity, checkConcurrency, collection, CancellationToken.None); + + public Task SaveAsync(object entity, bool checkConcurrency) + => SaveAsync(entity, checkConcurrency, null, CancellationToken.None); + + public Task SaveAsync(object entity) + => SaveAsync(entity, false, null, CancellationToken.None); + public bool Import(object entity, long id = 0, long version = 0, string collection = null) { CheckDisposed(); @@ -616,6 +625,12 @@ public IEnumerable Get(IList documents, string collection) where return result; } + public Task> GetAsync(long[] ids, string collection) where T : class + => GetAsync(ids, collection, CancellationToken.None); + + public Task> GetAsync(long[] ids) where T : class + => GetAsync(ids, null, CancellationToken.None); + public IQuery Query(string collection = null) { return new DefaultQuery(this, _tablePrefix, collection); @@ -690,6 +705,9 @@ public Task FlushAsync(CancellationToken cancellationToken = default) return FlushInternalAsync(false, cancellationToken); } + public Task FlushAsync() + => FlushAsync(CancellationToken.None); + private async Task FlushInternalAsync(bool saving, CancellationToken cancellationToken) { if (!HasWork()) @@ -943,6 +961,9 @@ public async Task SaveChangesAsync(CancellationToken cancellationToken = default } } + public Task SaveChangesAsync() + => SaveChangesAsync(CancellationToken.None); + public async ValueTask DisposeAsync() { // Do nothing if Dispose() was already called @@ -1407,11 +1428,17 @@ public async Task CreateConnectionAsync(CancellationToken cancella return _connection; } + public Task CreateConnectionAsync() + => CreateConnectionAsync(CancellationToken.None); + public DbTransaction CurrentTransaction => _transaction; public Task BeginTransactionAsync(CancellationToken cancellationToken = default) => BeginTransactionAsync(Store.Configuration.IsolationLevel, cancellationToken); + public Task BeginTransactionAsync() + => BeginTransactionAsync(CancellationToken.None); + /// /// Begins a new transaction if none has been yet. Use this method when writes need to be done. /// @@ -1431,6 +1458,9 @@ public async Task BeginTransactionAsync(IsolationLevel isolationL return _transaction; } + public Task BeginTransactionAsync(IsolationLevel isolationLevel) + => BeginTransactionAsync(isolationLevel, CancellationToken.None); + public Task CancelAsync() { EnterAsyncExecution(); diff --git a/src/YesSql.Core/Store.cs b/src/YesSql.Core/Store.cs index 6216fd854..7183b348d 100644 --- a/src/YesSql.Core/Store.cs +++ b/src/YesSql.Core/Store.cs @@ -115,6 +115,9 @@ public async Task InitializeAsync(CancellationToken cancellationToken = default) await InitializeCollectionAsync(string.Empty, cancellationToken); } + public Task InitializeAsync() + => InitializeAsync(CancellationToken.None); + public async Task InitializeCollectionAsync(string collection, CancellationToken cancellationToken = default) { var documentTable = Configuration.TableNameConvention.GetDocumentTable(collection); @@ -199,6 +202,9 @@ await builder.AlterTableAsync(documentTable, table => table } } + public Task InitializeCollectionAsync(string collection) + => InitializeCollectionAsync(collection, CancellationToken.None); + private void ValidateConfiguration() { if (Configuration.ConnectionFactory == null)