MultiQuery.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using InABox.Clients;
  7. namespace InABox.Core
  8. {
  9. public class MultiQuery
  10. {
  11. private readonly List<InternalQueryDef> _queries = new List<InternalQueryDef>();
  12. public int Count => _queries.Count;
  13. public Dictionary<object, IQueryDef> Definitions()
  14. {
  15. Dictionary<object, IQueryDef> result = new Dictionary<object, IQueryDef>();
  16. foreach (var query in _queries)
  17. result[query.Key] = query.Query;
  18. return result;
  19. }
  20. public IEnumerable<KeyValuePair<object, CoreTable>> Results()
  21. {
  22. foreach (var query in _queries)
  23. if(query.Result != null)
  24. yield return new KeyValuePair<object, CoreTable>(query.Key, query.Result);
  25. }
  26. public void Clear()
  27. {
  28. _queries.Clear();
  29. }
  30. public void Add(IQueryDef query, object key)
  31. {
  32. if (key == null)
  33. throw new Exception("MultiQuery Key many not be null");
  34. if (_queries.Any(x => Equals(x.Key, key)))
  35. throw new Exception("Key already exists");
  36. _queries.Add(new InternalQueryDef(key, query));
  37. }
  38. public void Query(Action<MultiQuery>? callback = null)
  39. {
  40. var tasks = new Dictionary<object, Task<CoreTable>>();
  41. foreach (var query in _queries)
  42. {
  43. tasks[query.Key] = Task.Run(() =>
  44. {
  45. return Client.Create(query.Query.Type)
  46. .Query(query.Query.Filter, query.Query.Columns, query.Query.SortOrder, query.Query.Range);
  47. });
  48. }
  49. if (callback is null)
  50. {
  51. Task.WaitAll(tasks.Values.ToArray());
  52. foreach(var query in _queries)
  53. {
  54. if(tasks.TryGetValue(query.Key, out var task))
  55. {
  56. query.Result = task.Result;
  57. }
  58. }
  59. }
  60. else
  61. {
  62. Task.WhenAll(tasks.Values.ToArray()).ContinueWith(t =>
  63. {
  64. foreach(var query in _queries)
  65. {
  66. if(tasks.TryGetValue(query.Key, out var task))
  67. {
  68. query.Result = task.Result;
  69. }
  70. }
  71. callback.Invoke(this);
  72. });
  73. }
  74. }
  75. public bool Contains(object key)
  76. {
  77. return _queries.Any(x => Equals(x.Key, key));
  78. }
  79. public CoreTable Get(object key)
  80. {
  81. var query = _queries.FirstOrDefault(x => Equals(x.Key, key));
  82. if (query == null)
  83. throw new Exception("Key does not exist");
  84. if (query.Result == null)
  85. throw new Exception("No result available");
  86. return query.Result;
  87. }
  88. public void Set(object key, CoreTable table)
  89. {
  90. var query = _queries.FirstOrDefault(x => Equals(x.Key, key))
  91. ?? throw new Exception("Key does not exist");
  92. query.Result = table;
  93. }
  94. private class InternalQueryDef
  95. {
  96. public object Key { get; set; }
  97. public IQueryDef Query { get; set; }
  98. public CoreTable? Result { get; set; }
  99. public InternalQueryDef(object key, IQueryDef query)
  100. {
  101. Key = key;
  102. Query = query;
  103. }
  104. }
  105. #region Simplified Generic Helpers
  106. public void Add<T>(QueryDef<T> query)
  107. where T : Entity, IRemotable, IPersistent, new()
  108. {
  109. Add(query, typeof(T));
  110. }
  111. public void Add<T>(Filter<T>? filter = null, Columns<T>? columns = null, SortOrder<T>? sort = null, CoreRange? range = null)
  112. where T : Entity, IRemotable, IPersistent, new()
  113. {
  114. Add(new QueryDef<T>(filter, columns, sort, range), typeof(T));
  115. }
  116. public CoreTable Get<T>()
  117. {
  118. return Get(typeof(T));
  119. }
  120. public bool Contains<T>()
  121. {
  122. return Contains(typeof(T));
  123. }
  124. #endregion
  125. }
  126. }