From 7eaa9e59074e5c4df3412ddcf07108e2a0172078 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 2 Sep 2021 19:26:01 +0000 Subject: [PATCH] --- .../DataListSqlFilterCriteriaBuilder.cs | 110 ++++++++++-------- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs index e0eef90a..81637fe5 100644 --- a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs +++ b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs @@ -948,63 +948,79 @@ namespace AyaNova.DataList This method and choices ensures users don't need to make a separate row for each one they can just treat the entire tag collection like they treat a single word match in a text field */ - switch (sOperator) + + //HAS VALUE / NO VALUE + if (sValue == "*NULL*") { - case DataListFilterComparisonOperator.Equality: - { - StringBuilder sbTags = new StringBuilder(); - sbTags.Append("@> array["); - //Note: with listOptions change to split filter and view the tags are now in sValue as a string of comma delimited strings so split them out here - List normalizedTags = TagBiz.NormalizeTags(sValue.Split(',').ToList()); - foreach (string s in normalizedTags) + if (sOperator == DataListFilterComparisonOperator.Equality) + return $"{SqlColumnNameToFilter} = '{{}}'"; + else + return $"{SqlColumnNameToFilter} <> '{{}}'"; + } + else + { + string PostgresTagArrayFragment = string.Empty; + //Filter ui builder allows multiple tag selection just like any other tag selection and sends the filter to the server like this: + //filter "[{\"column\":\"customertags\",\"any\":false,\"items\":[{\"op\":\"=\",\"value\":\"completed.reminder,burnaby.dispatchzone,cabling-fibre.user-skill\"}]}]" + //needs to be "ARRAY['red','green'::varchar(255)]" + StringBuilder sbTemp = new StringBuilder(); + sbTemp = sbTemp.Append("ARRAY["); + List normalizedTags = TagBiz.NormalizeTags(sValue.Split(',').ToList()); + if (normalizedTags.Count == 0) + throw new System.ArgumentNullException("DataListSqlFilterCriteriaBuilder::TagDataFilterToColumnCriteria - NO tags were provided for filtering"); + + foreach (string s in normalizedTags) + sbTemp.Append($"'{s}',"); + PostgresTagArrayFragment = sbTemp.ToString().TrimEnd(','); + PostgresTagArrayFragment += "::VARCHAR(255)]"; + + switch (sOperator) + { + case DataListFilterComparisonOperator.Equality: { + //WHERE ARRAY['green'::varchar(255)] <@ tags and array_length(tags,1) = 1 + StringBuilder sbTags = new StringBuilder(); + sbTags.Append("@> array["); + //Note: with listOptions change to split filter and view the tags are now in sValue as a string of comma delimited strings so split them out here + List normalizedTags = TagBiz.NormalizeTags(sValue.Split(',').ToList()); + foreach (string s in normalizedTags) + { - sbTags.Append($"'{s}',"); + sbTags.Append($"'{s}',"); + } + sb.Append(sbTags.ToString().TrimEnd(',')); + sb.Append("::varchar(255)]"); } - sb.Append(sbTags.ToString().TrimEnd(',')); - sb.Append("::varchar(255)]"); - } - break; - case DataListFilterComparisonOperator.NotEqual: - sb.Append("<>'"); - sb.Append(sValue); - sb.Append("'"); - break; + break; + case DataListFilterComparisonOperator.NotEqual: + sb.Append("<>'"); + sb.Append(sValue); + sb.Append("'"); + break; - case DataListFilterComparisonOperator.NotContains: - sb.Append("Not Like '%"); - sb.Append(sValue); - sb.Append("%'"); - break; + case DataListFilterComparisonOperator.NotContains: + sb.Append("Not Like '%"); + sb.Append(sValue); + sb.Append("%'"); + break; + + case DataListFilterComparisonOperator.Contains: + + //TagSpecificWhereFragment = $"(array_to_string({tagColumn.GetSqlValueColumnName()},',') like '%{tagSpecificQuery}%')"; + sb.Append("Like '%"); + sb.Append(sValue); + sb.Append("%'"); + break; + + default: + throw new System.ArgumentOutOfRangeException("OPERATOR_TYPE", sOperator, "DataListSqlFilterCriteriaBuilder unhandled operator type [" + sOperator + "] IN TAGS"); + + } - case DataListFilterComparisonOperator.Contains: - //TagSpecificWhereFragment = $"(array_to_string({tagColumn.GetSqlValueColumnName()},',') like '%{tagSpecificQuery}%')"; - sb.Append("Like '%"); - sb.Append(sValue); - sb.Append("%'"); - break; - default: - throw new System.ArgumentOutOfRangeException("OPERATOR_TYPE", sOperator, "DataListSqlFilterCriteriaBuilder unhandled operator type [" + sOperator + "] IN TAGS"); } - - //NOTE: tag filter OPERATOR is ignored, query matches if all tags are found in a tag collection that could have other tags as well - - //for initial release a tag filter is inclusive of all tags only - //in other words all tags presented must be in record to match (simple AND) - //select * from awidget where awidget.tags @> array['blah','blah3'::varchar(255)] - - //NOTE: After coding this discovered *can* do a LIKE query with tags like this: - //(array_to_string(awidget.tags,',') like '%zo%') - //implemented that way in picklistquery builder - //also ilike is a postgres case insensitive like but works on current locale of server which - //sounds like it might fuck up when using other languages so... - - - - return sb.ToString();