mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
there should be WHERE statement in Update/Delete operations
This commit is contained in:
@ -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...)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)...,
|
||||
)
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user