| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 | using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Timers;using InABox.Core;namespace InABox.Clients{    public enum SerializerProtocol    {        Rest,        RPC    }    public class QueryMultipleResults    {        private readonly Dictionary<string, CoreTable> Results;        internal QueryMultipleResults(Dictionary<string, CoreTable> results)        {            Results = results;        }        public CoreTable this[string name] => Results[name];        public CoreTable Get<T>() => Results[typeof(T).Name];        /// <summary>        /// Like <see cref="Get{T}"/>, but calls <see cref="CoreTable.ToObjects{T}"/> on the table.        /// </summary>        /// <typeparam name="T"></typeparam>        /// <returns></returns>        public IEnumerable<T> GetObjects<T>()            where T: BaseObject, new()             => Results[typeof(T).Name].ToObjects<T>();        public CoreTable Get(string name) => Results[name];    }    public abstract class Client    {        public abstract CoreTable Query(IFilter? filter = null, IColumns? columns = null, ISortOrder? sortOrder = null);        public abstract void Save(Entity entity, string auditNote);        public abstract void Save(IEnumerable<Entity> entity, string auditNote);        private static IClient CheckClient()        {            using (new Profiler(true))                return ClientFactory.CreateClient<User>();        }        public static Dictionary<string, CoreTable> QueryMultiple(Dictionary<string, IQueryDef> queries)        {            try            {                using var timer = new Profiler(false);                var result = CheckClient().QueryMultiple(queries);                timer.Log(result.Sum(x => x.Value.Rows.Count));                return result;            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static void QueryMultiple(            Action<Dictionary<string, CoreTable>?, Exception?> callback,            Dictionary<string, IQueryDef> queries)        {            try            {                using var timer = new Profiler(false);                CheckClient().QueryMultiple((result, e) =>                {                    timer.Dispose(result != null ? result.Sum(x => x.Value.Rows.Count) : -1);                    callback?.Invoke(result, e);                }, queries);            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static QueryMultipleResults QueryMultiple(params IKeyedQueryDef[] queries) =>            new QueryMultipleResults(QueryMultiple(queries.ToDictionary(x => x.Key, x => x as IQueryDef)));        public static void QueryMultiple(Action<QueryMultipleResults?, Exception?> callback, params IKeyedQueryDef[] queries) =>            QueryMultiple((results, e) =>            {                if (results != null)                {                    callback?.Invoke(new QueryMultipleResults(results), e);                }                else                {                    callback?.Invoke(null, e);                }            }, queries.ToDictionary(x => x.Key, x => x as IQueryDef));        public static QueryMultipleResults QueryMultiple(IEnumerable<IKeyedQueryDef> queries) =>            new QueryMultipleResults(QueryMultiple(queries.ToDictionary(x => x.Key, x => x as IQueryDef)));        public static void QueryMultiple(Action<QueryMultipleResults?, Exception?> callback, IEnumerable<IKeyedQueryDef> queries) =>            QueryMultiple((results, e) =>            {                if(results != null)                {                    callback?.Invoke(new QueryMultipleResults(results), e);                }                else                {                    callback?.Invoke(null, e);                }            }, queries.ToDictionary(x => x.Key, x => x as IQueryDef));        public static IValidationData Validate(Guid session)        {            try            {                using (new Profiler(true))                    return CheckClient().Validate(session);            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static IValidationData Validate(string pin, Guid session = default)        {            try            {                using (new Profiler(true))                    return CheckClient().Validate(pin, session);            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static IValidationData Validate(string userid, string password, Guid session = default)        {            try            {                using (new Profiler(true))                    return CheckClient().Validate(userid, password, session);            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static bool Check2FA(string code, Guid? session = null)        {            try            {                using (new Profiler(true))                    return CheckClient().Check2FA(code, session);            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static bool Ping()        {            try            {                using (new Profiler(true))                    return CheckClient().Ping();            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static DatabaseInfo Info()        {            try            {                using (new Profiler(true))                    return CheckClient().Info();            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public static Client Create(Type TEntity) =>             (Activator.CreateInstance(typeof(Client<>).MakeGenericType(TEntity)) as Client)!;    }    public class Client<TEntity> : Client, IDisposable where TEntity : Entity, IPersistent, IRemotable, new()    {        private IClient<TEntity> _client;        public Client()        {            _client = ClientFactory.CreateClient<TEntity>();        }        public void Dispose()        {        }        private void CheckSupported()        {            if (!ClientFactory.IsSupported<TEntity>())                throw new NotSupportedException(string.Format("{0} is not supported in this context", typeof(TEntity).EntityName()));        }        private string FilterToString(Filter<TEntity> filter)        {            return filter != null ? filter.AsOData() : "";        }        private string OrderToString(SortOrder<TEntity> order)        {            return order != null ? order.AsOData() : "";        }        public CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? orderby = null)        {            try            {                using (var timer = new Profiler<TEntity>(false))                {                    CheckSupported();                    var result = _client.Query(filter, columns, orderby);                    timer.Log(result.Rows.Count);                    return result;                }            }            catch(RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public override CoreTable Query(IFilter? filter, IColumns? columns, ISortOrder? sortOrder)        {            return Query(filter as Filter<TEntity>, columns as Columns<TEntity>, sortOrder as SortOrder<TEntity>);        }        public void Query(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort, Action<CoreTable?, Exception?> callback)        {            try            {                var timer = new Profiler<TEntity>(false);                CheckSupported();                _client.Query(filter, columns, sort, (c, e) =>                {                    timer.Dispose(c != null ? c.Rows.Count : -1);                    callback?.Invoke(c, e);                });            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public TEntity[] Load(Filter<TEntity>? filter = null, SortOrder<TEntity>? sort = null)        {            try            {                using (var timer = new Profiler<TEntity>(false))                {                    CheckSupported();                    var result = _client.Load(filter, sort);                    foreach (var entity in result)                        entity.CommitChanges();                    timer.Log(result.Length);                    return result;                }            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Load(Filter<TEntity> filter, SortOrder<TEntity> sort, Action<TEntity[]?, Exception?> callback)        {            try            {                var timer = new Profiler<TEntity>(false);                CheckSupported();                _client.Load(filter, sort, (i, e) =>                {                    timer.Dispose(i != null ? i.Length : -1);                    callback?.Invoke(i, e);                });            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public override void Save(Entity entity, string auditNote)        {            try            {                Save((entity as TEntity)!, auditNote);            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public override void Save(IEnumerable<Entity> entities, string auditNote)        {            try            {                Save(entities.Cast<TEntity>(), auditNote);            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Save(TEntity entity, string auditnote)        {            try            {                using (new Profiler<TEntity>(true))                {                    CheckSupported();                    entity.LastUpdate = DateTime.Now;                    entity.LastUpdateBy = ClientFactory.UserID;                    _client.Save(entity, auditnote);                    entity.CommitChanges();                }            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Save(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)        {            try            {                var timer = new Profiler<TEntity>(false);                CheckSupported();                _client.Save(entity, auditnote, (i, c) =>                {                    timer.Dispose();                    callback?.Invoke(i, c);                });            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Save(IEnumerable<TEntity> entities, string auditnote)        {            try            {                using var timer = new Profiler<TEntity>(false);                CheckSupported();                if (entities.Any())                    _client.Save(entities, auditnote);                timer.Log(entities.Count());            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Save(IEnumerable<TEntity> entities, string auditnote, Action<IEnumerable<TEntity>, Exception?> callback)        {            try            {                var timer = new Profiler<TEntity>(false);                CheckSupported();                if (entities.Any())                    _client.Save(entities, auditnote, (i, e) =>                    {                        timer.Dispose(i.Count());                        callback?.Invoke(i, e);                    });            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Delete(TEntity entity, string auditnote)        {            try            {                using (new Profiler<TEntity>(true))                {                    CheckSupported();                    _client.Delete(entity, auditnote);                }            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Delete(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)        {            try            {                var timer = new Profiler<TEntity>(true);                CheckSupported();                _client.Delete(entity, auditnote, (i, e) =>                {                    timer.Dispose();                    callback?.Invoke(i, e);                });            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Delete(IList<TEntity> entities, string auditnote)        {            try            {                using var timer = new Profiler<TEntity>(false);                CheckSupported();                _client.Delete(entities, auditnote);                timer.Log(entities.Count());            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public void Delete(IList<TEntity> entities, string auditnote, Action<IList<TEntity>, Exception?> callback)        {            try            {                var timer = new Profiler<TEntity>(false);                CheckSupported();                _client.Delete(entities, auditnote, (i, e) =>                {                    timer.Dispose(entities.Count());                    callback?.Invoke(i, e);                });            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public IEnumerable<string> SupportedTypes()        {            try            {                using (new Profiler(true))                    return _client.SupportedTypes();            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }        public new DatabaseInfo Info()        {            try            {                using (new Profiler(true))                    return _client.Info();            }            catch (RequestException e)            {                ClientFactory.RaiseRequestError(e);                throw;            }        }    }}
 |