diff --git a/server/AyaNova/Controllers/PickListController.cs b/server/AyaNova/Controllers/PickListController.cs index f2f19a38..4bd3822c 100644 --- a/server/AyaNova/Controllers/PickListController.cs +++ b/server/AyaNova/Controllers/PickListController.cs @@ -43,11 +43,12 @@ namespace AyaNova.Api.Controllers /// - /// Get picklist + /// Get picklist of all Active objects of type specified and filtered by query specified + /// Note that this list is capped automatically to return no more than 100 results /// /// The AyaType object type to select from /// The query to filter the returned list by - /// Include inactive objects in the returned list + /// Include inactive objects in the returned list /// Filtered list [HttpGet("List")] public async Task GetList([FromQuery]AyaType ayaType, [FromQuery]string query, [FromQuery] bool inactive) diff --git a/server/AyaNova/PickList/PickListFetcher.cs b/server/AyaNova/PickList/PickListFetcher.cs index a5b80040..b4de4a34 100644 --- a/server/AyaNova/PickList/PickListFetcher.cs +++ b/server/AyaNova/PickList/PickListFetcher.cs @@ -74,6 +74,9 @@ namespace AyaNova.PickList { while (dr.Read()) { + //query is always in the same order: + //plId, plActive, plName + // List row = new List(returnRowColumnCount); diff --git a/server/AyaNova/PickList/PickListSqlBuilder.cs b/server/AyaNova/PickList/PickListSqlBuilder.cs index d71d9dc3..23e3eb19 100644 --- a/server/AyaNova/PickList/PickListSqlBuilder.cs +++ b/server/AyaNova/PickList/PickListSqlBuilder.cs @@ -27,27 +27,51 @@ namespace AyaNova.PickList string ActiveWhereFragment = string.Empty; List lWhere = new List(); List lOrderBy = new List(); + string PlIdSelectFragment = string.Empty; + string ActiveSelectFragment = string.Empty; - //Add rowid column as it's always required + //PROCESS ROW ID "VALUE" COLUMN + // 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"); + PlIdSelectFragment = rowIdColumn.SqlIdColumnName + " as plId"; - //add active only as default for all lists unless inactive is specified - if (!IncludeInactive) + + //PROCESS ACTIVE COLUMN + // + //NOTE: default is to filter *out* inactive objects because that's the most common need at the Client + //but we provide the override for that if necessary as there are often (management usually) cases where user needs to select inactive records + + //add active column, fake it if necessary + AyaPickListFieldDefinition activeColumn = pickList.ColumnDefinitions.FirstOrDefault(x => x.IsActiveColumn == true); + if (activeColumn == null) { - 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) + //no active column which is normal for some types of objects + //so make a fake one and return them all as active=true as all lists must return the same format + ActiveSelectFragment = "true as plActive"; + + } + else + { + //we have an active column, set accordingly + + //regardless of wanting to see inactive, we always want to see the column itself + ActiveSelectFragment = activeColumn.SqlValueColumnName + " as plActive"; + + //this is the normal path unless there is an override + //if there is an override to see inactive too then we just don't set the filter on active + if (!IncludeInactive) { - lSelect.Add(activeColumn.SqlValueColumnName); ActiveWhereFragment = activeColumn.SqlValueColumnName + " = true"; } } + + //PROCESS TEMPLATED COLUMNS TO BE RETURNED IN RESULTS + // foreach (string ColumnName in templateColumnNames) { @@ -63,20 +87,16 @@ namespace AyaNova.PickList var valueColumnName = o.GetSqlValueColumnName(); - // - // - - - string sWhere = string.Empty; - //Tags column + //TAGS COLUMN + // if (o.ColumnDataType == UiFieldDataType.Tags) { //Handle tags for each part of the sql query - //idea is they display as a comma separated list - //filter as a like comparison to each individual tag - //order by the array which appears to do it left to right as if it was a giant string + //idea is they display as a comma separated list, + //filter as a like comparison to each individual tag and + //order by the array which appears in testing to do it left to right as if it was a giant string lSelect.Add($"(array_to_string({valueColumnName},',')"); //tags can order by without the arraytostring @@ -90,16 +110,19 @@ namespace AyaNova.PickList } else if (o.ColumnDataType == UiFieldDataType.Text || o.ColumnDataType == UiFieldDataType.EmailAddress || o.ColumnDataType == UiFieldDataType.HTTP) { - //regular text field, no special requirements + //TEXT COLUMN + // lSelect.Add(valueColumnName); lOrderBy.Add(valueColumnName); if (HasAutoCompleteQuery) - sWhere = $"({valueColumnName} LIKE '%{autoCompleteQuery}%')"; + sWhere = $"({valueColumnName} like '%{autoCompleteQuery}%')"; } else { + //NON-TEXT COLUMN + // - //if any part of a select contatenation query using the || postgres concat is text then all fields are automatically converted to text + //Note: if any part of a select contatenation query using the || postgres concat is text then all fields are automatically converted to text //so no need to make it text here as the automatic spacing character will force the whole thing to a text concat anyway //ref: https://stackoverflow.com/a/19943343/8939 lSelect.Add(valueColumnName); @@ -107,10 +130,10 @@ namespace AyaNova.PickList //order by for now seems to be best as just order by it's value whatever it is lOrderBy.Add(valueColumnName); - //needs to be cast to text to query on it + //Where fragment is different for non text fields: it needs to be cast to text to like query on it //(cast (awidget.serial as text) like '%some%') if (HasAutoCompleteQuery) - sWhere = $"(cast ({valueColumnName} as text) LIKE '%{autoCompleteQuery}%')"; + sWhere = $"(cast ({valueColumnName} as text) like '%{autoCompleteQuery}%')"; } @@ -125,14 +148,24 @@ namespace AyaNova.PickList //SELECT sb.Append("select "); + + //ID COLUMN + sb.Append(PlIdSelectFragment); + sb.Append(", "); + + //ACTIVE COLUMN + sb.Append(ActiveSelectFragment); + sb.Append(", "); + //select name || ' ' || serial || ' ' || array_to_string(tags,',') as display from awidget foreach (string s in lSelect) { sb.Append(s); - sb.Append(","); + sb.Append(" || ' ' || ");//sb 11 characters } - //clear trailing comma - sb.Length--; + //clear trailing concat element + sb.Length -= 11;//length of last concat fragment above + sb.Append(" as plname"); //FROM sb.Append(" "); @@ -176,7 +209,8 @@ namespace AyaNova.PickList return sb.ToString(); } - + //"select awidget.id as plId || ' 'awidget.active as plActive || ' 'awidget.name || ' 'awidget.serial || ' 'auser.name as plname from awidget left outer join auser on (awidget.userid=auser.id) + //where awidget.active = true and ((awidget.name like '%on%') or (cast (awidget.serial as text) like '%on%') or (auser.name like '%on%')) order by awidget.name,awidget.serial,auser.name limit 100" }//eoc