Beispiel #1
0
        private static string BuildWhereClause(BlockFilterCriteria filter, out DynamicParameters param)
        {
            param = new DynamicParameters();

            var whereClause = new StringBuilder();

            if (filter.HeightFrom.HasValue)
            {
                var fromHeight = filter.HeightFrom.Value;
                param.Add(nameof(fromHeight), fromHeight);
                whereClause.Append($"AND b.[Height] >= @fromHeight ");
            }

            if (filter.HeightTo.HasValue)
            {
                var toHeight = filter.HeightTo.Value;
                param.Add(nameof(toHeight), toHeight);
                whereClause.Append($"AND b.[Height] <= @toHeight ");
            }

            if (filter.MinSize.HasValue)
            {
                var min = filter.MinSize.Value;
                param.Add(nameof(min), min);
                whereClause.Append($"AND b.[Size] >= @min ");
            }

            if (filter.MaxSize.HasValue)
            {
                var max = filter.MaxSize.Value;
                param.Add(nameof(max), max);
                whereClause.Append($"AND b.[Size] <= @max ");
            }

            if (filter.UtcFrom.HasValue)
            {
                var fromDate = filter.UtcFrom.Value;
                param.Add(nameof(fromDate), fromDate);
                whereClause.Append($"AND b.[Timestamp] >= @fromDate ");
            }

            if (filter.UtcTo.HasValue)
            {
                var toDate = filter.UtcTo.Value;
                param.Add(nameof(toDate), toDate);
                whereClause.Append($"AND b.[Timestamp] <= @toDate ");
            }

            if (filter.Channel.HasValue)
            {
                var channel = filter.Channel.Value;
                param.Add(nameof(channel), channel);
                whereClause.Append($"AND b.[Channel] = @channel ");
            }

            return(whereClause.ToString());
        }
Beispiel #2
0
        public async Task <FilterResult <BlockLiteDto> > GetBlocksFilteredAsync(BlockFilterCriteria filter, int start, int count, bool countResults, int?maxResults = null)
        {
            const string from = @"
                FROM [dbo].[Block] b
                INNER JOIN [dbo].[Transaction] t ON t.[BlockHeight] = b.[Height]
                WHERE 1 = 1 ";

            const string groupBy = @"
                GROUP BY b.[Height], b.[Hash], b.[Size], b.[Channel], b.[Version], b.[MerkleRoot], 
		                 b.[Timestamp], b.[Nonce], b.[Bits], b.[Difficulty], b.[Mint] "        ;

            var where = BuildWhereClause(filter, out var param);

            var sqlOrderBy = "ORDER BY ";

            switch (filter.OrderBy)
            {
            case OrderBlocksBy.Highest:
                sqlOrderBy += "b.[Height] DESC ";
                break;

            case OrderBlocksBy.Lowest:
                sqlOrderBy += "b.[Height] ";
                break;

            case OrderBlocksBy.Largest:
                sqlOrderBy += "b.[Size] DESC ";
                break;

            case OrderBlocksBy.Smallest:
                sqlOrderBy += "b.[Size] ";
                break;

            default:
                sqlOrderBy += "b.[Height] DESC ";
                throw new ArgumentOutOfRangeException();
            }

            var sqlQ = $@"SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
                          SELECT
                          b.[Height],
	                      b.[Hash],
                          b.[Size],
                          b.[Channel],
                          b.[Timestamp],
                          b.[Difficulty],
                          b.[Mint],
	                      COUNT(t.[TransactionId]) AS TransactionCount
                          {from}
                          {where} 
                          {groupBy}                                          
                          {sqlOrderBy}
                          OFFSET @start ROWS FETCH NEXT @count ROWS ONLY;";

            var sqlC = $@"SELECT 
                         COUNT(*)
                         FROM (SELECT TOP (@maxResults)
                               1 AS Cnt
                               {from}
                               {where}
                               {groupBy}) AS resultCount;";

            using (var sqlCon = await DbConnectionFactory.GetNexusDbConnectionAsync())
            {
                var results = new FilterResult <BlockLiteDto>();

                param.Add(nameof(count), count);
                param.Add(nameof(start), start);
                param.Add(nameof(maxResults), maxResults ?? int.MaxValue);

                using (var multi = await sqlCon.QueryMultipleAsync(string.Concat(sqlQ, sqlC), param))
                {
                    var dbBlocks = (await multi.ReadAsync()).Select(x => new BlockLiteDto
                    {
                        Height           = x.Height,
                        Hash             = x.Hash,
                        Size             = x.Size,
                        Channel          = x.Channel,
                        Timestamp        = x.Timestamp,
                        Difficulty       = x.Difficulty,
                        Mint             = x.Mint,
                        TransactionCount = x.TransactionCount
                    });

                    results.Results     = dbBlocks.ToList();
                    results.ResultCount = countResults
                        ? (int)(await multi.ReadAsync <int>()).FirstOrDefault()
                        : -1;
                }

                return(results);
            }
        }