Browse Source

New Query provider stuff

Kenric Nugteren 6 months ago
parent
commit
12c936e2c7

+ 5 - 0
InABox.Core/Client/BaseClient.cs

@@ -46,6 +46,11 @@ namespace InABox.Clients
             return DoQuery((Filter<TEntity>?)filter, (Columns<TEntity>?)columns, (SortOrder<TEntity>?)sort, range);
         }
 
+        public CoreTable Query(IFilter? filter = null, IColumns? columns = null, ISortOrder? sort = null, CoreRange? range = null)
+        {
+            return DoQuery((Filter<TEntity>?)filter, (Columns<TEntity>?)columns, (SortOrder<TEntity>?)sort, range);
+        }
+
         public CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? sort = null, CoreRange? range = null)
         {
             return DoQuery(filter, columns, sort, range);

+ 85 - 9
InABox.Core/Client/Client.cs

@@ -2,8 +2,10 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
+using System.Threading.Tasks;
 using System.Timers;
 using InABox.Core;
+using IQueryProvider = InABox.Core.IQueryProvider;
 
 namespace InABox.Clients
 {
@@ -58,8 +60,84 @@ namespace InABox.Clients
         public CoreTable GetOrDefault(string name) => Results.GetValueOrDefault(name);
     }
 
+    public class ClientQueryProvider<TEntity> : IQueryProvider<TEntity>
+        where TEntity : Entity, IRemotable, new()
+    {
+        #region Non-generic
+
+        public CoreTable Query(IFilter? filter = null, IColumns? columns = null, ISortOrder? sort = null, CoreRange? range = null)
+        {
+            return new Client<TEntity>().Query(filter, columns, sort, range);
+        }
+
+        #endregion
+
+        public CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? sort = null, CoreRange? range = null)
+        {
+            return Client.Query(filter, columns, sort, range);
+        }
+
+        public void Query(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort, CoreRange? range, Action<CoreTable?, Exception?> action)
+        {
+            Client.Query(filter, columns, sort, range, action);
+        }
+
+        public void Save(TEntity entity, string auditNote)
+        {
+            Client.Save(entity, auditNote);
+        }
+
+        public void Save(IEnumerable<TEntity> entities, string auditNote)
+        {
+            Client.Save(entities, auditNote);
+        }
+
+        public void Save(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)
+        {
+            Client.Save(entity, auditnote, callback);
+        }
+
+        public void Save(IEnumerable<TEntity> entities, string auditnote, Action<IEnumerable<TEntity>, Exception?> callback)
+        {
+            Client.Save(entities, auditnote, callback);
+        }
+
+        public void Delete(TEntity entity, string auditNote)
+        {
+            Client.Delete(entity, auditNote);
+        }
+
+        public void Delete(IEnumerable<TEntity> entities, string auditNote)
+        {
+            Client.Delete(entities, auditNote);
+        }
+
+        public void Delete(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)
+        {
+            Client.Delete(entity, auditnote, callback);
+        }
+
+        public void Delete(IEnumerable<TEntity> entities, string auditnote, Action<IList<TEntity>, Exception?> callback)
+        {
+            Client.Delete(entities, auditnote, callback);
+        }
+    }
+
     public abstract class Client
     {
+        #region IQueryProvider Factory
+
+        private class _Factory : IQueryProviderFactory
+        {
+            public IQueryProvider Create(Type T)
+            {
+                return (typeof(ClientQueryProvider<>).MakeGenericType(T) as IQueryProvider)!;
+            }
+        }
+
+        public static IQueryProviderFactory Factory { get; } = new _Factory();
+
+        #endregion
 
         public abstract CoreTable Query(IFilter? filter = null, IColumns? columns = null, ISortOrder? sortOrder = null, CoreRange? range = null);
         public abstract void Save(Entity entity, string auditNote);
@@ -183,6 +261,12 @@ namespace InABox.Clients
             new Client<TEntity>().Delete(entities, auditNote);
         }
 
+        public static void Delete<TEntity>(IEnumerable<TEntity> entities, string auditNote, Action<IList<TEntity>, Exception?> callback)
+            where TEntity : Entity, IRemotable, new()
+        {
+            new Client<TEntity>().Delete(entities, auditNote, callback);
+        }
+
         public static void QueryMultiple(
             Action<Dictionary<string, CoreTable>?, Exception?> callback,
             Dictionary<string, IQueryDef> queries)
@@ -369,15 +453,7 @@ namespace InABox.Clients
     {
         #region IQueryProvider
 
-        private class ClientQueryProvider : IQueryProvider<TEntity>
-        {
-            public CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? sort = null, CoreRange? range = null)
-            {
-                return Client.Query(filter, columns, sort, range);
-            }
-        }
-
-        public static IQueryProvider<TEntity> Provider { get; private set; } = new ClientQueryProvider();
+        public static IQueryProvider<TEntity> Provider { get; private set; } = new ClientQueryProvider<TEntity>();
 
         #endregion
 

+ 2 - 16
InABox.Core/Client/IClient.cs

@@ -6,7 +6,7 @@ namespace InABox.Clients
 {
     
     
-    public interface IClient
+    public interface IClient : IQueryProvider
     {
         IValidationData Validate(string userid, string password, Guid session = default);
         IValidationData Validate(string pin, Guid session = default);
@@ -50,24 +50,10 @@ namespace InABox.Clients
 
     }
 
-    public interface IClient<TEntity> : IClient where TEntity : Entity, new()
+    public interface IClient<TEntity> : IClient, IQueryProvider<TEntity> where TEntity : Entity, new()
     {
-        CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? sort = null, CoreRange? range = null);
-        void Query(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort, CoreRange? range, Action<CoreTable?, Exception?> callback);
-
         TEntity[] Load(Filter<TEntity>? filter = null, SortOrder<TEntity>? sort = null, CoreRange? range = null);
         void Load(Filter<TEntity>? filter, SortOrder<TEntity>? sort, CoreRange? range, Action<TEntity[]?, Exception?> callback);
-
-        void Save(TEntity entity, string auditnote);
-        void Save(IEnumerable<TEntity> entities, string auditnote);
-        void Save(TEntity entity, string auditnote, Action<TEntity, Exception?> callback);
-        void Save(IEnumerable<TEntity> entity, string auditnote, Action<IEnumerable<TEntity>, Exception?> callback);
-
-        void Delete(TEntity entity, string auditnote);
-        void Delete(IEnumerable<TEntity> entities, string auditnote);
-        void Delete(TEntity entity, string auditnote, Action<TEntity, Exception?> callback);
-        void Delete(IEnumerable<TEntity> entity, string auditnote, Action<IList<TEntity>, Exception?> callback);
-        
     }
 
 }

+ 66 - 1
InABox.Core/Client/IQueryProvider.cs

@@ -4,8 +4,73 @@ using System.Text;
 
 namespace InABox.Core
 {
-    public interface IQueryProvider<T>
+    public interface IQueryProvider
+    {
+        CoreTable Query(IFilter? filter = null, IColumns? columns = null, ISortOrder? sort = null, CoreRange? range = null);
+    }
+
+    public interface IQueryProvider<T> : IQueryProvider
     {
         CoreTable Query(Filter<T>? filter = null, Columns<T>? columns = null, SortOrder<T>? sort = null, CoreRange? range = null);
+
+        void Query(Filter<T>? filter, Columns<T>? columns, SortOrder<T>? sort, CoreRange? range, Action<CoreTable?, Exception?> action);
+
+        void Save(T entity, string auditNote);
+
+        void Save(IEnumerable<T> entities, string auditNote);
+
+        void Save(T entity, string auditnote, Action<T, Exception?> callback);
+        void Save(IEnumerable<T> entities, string auditnote, Action<IEnumerable<T>, Exception?> callback);
+
+        void Delete(T entity, string auditNote);
+
+        void Delete(IEnumerable<T> entities, string auditNote);
+
+        void Delete(T entity, string auditnote, Action<T, Exception?> callback);
+        void Delete(IEnumerable<T> entities, string auditnote, Action<IList<T>, Exception?> callback);
+    }
+
+    public interface IQueryProviderFactory
+    {
+        IQueryProvider Create(Type T);
+
+        IQueryProvider<T> Create<T>()
+            where T : BaseObject, new()
+        {
+            return (Create(typeof(T)) as IQueryProvider<T>)!;
+        }
+    }
+
+    public static class QueryProviderFactoryExtensions
+    {
+        public static CoreTable Query<T>(this IQueryProviderFactory factory, Filter<T>? filter = null, Columns<T>? columns = null, SortOrder<T>? sort = null, CoreRange? range = null)
+            where T : BaseObject, new()
+        {
+            return factory.Create<T>().Query(filter, columns, sort, range);
+        }
+
+        public static void Query<T>(this IQueryProviderFactory factory, Filter<T>? filter, Columns<T>? columns, SortOrder<T>? sort, CoreRange? range, Action<CoreTable?, Exception?> action)
+            where T : BaseObject, new()
+        {
+            factory.Create<T>().Query(filter, columns, sort, range, action);
+        }
+
+        public static void Save<T>(this IQueryProviderFactory factory, T entity, string auditNote)
+            where T : BaseObject, new()
+        {
+            factory.Create<T>().Save(entity, auditNote);
+        }
+
+        public static void Save<T>(this IQueryProviderFactory factory, IEnumerable<T> entities, string auditNote)
+            where T : BaseObject, new()
+        {
+            factory.Create<T>().Save(entities, auditNote);
+        }
+
+        public static void Delete<T>(this IQueryProviderFactory factory, T entity, string auditNote)
+            where T : BaseObject, new()
+        {
+            factory.Create<T>().Delete(entity, auditNote);
+        }
     }
 }

