Skip to content
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

feat: build delete support limit #148

Merged
merged 4 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var (
errHavingUnsupportedOperator = errors.New(`[builder] "_having" contains unsupported operator`)
errLockModeValueType = errors.New(`[builder] the value of "_lockMode" must be of string type`)
errNotAllowedLockMode = errors.New(`[builder] the value of "_lockMode" is not allowed`)
errUpdateLimitType = errors.New(`[builder] the value of "_limit" in update query must be one of int,uint,int64,uint64`)
errLimitType = errors.New(`[builder] the value of "_limit" must be one of int,uint,int64,uint64`)

errWhereInterfaceSliceType = `[builder] the value of "xxx %s" must be of []interface{} type`
errEmptySliceCondition = `[builder] the value of "%s" must contain at least one element`
Expand Down Expand Up @@ -170,8 +170,7 @@ func resolveHaving(having interface{}) (map[string]interface{}, error) {
return copiedMap, nil
}

// BuildUpdate work as its name says
func BuildUpdate(table string, where map[string]interface{}, update map[string]interface{}) (string, []interface{}, error) {
func getLimit(where map[string]interface{}) (uint, error) {
var limit uint
if v, ok := where["_limit"]; ok {
switch val := v.(type) {
Expand All @@ -184,9 +183,18 @@ func BuildUpdate(table string, where map[string]interface{}, update map[string]i
case uint64:
limit = uint(val)
default:
return "", nil, errUpdateLimitType
return 0, errLimitType
}
}
return limit, nil
}

// BuildUpdate work as its name says
func BuildUpdate(table string, where map[string]interface{}, update map[string]interface{}) (string, []interface{}, error) {
limit, err := getLimit(where)
if err != nil {
return "", nil, err
}
conditions, err := getWhereConditions(where, defaultIgnoreKeys)
if nil != err {
return "", nil, err
Expand All @@ -196,11 +204,15 @@ func BuildUpdate(table string, where map[string]interface{}, update map[string]i

// BuildDelete work as its name says
func BuildDelete(table string, where map[string]interface{}) (string, []interface{}, error) {
limit, err := getLimit(where)
if err != nil {
return "", nil, err
}
conditions, err := getWhereConditions(where, defaultIgnoreKeys)
if nil != err {
return "", nil, err
}
return buildDelete(table, conditions...)
return buildDelete(table, limit, conditions...)
}

// BuildInsert work as its name says
Expand Down
7 changes: 4 additions & 3 deletions builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,12 @@ func Test_BuildDelete(t *testing.T) {
"age >=": 21,
"sex in": []interface{}{"male", "female"},
"hobby in": []interface{}{"soccer", "basketball", "tenis"},
"_limit": 10,
},
},
out: outStruct{
cond: "DELETE FROM tb WHERE (hobby IN (?,?,?) AND sex IN (?,?) AND age>=?)",
vals: []interface{}{"soccer", "basketball", "tenis", "male", "female", 21},
cond: "DELETE FROM tb WHERE (hobby IN (?,?,?) AND sex IN (?,?) AND age>=?) LIMIT ?",
vals: []interface{}{"soccer", "basketball", "tenis", "male", "female", 21, 10},
err: nil,
},
},
Expand Down Expand Up @@ -486,7 +487,7 @@ func Test_BuildUpdate(t *testing.T) {
out: outStruct{
cond: "",
vals: nil,
err: errUpdateLimitType,
err: errLimitType,
},
},
}
Expand Down
6 changes: 5 additions & 1 deletion builder/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,14 +439,18 @@ func buildUpdate(table string, update map[string]interface{}, limit uint, condit
return cond, vals, nil
}

func buildDelete(table string, conditions ...Comparable) (string, []interface{}, error) {
func buildDelete(table string, limit uint, conditions ...Comparable) (string, []interface{}, error) {
whereString, vals := whereConnector("AND", conditions...)
if "" == whereString {
return fmt.Sprintf("DELETE FROM %s", table), nil, nil
}
format := "DELETE FROM %s WHERE %s"

cond := fmt.Sprintf(format, quoteField(table), whereString)
if limit > 0 {
cond += " LIMIT ?"
vals = append(vals, int(limit))
}
return cond, vals, nil
}

Expand Down
8 changes: 5 additions & 3 deletions builder/dao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,13 +363,15 @@ func TestBuildUpdate(t *testing.T) {
func TestBuildDelete(t *testing.T) {
var data = []struct {
table string
limit uint
where []Comparable
outStr string
outVals []interface{}
outErr error
}{
{
table: "tb",
limit: 5,
where: []Comparable{
Eq(map[string]interface{}{
"foo": 1,
Expand All @@ -378,14 +380,14 @@ func TestBuildDelete(t *testing.T) {
"gmt_create": Raw("gmt_modified"),
}),
},
outStr: "DELETE FROM tb WHERE (bar=? AND baz=? AND foo=? AND gmt_create=gmt_modified)",
outVals: []interface{}{2, "tt", 1},
outStr: "DELETE FROM tb WHERE (bar=? AND baz=? AND foo=? AND gmt_create=gmt_modified) LIMIT ?",
outVals: []interface{}{2, "tt", 1, 5},
outErr: nil,
},
}
ass := assert.New(t)
for _, tc := range data {
actualStr, actualVals, err := buildDelete(tc.table, tc.where...)
actualStr, actualVals, err := buildDelete(tc.table, tc.limit, tc.where...)
ass.Equal(tc.outErr, err)
ass.Equal(tc.outStr, actualStr)
ass.Equal(tc.outVals, actualVals)
Expand Down
Loading