170 lines
6.5 KiB
C#
170 lines
6.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Linq;
|
|
using AyaNova.Biz;
|
|
|
|
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
|
|
//WORKING QUERY
|
|
//select awidget.id AS rowid,awidget.active,awidget.name,awidget.serial,auser.name from awidget left outer join auser on (awidget.userid=auser.id)
|
|
//where awidget.active = true and ((awidget.name like '%some%') or (cast (awidget.serial as text) like '%some%') or (auser.name like '%some%') ) order by awidget.name,awidget.serial,auser.name limit 100
|
|
|
|
|
|
//TODO: TAGS
|
|
//TODO: Clean out unnneeded stuff in AyaPickListFieldDefinition (stuff from datalist copied over)
|
|
|
|
//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>();
|
|
string ActiveWhereFragment = string.Empty;
|
|
List<string> lWhere = new List<string>();
|
|
List<string> lOrderBy = 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)
|
|
{
|
|
lSelect.Add(activeColumn.SqlValueColumnName);
|
|
ActiveWhereFragment = 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);
|
|
lOrderBy.Add(valueColumnName);
|
|
|
|
if (HasAutoCompleteQuery)
|
|
{
|
|
string sWhere = string.Empty;
|
|
|
|
//Tag?
|
|
if (o.ColumnDataType == UiFieldDataType.Tags)
|
|
{
|
|
|
|
}
|
|
else if (o.ColumnDataType == UiFieldDataType.Text || o.ColumnDataType == UiFieldDataType.EmailAddress || o.ColumnDataType == UiFieldDataType.HTTP)
|
|
{
|
|
//regular text field
|
|
sWhere = $"({valueColumnName} LIKE '%{autoCompleteQuery}%')";
|
|
}
|
|
else
|
|
{
|
|
//needs to be cast to text
|
|
//(cast (awidget.serial as text) like '%some%')
|
|
sWhere = $"(cast ({valueColumnName} as text) LIKE '%{autoCompleteQuery}%')";
|
|
}
|
|
|
|
|
|
|
|
lWhere.Add(sWhere);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
//SELECT
|
|
sb.Append("select ");
|
|
foreach (string s in lSelect)
|
|
{
|
|
sb.Append(s);
|
|
sb.Append(",");
|
|
}
|
|
//clear trailing comma
|
|
sb.Length--;
|
|
|
|
//FROM
|
|
sb.Append(" ");
|
|
sb.Append(pickList.SQLFrom);
|
|
|
|
|
|
//WHERE
|
|
sb.Append(" where ");
|
|
if (!IncludeInactive)
|
|
{
|
|
sb.Append(ActiveWhereFragment);
|
|
sb.Append(" and (");
|
|
}
|
|
|
|
foreach (string s in lWhere)
|
|
{
|
|
sb.Append(s);
|
|
sb.Append(" or ");
|
|
}
|
|
//clear trailing or
|
|
sb.Length -= 4;
|
|
//enclosing parenthesis
|
|
if (!IncludeInactive)
|
|
{
|
|
sb.Append(")");
|
|
}
|
|
|
|
//ORDER BY
|
|
sb.Append(" order by ");
|
|
foreach (string s in lOrderBy)
|
|
{
|
|
sb.Append(s);
|
|
sb.Append(",");
|
|
}
|
|
//clear trailing comma
|
|
sb.Length--;
|
|
|
|
//LIMIT
|
|
sb.Append($" limit {MAXIMUM_RESULT_COUNT}");
|
|
|
|
return sb.ToString();
|
|
|
|
}
|
|
|
|
|
|
|
|
}//eoc
|
|
}//ens
|