void IStorage.CommitAddedMessages(long transId, IStorageTransaction storageTrans)
        {
            var sql =
                "Update Messages SET State = @State, TransactionId = NULL, TransactionAction = NULL where TransactionId = @TranId  and TransactionAction = @TranAction;";

            _con.Execute(sql, transaction: (storageTrans as InternalTransaction)?.SqliteTransaction, param: new { State = MessageState.Active.Value, TranId = transId, TranAction = TransactionAction.Add.Value });
        }
Exemple #2
0
        public async Task AddTrades(IStorageTransaction transaction, ILogger logger, TradeResult tradeResult)
        {
            try
            {
                var trades = tradeResult.Trades
                             .Select(trade => new MarketTrade
                {
                    Epoch         = trade.Epoch,
                    Exchange      = tradeResult.Exchange,
                    SymbolCode    = tradeResult.SymbolCode,
                    Side          = trade.Side.HasValue ? trade.Side : null,
                    Price         = trade.Price,
                    Volume        = trade.Volume,
                    SourceTradeId = trade.SourceTradeId
                }).OrderBy(t => t.Epoch.TimestampMilliseconds).ToList();

                if (trades.Count > 0)
                {
                    await MarketRepository.SaveTrades(transaction, trades);
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"Unable to save trades into the repository.");
            }
        }
        public async Task SaveTrades(IStorageTransaction transaction, ICollection <MarketTrade> trades)
        {
            var context = (HistorianDbContext)transaction.GetContext();

            using (var cmd = context.Database.GetDbConnection().CreateCommand())
            {
                cmd.Transaction = context.Database.CurrentTransaction.GetDbTransaction();

                var sql = @"insert ignore into `exchange_trade`
                (`exchange_id`,
                `symbol_id`,
                `timestamp`,
                `order_side_id`,
                `price`,
                `volume`,
                `source_trade_id`) values ";

                sql += string.Join(",", trades.Select(trade => $"({(int)trade.Exchange}," +
                                                      $"{(int)trade.SymbolCode}," +
                                                      $"{trade.Epoch.TimestampMilliseconds}," +
                                                      $"{(trade.Side.HasValue ? ((int)trade.Side).ToString() : "NULL")}," +
                                                      $"{trade.Price}," +
                                                      $"{trade.Volume}," +
                                                      $"{(trade.SourceTradeId != null ? trade.SourceTradeId : "NULL")})"));

                cmd.CommandText = sql;

                await cmd.ExecuteNonQueryAsync();
            }
        }
        void IStorage.CommitPulledMessages(long transId, IStorageTransaction storageTrans, DateTime commitDateTime)
        {
            var sql =
                "Update Messages SET State = @State, TransactionId = NULL, TransactionAction = NULL, CloseDateTime = @CloseDateTime where TransactionId = @TranId  and TransactionAction = @TranAction;";

            _con.Execute(sql, transaction: (storageTrans as InternalTransaction)?.SqliteTransaction,
                         param: new
            {
                State         = MessageState.Processed.Value,
                TranId        = transId,
                TranAction    = TransactionAction.Pull.Value,
                CloseDateTime = commitDateTime
            });
        }
        public void ChangeState(Job job, IState state, IStorageTransaction transaction)
        {
            var now = DateTime.UtcNow;

            if (state.ExpiresAfter != null)
            {
                job.ExpiresAt = now.Add(state.ExpiresAfter.Value);
            }
            else
            {
                job.ExpiresAt = null;
            }

            job.StateName = state.Name;
            state.Apply(job, transaction);
            transaction.UpdateJob(job);
        }
Exemple #6
0
        public void ChangeState(PublishedMessage message, IState state, IStorageTransaction transaction)
        {
            var now = DateTime.Now;

            if (state.ExpiresAfter != null)
            {
                message.ExpiresAt = now.Add(state.ExpiresAfter.Value);
            }
            else
            {
                message.ExpiresAt = null;
            }

            message.StatusName = state.Name;
            state.Apply(message, transaction);
            transaction.UpdateMessage(message);
        }
Exemple #7
0
 /// <inheritdoc/>
 public async ValueTask UpdateTransactionState(IStorageTransaction storageTrans, long transId, TransactionState state, string?endReason = null, DateTime?endDateTime = null)
 {
     await this.ExecuteAsync(
         async (connection) =>
     {
         const string sql = "UPDATE transactions SET end_datetime = @EndDateTime, state = @State, end_reason = @EndReason WHERE id = @Id;";
         await connection.ExecuteAsync(
             sql,
             new
         {
             Id          = transId,
             State       = state,
             EndDateTime = endDateTime,
             EndReason   = endReason
         },
             storageTrans.NpgsqlTransaction());
     },
         storageTrans.NpgsqlTransaction().Connection);
 }
