-
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 3 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,44 @@ func Lte(column string, value interface{}) Builder { | |
return buildCmp(d, buf, "<=", column, value) | ||
}) | ||
} | ||
|
||
func buildLikeCmp(d Dialect, buf Buffer, pred string, column string, value interface{}) error { | ||
if value == nil { | ||
return fmt.Errorf("Column %s %s nil is Not Supported", column, pred) | ||
} | ||
|
||
v := reflect.ValueOf(value) | ||
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. Please clarify why does condition 'v.Len() != 0' need here. 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. Sorry, the empty int slice and the byte slice were caught on Detect of the Rune slice so I temporarily left it. |
||
return buildCmp(d, buf, pred, column, string(value.([]rune))) | ||
|
||
case v.Kind() == reflect.TypeOf([0]rune{}).Kind() && v.Len() != 0: | ||
return buildCmp(d, buf, pred, column, string(value.([]rune)[:])) | ||
|
||
case v.Kind() == reflect.Slice || v.Kind() == reflect.Array: | ||
return fmt.Errorf("Column %s %s Multiple Value is Not Supported", column, pred) | ||
|
||
default: | ||
return buildCmp(d, buf, pred, column, value) | ||
} | ||
} | ||
|
||
// Lk is `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 `LIKE`. | ||
func Like(column string, value interface{}) Builder { | ||
return BuildFunc(func(d Dialect, buf Buffer) error { | ||
return buildLikeCmp(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 { | ||
return buildLikeCmp(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 an exported error 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.
@tyler-smith I’m sorry, but because there was a problem with my repository management, I issued a new PR and the same content PR. And I fixed the pointed out matter.
#103