Client.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Timers;
  6. using InABox.Core;
  7. namespace InABox.Clients
  8. {
  9. public enum SerializerProtocol
  10. {
  11. Rest
  12. }
  13. public class QueryMultipleResults
  14. {
  15. private readonly Dictionary<string, CoreTable> Results;
  16. internal QueryMultipleResults(Dictionary<string, CoreTable> results)
  17. {
  18. Results = results;
  19. }
  20. public CoreTable this[string name] => Results[name];
  21. public CoreTable Get<T>() => Results[typeof(T).Name];
  22. public CoreTable Get(string name) => Results[name];
  23. }
  24. public abstract class Client
  25. {
  26. public abstract CoreTable Query(IFilter? filter = null, IColumns? columns = null, ISortOrder? sortOrder = null);
  27. public abstract void Save(Entity entity, string auditNote);
  28. private static IClient CheckClient()
  29. {
  30. using (new Profiler(true))
  31. return ClientFactory.CreateClient<User>();
  32. }
  33. public static Dictionary<string, CoreTable> QueryMultiple(Dictionary<string, IQueryDef> queries)
  34. {
  35. using (var timer = new Profiler(false))
  36. {
  37. var result = CheckClient().QueryMultiple(queries);
  38. timer.Log(result.Sum(x => x.Value.Rows.Count));
  39. return result;
  40. }
  41. }
  42. public static QueryMultipleResults QueryMultiple(params IKeyedQueryDef[] queries)
  43. {
  44. using (var timer = new Profiler(false))
  45. {
  46. var result = CheckClient().QueryMultiple(queries.ToDictionary(x => x.Key, x => x as IQueryDef));
  47. timer.Log(result.Sum(x => x.Value.Rows.Count));
  48. return new QueryMultipleResults(result);
  49. }
  50. }
  51. public static QueryMultipleResults QueryMultiple(IEnumerable<IKeyedQueryDef> queries)
  52. {
  53. using (var timer = new Profiler(false))
  54. {
  55. var result = CheckClient().QueryMultiple(queries.ToDictionary(x => x.Key, x => x as IQueryDef));
  56. timer.Log(result.Sum(x => x.Value.Rows.Count));
  57. return new QueryMultipleResults(result);
  58. }
  59. }
  60. public static ValidationData Validate(Guid session)
  61. {
  62. using (new Profiler(true))
  63. return CheckClient().Validate(session);
  64. }
  65. public static ValidationData Validate(string pin, Guid session = default)
  66. {
  67. using (new Profiler(true))
  68. return CheckClient().Validate(pin, session);
  69. }
  70. public static ValidationData Validate(string userid, string password, Guid session = default)
  71. {
  72. using (new Profiler(true))
  73. return CheckClient().Validate(userid, password, session);
  74. }
  75. public static bool Check2FA(string code, Guid? session = null)
  76. {
  77. using (new Profiler(true))
  78. return CheckClient().Check2FA(code, session);
  79. }
  80. public static bool Ping()
  81. {
  82. using (new Profiler(true))
  83. return CheckClient().Ping();
  84. }
  85. public static DatabaseInfo Info()
  86. {
  87. using (new Profiler(true))
  88. return CheckClient().Info();
  89. }
  90. public static Client Create(Type TEntity) =>
  91. (Activator.CreateInstance(typeof(Client<>).MakeGenericType(TEntity)) as Client)!;
  92. }
  93. public class Client<TEntity> : Client, IDisposable where TEntity : Entity, IPersistent, IRemotable, new()
  94. {
  95. private IClient<TEntity> _client;
  96. public Client()
  97. {
  98. _client = ClientFactory.CreateClient<TEntity>();
  99. }
  100. public void Dispose()
  101. {
  102. }
  103. private void CheckSupported()
  104. {
  105. if (!ClientFactory.IsSupported<TEntity>())
  106. throw new NotSupportedException(string.Format("{0} is not supported in this context", typeof(TEntity).EntityName()));
  107. }
  108. private string FilterToString(Filter<TEntity> filter)
  109. {
  110. return filter != null ? filter.AsOData() : "";
  111. }
  112. private string OrderToString(SortOrder<TEntity> order)
  113. {
  114. return order != null ? order.AsOData() : "";
  115. }
  116. public CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? orderby = null)
  117. {
  118. using (var timer = new Profiler<TEntity>(false))
  119. {
  120. CheckSupported();
  121. var result = _client.Query(filter, columns, orderby);
  122. timer.Log(result.Rows.Count);
  123. return result;
  124. }
  125. }
  126. public override CoreTable Query(IFilter? filter, IColumns? columns, ISortOrder? sortOrder)
  127. {
  128. return Query(filter as Filter<TEntity>, columns as Columns<TEntity>, sortOrder as SortOrder<TEntity>);
  129. }
  130. public void Query(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort, Action<CoreTable?, Exception?> callback)
  131. {
  132. var timer = new Profiler<TEntity>(false);
  133. CheckSupported();
  134. _client.Query(filter, columns, sort, (c, e) =>
  135. {
  136. timer.Dispose(c != null ? c.Rows.Count : -1);
  137. callback?.Invoke(c, e);
  138. });
  139. }
  140. public TEntity[] Load(Filter<TEntity>? filter = null, SortOrder<TEntity>? sort = null)
  141. {
  142. using (var timer = new Profiler<TEntity>(false))
  143. {
  144. CheckSupported();
  145. var result = _client.Load(filter, sort);
  146. foreach (var entity in result)
  147. entity.CommitChanges();
  148. timer.Log(result.Length);
  149. return result;
  150. }
  151. }
  152. public void Load(Filter<TEntity> filter, SortOrder<TEntity> sort, Action<TEntity[]?, Exception?> callback)
  153. {
  154. var timer = new Profiler<TEntity>(false);
  155. CheckSupported();
  156. _client.Load(filter, sort, (i,e) =>
  157. {
  158. timer.Dispose(i != null ? i.Length : -1);
  159. callback?.Invoke(i, e);
  160. });
  161. }
  162. public override void Save(Entity entity, string auditNote)
  163. {
  164. Save((entity as TEntity)!, auditNote);
  165. }
  166. public void Save(TEntity entity, string auditnote)
  167. {
  168. using (new Profiler<TEntity>(true))
  169. {
  170. CheckSupported();
  171. entity.LastUpdate = DateTime.Now;
  172. entity.LastUpdateBy = ClientFactory.UserID;
  173. _client.Save(entity, auditnote);
  174. entity.CommitChanges();
  175. }
  176. }
  177. public void Save(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)
  178. {
  179. var timer = new Profiler<TEntity>(false);
  180. CheckSupported();
  181. _client.Save(entity, auditnote, (i,c) =>
  182. {
  183. timer.Dispose();
  184. callback?.Invoke(i, c);
  185. });
  186. }
  187. public void Save(IEnumerable<TEntity> entities, string auditnote)
  188. {
  189. using (var timer = new Profiler<TEntity>(false))
  190. {
  191. CheckSupported();
  192. if (entities.Any())
  193. _client.Save(entities, auditnote);
  194. timer.Log(entities.Count());
  195. }
  196. }
  197. public void Save(IEnumerable<TEntity> entities, string auditnote, Action<IEnumerable<TEntity>, Exception?> callback)
  198. {
  199. var timer = new Profiler<TEntity>(false);
  200. CheckSupported();
  201. if (entities.Any())
  202. _client.Save(entities, auditnote, (i,e) =>
  203. {
  204. timer.Dispose(i.Count());
  205. callback?.Invoke(i,e);
  206. });
  207. }
  208. public void Delete(TEntity entity, string auditnote)
  209. {
  210. using (new Profiler<TEntity>(true))
  211. {
  212. CheckSupported();
  213. _client.Delete(entity, auditnote);
  214. }
  215. }
  216. public void Delete(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)
  217. {
  218. var timer = new Profiler<TEntity>(true);
  219. CheckSupported();
  220. _client.Delete(entity, auditnote, (i,e) =>
  221. {
  222. timer.Dispose();
  223. callback?.Invoke(i, e);
  224. });
  225. }
  226. public void Delete(IList<TEntity> entities, string auditnote)
  227. {
  228. using (var timer = new Profiler<TEntity>(false))
  229. {
  230. CheckSupported();
  231. _client.Delete(entities, auditnote);
  232. timer.Log(entities.Count());
  233. }
  234. }
  235. public void Delete(IList<TEntity> entities, string auditnote, Action<IList<TEntity>, Exception?> callback)
  236. {
  237. var timer = new Profiler<TEntity>(false);
  238. CheckSupported();
  239. _client.Delete(entities, auditnote, (i,e) =>
  240. {
  241. timer.Dispose(entities.Count());
  242. callback?.Invoke(i,e);
  243. });
  244. }
  245. public IEnumerable<string> SupportedTypes()
  246. {
  247. using (new Profiler(true))
  248. return _client.SupportedTypes();
  249. }
  250. public new DatabaseInfo Info()
  251. {
  252. using (new Profiler(true))
  253. return _client.Info();
  254. }
  255. }
  256. }