diff --git a/base_test.go b/base_test.go index 60c8aa08..98e11e84 100644 --- a/base_test.go +++ b/base_test.go @@ -704,6 +704,36 @@ func testCustomType(engine *Engine, t *testing.T) { func testTrans(engine *Engine, t *testing.T) { } +type UserCU struct { + Id int64 + Name string + Created time.Time `xorm:"created"` + Updated time.Time `xorm:"updated"` +} + +func testCreatedAndUpdated(engine *Engine, t *testing.T) { + u := new(UserCU) + err := engine.CreateTables(u) + if err != nil { + t.Error(err) + panic(err) + } + + u.Name = "sss" + _, err = engine.Insert(u) + if err != nil { + t.Error(err) + panic(err) + } + + u.Name = "xxx" + _, err = engine.Id(u.Id).Update(u) + if err != nil { + t.Error(err) + panic(err) + } +} + func testAll(engine *Engine, t *testing.T) { directCreateTable(engine, t) mapper(engine, t) @@ -737,4 +767,5 @@ func testAll(engine *Engine, t *testing.T) { testExtends(engine, t) testColTypes(engine, t) testCustomType(engine, t) + testCreatedAndUpdated(engine, t) } diff --git a/engine.go b/engine.go index c54e7aa9..9a2ea09a 100644 --- a/engine.go +++ b/engine.go @@ -277,13 +277,16 @@ func (engine *Engine) MapType(t reflect.Type) *Table { case k == "PK": col.IsPrimaryKey = true col.Nullable = false - table.PrimaryKey = col.Name case k == "NULL": col.Nullable = (strings.ToUpper(tags[j-1]) != "NOT") case k == "AUTOINCR": col.IsAutoIncrement = true case k == "DEFAULT": col.Default = tags[j+1] + case k == "CREATED": + col.IsCreated = true + case k == "UPDATED": + col.IsUpdated = true case strings.HasPrefix(k, "INDEX"): if k == "INDEX" { col.IndexName = "" @@ -302,7 +305,11 @@ func (engine *Engine) MapType(t reflect.Type) *Table { } case k == "NOT": default: - if strings.Contains(k, "(") && strings.HasSuffix(k, ")") { + if strings.HasPrefix(k, "'") && strings.HasSuffix(k, "'") { + if key != col.Default { + col.Name = key[1 : len(key)-1] + } + } else if strings.Contains(k, "(") && strings.HasSuffix(k, ")") { fs := strings.Split(k, "(") if _, ok := sqlTypes[fs[0]]; !ok { continue @@ -318,7 +325,7 @@ func (engine *Engine) MapType(t reflect.Type) *Table { } else { if _, ok := sqlTypes[k]; ok { col.SQLType = SQLType{k, 0, 0} - } else if k != col.Default { + } else if key != col.Default { col.Name = key } } @@ -339,6 +346,15 @@ func (engine *Engine) MapType(t reflect.Type) *Table { if col.Name == "" { col.Name = engine.Mapper.Obj2Table(t.Field(i).Name) } + if col.IsPrimaryKey { + table.PrimaryKey = col.Name + } + if col.IsCreated { + table.Created = col.Name + } + if col.IsUpdated { + table.Updated = col.Name + } if col.IndexType == SINGLEINDEX { col.IndexName = col.Name table.Indexes[col.IndexName] = []string{col.Name} @@ -364,8 +380,8 @@ func (engine *Engine) MapType(t reflect.Type) *Table { } else { sqlType := Type2SQLType(fieldType) col = &Column{engine.Mapper.Obj2Table(t.Field(i).Name), t.Field(i).Name, sqlType, - sqlType.DefaultLength, sqlType.DefaultLength2, true, "", NONEUNIQUE, "", NONEINDEX, "", false, false, TWOSIDES} - + sqlType.DefaultLength, sqlType.DefaultLength2, true, "", NONEUNIQUE, "", + NONEINDEX, "", false, false, TWOSIDES, false, false} } if col.IsAutoIncrement { col.Nullable = false diff --git a/session.go b/session.go index 582e0464..96fb93fc 100644 --- a/session.go +++ b/session.go @@ -243,13 +243,7 @@ func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]b case reflect.Bool: v = (string(data) == "1") structField.Set(reflect.ValueOf(v)) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: - x, err := strconv.Atoi(string(data)) - if err != nil { - return errors.New("arg " + key + " as int: " + err.Error()) - } - structField.SetInt(int64(x)) - case reflect.Int64: + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: x, err := strconv.ParseInt(string(data), 10, 64) if err != nil { return errors.New("arg " + key + " as int: " + err.Error()) @@ -814,12 +808,21 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error if col.MapType == ONLYFROMDB { continue } - arg, err := session.value2Interface(fieldValue) - if err != nil { - return 0, err + if session.Statement.ColumnStr != "" { + if _, ok := session.Statement.columnMap[col.Name]; !ok { + continue + } + } + if col.IsCreated || col.IsUpdated { + args = append(args, time.Now()) + } else { + arg, err := session.value2Interface(fieldValue) + if err != nil { + return 0, err + } + args = append(args, arg) } - args = append(args, arg) colNames = append(colNames, col.Name) cols = append(cols, col) colPlaces = append(colPlaces, "?") @@ -838,12 +841,16 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error continue } } - arg, err := session.value2Interface(fieldValue) - if err != nil { - return 0, err + if col.IsCreated || col.IsUpdated { + args = append(args, time.Now()) + } else { + arg, err := session.value2Interface(fieldValue) + if err != nil { + return 0, err + } + args = append(args, arg) } - args = append(args, arg) colPlaces = append(colPlaces, "?") } } @@ -951,12 +958,16 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) { } } - arg, err := session.value2Interface(fieldValue) - if err != nil { - return 0, err + if col.IsCreated || col.IsUpdated { + args = append(args, time.Now()) + } else { + arg, err := session.value2Interface(fieldValue) + if err != nil { + return 0, err + } + args = append(args, arg) } - args = append(args, arg) colNames = append(colNames, col.Name) colPlaces = append(colPlaces, "?") } @@ -1033,10 +1044,15 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 table := session.Engine.AutoMap(bean) session.Statement.RefTable = table colNames, args = BuildConditions(session.Engine, table, bean) + if table.Updated != "" { + colNames = append(colNames, session.Engine.Quote(table.Updated)+" = ?") + args = append(args, time.Now()) + } } else if t.Kind() == reflect.Map { if session.Statement.RefTable == nil { return -1, TableNotFoundError } + table := session.Statement.RefTable colNames = make([]string, 0) args = make([]interface{}, 0) bValue := reflect.ValueOf(bean) @@ -1045,7 +1061,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 colNames = append(colNames, session.Engine.Quote(v.String())+" = ?") args = append(args, bValue.MapIndex(v).Interface()) } - + if table.Updated != "" { + colNames = append(colNames, session.Engine.Quote(table.Updated)+" = ?") + args = append(args, time.Now()) + } } else { return -1, ParamsTypeError } diff --git a/table.go b/table.go index 3e3f1a4a..aedbc25f 100644 --- a/table.go +++ b/table.go @@ -124,9 +124,11 @@ func Type2SQLType(t reflect.Type) (st SQLType) { case reflect.Struct: if t == reflect.TypeOf(tm) { st = SQLType{DateTime, 0, 0} + } else { + st = SQLType{Text, 0, 0} } default: - st = SQLType{Varchar, 255, 0} + st = SQLType{Text, 0, 0} } return } @@ -164,6 +166,8 @@ type Column struct { IsPrimaryKey bool IsAutoIncrement bool MapType int + IsCreated bool + IsUpdated bool } func (col *Column) String(engine *Engine) string { @@ -215,6 +219,8 @@ type Table struct { Indexes map[string][]string Uniques map[string][]string PrimaryKey string + Created string + Updated string } func (table *Table) PKColumn() *Column {