mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-01 15:15:56 +00:00
* fix(query): escape like wildcards * test: search query wildcards * add do nothing
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -76,6 +76,7 @@ migrations/cockroach/migrate_cloud.go
|
|||||||
!/.artifacts/zitadel
|
!/.artifacts/zitadel
|
||||||
/zitadel
|
/zitadel
|
||||||
node_modules/
|
node_modules/
|
||||||
|
.kreya
|
||||||
|
|
||||||
go.work
|
go.work
|
||||||
go.work.sum
|
go.work.sum
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
@@ -84,6 +85,7 @@ func (db *DB) QueryRowContext(ctx context.Context, scan func(row *sql.Row) error
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
row := tx.QueryRowContext(ctx, query, args...)
|
row := tx.QueryRowContext(ctx, query, args...)
|
||||||
|
logging.OnError(row.Err()).Error("unexpected query error")
|
||||||
|
|
||||||
err = scan(row)
|
err = scan(row)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -170,3 +172,9 @@ func (c Config) Password() string {
|
|||||||
func (c Config) Type() string {
|
func (c Config) Type() string {
|
||||||
return c.connector.Type()
|
return c.connector.Type()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EscapeLikeWildcards(value string) string {
|
||||||
|
value = strings.ReplaceAll(value, "%", "\\%")
|
||||||
|
value = strings.ReplaceAll(value, "_", "\\_")
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
sq "github.com/Masterminds/squirrel"
|
sq "github.com/Masterminds/squirrel"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/database"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -255,7 +256,7 @@ func NewInTextQuery(col Column, values []string) (*InTextQuery, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextQuery struct {
|
type textQuery struct {
|
||||||
Column Column
|
Column Column
|
||||||
Text string
|
Text string
|
||||||
Compare TextComparison
|
Compare TextComparison
|
||||||
@@ -269,21 +270,38 @@ var (
|
|||||||
ErrEmptyValues = errors.New("values array must not be empty")
|
ErrEmptyValues = errors.New("values array must not be empty")
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTextQuery(col Column, value string, compare TextComparison) (*TextQuery, error) {
|
func NewTextQuery(col Column, value string, compare TextComparison) (*textQuery, error) {
|
||||||
if compare < 0 || compare >= textCompareMax {
|
if compare < 0 || compare >= textCompareMax {
|
||||||
return nil, ErrInvalidCompare
|
return nil, ErrInvalidCompare
|
||||||
}
|
}
|
||||||
if col.isZero() {
|
if col.isZero() {
|
||||||
return nil, ErrMissingColumn
|
return nil, ErrMissingColumn
|
||||||
}
|
}
|
||||||
return &TextQuery{
|
// handle the comparisons which use (i)like and therefore need to escape potential wildcards in the value
|
||||||
|
switch compare {
|
||||||
|
case TextEqualsIgnoreCase,
|
||||||
|
TextStartsWith,
|
||||||
|
TextStartsWithIgnoreCase,
|
||||||
|
TextEndsWith,
|
||||||
|
TextEndsWithIgnoreCase,
|
||||||
|
TextContains,
|
||||||
|
TextContainsIgnoreCase:
|
||||||
|
value = database.EscapeLikeWildcards(value)
|
||||||
|
case TextEquals,
|
||||||
|
TextListContains,
|
||||||
|
TextNotEquals,
|
||||||
|
textCompareMax:
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
return &textQuery{
|
||||||
Column: col,
|
Column: col,
|
||||||
Text: value,
|
Text: value,
|
||||||
Compare: compare,
|
Compare: compare,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *TextQuery) Col() Column {
|
func (q *textQuery) Col() Column {
|
||||||
return q.Column
|
return q.Column
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,11 +314,11 @@ func (q *InTextQuery) comp() sq.Sqlizer {
|
|||||||
return sq.Eq{q.Column.identifier(): q.Values}
|
return sq.Eq{q.Column.identifier(): q.Values}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *TextQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
func (q *textQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||||
return query.Where(q.comp())
|
return query.Where(q.comp())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *TextQuery) comp() sq.Sqlizer {
|
func (q *textQuery) comp() sq.Sqlizer {
|
||||||
switch q.Compare {
|
switch q.Compare {
|
||||||
case TextEquals:
|
case TextEquals:
|
||||||
return sq.Eq{q.Column.identifier(): q.Text}
|
return sq.Eq{q.Column.identifier(): q.Text}
|
||||||
@@ -346,32 +364,6 @@ const (
|
|||||||
textCompareMax
|
textCompareMax
|
||||||
)
|
)
|
||||||
|
|
||||||
// Deprecated: Use TextComparison, will be removed as soon as all calls are changed to query
|
|
||||||
func TextComparisonFromMethod(m domain.SearchMethod) TextComparison {
|
|
||||||
switch m {
|
|
||||||
case domain.SearchMethodEquals:
|
|
||||||
return TextEquals
|
|
||||||
case domain.SearchMethodEqualsIgnoreCase:
|
|
||||||
return TextEqualsIgnoreCase
|
|
||||||
case domain.SearchMethodStartsWith:
|
|
||||||
return TextStartsWith
|
|
||||||
case domain.SearchMethodStartsWithIgnoreCase:
|
|
||||||
return TextStartsWithIgnoreCase
|
|
||||||
case domain.SearchMethodContains:
|
|
||||||
return TextContains
|
|
||||||
case domain.SearchMethodContainsIgnoreCase:
|
|
||||||
return TextContainsIgnoreCase
|
|
||||||
case domain.SearchMethodEndsWith:
|
|
||||||
return TextEndsWith
|
|
||||||
case domain.SearchMethodEndsWithIgnoreCase:
|
|
||||||
return TextEndsWithIgnoreCase
|
|
||||||
case domain.SearchMethodListContains:
|
|
||||||
return TextListContains
|
|
||||||
default:
|
|
||||||
return textCompareMax
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type NumberQuery struct {
|
type NumberQuery struct {
|
||||||
Column Column
|
Column Column
|
||||||
Number interface{}
|
Number interface{}
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ func TestNewSubSelect(t *testing.T) {
|
|||||||
name: "no column 1",
|
name: "no column 1",
|
||||||
args: args{
|
args: args{
|
||||||
column: Column{},
|
column: Column{},
|
||||||
queries: []SearchQuery{&TextQuery{testCol, "horst", TextEquals}},
|
queries: []SearchQuery{&textQuery{testCol, "horst", TextEquals}},
|
||||||
},
|
},
|
||||||
wantErr: func(err error) bool {
|
wantErr: func(err error) bool {
|
||||||
return errors.Is(err, ErrMissingColumn)
|
return errors.Is(err, ErrMissingColumn)
|
||||||
@@ -201,7 +201,7 @@ func TestNewSubSelect(t *testing.T) {
|
|||||||
name: "no column name 1",
|
name: "no column name 1",
|
||||||
args: args{
|
args: args{
|
||||||
column: testNoCol,
|
column: testNoCol,
|
||||||
queries: []SearchQuery{&TextQuery{testCol, "horst", TextEquals}},
|
queries: []SearchQuery{&textQuery{testCol, "horst", TextEquals}},
|
||||||
},
|
},
|
||||||
wantErr: func(err error) bool {
|
wantErr: func(err error) bool {
|
||||||
return errors.Is(err, ErrMissingColumn)
|
return errors.Is(err, ErrMissingColumn)
|
||||||
@@ -211,22 +211,22 @@ func TestNewSubSelect(t *testing.T) {
|
|||||||
name: "correct 1",
|
name: "correct 1",
|
||||||
args: args{
|
args: args{
|
||||||
column: testCol,
|
column: testCol,
|
||||||
queries: []SearchQuery{&TextQuery{testCol, "horst", TextEquals}},
|
queries: []SearchQuery{&textQuery{testCol, "horst", TextEquals}},
|
||||||
},
|
},
|
||||||
want: &SubSelect{
|
want: &SubSelect{
|
||||||
Column: testCol,
|
Column: testCol,
|
||||||
Queries: []SearchQuery{&TextQuery{testCol, "horst", TextEquals}},
|
Queries: []SearchQuery{&textQuery{testCol, "horst", TextEquals}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "correct 3",
|
name: "correct 3",
|
||||||
args: args{
|
args: args{
|
||||||
column: testCol,
|
column: testCol,
|
||||||
queries: []SearchQuery{&TextQuery{testCol, "horst1", TextEquals}, &TextQuery{testCol, "horst2", TextEquals}, &TextQuery{testCol, "horst3", TextEquals}},
|
queries: []SearchQuery{&textQuery{testCol, "horst1", TextEquals}, &textQuery{testCol, "horst2", TextEquals}, &textQuery{testCol, "horst3", TextEquals}},
|
||||||
},
|
},
|
||||||
want: &SubSelect{
|
want: &SubSelect{
|
||||||
Column: testCol,
|
Column: testCol,
|
||||||
Queries: []SearchQuery{&TextQuery{testCol, "horst1", TextEquals}, &TextQuery{testCol, "horst2", TextEquals}, &TextQuery{testCol, "horst3", TextEquals}},
|
Queries: []SearchQuery{&textQuery{testCol, "horst1", TextEquals}, &textQuery{testCol, "horst2", TextEquals}, &textQuery{testCol, "horst3", TextEquals}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -275,7 +275,7 @@ func TestSubSelect_comp(t *testing.T) {
|
|||||||
name: "queries 1",
|
name: "queries 1",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
Column: testCol,
|
Column: testCol,
|
||||||
Queries: []SearchQuery{&TextQuery{testCol, "horst", TextEquals}},
|
Queries: []SearchQuery{&textQuery{testCol, "horst", TextEquals}},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
query: sq.Select("test_table.test_col").From("test_table").Where(sq.Eq{"test_table.test_col": interface{}("horst")}),
|
query: sq.Select("test_table.test_col").From("test_table").Where(sq.Eq{"test_table.test_col": interface{}("horst")}),
|
||||||
@@ -285,7 +285,7 @@ func TestSubSelect_comp(t *testing.T) {
|
|||||||
name: "queries 1 with alias",
|
name: "queries 1 with alias",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
Column: testColAlias,
|
Column: testColAlias,
|
||||||
Queries: []SearchQuery{&TextQuery{testColAlias, "horst", TextEquals}},
|
Queries: []SearchQuery{&textQuery{testColAlias, "horst", TextEquals}},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
query: sq.Select("test_alias.test_col").From("test_table AS test_alias").Where(sq.Eq{"test_alias.test_col": interface{}("horst")}),
|
query: sq.Select("test_alias.test_col").From("test_table AS test_alias").Where(sq.Eq{"test_alias.test_col": interface{}("horst")}),
|
||||||
@@ -295,7 +295,7 @@ func TestSubSelect_comp(t *testing.T) {
|
|||||||
name: "queries 3",
|
name: "queries 3",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
Column: testCol,
|
Column: testCol,
|
||||||
Queries: []SearchQuery{&TextQuery{testCol, "horst1", TextEquals}, &TextQuery{testCol, "horst2", TextEquals}, &TextQuery{testCol, "horst3", TextEquals}},
|
Queries: []SearchQuery{&textQuery{testCol, "horst1", TextEquals}, &textQuery{testCol, "horst2", TextEquals}, &textQuery{testCol, "horst3", TextEquals}},
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
query: sq.Select("test_table.test_col").From("test_table").From("test_table").Where(sq.Eq{"test_table.test_col": "horst1"}).From("test_table").Where(sq.Eq{"test_table.test_col": "horst2"}).From("test_table").Where(sq.Eq{"test_table.test_col": "horst3"}),
|
query: sq.Select("test_table.test_col").From("test_table").From("test_table").Where(sq.Eq{"test_table.test_col": "horst1"}).From("test_table").Where(sq.Eq{"test_table.test_col": "horst2"}).From("test_table").Where(sq.Eq{"test_table.test_col": "horst3"}),
|
||||||
@@ -585,12 +585,12 @@ func TestNewListQuery(t *testing.T) {
|
|||||||
name: "correct",
|
name: "correct",
|
||||||
args: args{
|
args: args{
|
||||||
column: testCol,
|
column: testCol,
|
||||||
data: &SubSelect{Column: testCol, Queries: []SearchQuery{&TextQuery{testCol, "horst1", TextEquals}}},
|
data: &SubSelect{Column: testCol, Queries: []SearchQuery{&textQuery{testCol, "horst1", TextEquals}}},
|
||||||
compare: ListIn,
|
compare: ListIn,
|
||||||
},
|
},
|
||||||
want: &ListQuery{
|
want: &ListQuery{
|
||||||
Column: testCol,
|
Column: testCol,
|
||||||
Data: &SubSelect{Column: testCol, Queries: []SearchQuery{&TextQuery{testCol, "horst1", TextEquals}}},
|
Data: &SubSelect{Column: testCol, Queries: []SearchQuery{&textQuery{testCol, "horst1", TextEquals}}},
|
||||||
Compare: ListIn,
|
Compare: ListIn,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -697,7 +697,7 @@ func TestListQuery_comp(t *testing.T) {
|
|||||||
name: "in subquery text",
|
name: "in subquery text",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
Column: testCol,
|
Column: testCol,
|
||||||
Data: &SubSelect{Column: testCol, Queries: []SearchQuery{&TextQuery{testCol, "horst", TextEquals}}},
|
Data: &SubSelect{Column: testCol, Queries: []SearchQuery{&textQuery{testCol, "horst", TextEquals}}},
|
||||||
Compare: ListIn,
|
Compare: ListIn,
|
||||||
},
|
},
|
||||||
want: want{
|
want: want{
|
||||||
@@ -779,7 +779,7 @@ func TestNewTextQuery(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
want *TextQuery
|
want *textQuery
|
||||||
wantErr func(error) bool
|
wantErr func(error) bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -827,18 +827,317 @@ func TestNewTextQuery(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "correct",
|
name: "equals",
|
||||||
args: args{
|
args: args{
|
||||||
column: testCol,
|
column: testCol,
|
||||||
value: "hurst",
|
value: "hurst",
|
||||||
compare: TextEquals,
|
compare: TextEquals,
|
||||||
},
|
},
|
||||||
want: &TextQuery{
|
want: &textQuery{
|
||||||
Column: testCol,
|
Column: testCol,
|
||||||
Text: "hurst",
|
Text: "hurst",
|
||||||
Compare: TextEquals,
|
Compare: TextEquals,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "equals ignore case",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "equals ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hu%rst",
|
||||||
|
compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hu\\%rst",
|
||||||
|
Compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "equals ignore case _ wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hu_rst",
|
||||||
|
compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hu\\_rst",
|
||||||
|
Compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "equals ignore case _, % wildcards",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "h_urst%",
|
||||||
|
compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "h\\_urst\\%",
|
||||||
|
Compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not equal",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextNotEquals,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextNotEquals,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with _ wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "_hurst",
|
||||||
|
compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "\\_hurst",
|
||||||
|
Compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with % wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst%",
|
||||||
|
compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst\\%",
|
||||||
|
Compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with %, % wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hu%%rst",
|
||||||
|
compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hu\\%\\%rst",
|
||||||
|
Compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case _ wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hur_st",
|
||||||
|
compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hur\\_st",
|
||||||
|
Compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst%",
|
||||||
|
compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst\\%",
|
||||||
|
Compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case _, _ wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "h_r_t",
|
||||||
|
compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "h\\_r\\_t",
|
||||||
|
Compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with % wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "%hurst",
|
||||||
|
compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "\\%hurst",
|
||||||
|
Compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with _ wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst_",
|
||||||
|
compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst\\_",
|
||||||
|
Compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with _, % wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst_%",
|
||||||
|
compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst\\_\\%",
|
||||||
|
Compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with ignore case",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with ignore case _, %, _ wildcards",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "h_r_t%",
|
||||||
|
compare: TextEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "h\\_r\\_t\\%",
|
||||||
|
Compare: TextEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextContains,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextContains,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains % wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "%",
|
||||||
|
compare: TextContains,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "\\%",
|
||||||
|
Compare: TextContains,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains ignore csae",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurst",
|
||||||
|
compare: TextContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurst",
|
||||||
|
Compare: TextContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains ignore csae _ wildcard",
|
||||||
|
args: args{
|
||||||
|
column: testCol,
|
||||||
|
value: "hurs_",
|
||||||
|
compare: TextContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: &textQuery{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "hurs\\_",
|
||||||
|
Compare: TextContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@@ -894,6 +1193,17 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
query: sq.ILike{"test_table.test_col": "Hurst"},
|
query: sq.ILike{"test_table.test_col": "Hurst"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "equals ignore case wildcard",
|
||||||
|
fields: fields{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "Hu%%rst",
|
||||||
|
Compare: TextEqualsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: sq.ILike{"test_table.test_col": "Hu\\%\\%rst"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "starts with",
|
name: "starts with",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -905,6 +1215,17 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
query: sq.Like{"test_table.test_col": "Hurst%"},
|
query: sq.Like{"test_table.test_col": "Hurst%"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "starts with wildcards",
|
||||||
|
fields: fields{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "_Hurst%",
|
||||||
|
Compare: TextStartsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: sq.Like{"test_table.test_col": "\\_Hurst\\%%"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "starts with ignore case",
|
name: "starts with ignore case",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -916,6 +1237,17 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
query: sq.ILike{"test_table.test_col": "Hurst%"},
|
query: sq.ILike{"test_table.test_col": "Hurst%"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case wildcards",
|
||||||
|
fields: fields{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "Hurst%",
|
||||||
|
Compare: TextStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: sq.ILike{"test_table.test_col": "Hurst\\%%"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ends with",
|
name: "ends with",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -927,6 +1259,17 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
query: sq.Like{"test_table.test_col": "%Hurst"},
|
query: sq.Like{"test_table.test_col": "%Hurst"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ends with wildcards",
|
||||||
|
fields: fields{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "Hurst%",
|
||||||
|
Compare: TextEndsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: sq.Like{"test_table.test_col": "%Hurst\\%"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ends with ignore case",
|
name: "ends with ignore case",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -938,6 +1281,17 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
query: sq.ILike{"test_table.test_col": "%Hurst"},
|
query: sq.ILike{"test_table.test_col": "%Hurst"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "ends with ignore case wildcards",
|
||||||
|
fields: fields{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "%Hurst",
|
||||||
|
Compare: TextEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: sq.ILike{"test_table.test_col": "%\\%Hurst"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "contains",
|
name: "contains",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -949,6 +1303,17 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
query: sq.Like{"test_table.test_col": "%Hurst%"},
|
query: sq.Like{"test_table.test_col": "%Hurst%"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "contains wildcards",
|
||||||
|
fields: fields{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "Hu%rst%",
|
||||||
|
Compare: TextContains,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: sq.Like{"test_table.test_col": "%Hu\\%rst\\%%"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "containts ignore case",
|
name: "containts ignore case",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -960,6 +1325,17 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
query: sq.ILike{"test_table.test_col": "%Hurst%"},
|
query: sq.ILike{"test_table.test_col": "%Hurst%"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "contains ignore case wildcards",
|
||||||
|
fields: fields{
|
||||||
|
Column: testCol,
|
||||||
|
Text: "%Hurst%",
|
||||||
|
Compare: TextContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: sq.ILike{"test_table.test_col": "%\\%Hurst\\%%"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "list containts",
|
name: "list containts",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -999,10 +1375,10 @@ func TestTextQuery_comp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
s := &TextQuery{
|
s, _ := NewTextQuery(tt.fields.Column, tt.fields.Text, tt.fields.Compare)
|
||||||
Column: tt.fields.Column,
|
if s == nil {
|
||||||
Text: tt.fields.Text,
|
// used to check correct behavior of comp
|
||||||
Compare: tt.fields.Compare,
|
s = &textQuery{Column: tt.fields.Column, Text: tt.fields.Text, Compare: tt.fields.Compare}
|
||||||
}
|
}
|
||||||
query := s.comp()
|
query := s.comp()
|
||||||
if query == nil && tt.want.isNil {
|
if query == nil && tt.want.isNil {
|
||||||
|
|||||||
@@ -95,36 +95,42 @@ func SetQuery(query *gorm.DB, key ColumnKey, value interface{}, method domain.Se
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-SLj7s", "Starts with only possible for strings")
|
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-SLj7s", "Starts with only possible for strings")
|
||||||
}
|
}
|
||||||
|
valueText = database.EscapeLikeWildcards(valueText)
|
||||||
query = query.Where(column+" LIKE ?", valueText+"%")
|
query = query.Where(column+" LIKE ?", valueText+"%")
|
||||||
case domain.SearchMethodStartsWithIgnoreCase:
|
case domain.SearchMethodStartsWithIgnoreCase:
|
||||||
valueText, ok := value.(string)
|
valueText, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-eidus", "Starts with ignore case only possible for strings")
|
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-eidus", "Starts with ignore case only possible for strings")
|
||||||
}
|
}
|
||||||
|
valueText = database.EscapeLikeWildcards(valueText)
|
||||||
query = query.Where("LOWER("+column+") LIKE LOWER(?)", valueText+"%")
|
query = query.Where("LOWER("+column+") LIKE LOWER(?)", valueText+"%")
|
||||||
case domain.SearchMethodEndsWith:
|
case domain.SearchMethodEndsWith:
|
||||||
valueText, ok := value.(string)
|
valueText, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-Hswd3", "Ends with only possible for strings")
|
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-Hswd3", "Ends with only possible for strings")
|
||||||
}
|
}
|
||||||
|
valueText = database.EscapeLikeWildcards(valueText)
|
||||||
query = query.Where(column+" LIKE ?", "%"+valueText)
|
query = query.Where(column+" LIKE ?", "%"+valueText)
|
||||||
case domain.SearchMethodEndsWithIgnoreCase:
|
case domain.SearchMethodEndsWithIgnoreCase:
|
||||||
valueText, ok := value.(string)
|
valueText, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-dAG31", "Ends with ignore case only possible for strings")
|
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-dAG31", "Ends with ignore case only possible for strings")
|
||||||
}
|
}
|
||||||
|
valueText = database.EscapeLikeWildcards(valueText)
|
||||||
query = query.Where("LOWER("+column+") LIKE LOWER(?)", "%"+valueText)
|
query = query.Where("LOWER("+column+") LIKE LOWER(?)", "%"+valueText)
|
||||||
case domain.SearchMethodContains:
|
case domain.SearchMethodContains:
|
||||||
valueText, ok := value.(string)
|
valueText, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-3ids", "Contains with only possible for strings")
|
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-3ids", "Contains with only possible for strings")
|
||||||
}
|
}
|
||||||
|
valueText = database.EscapeLikeWildcards(valueText)
|
||||||
query = query.Where(column+" LIKE ?", "%"+valueText+"%")
|
query = query.Where(column+" LIKE ?", "%"+valueText+"%")
|
||||||
case domain.SearchMethodContainsIgnoreCase:
|
case domain.SearchMethodContainsIgnoreCase:
|
||||||
valueText, ok := value.(string)
|
valueText, ok := value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-eid73", "Contains with ignore case only possible for strings")
|
return nil, zerrors.ThrowInvalidArgument(nil, "VIEW-eid73", "Contains with ignore case only possible for strings")
|
||||||
}
|
}
|
||||||
|
valueText = database.EscapeLikeWildcards(valueText)
|
||||||
query = query.Where("LOWER("+column+") LIKE LOWER(?)", "%"+valueText+"%")
|
query = query.Where("LOWER("+column+") LIKE LOWER(?)", "%"+valueText+"%")
|
||||||
case domain.SearchMethodNotEquals:
|
case domain.SearchMethodNotEquals:
|
||||||
query = query.Where(""+column+" <> ?", value)
|
query = query.Where(""+column+" <> ?", value)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
@@ -155,3 +156,304 @@ func TestPrepareSearchQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetQuery(t *testing.T) {
|
||||||
|
query := mockDB(t).db.Select("test_field").Table("test_table")
|
||||||
|
exprPrefix := `(SELECT test_field FROM "test_table" WHERE `
|
||||||
|
type args struct {
|
||||||
|
key ColumnKey
|
||||||
|
value interface{}
|
||||||
|
method domain.SearchMethod
|
||||||
|
}
|
||||||
|
type want struct {
|
||||||
|
isErr func(t *testing.T, got error)
|
||||||
|
query *gorm.SqlExpr
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want want
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "contains",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "asdf",
|
||||||
|
method: domain.SearchMethodContains,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%asdf%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains _ wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as_df",
|
||||||
|
method: domain.SearchMethodContains,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%as\\_df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as%df",
|
||||||
|
method: domain.SearchMethodContains,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%as\\%df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "a_s%d_f",
|
||||||
|
method: domain.SearchMethodContains,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%a\\_s\\%d\\_f%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "asdf",
|
||||||
|
method: domain.SearchMethodStartsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "asdf%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with _ wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as_df",
|
||||||
|
method: domain.SearchMethodStartsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "as\\_df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as%df",
|
||||||
|
method: domain.SearchMethodStartsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "as\\%df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "a_s%d_f",
|
||||||
|
method: domain.SearchMethodStartsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "a\\_s\\%d\\_f%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "asdf",
|
||||||
|
method: domain.SearchMethodEndsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%asdf"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with _ wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as_df",
|
||||||
|
method: domain.SearchMethodEndsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%as\\_df"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as%df",
|
||||||
|
method: domain.SearchMethodEndsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%as\\%df"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "a_s%d_f",
|
||||||
|
method: domain.SearchMethodEndsWith,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(test LIKE ?))", "%a\\_s\\%d\\_f"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "asdf",
|
||||||
|
method: domain.SearchMethodStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "asdf%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case _ wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as_df",
|
||||||
|
method: domain.SearchMethodStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "as\\_df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as%df",
|
||||||
|
method: domain.SearchMethodStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "as\\%df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "starts with ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "a_s%d_f",
|
||||||
|
method: domain.SearchMethodStartsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "a\\_s\\%d\\_f%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with ignore case",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "asdf",
|
||||||
|
method: domain.SearchMethodEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%asdf"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with ignore case _ wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as_df",
|
||||||
|
method: domain.SearchMethodEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%as\\_df"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as%df",
|
||||||
|
method: domain.SearchMethodEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%as\\%df"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ends with ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "a_s%d_f",
|
||||||
|
method: domain.SearchMethodEndsWithIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%a\\_s\\%d\\_f"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains ignore case",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "asdf",
|
||||||
|
method: domain.SearchMethodContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%asdf%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains ignore case _ wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as_df",
|
||||||
|
method: domain.SearchMethodContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%as\\_df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "as%df",
|
||||||
|
method: domain.SearchMethodContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%as\\%df%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contains ignore case % wildcard",
|
||||||
|
args: args{
|
||||||
|
key: TestSearchKey_TEST,
|
||||||
|
value: "a_s%d_f",
|
||||||
|
method: domain.SearchMethodContainsIgnoreCase,
|
||||||
|
},
|
||||||
|
want: want{
|
||||||
|
query: gorm.Expr(exprPrefix+"(LOWER(test) LIKE LOWER(?)))", "%a\\_s\\%d\\_f%"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
if tt.want.isErr == nil {
|
||||||
|
tt.want.isErr = func(t *testing.T, got error) {
|
||||||
|
if got == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Errorf("no error expected got: %v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := SetQuery(query, tt.args.key, tt.args.value, tt.args.method)
|
||||||
|
tt.want.isErr(t, err)
|
||||||
|
if !reflect.DeepEqual(got.SubQuery(), tt.want.query) {
|
||||||
|
t.Errorf("unexpected query: \nwant: %v\n got: %v", *tt.want.query, *got.SubQuery())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user