From 66efad893c4f139746584efc49dc4e82f3633c9e Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Mon, 2 Nov 2020 17:47:01 +1100 Subject: [PATCH 1/2] Fix encoding of string criteria --- ui/v2.5/src/models/list-filter/filter.ts | 5 +---- ui/v2.5/src/models/list-filter/types.ts | 4 +++- ui/v2.5/src/utils/navigation.ts | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ui/v2.5/src/models/list-filter/filter.ts b/ui/v2.5/src/models/list-filter/filter.ts index de035effe96..accddfd3816 100644 --- a/ui/v2.5/src/models/list-filter/filter.ts +++ b/ui/v2.5/src/models/list-filter/filter.ts @@ -329,10 +329,7 @@ export class ListFilterModel { } jsonParameters.forEach((jsonString) => { - // make sure we escape \ - const escaped = jsonString.replaceAll("\\", "\\\\"); - - const encodedCriterion = JSON.parse(escaped); + const encodedCriterion = JSON.parse(jsonString); const criterion = makeCriteria(encodedCriterion.type); // it's possible that we have unsupported criteria. Just skip if so. if (criterion) { diff --git a/ui/v2.5/src/models/list-filter/types.ts b/ui/v2.5/src/models/list-filter/types.ts index 5e00a172f7b..4507b63eb11 100644 --- a/ui/v2.5/src/models/list-filter/types.ts +++ b/ui/v2.5/src/models/list-filter/types.ts @@ -29,7 +29,9 @@ export interface ILabeledValue { } export function encodeILabeledId(o: ILabeledId) { - return { ...o, label: encodeURIComponent(o.label) }; + // escape \ to \\ so that it encodes to JSON correctly + const adjustedLabel = o.label.replaceAll("\\", "\\\\"); + return { ...o, label: encodeURIComponent(adjustedLabel) }; } export interface IOptionType { diff --git a/ui/v2.5/src/utils/navigation.ts b/ui/v2.5/src/utils/navigation.ts index 3a3cfadf8dc..25c3f1e0f73 100644 --- a/ui/v2.5/src/utils/navigation.ts +++ b/ui/v2.5/src/utils/navigation.ts @@ -29,7 +29,7 @@ const makePerformersCountryUrl = ( if (!performer.id) return "#"; const filter = new ListFilterModel(FilterMode.Performers); const criterion = new CountryCriterion(); - criterion.value = `${performer.country}`; + criterion.value = `"${performer.country}"`; filter.criteria.push(criterion); return `/performers?${filter.makeQueryParameters()}`; }; From 8e729ec433e70a8053ba97acc802529d00aa7ea8 Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Mon, 2 Nov 2020 18:16:45 +1100 Subject: [PATCH 2/2] Add equals and includes (and not) string criteria --- pkg/models/querybuilder_sql.go | 22 +++++++++---- .../models/list-filter/criteria/criterion.ts | 32 ++----------------- ui/v2.5/src/utils/navigation.ts | 2 +- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/pkg/models/querybuilder_sql.go b/pkg/models/querybuilder_sql.go index 1eb98edb888..a854d2309bb 100644 --- a/pkg/models/querybuilder_sql.go +++ b/pkg/models/querybuilder_sql.go @@ -60,20 +60,28 @@ func (qb *queryBuilder) handleIntCriterionInput(c *IntCriterionInput, column str func (qb *queryBuilder) handleStringCriterionInput(c *StringCriterionInput, column string) { if c != nil { - if modifier := c.Modifier.String(); c.Modifier.IsValid() { + if modifier := c.Modifier; c.Modifier.IsValid() { switch modifier { - case "EQUALS": + case CriterionModifierIncludes: clause, thisArgs := getSearchBinding([]string{column}, c.Value, false) qb.addWhere(clause) qb.addArg(thisArgs...) - case "NOT_EQUALS": + case CriterionModifierExcludes: clause, thisArgs := getSearchBinding([]string{column}, c.Value, true) qb.addWhere(clause) qb.addArg(thisArgs...) - case "IS_NULL": - qb.addWhere(column + " IS NULL") - case "NOT_NULL": - qb.addWhere(column + " IS NOT NULL") + case CriterionModifierEquals: + qb.addWhere(column + " LIKE ?") + qb.addArg(c.Value) + case CriterionModifierNotEquals: + qb.addWhere(column + " NOT LIKE ?") + qb.addArg(c.Value) + default: + clause, count := getSimpleCriterionClause(modifier, "?") + qb.addWhere(column + " " + clause) + if count == 1 { + qb.addArg(c.Value) + } } } } diff --git a/ui/v2.5/src/models/list-filter/criteria/criterion.ts b/ui/v2.5/src/models/list-filter/criteria/criterion.ts index 3aa50ae6259..07e77e308cd 100644 --- a/ui/v2.5/src/models/list-filter/criteria/criterion.ts +++ b/ui/v2.5/src/models/list-filter/criteria/criterion.ts @@ -250,6 +250,8 @@ export class StringCriterion extends Criterion { public modifierOptions = [ StringCriterion.getModifierOption(CriterionModifier.Equals), StringCriterion.getModifierOption(CriterionModifier.NotEquals), + StringCriterion.getModifierOption(CriterionModifier.Includes), + StringCriterion.getModifierOption(CriterionModifier.Excludes), StringCriterion.getModifierOption(CriterionModifier.IsNull), StringCriterion.getModifierOption(CriterionModifier.NotNull), ]; @@ -273,36 +275,6 @@ export class StringCriterion extends Criterion { this.parameterName = type; } } - - public static getModifierOption( - modifier: CriterionModifier = CriterionModifier.Equals - ): ILabeledValue { - switch (modifier) { - case CriterionModifier.Equals: - return { value: CriterionModifier.Equals, label: "Includes" }; - case CriterionModifier.NotEquals: - return { value: CriterionModifier.NotEquals, label: "Excludes" }; - default: - return super.getModifierOption(modifier); - } - } - - public getLabel(): string { - let modifierString: string; - switch (this.modifier) { - case CriterionModifier.Equals: - modifierString = "includes"; - break; - case CriterionModifier.NotEquals: - modifierString = "excludes"; - break; - default: - return super.getLabel(); - } - - const valueString = this.getLabelValue(); - return `${Criterion.getLabel(this.type)} ${modifierString} ${valueString}`; - } } export class MandatoryStringCriterion extends StringCriterion { diff --git a/ui/v2.5/src/utils/navigation.ts b/ui/v2.5/src/utils/navigation.ts index 25c3f1e0f73..3a3cfadf8dc 100644 --- a/ui/v2.5/src/utils/navigation.ts +++ b/ui/v2.5/src/utils/navigation.ts @@ -29,7 +29,7 @@ const makePerformersCountryUrl = ( if (!performer.id) return "#"; const filter = new ListFilterModel(FilterMode.Performers); const criterion = new CountryCriterion(); - criterion.value = `"${performer.country}"`; + criterion.value = `${performer.country}`; filter.criteria.push(criterion); return `/performers?${filter.makeQueryParameters()}`; };