there should be WHERE statement in Update/Delete operations

This commit is contained in:
John
2020-11-06 00:00:41 +08:00
parent 13330658cb
commit f4da179140
7 changed files with 68 additions and 12 deletions

View File

@ -9,7 +9,9 @@ package gdb
import (
"database/sql"
"fmt"
"github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/text/gstr"
)
// Delete does "DELETE FROM ... " statement for the model.
@ -38,5 +40,9 @@ func (m *Model) Delete(where ...interface{}) (result sql.Result, err error) {
append([]interface{}{gtime.Now().String()}, conditionArgs...),
)
}
return m.db.DoDelete(m.getLink(true), m.tables, conditionWhere+conditionExtra, conditionArgs...)
conditionStr := conditionWhere + conditionExtra
if !gstr.ContainsI(conditionStr, " WHERE ") {
return nil, gerror.New("there should be WHERE condition statement for DELETE operation")
}
return m.db.DoDelete(m.getLink(true), m.tables, conditionStr, conditionArgs...)
}

View File

@ -27,7 +27,7 @@ func (m *Model) Filter() *Model {
func (m *Model) Fields(fields ...string) *Model {
if len(fields) > 0 {
model := m.getModel()
model.fields = gstr.Join(fields, ",")
model.fields = gstr.Join(m.mappingToTableFields(fields), ",")
return model
}
return m
@ -38,7 +38,7 @@ func (m *Model) Fields(fields ...string) *Model {
func (m *Model) FieldsEx(fields ...string) *Model {
if len(fields) > 0 {
model := m.getModel()
model.fieldsEx = gstr.Join(fields, ",")
model.fieldsEx = gstr.Join(m.mappingToTableFields(fields), ",")
return model
}
return m

View File

@ -10,6 +10,7 @@ import (
"database/sql"
"errors"
"fmt"
"github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/util/gconv"
@ -77,11 +78,15 @@ func (m *Model) Update(dataAndWhere ...interface{}) (result sql.Result, err erro
if err != nil {
return nil, err
}
conditionStr := conditionWhere + conditionExtra
if !gstr.ContainsI(conditionStr, " WHERE ") {
return nil, gerror.New("there should be WHERE condition statement for UPDATE operation")
}
return m.db.DoUpdate(
m.getLink(true),
m.tables,
newData,
conditionWhere+conditionExtra,
conditionStr,
m.mergeArguments(conditionArgs)...,
)
}

View File

@ -13,6 +13,7 @@ import (
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/util/gutil"
"time"
)
@ -26,6 +27,33 @@ func (m *Model) getModel() *Model {
}
}
// mappingToTableFields mappings and changes given field name to really table field name.
func (m *Model) mappingToTableFields(fields []string) []string {
var (
foundKey = ""
fieldsArray = gstr.SplitAndTrim(gstr.Join(fields, ","), ",")
)
if fieldsMap, err := m.db.TableFields(m.tables); err == nil {
fieldsKeyMap := make(map[string]interface{}, len(fieldsMap))
for k, _ := range fieldsMap {
fieldsKeyMap[k] = nil
}
for i, v := range fieldsArray {
if _, ok := fieldsKeyMap[v]; !ok {
if gstr.Contains(v, " ") || gstr.Contains(v, ".") {
continue
}
foundKey, _ = gutil.MapPossibleItemByKey(fieldsKeyMap, v)
if foundKey != "" {
fieldsArray[i] = foundKey
}
}
}
}
return fieldsArray
}
// filterDataForInsertOrUpdate does filter feature with data for inserting/updating operations.
// Note that, it does not filter list item, which is also type of map, for "omit empty" feature.
func (m *Model) filterDataForInsertOrUpdate(data interface{}) (interface{}, error) {

View File

@ -719,7 +719,7 @@ func Test_DB_Delete(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
result, err := db.Delete(table, nil)
result, err := db.Delete(table, 1)
t.Assert(err, nil)
n, _ := result.RowsAffected()
t.Assert(n, SIZE)
@ -768,7 +768,7 @@ func Test_DB_Time(t *testing.T) {
})
gtest.C(t, func(t *gtest.T) {
result, err := db.Delete(table, nil)
result, err := db.Delete(table, 1)
t.Assert(err, nil)
n, _ := result.RowsAffected()
t.Assert(n, 2)

View File

@ -389,7 +389,7 @@ func Test_Model_Update(t *testing.T) {
defer dropTable(table)
// UPDATE...LIMIT
gtest.C(t, func(t *gtest.T) {
result, err := db.Table(table).Data("nickname", "T100").Order("id desc").Limit(2).Update()
result, err := db.Table(table).Data("nickname", "T100").Where(1).Order("id desc").Limit(2).Update()
t.Assert(err, nil)
n, _ := result.RowsAffected()
t.Assert(n, 2)
@ -1769,14 +1769,14 @@ func Test_Model_Delete(t *testing.T) {
// DELETE...LIMIT
gtest.C(t, func(t *gtest.T) {
result, err := db.Table(table).Limit(2).Delete()
result, err := db.Table(table).Where(1).Limit(2).Delete()
t.Assert(err, nil)
n, _ := result.RowsAffected()
t.Assert(n, 2)
})
gtest.C(t, func(t *gtest.T) {
result, err := db.Table(table).Delete()
result, err := db.Table(table).Where(1).Delete()
t.Assert(err, nil)
n, _ := result.RowsAffected()
t.Assert(n, SIZE-2)
@ -2036,7 +2036,7 @@ func Test_Model_Option_Where(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
table := createInitTable()
defer dropTable(table)
r, err := db.Table(table).OmitEmpty().Data("nickname", 1).Where(g.Map{"id": 0, "passport": ""}).Update()
r, err := db.Table(table).OmitEmpty().Data("nickname", 1).Where(g.Map{"id": 0, "passport": ""}).And(1).Update()
t.Assert(err, nil)
n, _ := r.RowsAffected()
t.Assert(n, SIZE)
@ -2601,6 +2601,23 @@ func Test_Model_Min_Max(t *testing.T) {
})
}
func Test_Model_Fields_AutoMapping(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
value, err := db.Table(table).Fields("ID").Where("id", 2).Value()
t.Assert(err, nil)
t.Assert(value.Int(), 2)
})
gtest.C(t, func(t *gtest.T) {
value, err := db.Table(table).Fields("NICK_NAME").Where("id", 2).Value()
t.Assert(err, nil)
t.Assert(value.String(), "name_2")
})
}
func Test_Model_NullField(t *testing.T) {
table := createTable()
defer dropTable(table)

View File

@ -676,7 +676,7 @@ func Test_TX_Delete(t *testing.T) {
if err != nil {
gtest.Error(err)
}
if _, err := tx.Delete(table, nil); err != nil {
if _, err := tx.Delete(table, 1); err != nil {
gtest.Error(err)
}
if err := tx.Commit(); err != nil {
@ -696,7 +696,7 @@ func Test_TX_Delete(t *testing.T) {
if err != nil {
gtest.Error(err)
}
if _, err := tx.Delete(table, nil); err != nil {
if _, err := tx.Delete(table, 1); err != nil {
gtest.Error(err)
}
if n, err := tx.Table(table).Count(); err != nil {