Skip to content

Commit

Permalink
feat: build delete support limit (#148)
Browse files Browse the repository at this point in the history
* feat: build delete support limit

* feat: build delete support limit

* feat: build delete support limit

* feat: build delete support limit
  • Loading branch information
tuweizhong authored Sep 26, 2023
1 parent 19c2de2 commit 47b22f0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 12 deletions.
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

0 comments on commit 47b22f0

Please sign in to comment.