MultiQuery.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using InABox.Clients;
  6. namespace InABox.Core
  7. {
  8. public class MultiQuery
  9. {
  10. private readonly List<InternalQueryDef> _queries = new List<InternalQueryDef>();
  11. public int Count => _queries.Count;
  12. public void Clear()
  13. {
  14. _queries.Clear();
  15. }
  16. public void Add(IQueryDef query, object key)
  17. {
  18. if (key == null)
  19. throw new Exception("MultiQuery Key many not be null");
  20. if (_queries.Any(x => Equals(x.Key, key)))
  21. throw new Exception("Key already exists");
  22. _queries.Add(new InternalQueryDef
  23. {
  24. Key = key,
  25. Query = query
  26. });
  27. }
  28. public void Query(Action<MultiQuery> callback = null)
  29. {
  30. var tasks = new Dictionary<Task<CoreTable>, object>();
  31. foreach (var query in _queries)
  32. {
  33. var task = Task.Run(
  34. () =>
  35. {
  36. var client = ClientFactory.CreateClient(query.Query.Type);
  37. return client.Query(query.Query.Filter, query.Query.Columns, query.Query.SortOrder);
  38. }
  39. );
  40. tasks[task] = query.Key;
  41. }
  42. if (callback == null)
  43. {
  44. Task.WaitAll(tasks.Keys.ToArray());
  45. foreach (var task in tasks.Keys)
  46. {
  47. var query = _queries.FirstOrDefault(x => Equals(x.Key, tasks[task]));
  48. query.Result = task.Result;
  49. }
  50. }
  51. else
  52. {
  53. Task.WhenAll(tasks.Keys.ToArray()).ContinueWith(t =>
  54. {
  55. foreach (var task in tasks.Keys)
  56. {
  57. var query = _queries.FirstOrDefault(x => Equals(x.Key, tasks[task]));
  58. query.Result = task.Result;
  59. }
  60. callback.Invoke(this);
  61. });
  62. }
  63. }
  64. public bool Contains(object key)
  65. {
  66. return _queries.Any(x => Equals(x.Key, key));
  67. }
  68. public CoreTable Get(object key)
  69. {
  70. var query = _queries.FirstOrDefault(x => Equals(x.Key, key));
  71. if (query == null)
  72. throw new Exception("Key does not exist");
  73. if (query.Result == null)
  74. throw new Exception("No result available");
  75. return query.Result;
  76. }
  77. private class InternalQueryDef
  78. {
  79. public object Key { get; set; }
  80. public IQueryDef Query { get; set; }
  81. public CoreTable Result { get; set; }
  82. public Entity[] Updates { get; set; }
  83. }
  84. #region Simplified Generic Helpers
  85. public void Add<T>(Filter<T> filter = null, Columns<T> columns = null, SortOrder<T> sort = null)
  86. where T : Entity, IRemotable, IPersistent, new()
  87. {
  88. Add(new QueryDef<T>(filter, columns, sort), typeof(T));
  89. }
  90. public CoreTable Get<T>()
  91. {
  92. return Get(typeof(T));
  93. }
  94. #endregion
  95. }
  96. }