4c061fed by slene

orm support custom multi unique / index

1 parent 02d29905
...@@ -39,6 +39,7 @@ func getDbCreateSql(al *alias) (sqls []string) { ...@@ -39,6 +39,7 @@ func getDbCreateSql(al *alias) (sqls []string) {
39 39
40 Q := al.DbBaser.TableQuote() 40 Q := al.DbBaser.TableQuote()
41 T := al.DbBaser.DbTypes() 41 T := al.DbBaser.DbTypes()
42 sep := fmt.Sprintf("%s, %s", Q, Q)
42 43
43 for _, mi := range modelCache.allOrdered() { 44 for _, mi := range modelCache.allOrdered() {
44 sql := fmt.Sprintf("-- %s\n", strings.Repeat("-", 50)) 45 sql := fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
...@@ -49,6 +50,8 @@ func getDbCreateSql(al *alias) (sqls []string) { ...@@ -49,6 +50,8 @@ func getDbCreateSql(al *alias) (sqls []string) {
49 50
50 columns := make([]string, 0, len(mi.fields.fieldsDB)) 51 columns := make([]string, 0, len(mi.fields.fieldsDB))
51 52
53 sqlIndexes := [][]string{}
54
52 for _, fi := range mi.fields.fieldsDB { 55 for _, fi := range mi.fields.fieldsDB {
53 56
54 fieldType := fi.fieldType 57 fieldType := fi.fieldType
...@@ -120,6 +123,10 @@ func getDbCreateSql(al *alias) (sqls []string) { ...@@ -120,6 +123,10 @@ func getDbCreateSql(al *alias) (sqls []string) {
120 if fi.unique { 123 if fi.unique {
121 column += " " + "UNIQUE" 124 column += " " + "UNIQUE"
122 } 125 }
126
127 if fi.index {
128 sqlIndexes = append(sqlIndexes, []string{column})
129 }
123 } 130 }
124 131
125 if strings.Index(column, "%COL%") != -1 { 132 if strings.Index(column, "%COL%") != -1 {
...@@ -129,6 +136,21 @@ func getDbCreateSql(al *alias) (sqls []string) { ...@@ -129,6 +136,21 @@ func getDbCreateSql(al *alias) (sqls []string) {
129 columns = append(columns, column) 136 columns = append(columns, column)
130 } 137 }
131 138
139 if mi.model != nil {
140 for _, names := range getTableUnique(mi.addrField) {
141 cols := make([]string, 0, len(names))
142 for _, name := range names {
143 if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
144 cols = append(cols, fi.column)
145 } else {
146 panic(fmt.Errorf("cannot found column `%s` when parse UNIQUE in `%s.TableUnique`", name, mi.fullName))
147 }
148 }
149 column := fmt.Sprintf(" UNIQUE (%s%s%s)", Q, strings.Join(cols, sep), Q)
150 columns = append(columns, column)
151 }
152 }
153
132 sql += strings.Join(columns, ",\n") 154 sql += strings.Join(columns, ",\n")
133 sql += "\n)" 155 sql += "\n)"
134 156
...@@ -136,7 +158,30 @@ func getDbCreateSql(al *alias) (sqls []string) { ...@@ -136,7 +158,30 @@ func getDbCreateSql(al *alias) (sqls []string) {
136 sql += " ENGINE=INNODB" 158 sql += " ENGINE=INNODB"
137 } 159 }
138 160
161 sql += ";"
139 sqls = append(sqls, sql) 162 sqls = append(sqls, sql)
163
164 if mi.model != nil {
165 for _, names := range getTableIndex(mi.addrField) {
166 cols := make([]string, 0, len(names))
167 for _, name := range names {
168 if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
169 cols = append(cols, fi.column)
170 } else {
171 panic(fmt.Errorf("cannot found column `%s` when parse INDEX in `%s.TableIndex`", name, mi.fullName))
172 }
173 }
174 sqlIndexes = append(sqlIndexes, cols)
175 }
176 }
177
178 for _, names := range sqlIndexes {
179 name := strings.Join(names, "_")
180 cols := strings.Join(names, sep)
181 sql := fmt.Sprintf("CREATE INDEX %s%s%s ON %s%s%s (%s%s%s);", Q, name, Q, Q, mi.table, Q, Q, cols, Q)
182 sqls = append(sqls, sql)
183 }
184
140 } 185 }
141 186
142 return sqls 187 return sqls
......
...@@ -31,7 +31,7 @@ func newModelInfo(val reflect.Value) (info *modelInfo) { ...@@ -31,7 +31,7 @@ func newModelInfo(val reflect.Value) (info *modelInfo) {
31 ind := reflect.Indirect(val) 31 ind := reflect.Indirect(val)
32 typ := ind.Type() 32 typ := ind.Type()
33 33
34 info.addrField = ind.Addr() 34 info.addrField = val
35 35
36 info.name = typ.Name() 36 info.name = typ.Name()
37 info.fullName = getFullName(typ) 37 info.fullName = getFullName(typ)
......
...@@ -78,6 +78,18 @@ type User struct { ...@@ -78,6 +78,18 @@ type User struct {
78 ShouldSkip string `orm:"-"` 78 ShouldSkip string `orm:"-"`
79 } 79 }
80 80
81 func (u *User) TableIndex() [][]string {
82 return [][]string{
83 []string{"Id", "UserName"},
84 }
85 }
86
87 func (u *User) TableUnique() [][]string {
88 return [][]string{
89 []string{"UserName", "Email"},
90 }
91 }
92
81 func NewUser() *User { 93 func NewUser() *User {
82 obj := new(User) 94 obj := new(User)
83 return obj 95 return obj
......
...@@ -26,6 +26,38 @@ func getTableName(val reflect.Value) string { ...@@ -26,6 +26,38 @@ func getTableName(val reflect.Value) string {
26 return snakeString(ind.Type().Name()) 26 return snakeString(ind.Type().Name())
27 } 27 }
28 28
29 func getTableIndex(val reflect.Value) [][]string {
30 fun := val.MethodByName("TableIndex")
31 if fun.IsValid() {
32 vals := fun.Call([]reflect.Value{})
33 if len(vals) > 0 {
34 val := vals[0]
35 if val.CanInterface() {
36 if d, ok := val.Interface().([][]string); ok {
37 return d
38 }
39 }
40 }
41 }
42 return nil
43 }
44
45 func getTableUnique(val reflect.Value) [][]string {
46 fun := val.MethodByName("TableUnique")
47 if fun.IsValid() {
48 vals := fun.Call([]reflect.Value{})
49 if len(vals) > 0 {
50 val := vals[0]
51 if val.CanInterface() {
52 if d, ok := val.Interface().([][]string); ok {
53 return d
54 }
55 }
56 }
57 }
58 return nil
59 }
60
29 func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string { 61 func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string {
30 column := strings.ToLower(col) 62 column := strings.ToLower(col)
31 if column == "" { 63 if column == "" {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!