public async Task <PaginationResult <AuditLog> > GetAllAsync(RequestMethod method, int skip = 0, int limit = 0, OrderDirection direction = OrderDirection.None)
        {
            IQueryable <AuditLog> result;
            var rv = new PaginationResult <AuditLog>();

            if (method == RequestMethod.Any)
            {
                result = this.Data.AsQueryable();
            }
            else
            {
                result = this.Data.Where(log => log.Method == method);
            }

            result = direction switch {
                OrderDirection.Ascending => result.OrderBy(x => x.Timestamp),
                OrderDirection.Descending => result.OrderByDescending(x => x.Timestamp),
                _ => result
            };

            rv.Count = await result.CountAsync().AwaitBackground();

            if (skip > 0)
            {
                result = result.Skip(skip);
            }

            if (limit > 0)
            {
                result = result.Take(limit);
            }

            rv.Values = await result.ToListAsync().AwaitBackground();

            foreach (var log in rv.Values)
            {
                log.Timestamp = DateTime.SpecifyKind(log.Timestamp, DateTimeKind.Utc);
            }

            return(rv);
        }
        public IList <MeasurementsQueryResult> GetMeasurementsNear(List <MeasurementsQueryResult> measurements,
                                                                   GeoJsonPoint coords,
                                                                   int radius           = 100,
                                                                   int skip             = -1,
                                                                   int limit            = -1,
                                                                   OrderDirection order = OrderDirection.None,
                                                                   CancellationToken ct = default)
        {
            DistanceCalcuationMethod calc;
            var queryResults = new List <MeasurementsQueryResult>(measurements.Count);

            for (var idx = 0; idx < measurements.Count; idx++)
            {
                queryResults.Add(null);
            }

            var results = queryResults;

            if (radius >= ErrorMarginBoundary || measurements.Count > MeasurementMargin)
            {
                calc = FastCalculateDistanceBetween;
            }
            else
            {
                calc = CalculateDistanceBetween;
            }

            var geoCoords = coords.ToCoordinates();

            Parallel.For(0, measurements.Count, (index, state) => {
                double maxDist  = radius;
                var measurement = measurements[index];
                var dist        = calc(geoCoords, measurement.Location.Coordinates);

                if (dist > maxDist)
                {
                    return;
                }

                results[index] = measurement;
            });

            queryResults.RemoveAll(x => x == null);

            queryResults = order switch {
                OrderDirection.Descending => queryResults.OrderByDescending(x => x.Timestamp).ToList(),
                OrderDirection.Ascending => queryResults.OrderBy(x => x.Timestamp).ToList(),
                _ => queryResults
            };

            if (skip > 0)
            {
                queryResults = queryResults.Skip(skip).ToList();
            }

            if (limit > 0)
            {
                queryResults = queryResults.Take(limit).ToList();
            }

            return(queryResults);
        }
        public async Task <PaginationResult <AuditLog> > FindAsync(
            IEnumerable <string> uids,
            string text,
            RequestMethod method     = RequestMethod.Any,
            int skip                 = 0,
            int limit                = 0,
            OrderDirection direction = OrderDirection.None
            )
        {
            IQueryable <AuditLog> logs;
            var rv = new PaginationResult <AuditLog>();

            if (method == RequestMethod.Any)
            {
                if (text == null)
                {
                    logs =
                        from log in this.Data
                        where uids.Contains(log.AuthorId)
                        select log;
                }
                else
                {
                    logs =
                        from log in this.Data
                        where uids.Contains(log.AuthorId) &&
                        log.Route.Contains(text)
                        select log;
                }
            }
            else
            {
                if (text == null)
                {
                    logs = this.Data.Where(log => uids.Contains(log.AuthorId) && log.Method == method);
                }
                else
                {
                    logs = this.Data.Where(log => uids.Contains(log.AuthorId) && log.Method == method && log.Route.Contains(text));
                }
            }

            logs = direction switch {
                OrderDirection.Ascending => logs.OrderBy(x => x.Timestamp),
                OrderDirection.Descending => logs.OrderByDescending(x => x.Timestamp),
                _ => logs
            };

            rv.Count = await logs.CountAsync().AwaitBackground();

            if (skip > 0)
            {
                logs = logs.Skip(skip);
            }

            if (limit > 0)
            {
                logs = logs.Take(limit);
            }

            rv.Values = await logs.ToListAsync().AwaitBackground();

            foreach (var log in rv.Values)
            {
                log.Timestamp = DateTime.SpecifyKind(log.Timestamp, DateTimeKind.Utc);
            }

            return(rv);
        }