Exemple #8
0
 /// <inheritdoc/>
 public async ValueTask UpdateTransactionState(IStorageTransaction storageTrans, long transId, TransactionState state, string?endReason = null, DateTime?endDateTime = null)
 {
     await this.ExecuteAsync(
         async (connection) =>
     {
         const string sql = "UPDATE Transactions SET EndDateTime = @EndDateTime, State = @State, EndReason = @EndReason WHERE ID = @Id;";
         await connection.ExecuteAsync(
             sql,
             new
         {
             Id          = transId,
             State       = state,
             EndDateTime = endDateTime?.ToUnixEpoch(),
             EndReason   = endReason
         },
             storageTrans.SqliteTransaction());
     },
         storageTrans.SqliteTransaction().Connection);
 }
Exemple #9
0
        public async Task SetLastTradeStatId(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, long lastTradeStatId)
        {
            var context = (HistorianDbContext)transaction.GetContext();

            var history = await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode);

            if (history == null)
            {
                history = new HistorianExchangeSymbolEntity
                {
                    ExchangeId = (int)exchange,
                    SymbolId   = (int)symbolCode
                };

                await context.HistorianExchangeSymbol.AddAsync(history);
            }

            history.LastTradeStatId = lastTradeStatId;
        }
Exemple #10
0
        /// <inheritdoc/>
        public async ValueTask <int> DeleteAddedMessages(IStorageTransaction storageTrans, long transId)
        {
            const string sql = "DELETE FROM messages where transaction_id = @TransId AND transaction_action = @TransactionAction AND state = @MessageState;";
            var          sqliteConnection = storageTrans.NpgsqlTransaction().Connection;

            return(await this.ExecuteAsync <int>(
                       async (connection) =>
            {
                return await connection.ExecuteAsync(
                    sql,
                    transaction: (storageTrans as DbTransaction)?.NpgsqlTransaction,
                    param: new
                {
                    TransId = transId,
                    TransactionAction = TransactionAction.Add,
                    MessageState = MessageState.InTransaction
                });
            },
                       sqliteConnection));
        }
Exemple #11
0
        /// <inheritdoc/>
        public async ValueTask <int> UpdateMessageAttemptCount(IStorageTransaction storageTrans, long transId, TransactionAction transactionAction, MessageState messageState)
        {
            const string sql = "Update messages set attempts = attempts + 1 " +
                               "where transaction_id = @TransId AND transaction_action = @TransactionAction AND state = @MessageState;";
            var sqliteConnection = storageTrans.NpgsqlTransaction().Connection;

            return(await this.ExecuteAsync <int>(
                       async (connection) =>
            {
                return await connection.ExecuteAsync(
                    sql,
                    transaction: (storageTrans as DbTransaction)?.NpgsqlTransaction,
                    param: new
                {
                    TransId = transId,
                    TransactionAction = transactionAction,
                    MessageState = messageState
                });
            },
                       sqliteConnection));
        }
        void IStorage.AddMessage(long transId, IStorageTransaction storageTrans, long nextId, long queueId, byte[] compressedMessage, DateTime addDateTime, string metaData = "", int priority = 0, int maxRetries = 3, DateTime?expiryDateTime = null, int correlation = 0, string groupName = "")
        {
            var sql = "INSERT INTO Messages (Id, QueueId, TransactionId, TransactionAction, State, AddDateTime, Priority, MaxRetries, Retries, ExpiryDate, Data, CorrelationId, GroupName, Metadata) VALUES " +
                      "(@Id, @QueueId, @TransactionId, @TransactionAction, @State, @AddDateTime, @Priority, @MaxRetries, 0, @ExpiryDate, @Data, @CorrelationId, @GroupName, @Metadata);";

            _con.Execute(sql, transaction: (storageTrans as InternalTransaction)?.SqliteTransaction, param: new
            {
                Id                = nextId,
                QueueId           = queueId,
                TransactionId     = transId,
                TransactionAction = TransactionAction.Pull.Value,
                State             = MessageState.InTransaction.Value,
                AddDateTime       = addDateTime,
                Priority          = priority,
                MaxRetries        = maxRetries,
                ExpiryDate        = expiryDateTime ?? DateTime.MaxValue,
                Data              = compressedMessage,
                CorrelationId     = correlation,
                GroupName         = groupName,
                Metadata          = metaData
            });
        }
