Fix create table with struct missing columns (#1938)
Fix #1911, #1790 Reviewed-on: https://gitea.com/xorm/xorm/pulls/1938 Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-committed-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
8e22bad304
commit
2b78150f70
|
@ -39,6 +39,82 @@ func TestCreateTable(t *testing.T) {
|
||||||
assert.NoError(t, testEngine.Table("user_user").CreateTable(&UserinfoCreateTable{}))
|
assert.NoError(t, testEngine.Table("user_user").CreateTable(&UserinfoCreateTable{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateTable2(t *testing.T) {
|
||||||
|
type BaseModelLogicalDel struct {
|
||||||
|
Id string `xorm:"varchar(46) pk"`
|
||||||
|
CreatedAt time.Time `xorm:"created"`
|
||||||
|
UpdatedAt time.Time `xorm:"updated"`
|
||||||
|
DeletedAt *time.Time `xorm:"deleted"`
|
||||||
|
}
|
||||||
|
type TestPerson struct {
|
||||||
|
BaseModelLogicalDel `xorm:"extends"`
|
||||||
|
UserId string `xorm:"varchar(46) notnull"`
|
||||||
|
PersonId string `xorm:"varchar(46) notnull"`
|
||||||
|
Star bool
|
||||||
|
SortNo int
|
||||||
|
DispName string `xorm:"varchar(100)"`
|
||||||
|
FirstName string
|
||||||
|
LastName string
|
||||||
|
FirstNameKana string
|
||||||
|
LastNameKana string
|
||||||
|
BirthYear *int
|
||||||
|
BirthMonth *int
|
||||||
|
BirthDay *int
|
||||||
|
ImageId string `xorm:"varchar(46)"`
|
||||||
|
ImageDefaultId string `xorm:"varchar(46)"`
|
||||||
|
UserText string `xorm:"varchar(2000)"`
|
||||||
|
GenderId *int
|
||||||
|
At1 string `xorm:"varchar(10)"`
|
||||||
|
At1Rate int
|
||||||
|
At2 string `xorm:"varchar(10)"`
|
||||||
|
At2Rate int
|
||||||
|
At3 string `xorm:"varchar(10)"`
|
||||||
|
At3Rate int
|
||||||
|
At4 string `xorm:"varchar(10)"`
|
||||||
|
At4Rate int
|
||||||
|
At5 string `xorm:"varchar(10)"`
|
||||||
|
At5Rate int
|
||||||
|
At6 string `xorm:"varchar(10)"`
|
||||||
|
At6Rate int
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, PrepareEngine())
|
||||||
|
|
||||||
|
tb1, err := testEngine.TableInfo(TestPerson{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
tb2, err := testEngine.TableInfo(new(TestPerson))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
cols1, cols2 := tb1.ColumnsSeq(), tb2.ColumnsSeq()
|
||||||
|
assert.EqualValues(t, len(cols1), len(cols2))
|
||||||
|
for i, col := range cols1 {
|
||||||
|
assert.EqualValues(t, col, cols2[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := testEngine.IsTableExist(new(TestPerson))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if result {
|
||||||
|
assert.NoError(t, testEngine.DropTables(new(TestPerson)))
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, testEngine.CreateTables(new(TestPerson)))
|
||||||
|
tables1, err := testEngine.DBMetas()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, tables1, 1)
|
||||||
|
assert.EqualValues(t, len(cols1), len(tables1[0].Columns()))
|
||||||
|
|
||||||
|
result, err = testEngine.IsTableExist(new(TestPerson))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if result {
|
||||||
|
assert.NoError(t, testEngine.DropTables(new(TestPerson)))
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, testEngine.CreateTables(TestPerson{}))
|
||||||
|
tables2, err := testEngine.DBMetas()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, tables2, 1)
|
||||||
|
assert.EqualValues(t, len(cols1), len(tables2[0].Columns()))
|
||||||
|
}
|
||||||
|
|
||||||
func TestCreateMultiTables(t *testing.T) {
|
func TestCreateMultiTables(t *testing.T) {
|
||||||
assert.NoError(t, PrepareEngine())
|
assert.NoError(t, PrepareEngine())
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"xorm.io/xorm/caches"
|
"xorm.io/xorm/caches"
|
||||||
"xorm.io/xorm/convert"
|
"xorm.io/xorm/convert"
|
||||||
|
@ -143,8 +144,18 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
|
||||||
var hasCacheTag, hasNoCacheTag bool
|
var hasCacheTag, hasNoCacheTag bool
|
||||||
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
for i := 0; i < t.NumField(); i++ {
|
||||||
tag := t.Field(i).Tag
|
var isUnexportField bool
|
||||||
|
for _, c := range t.Field(i).Name {
|
||||||
|
if unicode.IsLower(c) {
|
||||||
|
isUnexportField = true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if isUnexportField {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tag := t.Field(i).Tag
|
||||||
ormTagStr := tag.Get(parser.identifier)
|
ormTagStr := tag.Get(parser.identifier)
|
||||||
var col *schemas.Column
|
var col *schemas.Column
|
||||||
fieldValue := v.Field(i)
|
fieldValue := v.Field(i)
|
||||||
|
@ -267,7 +278,7 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
|
||||||
addIndex(indexName, table, col, indexType)
|
addIndex(indexName, table, col, indexType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if fieldValue.CanSet() {
|
} else {
|
||||||
var sqlType schemas.SQLType
|
var sqlType schemas.SQLType
|
||||||
if fieldValue.CanAddr() {
|
if fieldValue.CanAddr() {
|
||||||
if _, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
|
if _, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
|
||||||
|
@ -286,15 +297,12 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
|
||||||
if fieldType.Kind() == reflect.Int64 && (strings.ToUpper(col.FieldName) == "ID" || strings.HasSuffix(strings.ToUpper(col.FieldName), ".ID")) {
|
if fieldType.Kind() == reflect.Int64 && (strings.ToUpper(col.FieldName) == "ID" || strings.HasSuffix(strings.ToUpper(col.FieldName), ".ID")) {
|
||||||
idFieldColName = col.Name
|
idFieldColName = col.Name
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if col.IsAutoIncrement {
|
if col.IsAutoIncrement {
|
||||||
col.Nullable = false
|
col.Nullable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
table.AddColumn(col)
|
table.AddColumn(col)
|
||||||
|
|
||||||
} // end for
|
} // end for
|
||||||
|
|
||||||
if idFieldColName != "" && len(table.PrimaryKeys) == 0 {
|
if idFieldColName != "" && len(table.PrimaryKeys) == 0 {
|
||||||
|
|
|
@ -53,7 +53,7 @@ func TestUnexportField(t *testing.T) {
|
||||||
)
|
)
|
||||||
|
|
||||||
type VanilaStruct struct {
|
type VanilaStruct struct {
|
||||||
private int
|
private int // unexported fields will be ignored
|
||||||
Public int
|
Public int
|
||||||
}
|
}
|
||||||
table, err := parser.Parse(reflect.ValueOf(new(VanilaStruct)))
|
table, err := parser.Parse(reflect.ValueOf(new(VanilaStruct)))
|
||||||
|
@ -67,18 +67,13 @@ func TestUnexportField(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TaggedStruct struct {
|
type TaggedStruct struct {
|
||||||
private int `xorm:"private"`
|
private int `xorm:"private"` // unexported fields will be ignored
|
||||||
Public int `xorm:"-"`
|
Public int `xorm:"-"`
|
||||||
}
|
}
|
||||||
table, err = parser.Parse(reflect.ValueOf(new(TaggedStruct)))
|
table, err = parser.Parse(reflect.ValueOf(new(TaggedStruct)))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, "tagged_struct", table.Name)
|
assert.EqualValues(t, "tagged_struct", table.Name)
|
||||||
assert.EqualValues(t, 1, len(table.Columns()))
|
assert.EqualValues(t, 0, len(table.Columns()))
|
||||||
|
|
||||||
for _, col := range table.Columns() {
|
|
||||||
assert.EqualValues(t, "private", col.Name)
|
|
||||||
assert.NotEqual(t, "public", col.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseWithOtherIdentifier(t *testing.T) {
|
func TestParseWithOtherIdentifier(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue