Files
raven/server/AyaNova/PickList/PickListSqlBuilder.cs
2020-03-13 19:47:45 +00:00

99 lines
4.0 KiB
C#

using System.Collections.Generic;
using System;
using System.Globalization;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace AyaNova.PickList
{
internal static class PickListSqlBuilder
{
//Maximum number of results to return at any given time
//did a little research and may adjust this but it can be fairly girthy in this day and age
//and many people might not want or need to autocomplete type if we provide enough leeway.
//for example, if you're selecting a
const int MAXIMUM_RESULT_COUNT = 100;
//Build the query for a picklist request
internal static string Build(IAyaPickList pickList, List<string> templateColumnNames, string autoCompleteQuery, bool IncludeInactive)
{
//TODO: if no autocompletequery returns the first XX results without querying in natural order by column names
//if autocomplete returns teh first XX results with query in natural order by column names
//TODO: build a sql List<AyaPickListFieldDefinition> columnDefinitionsselect and order by and a where clause that searches appropriately in each field (tags)
//it should return results based on the query where there is a single name (display) column and an id column for rowid
//and the fields should be combined in a standard way separated by spaces "Widget widgetserial username" for compactness
//determine this in advance as it will be used in a loop later
bool HasAutoCompleteQuery = !string.IsNullOrWhiteSpace(autoCompleteQuery);
//lists to collect the clauses so to avoid comma fuckery
List<string> lSelect = new List<string>();
List<string> lWhere = new List<string>();
//Add rowid column as it's always required
AyaPickListFieldDefinition rowIdColumn = pickList.ColumnDefinitions.FirstOrDefault(x => x.IsRowId == true);
//this should only happen with a development error
if (rowIdColumn == null)
throw new System.ArgumentNullException($"DEV ERROR in PickListSqlBuilder.cs: picklist for {pickList.DefaultListObjectType.ToString()} has no rowId column specified in columnDefinitions list");
lSelect.Add(rowIdColumn.SqlIdColumnName + " AS rowid");
//add active only as default for all lists unless inactive is specified
if (!IncludeInactive)
{
AyaPickListFieldDefinition activeColumn = pickList.ColumnDefinitions.FirstOrDefault(x => x.IsActiveColumn == true);
//it's ok if there is no active column, it could happen so just roll with it
if (activeColumn != null)
{
lWhere.Add(activeColumn.SqlValueColumnName + " = true");
}
}
foreach (string ColumnName in templateColumnNames)
{
AyaPickListFieldDefinition o = pickList.ColumnDefinitions.FirstOrDefault(x => x.FieldKey == ColumnName);
#if (DEBUG)
if (o == null)
{
throw new System.ArgumentNullException($"DEV ERROR in PickListSqlBuilder.cs: field {ColumnName} specified in template was NOT found in columnDefinitions list");
}
#endif
if (o != null)
{//Ignore missing fields in production
var valueColumnName = o.GetSqlValueColumnName();
lSelect.Add(valueColumnName);
if (HasAutoCompleteQuery)
{
string sWhere = $"{valueColumnName} LIKE '%{autoCompleteQuery}%'";
lWhere.Add(sWhere);
}
}
}
//Now build up the return query
//select
//from
//where
//orderby
//limit, actual sql: "LIMIT {MAXIMUM_RESULT_COUNT}"
return sbSelect.ToString() + pickList.SQLFrom + sbWhere.ToString();
}
}//eoc
}//ens