+ 121 - 3
InABox.Database/IProvider.cs

@@ -108,18 +108,136 @@ public static class ProviderExtensions
         }
     }
 
-    private class ProviderQueryProvider<TEntity>(IProvider provider) : IQueryProvider<TEntity>
+    private class ProviderQueryProvider<TEntity>(IProvider provider, string userID) : IQueryProvider<TEntity>
         where TEntity : Entity, new()
     {
         private IProvider Provider = provider;
 
+        private string UserID = userID;
+
         public CoreTable Query(Filter<TEntity>? filter = null, Columns<TEntity>? columns = null, SortOrder<TEntity>? sort = null, CoreRange? range = null)
         {
             return Provider.Query(filter, columns, sort, range);
         }
+
+        public void Query(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort, CoreRange? range, Action<CoreTable?, Exception?> action)
+        {
+            Task.Run(() =>
+            {
+                try
+                {
+                    var result = Provider.Query(filter, columns, sort, range);
+                    action(result, null);
+                }
+                catch(Exception e)
+                {
+                    action(null, e);
+                }
+            });
+        }
+
+        public void Delete(TEntity entity, string auditNote)
+        {
+            Provider.Delete(entity, UserID);
+        }
+
+        public void Delete(IEnumerable<TEntity> entities, string auditNote)
+        {
+            Provider.Delete(entities, UserID);
+        }
+
+        public void Delete(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)
+        {
+            Task.Run(() =>
+            {
+                try
+                {
+                    Provider.Delete(entity, UserID);
+                    callback(entity, null);
+                }
+                catch (Exception e)
+                {
+                    callback(entity, e);
+                }
+            });
+        }
+
+        public void Delete(IEnumerable<TEntity> entities, string auditnote, Action<IList<TEntity>, Exception?> callback)
+        {
+            var ents = entities.AsIList();
+            Task.Run(() =>
+            {
+                try
+                {
+                    Provider.Delete(ents, UserID);
+                    callback(ents, null);
+                }
+                catch (Exception e)
+                {
+                    callback(ents, e);
+                }
+            });
+        }
+
+        public void Save(TEntity entity, string auditNote)
+        {
+            Provider.Save(entity);
+        }
+
+        public void Save(IEnumerable<TEntity> entities, string auditNote)
+        {
+            Provider.Save(entities);
+        }
+
+        public void Save(TEntity entity, string auditnote, Action<TEntity, Exception?> callback)
+        {
+            Task.Run(() =>
+            {
+                try
+                {
+                    Provider.Save(entity);
+                    callback(entity, null);
+                }
+                catch (Exception e)
+                {
+                    callback(entity, e);
+                }
+            });
+        }
+
+        public void Save(IEnumerable<TEntity> entities, string auditnote, Action<IEnumerable<TEntity>, Exception?> callback)
+        {
+            var ents = entities.AsIList();
+            Task.Run(() =>
+            {
+                try
+                {
+                    Provider.Save(ents);
+                    callback(ents, null);
+                }
+                catch (Exception e)
+                {
+                    callback(ents, e);
+                }
+            });
+        }
+
+        #region Non-generics
+
+        public CoreTable Query(IFilter? filter = null, IColumns? columns = null, ISortOrder? sort = null, CoreRange? range = null)
+        {
+            return Provider.Query(typeof(TEntity), filter, columns, sort, range);
+        }
+
+        #endregion
+    }
+
+    public static IQueryProvider<TEntity> QueryProvider<TEntity>(this IProvider provider, string userID) where TEntity : Entity, new()
+    {
+        return new ProviderQueryProvider<TEntity>(provider, userID);
     }
-    public static IQueryProvider<TEntity> QueryProvider<TEntity>(this IProvider provider) where TEntity : Entity, new()
+    public static IQueryProvider<TEntity> QueryProvider<TEntity>(this IStore store) where TEntity : Entity, new()
     {
-        return new ProviderQueryProvider<TEntity>(provider);
+        return new ProviderQueryProvider<TEntity>(store.Provider, store.UserID);
     }
 }

+ 5 - 7
inabox.wpf/DynamicGrid/DynamicDocumentGrid.cs

@@ -9,7 +9,6 @@ using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
-using InABox.Clients;
 using InABox.Core;
 using InABox.WPF;
 using Microsoft.Win32;
@@ -497,10 +496,9 @@ public class DynamicDocumentGrid<TDocument, TEntity, TEntityLink> : DynamicManyT
                     columns.Add(string.Join('.', column.ColumnName.Split('.').Skip(1)));
                 }
             }
-            var docs = new Client<Document>()
-                .Query(
-                    new Filter<Document>(x => x.ID).InList(docIDS),
-                    columns);
+            var docs = Client.Query(
+                new Filter<Document>(x => x.ID).InList(docIDS),
+                columns);
 
             foreach (var doc in docs.ToObjects<Document>())
             {
@@ -527,7 +525,7 @@ public class DynamicDocumentGrid<TDocument, TEntity, TEntityLink> : DynamicManyT
     {
         if (documents.Any())
         {
-            new Client<Document>().Save(documents, "Initial Upload");
+            Client.Save(documents, "Initial Upload");
             foreach (var doc in documents)
             {
                 var newitem = CreateItem();
@@ -601,7 +599,7 @@ public class DynamicDocumentGrid<TDocument, TEntity, TEntityLink> : DynamicManyT
                                 row.Set<TDocument, byte[]>(x => x.Thumbnail!, data);
                             }
                         }
-                        Dispatcher.BeginInvoke(() => Refresh(false,false));
+                        Dispatcher.BeginInvoke(() => base.Refresh(false,false));
                     }
                 );
             }

+ 3 - 3
inabox.wpf/DynamicGrid/DynamicManyToManyDataGrid.cs

@@ -49,7 +49,7 @@ namespace InABox.DynamicGrid
         {
             var expr = CoreUtils.CreateLambdaExpression<TManyToMany>(prop.Name + ".ID");
             criteria.Add(new Filter<TManyToMany>(expr).IsEqualTo(ID));
-            Client.Query(criteria.Combine(), columns, sort, null, action);
+            Clients.Client.Query(criteria.Combine(), columns, sort, null, action);
         }
 
         public override TManyToMany LoadItem(CoreRow row)
@@ -66,12 +66,12 @@ namespace InABox.DynamicGrid
         {
             var items = LoadItems(rows);
             foreach (var item in items)
-                Client.Delete(item, "");
+                Clients.Client.Delete(item, "");
         }
 
         public override void SaveItem(TManyToMany item)
         {
-            Client.Save(item, "");
+            Clients.Client.Save(item, "");
         }
     }
 }

+ 3 - 2
inabox.wpf/DynamicGrid/DynamicManyToManyGrid.cs

@@ -27,6 +27,8 @@ public class DynamicManyToManyGrid<TManyToMany, TThis> : DynamicGrid<TManyToMany
     where TThis : Entity, new()
     where TManyToMany : Entity, IPersistent, IRemotable, new()
 {
+    public IQueryProviderFactory Client = Clients.Client.Factory;
+
     //private Guid ID = Guid.Empty;
     protected TThis Item;
 
@@ -410,8 +412,7 @@ public class DynamicManyToManyGrid<TManyToMany, TThis> : DynamicGrid<TManyToMany
     public override void LoadEditorButtons(TManyToMany item, DynamicEditorButtons buttons)
     {
         base.LoadEditorButtons(item, buttons);
-        if (ClientFactory.IsSupported<AuditTrail>())
-            buttons.Add("Audit Trail", Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
+        buttons.Add("Audit Trail", Wpf.Resources.view.AsBitmapImage(), item, AuditTrailClick);
     }
 
     private void AuditTrailClick(object sender, object? item)