Exemple #13
0
        /// <inheritdoc/>
        public async ValueTask <int> DeleteAddedMessagesInExpiredTrans(IStorageTransaction storageTrans, DateTime currentDateTime)
        {
            const string sql =
                "Delete from messages where TransactionAction = @TransactionAction AND State = @MessageState AND " +
                "TransactionId in (select ID from Transactions Where ExpiryDateTime <= @CurrentDateTime);";
            var sqliteConnection = storageTrans.SqliteTransaction().Connection;

            return(await this.ExecuteAsync <int>(
                       async (connection) =>
            {
                return await connection.ExecuteAsync(
                    sql,
                    transaction: (storageTrans as DbTransaction)?.SqliteTransaction,
                    param: new
                {
                    TransactionAction = TransactionAction.Add,
                    MessageState = MessageState.InTransaction,
                    CurrentDateTime = currentDateTime.ToUnixEpoch()
                });
            },
                       sqliteConnection));
        }
Exemple #14
0
        /// <inheritdoc/>
        public async ValueTask <int> DeleteAddedMessagesInExpiredTrans(IStorageTransaction storageTrans, DateTime currentDateTime)
        {
            const string sql =
                "Delete from messages where transaction_action = @TransactionAction AND state = @MessageState AND " +
                "transaction_id in (select id from transactions Where expiry_datetime <= @CurrentDateTime);";
            var sqliteConnection = storageTrans.NpgsqlTransaction().Connection;

            return(await this.ExecuteAsync <int>(
                       async (connection) =>
            {
                return await connection.ExecuteAsync(
                    sql,
                    transaction: (storageTrans as DbTransaction)?.NpgsqlTransaction,
                    param: new
                {
                    TransactionAction = TransactionAction.Add,
                    MessageState = MessageState.InTransaction,
                    CurrentDateTime = currentDateTime
                });
            },
                       sqliteConnection));
        }
        public async Task SaveTradeStats(IStorageTransaction transaction, ICollection <MarketTradeStat> tradeStats)
        {
            using (var context = ContextFactory.CreateDbContext(null))
            {
                using (var cmd = context.Database.GetDbConnection().CreateCommand())
                {
                    cmd.CommandText = $@"insert ignore into `exchange_trade_stat`
                    (`exchange_id`,
                    `symbol_id`,
                    `stat_key_id`,
                    `timestamp`,
                    `value`)
                    values {string.Join(",\r\n", tradeStats.Select(t => $"({(int)t.Exchange},{(int)t.SymbolCode},{(int)t.StatKey},{t.Epoch.TimestampMilliseconds},{t.Value})"))}
                    on duplicate key update `value` = values(`value`)";

                    await cmd.Connection.OpenAsync();

                    await cmd.ExecuteNonQueryAsync();

                    cmd.Connection.Close();
                }
            }
        }
Exemple #16
0
        /// <inheritdoc/>
        public async ValueTask <int> ExpireTransactions(IStorageTransaction storageTrans, DateTime currentDateTime)
        {
            const string sql =
                "Update transactions SET state = @NewTransactionState, end_datetime = @CurrentDateTime, end_reason = 'Expired' " +
                "Where expiry_datetime <= @CurrentDateTime AND state = @OldTransactionState;";
            var sqliteConnection = storageTrans.NpgsqlTransaction().Connection;

            return(await this.ExecuteAsync <int>(
                       async (connection) =>
            {
                return await connection.ExecuteAsync(
                    sql,
                    transaction: (storageTrans as DbTransaction)?.NpgsqlTransaction,
                    param: new
                {
                    NewTransactionState = TransactionState.Expired,
                    MessageState = MessageState.InTransaction,
                    CurrentDateTime = currentDateTime,
                    OldTransactionState = TransactionState.Active
                });
            },
                       sqliteConnection));
        }
