Esempio n. 1
0
        /// <summary>
        /// Executes the specified implementation asynchronously.
        /// </summary>
        /// <param name="executionToken">The execution token.</param>
        /// <param name="implementation">The implementation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="state">The state.</param>
        /// <returns>The caller is expected to use the StreamingCommandCompletionToken to close any lingering connections and fire appropriate events.</returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public override async Task <StreamingCommandCompletionToken> ExecuteStreamAsync(CommandExecutionToken <SQLiteCommand, SQLiteParameter> executionToken, StreamingCommandImplementationAsync <SQLiteCommand> implementation, CancellationToken cancellationToken, object?state)
        {
            if (executionToken == null)
            {
                throw new ArgumentNullException(nameof(executionToken), $"{nameof(executionToken)} is null.");
            }
            if (implementation == null)
            {
                throw new ArgumentNullException(nameof(implementation), $"{nameof(implementation)} is null.");
            }

            var mode = DisableLocks ? LockType.None : (executionToken as SQLiteCommandExecutionToken)?.LockType ?? LockType.Write;

            var startTime = DateTimeOffset.Now;

            OnExecutionStarted(executionToken, startTime, state);

            IDisposable?lockToken = null;

            try
            {
                switch (mode)
                {
                case LockType.Read: lockToken = await SyncLock.ReaderLockAsync().ConfigureAwait(false); break;

                case LockType.Write: lockToken = await SyncLock.WriterLockAsync().ConfigureAwait(false); break;
                }

                var cmd = new SQLiteCommand();

                cmd.Connection = m_Connection;
                if (m_Transaction != null)
                {
                    cmd.Transaction = m_Transaction;
                }
                executionToken.PopulateCommand(cmd, DefaultCommandTimeout);

                await implementation(cmd).ConfigureAwait(false);

                return(new StreamingCommandCompletionToken(this, executionToken, startTime, state, cmd)
                {
                    LockToken = lockToken
                });
            }
            catch (Exception ex)
            {
                lockToken?.Dispose();

                if (cancellationToken.IsCancellationRequested)                 //convert SQLiteException into a OperationCanceledException
                {
                    var ex2 = new OperationCanceledException("Operation was canceled.", ex, cancellationToken);
                    OnExecutionError(executionToken, startTime, DateTimeOffset.Now, ex2, state);
                    throw ex2;
                }
                else
                {
                    OnExecutionError(executionToken, startTime, DateTimeOffset.Now, ex, state);
                    throw;
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Executes the specified implementation asynchronously.
        /// </summary>
        /// <param name="executionToken">The execution token.</param>
        /// <param name="implementation">The implementation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <param name="state">The state.</param>
        /// <returns>The caller is expected to use the StreamingCommandCompletionToken to close any lingering connections and fire appropriate events.</returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public override async Task <StreamingCommandCompletionToken> ExecuteStreamAsync(CommandExecutionToken <NpgsqlCommand, NpgsqlParameter> executionToken, StreamingCommandImplementationAsync <NpgsqlCommand> implementation, CancellationToken cancellationToken, object?state)
        {
            if (executionToken == null)
            {
                throw new ArgumentNullException(nameof(executionToken), $"{nameof(executionToken)} is null.");
            }
            if (implementation == null)
            {
                throw new ArgumentNullException(nameof(implementation), $"{nameof(implementation)} is null.");
            }

            var startTime = DateTimeOffset.Now;

            OnExecutionStarted(executionToken, startTime, state);

            try
            {
                var cmd = new NpgsqlCommand();

                cmd.Connection = m_Connection;
                if (m_Transaction != null)
                {
                    cmd.Transaction = m_Transaction;
                }
                executionToken.PopulateCommand(cmd, DefaultCommandTimeout);

                if (((PostgreSqlCommandExecutionToken)executionToken).DereferenceCursors)
                {
                    await DereferenceCursorsAsync(cmd, implementation).ConfigureAwait(false);
                }
                else
                {
                    await implementation(cmd).ConfigureAwait(false);
                }

                return(new StreamingCommandCompletionToken(this, executionToken, startTime, state, cmd));
            }
            catch (Exception ex)
            {
                if (cancellationToken.IsCancellationRequested)                 //convert Exception into a OperationCanceledException
                {
                    var ex2 = new OperationCanceledException("Operation was canceled.", ex, cancellationToken);
                    OnExecutionCanceled(executionToken, startTime, DateTimeOffset.Now, state);
                    throw ex2;
                }
                else
                {
                    OnExecutionError(executionToken, startTime, DateTimeOffset.Now, ex, state);
                    throw;
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Dereferences cursors returned by a stored procedure.
        /// </summary>
        /// <param name="cmd">The command.</param>
        /// <param name="implementation">The implementation.</param>
        protected static async Task <NpgsqlTransaction?> DereferenceCursorsAsync(NpgsqlCommand cmd, StreamingCommandImplementationAsync <NpgsqlCommand> implementation)
        {
            if (cmd == null)
            {
                throw new ArgumentNullException(nameof(cmd), $"{nameof(cmd)} is null.");
            }
            if (cmd.Connection == null)
            {
                throw new ArgumentNullException($"{nameof(cmd)}.{nameof(cmd.Connection)}", $"{nameof(cmd)}.{nameof(cmd.Connection)} is null.");
            }
            if (implementation == null)
            {
                throw new ArgumentNullException(nameof(implementation), $"{nameof(implementation)} is null.");
            }

            var closeTransaction = false;

            if (cmd.Transaction == null)
            {
                cmd.Transaction  = cmd.Connection.BeginTransaction();
                closeTransaction = true;
            }

            var sql = new StringBuilder();

            using (var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))
                while (await reader.ReadAsync().ConfigureAwait(false))
                {
                    sql.AppendLine($"FETCH ALL IN \"{reader.GetString(0)}\";");
                }

            using (var cmd2 = new NpgsqlCommand())
            {
                cmd2.Connection     = cmd.Connection;
                cmd2.Transaction    = cmd.Transaction;
                cmd2.CommandTimeout = cmd.CommandTimeout;
                cmd2.CommandText    = sql.ToString();
                cmd2.CommandType    = CommandType.Text;
                await implementation(cmd2).ConfigureAwait(false);
            }

            return(closeTransaction ? cmd.Transaction : null);
        }
Esempio n. 4
0
    /// <summary>
    /// Execute stream as an asynchronous operation.
    /// </summary>
    /// <param name="executionToken">The execution token.</param>
    /// <param name="implementation">The implementation.</param>
    /// <param name="cancellationToken">The cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
    /// <param name="state">The state.</param>
    /// <returns>A Task&lt;StreamingCommandCompletionToken&gt; representing the asynchronous operation.</returns>
    /// <exception cref="System.ArgumentNullException">executionToken</exception>
    /// <exception cref="System.ArgumentNullException">implementation</exception>
    /// <exception cref="System.ArgumentNullException">executionToken - only AccessCommandExecutionToken is supported.</exception>
    /// <exception cref="System.InvalidOperationException">currentToken.ExecutionMode is ExecuteScalarAndForward, but currentToken.ForwardResult is null.</exception>
    public override async Task <StreamingCommandCompletionToken> ExecuteStreamAsync(CommandExecutionToken <OleDbCommand, OleDbParameter> executionToken, StreamingCommandImplementationAsync <OleDbCommand> implementation, CancellationToken cancellationToken, object?state)
    {
        if (executionToken == null)
        {
            throw new ArgumentNullException(nameof(executionToken), $"{nameof(executionToken)} is null.");
        }
        if (implementation == null)
        {
            throw new ArgumentNullException(nameof(implementation), $"{nameof(implementation)} is null.");
        }
        var currentToken = executionToken as AccessCommandExecutionToken;

        if (currentToken == null)
        {
            throw new ArgumentNullException(nameof(executionToken), "only AccessCommandExecutionToken is supported.");
        }

        var startTime = DateTimeOffset.Now;

        OleDbConnection?con = null;

        try
        {
            con = await CreateConnectionAsync(cancellationToken).ConfigureAwait(false);

            OleDbCommand?cmdToReturn = null;
            while (currentToken != null)
            {
                OnExecutionStarted(currentToken, startTime, state);
                using (var cmd = new OleDbCommand())
                {
                    cmd.Connection = con;
                    currentToken.PopulateCommand(cmd, DefaultCommandTimeout);

                    if (currentToken.ExecutionMode == AccessCommandExecutionMode.Materializer)
                    {
                        await implementation(cmd).ConfigureAwait(false);

                        cmdToReturn = cmd;
                    }
                    else if (currentToken.ExecutionMode == AccessCommandExecutionMode.ExecuteScalarAndForward)
                    {
                        if (currentToken.ForwardResult == null)
                        {
                            throw new InvalidOperationException("currentToken.ExecutionMode is ExecuteScalarAndForward, but currentToken.ForwardResult is null.");
                        }

                        currentToken.ForwardResult(await cmd.ExecuteScalarAsync().ConfigureAwait(false));
                    }
                    else
                    {
                        await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
                    }
                }
                currentToken = currentToken.NextCommand;
            }

            return(new StreamingCommandCompletionToken(this, executionToken, startTime, state, cmdToReturn, con));
        }
        catch (Exception ex)
        {
#if NET6_0_OR_GREATER
            if (con != null)
            {
                await con.DisposeAsync().ConfigureAwait(false);
            }
#else
            con?.Dispose();
#endif

            if (cancellationToken.IsCancellationRequested)             //convert Exception into a OperationCanceledException
            {
                var ex2 = new OperationCanceledException("Operation was canceled.", ex, cancellationToken);
                OnExecutionError(executionToken, startTime, DateTimeOffset.Now, ex2, state);
                throw ex2;
            }
            else
            {
                OnExecutionError(executionToken, startTime, DateTimeOffset.Now, ex, state);
                throw;
            }
        }
    }
Esempio n. 5
0
 /// <summary>
 /// Executes the specified implementation asynchronously.
 /// </summary>
 /// <param name="executionToken">The execution token.</param>
 /// <param name="implementation">The implementation.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <param name="state">The state.</param>
 /// <returns>The caller is expected to use the StreamingCommandCompletionToken to close any lingering connections and fire appropriate events.</returns>
 public abstract Task <StreamingCommandCompletionToken> ExecuteStreamAsync(CommandExecutionToken <TCommand, TParameter> executionToken, StreamingCommandImplementationAsync <TCommand> implementation, CancellationToken cancellationToken, object?state);
Esempio n. 6
0
    /// <summary>
    /// Executes the specified implementation asynchronously.
    /// </summary>
    /// <param name="executionToken">The execution token.</param>
    /// <param name="implementation">The implementation.</param>
    /// <param name="cancellationToken">The cancellation token.</param>
    /// <param name="state">The state.</param>
    /// <returns>The caller is expected to use the StreamingCommandCompletionToken to close any lingering connections and fire appropriate events.</returns>
    /// <exception cref="System.NotImplementedException"></exception>
    public override async Task <StreamingCommandCompletionToken> ExecuteStreamAsync(CommandExecutionToken <SqlCommand, SqlParameter> executionToken, StreamingCommandImplementationAsync <SqlCommand> implementation, CancellationToken cancellationToken, object?state)
    {
        if (executionToken == null)
        {
            throw new ArgumentNullException(nameof(executionToken), $"{nameof(executionToken)} is null.");
        }
        if (implementation == null)
        {
            throw new ArgumentNullException(nameof(implementation), $"{nameof(implementation)} is null.");
        }

        var startTime = DateTimeOffset.Now;

        OnExecutionStarted(executionToken, startTime, state);

        SqlConnection?con = null;

        try
        {
            con = await CreateConnectionAsync(cancellationToken).ConfigureAwait(false);

            var cmd = new SqlCommand();

            cmd.Connection = con;
            executionToken.PopulateCommand(cmd, DefaultCommandTimeout);

            await implementation(cmd).ConfigureAwait(false);

            return(new StreamingCommandCompletionToken(this, executionToken, startTime, state, cmd, con));
        }
        catch (Exception ex)
        {
#if NET6_0_OR_GREATER
            if (con != null)
            {
                await con.DisposeAsync().ConfigureAwait(false);
            }
#else
            con?.Dispose();
#endif

            if (cancellationToken.IsCancellationRequested)             //convert Exception into a OperationCanceledException
            {
                var ex2 = new OperationCanceledException("Operation was canceled.", ex, cancellationToken);
                OnExecutionCanceled(executionToken, startTime, DateTimeOffset.Now, state);
                throw ex2;
            }
            else
            {
                OnExecutionError(executionToken, startTime, DateTimeOffset.Now, ex, state);
                throw;
            }
        }
    }