From bd97a57c112781322b90b0f08aa11b95660806db Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Mon, 16 Mar 2020 18:49:06 +0000 Subject: [PATCH] --- devdocs/todo.txt | 2 + server/AyaNova/PickList/PickListSqlBuilder.cs | 83 +++++++++++-------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 7f671110..538ca3a4 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -10,6 +10,8 @@ todo: I think query builder part is done for now todo: actualy return results bit in picklistfetcher that concatenates into space delimited segments as per template into name and id and active to return to user todo: all template routes and actual backing code and also validation, needs to validate todo: clean out unneeded leftovers from AyaPickListFieldDefinition +todo: add pickers for all CORE objects (User...?) +todo: write a guide in ayatype for what to do when making a new core object as there are a few things now todo: tests once it's all completed for server - test regular, tags, non-text column, max-results, order, template routes etc diff --git a/server/AyaNova/PickList/PickListSqlBuilder.cs b/server/AyaNova/PickList/PickListSqlBuilder.cs index 85a5ef67..d71d9dc3 100644 --- a/server/AyaNova/PickList/PickListSqlBuilder.cs +++ b/server/AyaNova/PickList/PickListSqlBuilder.cs @@ -19,10 +19,6 @@ namespace AyaNova.PickList { - //TODO: custom template routes and tests - //TODO: TESTS FOR ALL FORMS OF QUERY (tags, non text fields etc) - //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); @@ -67,44 +63,60 @@ namespace AyaNova.PickList var valueColumnName = o.GetSqlValueColumnName(); - lSelect.Add(valueColumnName); - lOrderBy.Add(valueColumnName); + // + // - if (HasAutoCompleteQuery) + + + string sWhere = string.Empty; + + //Tags column + if (o.ColumnDataType == UiFieldDataType.Tags) { - string sWhere = string.Empty; + //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 - //Tag? - if (o.ColumnDataType == UiFieldDataType.Tags) - { - //awidget.tags @> array['blah','blah3'::varchar(255)] - //or in real life: ((awidget.name like '%o34%') or (awidget.tags @> array['zone-0'::varchar(255)]) ) - //but this means exact match only, not like comparison here + lSelect.Add($"(array_to_string({valueColumnName},',')"); + //tags can order by without the arraytostring + lOrderBy.Add(valueColumnName); - //This also works: ((awidget.name like '%o34%') or ('blue' like any(awidget.tags)) ) - //but again, not a like query only exact match - - //THIS is the one: - //(array_to_string(awidget.tags,',') like '%zo%') + //THIS is the best filter method for a like comparison to each individual tag: + //(array_to_string(awidget.tags,',') like '%zo%') + if (HasAutoCompleteQuery) sWhere = $"(array_to_string({valueColumnName},',') like '%{autoCompleteQuery}%')"; - } - 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); } + else if (o.ColumnDataType == UiFieldDataType.Text || o.ColumnDataType == UiFieldDataType.EmailAddress || o.ColumnDataType == UiFieldDataType.HTTP) + { + //regular text field, no special requirements + lSelect.Add(valueColumnName); + lOrderBy.Add(valueColumnName); + if (HasAutoCompleteQuery) + sWhere = $"({valueColumnName} LIKE '%{autoCompleteQuery}%')"; + } + else + { + + //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); + + //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 + //(cast (awidget.serial as text) like '%some%') + if (HasAutoCompleteQuery) + sWhere = $"(cast ({valueColumnName} as text) LIKE '%{autoCompleteQuery}%')"; + } + + + if (HasAutoCompleteQuery) + lWhere.Add(sWhere); + } } @@ -113,6 +125,7 @@ namespace AyaNova.PickList //SELECT sb.Append("select "); + //select name || ' ' || serial || ' ' || array_to_string(tags,',') as display from awidget foreach (string s in lSelect) { sb.Append(s);