-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add feature LIKE & NOT LIKE condition. #75
Changes from 2 commits
9cf824b
74c2714
d62a681
f20e605
7d744fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
package dbr | ||
|
||
import "reflect" | ||
import ( | ||
"fmt" | ||
"reflect" | ||
) | ||
|
||
func buildCond(d Dialect, buf Buffer, pred string, cond ...Builder) error { | ||
for i, c := range cond { | ||
|
@@ -117,3 +120,57 @@ func Lte(column string, value interface{}) Builder { | |
return buildCmp(d, buf, "<=", column, value) | ||
}) | ||
} | ||
|
||
// Lk is `LIKE`. | ||
// When value is nil, do nothing. | ||
// When value is a slice, do nothing. | ||
// Otherwise it will be translated to `LIKE`. | ||
func Like(column string, value interface{}) Builder { | ||
return BuildFunc(func(d Dialect, buf Buffer) error { | ||
if value == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO: it would be better avoid some logic here and pass arguments as is to underlayed level. if aguments is not valid, user will be notified about this via query builder error or via sql error. |
||
return fmt.Errorf("Column %s LIKE nil is Not Supported", column) | ||
} | ||
|
||
v := reflect.ValueOf(value) | ||
switch { | ||
case v.Kind() == reflect.TypeOf([]rune{}).Kind() && v.Len() != 0: | ||
return buildCmp(d, buf, "LIKE", column, string(value.([]rune))) | ||
|
||
case v.Kind() == reflect.TypeOf([0]rune{}).Kind() && v.Len() != 0: | ||
return buildCmp(d, buf, "LIKE", column, string(value.([]rune)[:])) | ||
|
||
case v.Kind() == reflect.Slice || v.Kind() == reflect.Array: | ||
return fmt.Errorf("Column %s LIKE Multiple Value is Not Supported", column) | ||
|
||
default: | ||
return buildCmp(d, buf, "LIKE", column, value) | ||
} | ||
}) | ||
} | ||
|
||
// Nlk is `NOT LIKE`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use the correct function name for golint. |
||
// When value is nil, do nothing. | ||
// When value is a slice, do nothing. | ||
// Otherwise it will be translated to `NOT LIKE`. | ||
func NotLike(column string, value interface{}) Builder { | ||
return BuildFunc(func(d Dialect, buf Buffer) error { | ||
if value == nil { | ||
return fmt.Errorf("Column %s NOT LIKE nil is Not Supported", column) | ||
} | ||
|
||
v := reflect.ValueOf(value) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the common part of this 2 functions can be moved to separate function. |
||
switch { | ||
case v.Kind() == reflect.TypeOf([]rune{}).Kind() && v.Len() != 0: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is not needed to check that v.Len() != 0, becuase 'LIKE ""' is valid expression. |
||
return buildCmp(d, buf, "NOT LIKE", column, string(value.([]rune))) | ||
|
||
case v.Kind() == reflect.TypeOf([0]rune{}).Kind() && v.Len() != 0: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
return buildCmp(d, buf, "NOT LIKE", column, string(value.([]rune)[:])) | ||
|
||
case v.Kind() == reflect.Slice || v.Kind() == reflect.Array: | ||
return fmt.Errorf("Column %s NOT LIKE Multiple Value is Not Supported", column) | ||
|
||
default: | ||
return buildCmp(d, buf, "NOT LIKE", column, value) | ||
} | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,61 +12,134 @@ func TestCondition(t *testing.T) { | |
cond Builder | ||
query string | ||
value []interface{} | ||
isErr bool | ||
}{ | ||
{ | ||
cond: Eq("col", 1), | ||
query: "`col` = ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Eq("col", nil), | ||
query: "`col` IS NULL", | ||
value: nil, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Eq("col", []int{}), | ||
query: "0", | ||
value: nil, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Neq("col", 1), | ||
query: "`col` != ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Neq("col", nil), | ||
query: "`col` IS NOT NULL", | ||
value: nil, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Gt("col", 1), | ||
query: "`col` > ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Gte("col", 1), | ||
query: "`col` >= ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Lt("col", 1), | ||
query: "`col` < ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Lte("col", 1), | ||
query: "`col` <= ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LGTM. |
||
cond: Like("col", 1), | ||
query: "`col` LIKE ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Like("col", "like"), | ||
query: "`col` LIKE ?", | ||
value: []interface{}{"like"}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Like("col", []rune{'l', 'i', 'k', 'e'}), | ||
query: "`col` LIKE ?", | ||
value: []interface{}{"like"}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: Like("col", []int{}), | ||
query: "", | ||
value: nil, | ||
isErr: true, | ||
}, | ||
{ | ||
cond: Like("col", nil), | ||
query: "", | ||
value: nil, | ||
isErr: true, | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add test with array of runs. |
||
{ | ||
cond: NotLike("col", 1), | ||
query: "`col` NOT LIKE ?", | ||
value: []interface{}{1}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: NotLike("col", "not like"), | ||
query: "`col` NOT LIKE ?", | ||
value: []interface{}{"not like"}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: NotLike("col", []rune{'n', 'o', 't', ' ', 'l', 'i', 'k', 'e'}), | ||
query: "`col` NOT LIKE ?", | ||
value: []interface{}{"not like"}, | ||
isErr: false, | ||
}, | ||
{ | ||
cond: NotLike("col", []int{}), | ||
query: "", | ||
value: nil, | ||
isErr: true, | ||
}, | ||
{ | ||
cond: NotLike("col", nil), | ||
query: "", | ||
value: nil, | ||
isErr: true, | ||
}, | ||
{ | ||
cond: And(Lt("a", 1), Or(Gt("b", 2), Neq("c", 3))), | ||
query: "(`a` < ?) AND ((`b` > ?) OR (`c` != ?))", | ||
value: []interface{}{1, 2, 3}, | ||
isErr: false, | ||
}, | ||
} { | ||
buf := NewBuffer() | ||
err := test.cond.Build(dialect.MySQL, buf) | ||
assert.NoError(t, err) | ||
if !test.isErr { | ||
assert.NoError(t, err) | ||
} | ||
assert.Equal(t, test.query, buf.String()) | ||
assert.Equal(t, test.value, buf.Value()) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the correct function name for golint.