mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve create_at,update_at,delete_at feature for package gdb
This commit is contained in:
@ -149,6 +149,7 @@ func (m *Model) doInsertWithOption(option int, data ...interface{}) (result sql.
|
||||
nowString = gtime.Now().String()
|
||||
fieldNameCreate = m.getSoftFieldNameCreate()
|
||||
fieldNameUpdate = m.getSoftFieldNameUpdate()
|
||||
fieldNameDelete = m.getSoftFieldNameDelete()
|
||||
)
|
||||
// Batch operation.
|
||||
if list, ok := m.data.(List); ok {
|
||||
@ -159,10 +160,11 @@ func (m *Model) doInsertWithOption(option int, data ...interface{}) (result sql.
|
||||
// Automatic handling for creating/updating time.
|
||||
if !m.unscoped && (fieldNameCreate != "" || fieldNameUpdate != "") {
|
||||
for k, v := range list {
|
||||
if fieldNameCreate != "" && !gutil.MapContainsPossibleKey(v, fieldNameCreate) {
|
||||
gutil.MapDelete(v, fieldNameCreate, fieldNameUpdate, fieldNameDelete)
|
||||
if fieldNameCreate != "" {
|
||||
v[fieldNameCreate] = nowString
|
||||
}
|
||||
if fieldNameUpdate != "" && !gutil.MapContainsPossibleKey(v, fieldNameUpdate) {
|
||||
if fieldNameUpdate != "" {
|
||||
v[fieldNameUpdate] = nowString
|
||||
}
|
||||
list[k] = v
|
||||
@ -180,10 +182,11 @@ func (m *Model) doInsertWithOption(option int, data ...interface{}) (result sql.
|
||||
if data, ok := m.data.(Map); ok {
|
||||
// Automatic handling for creating/updating time.
|
||||
if !m.unscoped && (fieldNameCreate != "" || fieldNameUpdate != "") {
|
||||
if fieldNameCreate != "" && !gutil.MapContainsPossibleKey(data, fieldNameCreate) {
|
||||
gutil.MapDelete(data, fieldNameCreate, fieldNameUpdate, fieldNameDelete)
|
||||
if fieldNameCreate != "" {
|
||||
data[fieldNameCreate] = nowString
|
||||
}
|
||||
if fieldNameUpdate != "" && !gutil.MapContainsPossibleKey(data, fieldNameUpdate) {
|
||||
if fieldNameUpdate != "" {
|
||||
data[fieldNameUpdate] = nowString
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,9 @@ func (m *Model) Update(dataAndWhere ...interface{}) (result sql.Result, err erro
|
||||
}
|
||||
var (
|
||||
updateData = m.data
|
||||
fieldNameCreate = m.getSoftFieldNameCreate()
|
||||
fieldNameUpdate = m.getSoftFieldNameUpdate()
|
||||
fieldNameDelete = m.getSoftFieldNameDelete()
|
||||
conditionWhere, conditionExtra, conditionArgs = m.formatCondition(false)
|
||||
)
|
||||
// Automatically update the record updating time.
|
||||
@ -58,7 +60,8 @@ func (m *Model) Update(dataAndWhere ...interface{}) (result sql.Result, err erro
|
||||
switch refKind {
|
||||
case reflect.Map, reflect.Struct:
|
||||
dataMap := DataToMapDeep(m.data)
|
||||
if fieldNameUpdate != "" && !gutil.MapContainsPossibleKey(dataMap, fieldNameUpdate) {
|
||||
gutil.MapDelete(dataMap, fieldNameCreate, fieldNameUpdate, fieldNameDelete)
|
||||
if fieldNameUpdate != "" {
|
||||
dataMap[fieldNameUpdate] = gtime.Now().String()
|
||||
}
|
||||
updateData = dataMap
|
||||
|
||||
@ -218,3 +218,153 @@ CREATE TABLE %s (
|
||||
t.Assert(one.IsEmpty(), true)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_CreateUpdateTime_Struct(t *testing.T) {
|
||||
table := "time_test_table"
|
||||
if _, err := db.Exec(fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(45) DEFAULT NULL,
|
||||
create_at datetime DEFAULT NULL,
|
||||
update_at datetime DEFAULT NULL,
|
||||
delete_at datetime DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
`, table)); err != nil {
|
||||
gtest.Error(err)
|
||||
}
|
||||
defer dropTable(table)
|
||||
|
||||
type Entity struct {
|
||||
Id uint64 `orm:"id,primary" json:"id"`
|
||||
Name string `orm:"name" json:"name"`
|
||||
CreateAt *gtime.Time `orm:"create_at" json:"create_at"`
|
||||
UpdateAt *gtime.Time `orm:"update_at" json:"update_at"`
|
||||
DeleteAt *gtime.Time `orm:"delete_at" json:"delete_at"`
|
||||
}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
// Insert
|
||||
dataInsert := &Entity{
|
||||
Id: 1,
|
||||
Name: "name_1",
|
||||
CreateAt: nil,
|
||||
UpdateAt: nil,
|
||||
DeleteAt: nil,
|
||||
}
|
||||
r, err := db.Table(table).Data(dataInsert).Insert()
|
||||
t.Assert(err, nil)
|
||||
n, _ := r.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
|
||||
oneInsert, err := db.Table(table).FindOne(1)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(oneInsert["id"].Int(), 1)
|
||||
t.Assert(oneInsert["name"].String(), "name_1")
|
||||
t.Assert(oneInsert["delete_at"].String(), "")
|
||||
t.AssertGE(oneInsert["create_at"].GTime().Timestamp(), gtime.Timestamp()-2)
|
||||
t.AssertGE(oneInsert["update_at"].GTime().Timestamp(), gtime.Timestamp())
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// Save
|
||||
dataSave := &Entity{
|
||||
Id: 1,
|
||||
Name: "name_10",
|
||||
CreateAt: nil,
|
||||
UpdateAt: nil,
|
||||
DeleteAt: nil,
|
||||
}
|
||||
r, err = db.Table(table).Data(dataSave).Save()
|
||||
t.Assert(err, nil)
|
||||
n, _ = r.RowsAffected()
|
||||
t.Assert(n, 2)
|
||||
|
||||
oneSave, err := db.Table(table).FindOne(1)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(oneSave["id"].Int(), 1)
|
||||
t.Assert(oneSave["name"].String(), "name_10")
|
||||
t.Assert(oneSave["delete_at"].String(), "")
|
||||
t.Assert(oneSave["create_at"].GTime().Timestamp(), oneInsert["create_at"].GTime().Timestamp())
|
||||
t.AssertNE(oneSave["update_at"].GTime().Timestamp(), oneInsert["update_at"].GTime().Timestamp())
|
||||
t.AssertGE(oneSave["update_at"].GTime().Timestamp(), gtime.Now().Timestamp()-2)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// Update
|
||||
dataUpdate := &Entity{
|
||||
Id: 1,
|
||||
Name: "name_1000",
|
||||
CreateAt: nil,
|
||||
UpdateAt: nil,
|
||||
DeleteAt: nil,
|
||||
}
|
||||
r, err = db.Table(table).Data(dataUpdate).WherePri(1).Update()
|
||||
t.Assert(err, nil)
|
||||
n, _ = r.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
|
||||
oneUpdate, err := db.Table(table).FindOne(1)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(oneUpdate["id"].Int(), 1)
|
||||
t.Assert(oneUpdate["name"].String(), "name_1000")
|
||||
t.Assert(oneUpdate["delete_at"].String(), "")
|
||||
t.Assert(oneUpdate["create_at"].GTime().Timestamp(), oneInsert["create_at"].GTime().Timestamp())
|
||||
t.AssertGE(oneUpdate["update_at"].GTime().Timestamp(), gtime.Now().Timestamp()-2)
|
||||
|
||||
// Replace
|
||||
dataReplace := &Entity{
|
||||
Id: 1,
|
||||
Name: "name_100",
|
||||
CreateAt: nil,
|
||||
UpdateAt: nil,
|
||||
DeleteAt: nil,
|
||||
}
|
||||
r, err = db.Table(table).Data(dataReplace).Replace()
|
||||
t.Assert(err, nil)
|
||||
n, _ = r.RowsAffected()
|
||||
t.Assert(n, 2)
|
||||
|
||||
oneReplace, err := db.Table(table).FindOne(1)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(oneReplace["id"].Int(), 1)
|
||||
t.Assert(oneReplace["name"].String(), "name_100")
|
||||
t.Assert(oneReplace["delete_at"].String(), "")
|
||||
t.AssertGE(oneReplace["create_at"].GTime().Timestamp(), oneInsert["create_at"].GTime().Timestamp())
|
||||
t.AssertGE(oneReplace["update_at"].GTime().Timestamp(), oneInsert["update_at"].GTime().Timestamp())
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// Delete
|
||||
r, err = db.Table(table).Delete("id", 1)
|
||||
t.Assert(err, nil)
|
||||
n, _ = r.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
// Delete Select
|
||||
one4, err := db.Table(table).FindOne(1)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(one4), 0)
|
||||
one5, err := db.Table(table).Unscoped().FindOne(1)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(one5["id"].Int(), 1)
|
||||
t.AssertGE(one5["delete_at"].GTime().Timestamp(), gtime.Now().Timestamp()-2)
|
||||
// Delete Count
|
||||
i, err := db.Table(table).FindCount()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(i, 0)
|
||||
i, err = db.Table(table).Unscoped().FindCount()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(i, 1)
|
||||
|
||||
// Delete Unscoped
|
||||
r, err = db.Table(table).Unscoped().Delete("id", 1)
|
||||
t.Assert(err, nil)
|
||||
n, _ = r.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
one6, err := db.Table(table).Unscoped().FindOne(1)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(one6), 0)
|
||||
i, err = db.Table(table).Unscoped().FindCount()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(i, 0)
|
||||
})
|
||||
}
|
||||
|
||||
@ -26,6 +26,16 @@ func MapContains(data map[string]interface{}, key string) (ok bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// MapDelete deletes all <key> from map <data>.
|
||||
func MapDelete(data map[string]interface{}, key ...string) {
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
for _, v := range key {
|
||||
delete(data, v)
|
||||
}
|
||||
}
|
||||
|
||||
// MapMerge merges all map from <src> to map <dst>.
|
||||
func MapMerge(dst map[string]interface{}, src ...map[string]interface{}) {
|
||||
if dst == nil {
|
||||
|
||||
Reference in New Issue
Block a user