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 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 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 lSelect = new List(); List lWhere = new List(); //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