orm support custom multi unique / index
Showing
4 changed files
with
90 additions
and
1 deletions
| ... | @@ -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 == "" { | ... | ... |
-
Please register or sign in to post a comment