improve create_at,update_at,delete_at feature for package gdb

This commit is contained in:
John
2020-04-15 12:56:41 +08:00
parent 371aef224d
commit 734aa5a6fe
4 changed files with 171 additions and 5 deletions

View File

@ -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
}
}

View File

@ -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

View File

@ -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)
})
}

View File

@ -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 {