Fix create table with struct missing columns #1938

Merged
lunny merged 2 commits from lunny/fix_create_table into master 2021-06-12 03:44:40 +00:00
3 changed files with 92 additions and 13 deletions

View File

@ -39,6 +39,82 @@ func TestCreateTable(t *testing.T) {
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) {
assert.NoError(t, PrepareEngine())

View File

@ -12,6 +12,7 @@ import (
"strings"
"sync"
"time"
"unicode"
"xorm.io/xorm/caches"
"xorm.io/xorm/convert"
@ -143,8 +144,18 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
var hasCacheTag, hasNoCacheTag bool
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)
var col *schemas.Column
fieldValue := v.Field(i)
@ -267,7 +278,7 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
addIndex(indexName, table, col, indexType)
}
}
} else if fieldValue.CanSet() {
} else {
var sqlType schemas.SQLType
if fieldValue.CanAddr() {
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")) {
idFieldColName = col.Name
}
} else {
continue
}
if col.IsAutoIncrement {
col.Nullable = false
}
table.AddColumn(col)
} // end for
if idFieldColName != "" && len(table.PrimaryKeys) == 0 {

View File

@ -53,7 +53,7 @@ func TestUnexportField(t *testing.T) {
)
type VanilaStruct struct {
private int
private int // unexported fields will be ignored
Public int
}
table, err := parser.Parse(reflect.ValueOf(new(VanilaStruct)))
@ -67,18 +67,13 @@ func TestUnexportField(t *testing.T) {
}
type TaggedStruct struct {
private int `xorm:"private"`
private int `xorm:"private"` // unexported fields will be ignored
Public int `xorm:"-"`
}
table, err = parser.Parse(reflect.ValueOf(new(TaggedStruct)))
assert.NoError(t, err)
assert.EqualValues(t, "tagged_struct", table.Name)
assert.EqualValues(t, 1, len(table.Columns()))
for _, col := range table.Columns() {
assert.EqualValues(t, "private", col.Name)
assert.NotEqual(t, "public", col.Name)
}
assert.EqualValues(t, 0, len(table.Columns()))
}
func TestParseWithOtherIdentifier(t *testing.T) {