| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 | using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using InABox.Clients;namespace InABox.Core{    public class MultiQuery    {        private readonly List<InternalQueryDef> _queries = new List<InternalQueryDef>();        public int Count => _queries.Count;        public Dictionary<object, IQueryDef> Definitions()        {            Dictionary<object, IQueryDef> result = new Dictionary<object, IQueryDef>();            foreach (var query in _queries)                result[query.Key] = query.Query;            return result;        }                public Dictionary<object, CoreTable> Results()        {            Dictionary<object, CoreTable> result = new Dictionary<object, CoreTable>();            foreach (var query in _queries)                result[query.Key] = query.Result;            return result;        }        public void Clear()        {            _queries.Clear();        }        public void Add(IQueryDef query, object key)        {            if (key == null)                throw new Exception("MultiQuery Key many not be null");            if (_queries.Any(x => Equals(x.Key, key)))                throw new Exception("Key already exists");            _queries.Add(new InternalQueryDef            {                Key = key,                Query = query            });        }        public void Query(Action<MultiQuery> callback = null)        {            var tasks = new Dictionary<Task<CoreTable>, object>();            foreach (var query in _queries)            {                var task = Task.Run(                    () =>                    {                        var client = ClientFactory.CreateClient(query.Query.Type);                        return client.Query(query.Query.Filter, query.Query.Columns, query.Query.SortOrder);                    }                );                tasks[task] = query.Key;            }            if (callback == null)            {                Task.WaitAll(tasks.Keys.ToArray());                foreach (var task in tasks.Keys)                {                    var query = _queries.FirstOrDefault(x => Equals(x.Key, tasks[task]));                    query.Result = task.Result;                }            }            else            {                Task.WhenAll(tasks.Keys.ToArray()).ContinueWith(t =>                {                    foreach (var task in tasks.Keys)                    {                        var query = _queries.FirstOrDefault(x => Equals(x.Key, tasks[task]));                        query.Result = task.Result;                    }                    callback.Invoke(this);                });            }        }        public bool Contains(object key)        {            return _queries.Any(x => Equals(x.Key, key));        }        public CoreTable Get(object key)        {            var query = _queries.FirstOrDefault(x => Equals(x.Key, key));            if (query == null)                throw new Exception("Key does not exist");            if (query.Result == null)                throw new Exception("No result available");            return query.Result;        }        public void Set(object key, CoreTable table)        {            var query = _queries.FirstOrDefault(x => Equals(x.Key, key));            if (query == null)                throw new Exception("Key does not exist");            query.Result = table;        }                private class InternalQueryDef        {            public object Key { get; set; }            public IQueryDef Query { get; set; }            public CoreTable Result { get; set; }            public Entity[] Updates { get; set; }        }        #region Simplified Generic Helpers        public void Add<T>(Filter<T> filter = null, Columns<T> columns = null, SortOrder<T> sort = null)            where T : Entity, IRemotable, IPersistent, new()        {            Add(new QueryDef<T>(filter, columns, sort), typeof(T));        }        public CoreTable Get<T>()        {            return Get(typeof(T));        }        public bool Contains<T>()        {            return Contains(typeof(T));        }        #endregion    }}
 |