Exemple #17
0
        public async Task <TradeResult> ReceiveTradesHttp(IStorageTransaction transaction, ILogger logger, ExchangeEnum exchange, ISymbol symbol, IExchangeHttpClient httpClient, int limit, string lastTradeFilter)
        {
            logger.LogInformation($"Requesting trades from filter '{lastTradeFilter}'");

            var response = await httpClient.GetTrades(symbol, limit, lastTradeFilter);

            var tradeResult = response.Data;

            if (response.StatusCode != WrappedResponseStatusCode.Ok)
            {
                var errorCode = !string.IsNullOrEmpty(response.ErrorCode) ? $"Error Code: {response.ErrorCode} Message: " : "";

                logger.LogWarning($"Unable to get trades: {errorCode}{response.ErrorMessage}");

                return(null);
            }

            if (tradeResult.Trades.Count > 0)
            {
                await AddTrades(transaction, logger, tradeResult);
            }

            return(tradeResult);
        }
Exemple #18
0
        public async Task SetTradeFilter(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, string filter)
        {
            var context = (HistorianDbContext)transaction.GetContext();

            var entity = await context.HistorianExchangeSymbol.FindAsync((int)exchange, (int)symbolCode);

            if (entity == null)
            {
                entity = new HistorianExchangeSymbolEntity
                {
                    ExchangeId  = (int)exchange,
                    SymbolId    = (int)symbolCode,
                    TradeFilter = filter
                };

                await context.HistorianExchangeSymbol.AddAsync(entity);
            }
            else
            {
                entity.TradeFilter = filter;

                context.Update(entity);
            }
        }
Exemple #19
0
        /// <inheritdoc/>
        public async ValueTask <int> UpdateMessageAttemptsInExpiredTrans(IStorageTransaction storageTrans, DateTime currentDateTime)
        {
            const string sql =
                "Update messages set attempts = attempts + 1, transaction_action = 0, transaction_id = null, state = @NewMessageState " +
                "where transaction_action = @TransactionAction AND state = @MessageState AND " +
                "transaction_id in (select id from transactions Where expiry_datetime <= @CurrentDateTime);";
            var sqliteConnection = storageTrans.NpgsqlTransaction().Connection;

            return(await this.ExecuteAsync <int>(
                       async (connection) =>
            {
                return await connection.ExecuteAsync(
                    sql,
                    transaction: (storageTrans as DbTransaction)?.NpgsqlTransaction,
                    param: new
                {
                    TransactionAction = TransactionAction.Pull,
                    MessageState = MessageState.InTransaction,
                    CurrentDateTime = currentDateTime,
                    NewMessageState = MessageState.Active         // Return to active for now. We won't worry about closing it here, if it needs to be.
                });
            },
                       sqliteConnection));
        }
Exemple #20
0
        /// <inheritdoc/>
        public async ValueTask <int> UpdateMessages(IStorageTransaction storageTrans, long transId, TransactionAction transactionAction, MessageState oldMessageState, MessageState newMessageState, DateTime?closeDateTime)
        {
            const string sql = "Update messages set transaction_id = null, transaction_action = 0,  " +
                               "state = @NewMessageState, close_datetime = @CloseDateTime " +
                               "where transaction_id = @TransId AND transaction_action = @TransactionAction AND state = @OldMessageState;";
            var sqliteConnection = storageTrans.NpgsqlTransaction().Connection;

            return(await this.ExecuteAsync <int>(
                       async (connection) =>
            {
                return await connection.ExecuteAsync(
                    sql,
                    transaction: (storageTrans as DbTransaction)?.NpgsqlTransaction,
                    param: new
                {
                    TransId = transId,
                    TransactionAction = transactionAction,
                    OldMessageState = oldMessageState,
                    NewMessageState = newMessageState,
                    CloseDateTime = closeDateTime
                });
            },
                       sqliteConnection));
        }
 public void Apply(Job job, IStorageTransaction transaction)
 {
     transaction.EnqueueJob(job);
 }
Exemple #22
0
 public void Apply(CapReceivedMessage message, IStorageTransaction transaction)
 {
 }
