Add interface to allow structs to provide specific index information
The current mechanism for adding information about indices cannot express the ordering of the columns in the index or add sorting information. Here we add a new interface TableIndices which a struct would implement to provide a slice of *schema.Index to provide additional indices to that gleaned from the tags. Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
f7e9fb74ac
commit
152e1bcc69
|
@ -21,10 +21,15 @@ import (
|
|||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupportedType represents an unsupported type error
|
||||
ErrUnsupportedType = errors.New("unsupported type")
|
||||
)
|
||||
var ErrUnsupportedType = errors.New("unsupported type")
|
||||
|
||||
// TableIndices is an interface that describes structs that provide additional index information above that which is automatically parsed
|
||||
type TableIndices interface {
|
||||
TableIndices() []*schemas.Index
|
||||
}
|
||||
|
||||
var tpTableIndices = reflect.TypeOf((*TableIndices)(nil)).Elem()
|
||||
|
||||
// Parser represents a parser for xorm tag
|
||||
type Parser struct {
|
||||
|
@ -177,7 +182,7 @@ func (parser *Parser) parseFieldWithNoTag(fieldIndex int, field reflect.StructFi
|
|||
}
|
||||
|
||||
func (parser *Parser) parseFieldWithTags(table *schemas.Table, fieldIndex int, field reflect.StructField, fieldValue reflect.Value, tags []tag) (*schemas.Column, error) {
|
||||
var col = &schemas.Column{
|
||||
col := &schemas.Column{
|
||||
FieldName: field.Name,
|
||||
FieldIndex: []int{fieldIndex},
|
||||
Nullable: true,
|
||||
|
@ -188,7 +193,7 @@ func (parser *Parser) parseFieldWithTags(table *schemas.Table, fieldIndex int, f
|
|||
DefaultIsEmpty: true,
|
||||
}
|
||||
|
||||
var ctx = Context{
|
||||
ctx := Context{
|
||||
table: table,
|
||||
col: col,
|
||||
fieldValue: fieldValue,
|
||||
|
@ -329,5 +334,46 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
|
|||
table.AddColumn(col)
|
||||
} // end for
|
||||
|
||||
indices := tableIndices(v)
|
||||
for _, index := range indices {
|
||||
// Override old information
|
||||
if oldIndex, ok := table.Indexes[index.Name]; ok {
|
||||
for _, colName := range oldIndex.Cols {
|
||||
col := table.GetColumn(colName)
|
||||
if col == nil {
|
||||
return nil, ErrUnsupportedType
|
||||
}
|
||||
delete(col.Indexes, index.Name)
|
||||
}
|
||||
}
|
||||
table.AddIndex(index)
|
||||
for _, colName := range index.Cols {
|
||||
col := table.GetColumn(colName)
|
||||
if col == nil {
|
||||
return nil, ErrUnsupportedType
|
||||
}
|
||||
col.Indexes[index.Name] = index.Type
|
||||
}
|
||||
}
|
||||
|
||||
return table, nil
|
||||
}
|
||||
|
||||
func tableIndices(v reflect.Value) []*schemas.Index {
|
||||
if v.Type().Implements(tpTableIndices) {
|
||||
return v.Interface().(TableIndices).TableIndices()
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
if v.Type().Implements(tpTableIndices) {
|
||||
return v.Interface().(TableIndices).TableIndices()
|
||||
}
|
||||
} else if v.CanAddr() {
|
||||
v1 := v.Addr()
|
||||
if v1.Type().Implements(tpTableIndices) {
|
||||
return v1.Interface().(TableIndices).TableIndices()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue