|  | @@ -1005,7 +1005,66 @@ public class SQLiteProviderFactory : IProviderFactory
 | 
	
		
			
				|  |  |                      sb.Append($" WHERE {String.Join(" AND ", filters)}");
 | 
	
		
			
				|  |  |                  ddl.Add(sb.ToString());
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +            else if (view.Generator is IAutoEntitySummaryGenerator summary)
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                // These things dont have the normal columns that an entity requires, so we have to provide default ones
 | 
	
		
			
				|  |  | +                List<String> allfields = new List<string>()
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    $"NULL as [ID]",
 | 
	
		
			
				|  |  | +                    $"NULL as [Created]",
 | 
	
		
			
				|  |  | +                    $"NULL as [CreatedBy]",
 | 
	
		
			
				|  |  | +                    $"NULL as [LastUpdate]",
 | 
	
		
			
				|  |  | +                    $"NULL as [LastUpdateBy]"
 | 
	
		
			
				|  |  | +                };
 | 
	
		
			
				|  |  | +                List<String> groupfields = new List<string>();
 | 
	
		
			
				|  |  | +                string having = "";
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +                foreach (var idcol in summary.IDColumns())
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    allfields.Add($"A1.[{idcol.Source}] as [{idcol.Property}]");
 | 
	
		
			
				|  |  | +                    groupfields.Add($"A1.[{idcol.Source}]");
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +                using (var command = access.CreateCommand())
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    var fieldmap = new Dictionary<string, string>();
 | 
	
		
			
				|  |  | +                    var tables = new List<Tuple<string, string, string, string>> ();
 | 
	
		
			
				|  |  | +                    var columns = new List<string>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    foreach (var aggCol in summary.AggregateColumns())
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        var formula = MainProvider.LoadComplexFormula(command, summary.SourceType, 'A', fieldmap, tables, columns,
 | 
	
		
			
				|  |  | +                            aggCol.Definition.GetFormula(), false);
 | 
	
		
			
				|  |  | +                        // formula already has brackets around it, so the apparent typo is correct
 | 
	
		
			
				|  |  | +                        var func = aggCol.Aggregate == AutoEntitySummaryAggregate.Sum
 | 
	
		
			
				|  |  | +                            ? $"sum{formula}"
 | 
	
		
			
				|  |  | +                            : aggCol.Aggregate == AutoEntitySummaryAggregate.Average
 | 
	
		
			
				|  |  | +                                ? $"avg{formula}"
 | 
	
		
			
				|  |  | +                                : aggCol.Aggregate == AutoEntitySummaryAggregate.Count
 | 
	
		
			
				|  |  | +                                    ? $"count{formula}"
 | 
	
		
			
				|  |  | +                                    : aggCol.Aggregate == AutoEntitySummaryAggregate.Minimum
 | 
	
		
			
				|  |  | +                                        ? $"min{formula}"
 | 
	
		
			
				|  |  | +                                        : aggCol.Aggregate == AutoEntitySummaryAggregate.Maximum
 | 
	
		
			
				|  |  | +                                            ? $"max{formula}"
 | 
	
		
			
				|  |  | +                                            : formula;
 | 
	
		
			
				|  |  | +                        allfields.Add($"{func} as [{aggCol.Property}]");
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +                    if (summary.HavingFilter != null)
 | 
	
		
			
				|  |  | +                    {
 | 
	
		
			
				|  |  | +                        having = MainProvider.GetFilterClauseNonGeneric(summary.Definition, command, 'A',
 | 
	
		
			
				|  |  | +                            summary.HavingFilter, tables, fieldmap, columns, false);
 | 
	
		
			
				|  |  | +                        // yep it would be cool to be able to have a non-prefixed "having" clause
 | 
	
		
			
				|  |  | +                        // But that's a fair bit of work, so I'm just gonna leave this here for 
 | 
	
		
			
				|  |  | +                        // another time
 | 
	
		
			
				|  |  | +                        having = having.Replace("A1.", "");
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                var sql = $"SELECT\n  {String.Join(",\n  ", allfields)} \nFROM \n  {summary.SourceType.Name.Split('.').Last()} A1 \nGROUP BY\n  {String.Join(",\n  ", groupfields)}";
 | 
	
		
			
				|  |  | +                if (!string.IsNullOrWhiteSpace(having))
 | 
	
		
			
				|  |  | +                    sql += $"\nHAVING \n  {having}";
 | 
	
		
			
				|  |  | +                ddl.Add(sql);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              ddl.Add(";");
 | 
	
		
			
				|  |  |              var viewstatement = string.Join(" ", ddl);
 | 
	
	
		
			
				|  | @@ -1872,7 +1931,7 @@ public class SQLiteProvider : IProvider
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private string GetFilterClauseNonGeneric(Type T, SQLiteCommand command, char prefix, IFilter? filter, List<Tuple<string, string, string, string>> tables,
 | 
	
		
			
				|  |  | +    public string GetFilterClauseNonGeneric(Type T, SQLiteCommand command, char prefix, IFilter? filter, List<Tuple<string, string, string, string>> tables,
 | 
	
		
			
				|  |  |          Dictionary<string, string> fieldmap, List<string> columns, bool useparams)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          if (filter == null)
 | 
	
	
		
			
				|  | @@ -2230,7 +2289,7 @@ public class SQLiteProvider : IProvider
 | 
	
		
			
				|  |  |              _right, _true, _false);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private string LoadComplexFormula(SQLiteCommand command, Type type, char prefix, Dictionary<string, string> fieldmap, List<Tuple<string, string, string, string>> tables, List<string> columns, IComplexFormulaNode node, bool useparams)
 | 
	
		
			
				|  |  | +    public string LoadComplexFormula(SQLiteCommand command, Type type, char prefix, Dictionary<string, string> fieldmap, List<Tuple<string, string, string, string>> tables, List<string> columns, IComplexFormulaNode node, bool useparams)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |          switch(node)
 | 
	
		
			
				|  |  |          {
 |