Exemple #23
0
 public void Apply(CapPublishedMessage message, IStorageTransaction transaction)
 {
 }
 public void Apply(Job job, IStorageTransaction transaction)
 {
 }
 /// <summary>
 /// Converts the IStorageTransaction to a SqliteTransaction.
 /// </summary>
 /// <param name="iTrans">The IStorageTransaction to convert.</param>
 /// <returns>SqliteTransaction.</returns>
 public static SqliteTransaction SqliteTransaction(this IStorageTransaction iTrans)
 {
     return((iTrans as DbTransaction).SqliteTransaction);
 }
        public async Task SaveTradeStatAggregates(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, ICollection <MarketTradeStat> tradeStats)
        {
            var min = tradeStats.Min(t => t.Epoch);
            var max = tradeStats.Max(t => t.Epoch);

            var expanded = new List <TradeStatCartesian>();

            foreach (var group in IntervalFactory.ListGroups())
            {
                foreach (var ik in IntervalFactory.ListIntervalKeys(group.IntervalGroup))
                {
                    foreach (var tradeStat in tradeStats)
                    {
                        var period = IntervalFactory.GenerateIntervals(ik, tradeStat.Epoch, tradeStat.Epoch).FirstOrDefault();

                        expanded.Add(new TradeStatCartesian
                        {
                            IntervalKey   = period.IntervalKey,
                            IntervalEpoch = period.From,
                            Exchange      = tradeStat.Exchange,
                            SymbolCode    = symbolCode,
                            StatKey       = tradeStat.StatKey,
                            Epoch         = tradeStat.Epoch,
                            Value         = tradeStat.Value
                        });
                    }
                }
            }

            using (var context = ContextFactory.CreateDbContext(null))
            {
                using (var cmd = context.Database.GetDbConnection().CreateCommand())
                {
                    var sql = @"insert into `exchange_trade_aggregate`
                    (`exchange_id`,
                    `symbol_id`,
                    `interval_key`,
                    `timestamp`,
                    `open`,
                    `open_timestamp`,
                    `high`,
                    `low`,
                    `close`,
                    `close_timestamp`,
                    `total_count`) values ";

                    sql += string.Join(",\r\n", expanded.Select(t => $"(" +
                                                                $"{(int)t.Exchange}," +
                                                                $"{(int)t.SymbolCode}," +
                                                                $"'{t.IntervalKey.Key}'," +
                                                                $"{t.IntervalEpoch.TimestampMilliseconds}," +
                                                                $"{t.Value}," +
                                                                $"{t.Epoch.TimestampMilliseconds}," +
                                                                $"{t.Value}," +
                                                                $"{t.Value}," +
                                                                $"{t.Value}," +
                                                                $"{t.Epoch.TimestampMilliseconds}," +
                                                                $"1)"));

                    sql += @"
                    on duplicate key update
	                    `open` = case when values(`open_timestamp`) < `open_timestamp` then values(`open`) else `open` end,
	                    `open_timestamp` = case when values(`open_timestamp`) < `open_timestamp` then values(`open_timestamp`) else `open_timestamp` end,
                        `high` = case when values(`high`) > `high` then values(`high`) else `high` end,
                        `low` = case when values(`low`) < `low` then values(`low`) else `low` end,
                        `close` = case when values(`close_timestamp`) > `close_timestamp` then values(`close`) else `close` end,
	                    `close_timestamp` = case when values(`close_timestamp`) > `close_timestamp` then values(`close_timestamp`) else `close_timestamp` end,
	                    `total_count` = `total_count` + values(`total_count`)"    ;

                    cmd.CommandText = sql;

                    await cmd.Connection.OpenAsync();

                    await cmd.ExecuteNonQueryAsync();

                    cmd.Connection.Close();
                }
            }
        }
        public async Task SaveTradeAggregates(IStorageTransaction transaction, ExchangeEnum exchange, SymbolCodeEnum symbolCode, ICollection <MarketTrade> trades)
        {
            var min = trades.Min(t => t.Epoch);
            var max = trades.Max(t => t.Epoch);

            var expanded = new List <TradeCartesian>();

            foreach (var group in IntervalFactory.ListGroups())
            {
                foreach (var ik in IntervalFactory.ListIntervalKeys(group.IntervalGroup))
                {
                    foreach (var trade in trades)
                    {
                        var period = IntervalFactory.GenerateIntervals(ik, trade.Epoch, trade.Epoch).FirstOrDefault();

                        expanded.Add(new TradeCartesian
                        {
                            IntervalKey   = period.IntervalKey,
                            IntervalEpoch = period.From,
                            Exchange      = trade.Exchange,
                            SymbolCode    = trade.SymbolCode,
                            Epoch         = trade.Epoch,
                            TradeId       = trade.TradeId,
                            Price         = trade.Price,
                            Volume        = trade.Volume,
                            Side          = trade.Side
                        });
                    }
                }
            }

            var context = (HistorianDbContext)transaction.GetContext();

            using (var cmd = context.Database.GetDbConnection().CreateCommand())
            {
                cmd.Transaction = context.Database.CurrentTransaction.GetDbTransaction();

                var sql = @"insert into `exchange_trade_aggregate`
                (`exchange_id`,
                `symbol_id`,
                `interval_key`,
                `timestamp`,
                `open`,
                `open_timestamp`,
                `high`,
                `low`,
                `close`,
                `close_timestamp`,
                `buy_volume`,
                `sell_volume`,
                `total_volume`,
                `buy_count`,
                `sell_count`,
                `total_count`) values ";

                sql += string.Join(",\r\n", expanded.Select(t => $"(" +
                                                            $"{(int)t.Exchange}," +
                                                            $"{(int)t.SymbolCode}," +
                                                            $"'{t.IntervalKey.Key}'," +
                                                            $"{t.IntervalEpoch.TimestampMilliseconds}," +
                                                            $"{t.Price}," +
                                                            $"{t.Epoch.TimestampMilliseconds}," +
                                                            $"{t.Price}," +
                                                            $"{t.Price}," +
                                                            $"{t.Price}," +
                                                            $"{t.Epoch.TimestampMilliseconds}," +
                                                            $"{(t.Side == OrderSideEnum.Buy ? t.Volume.ToString() : "NULL")}," +
                                                            $"{(t.Side == OrderSideEnum.Sell ? t.Volume.ToString() : "NULL")}," +
                                                            $"{t.Volume}," +
                                                            $"{(t.Side == OrderSideEnum.Buy ? "1" : "NULL")}," +
                                                            $"{(t.Side == OrderSideEnum.Sell ? "1" : "NULL")}," +
                                                            $"1)"));

                sql += @"
                on duplicate key update
	                `open` = case when values(`open_timestamp`) < `open_timestamp` then values(`open`) else `open` end,
	                `open_timestamp` = case when values(`open_timestamp`) < `open_timestamp` then values(`open_timestamp`) else `open_timestamp` end,
                    `high` = case when values(`high`) > `high` then values(`high`) else `high` end,
                    `low` = case when values(`low`) < `low` then values(`low`) else `low` end,
                    `close` = case when values(`close_timestamp`) > `close_timestamp` then values(`close`) else `close` end,
	                `close_timestamp` = case when values(`close_timestamp`) > `close_timestamp` then values(`close_timestamp`) else `close_timestamp` end,
	                `buy_volume` = case when values(`buy_volume`) is not null then ifnull(`buy_volume`, 0) + values(`buy_volume`) else `buy_volume` end,
                    `sell_volume` = case when values(`sell_volume`) is not null then ifnull(`sell_volume`, 0) + values(`sell_volume`) else `sell_volume` end,
                    `total_volume` = `total_volume` + values(`total_volume`),
                    `buy_count` = case when values(`buy_count`) is not null then ifnull(`buy_count`, 0) + values(`buy_count`) else `buy_count` end,
                    `sell_count` = case when values(`sell_count`) is not null then ifnull(`sell_count`, 0) + values(`sell_count`) else `sell_count` end,
                    `total_count` = `total_count` + values(`total_count`)";

                cmd.CommandText = sql;

                await cmd.ExecuteNonQueryAsync();
            }
        }
        void IStorage.UpdateRetriesOnRollbackedMessages(long transId, IStorageTransaction storageTrans)
        {
            var sql = "UPDATE Messages SET State = @State, TransactionId = NULL, TransactionAction = NULL, Retries = Retries + 1 WHERE TransactionId = @tranId and TransactionAction = @TranAction;";

            _con.Execute(sql, new { State = MessageState.Active, transId, TranAction = TransactionAction.Pull.Value }, (storageTrans as InternalTransaction)?.SqliteTransaction);
        }
        void IStorage.CommitMessageTransaction(long transId, IStorageTransaction storageTrans, DateTime commitDateTime)
        {
            var sql = "UPDATE Transactions SET Active = 0, EndDateTime = @EndDateTime WHERE Id = @TranId;";

            _con.Execute(sql, transaction: (storageTrans as InternalTransaction)?.SqliteTransaction, param: new { TranId = transId, EndDateTime = commitDateTime });
        }
        void IStorage.DeleteQueue(long id, IStorageTransaction storageTrans)
        {
            var sql = "DELETE FROM Queues WHERE Id = @Id;";

            _con.Execute(sql, transaction: (storageTrans as InternalTransaction)?.SqliteTransaction, param: new { Id = id });
        }