github.com/eden-framework/sqlx@v0.0.2/builder/def_table.go (about) 1 package builder 2 3 import ( 4 "bytes" 5 "container/list" 6 "context" 7 "fmt" 8 "sort" 9 "strings" 10 "text/scanner" 11 ) 12 13 type TableDefinition interface { 14 T() *Table 15 } 16 17 func T(tableName string, tableDefinitions ...TableDefinition) *Table { 18 t := &Table{ 19 Name: tableName, 20 } 21 22 for _, tableDef := range tableDefinitions { 23 switch d := tableDef.(type) { 24 case *Column: 25 t.AddCol(d) 26 } 27 } 28 for _, tableDef := range tableDefinitions { 29 switch d := tableDef.(type) { 30 case *Key: 31 t.AddKey(d) 32 } 33 } 34 return t 35 } 36 37 type Table struct { 38 Name string 39 Description []string 40 41 Schema string 42 ModelName string 43 Model Model 44 45 Columns 46 Keys 47 } 48 49 func (t *Table) TableName() string { 50 return t.Name 51 } 52 53 func (t *Table) IsNil() bool { 54 return t == nil || len(t.Name) == 0 55 } 56 57 func (t Table) WithSchema(schema string) *Table { 58 t.Schema = schema 59 60 cols := Columns{} 61 t.Columns.Range(func(col *Column, idx int) { 62 cols.Add(col.On(&t)) 63 }) 64 t.Columns = cols 65 66 keys := Keys{} 67 t.Keys.Range(func(key *Key, idx int) { 68 keys.Add(key.On(&t)) 69 }) 70 t.Keys = keys 71 72 return &t 73 } 74 75 func (t *Table) Ex(ctx context.Context) *Ex { 76 if t.Schema != "" { 77 return Expr(t.Schema + "." + t.Name).Ex(ctx) 78 } 79 return Expr(t.Name).Ex(ctx) 80 } 81 82 func (t *Table) AddCol(d *Column) { 83 if d == nil { 84 return 85 } 86 t.Columns.Add(d.On(t)) 87 } 88 89 func (t *Table) AddKey(key *Key) { 90 if key == nil { 91 return 92 } 93 t.Keys.Add(key.On(t)) 94 } 95 96 func (t *Table) Expr(query string, args ...interface{}) *Ex { 97 if query == "" { 98 return nil 99 } 100 101 e := Expr("") 102 103 s := &scanner.Scanner{} 104 s.Init(bytes.NewBuffer([]byte(query))) 105 106 fieldNameBuf := bytes.NewBuffer(nil) 107 108 n := len(args) 109 queryCount := 0 110 111 for tok := s.Next(); tok != scanner.EOF; tok = s.Next() { 112 switch tok { 113 case '#': 114 fieldNameBuf = bytes.NewBuffer(nil) 115 116 e.WriteHolder(0) 117 118 for { 119 tok = s.Next() 120 121 if tok == scanner.EOF { 122 break 123 } 124 125 if (tok >= 'A' && tok <= 'Z') || 126 (tok >= 'a' && tok <= 'z') || 127 (tok >= '0' && tok <= '9') || 128 tok == '_' { 129 130 fieldNameBuf.WriteRune(tok) 131 continue 132 } 133 134 e.WriteRune(tok) 135 136 break 137 } 138 139 //spew.Dump(fieldNameBuf.String()) 140 141 if fieldNameBuf.Len() == 0 { 142 e.AppendArgs(t) 143 } else { 144 fieldName := fieldNameBuf.String() 145 col := t.F(fieldNameBuf.String()) 146 if col == nil { 147 panic(fmt.Errorf("missing field fieldName %s of table %s", fieldName, t.Name)) 148 } 149 e.AppendArgs(col) 150 } 151 case '?': 152 e.WriteRune(tok) 153 if queryCount < n { 154 e.AppendArgs(args[queryCount]) 155 queryCount++ 156 } 157 default: 158 e.WriteRune(tok) 159 } 160 } 161 162 return e 163 } 164 165 func (t *Table) ColumnsAndValuesByFieldValues(fieldValues FieldValues) (columns *Columns, args []interface{}) { 166 fieldNames := make([]string, 0) 167 for fieldName := range fieldValues { 168 fieldNames = append(fieldNames, fieldName) 169 } 170 171 sort.Strings(fieldNames) 172 173 columns = &Columns{} 174 175 for _, fieldName := range fieldNames { 176 if col := t.F(fieldName); col != nil { 177 columns.Add(col) 178 args = append(args, fieldValues[fieldName]) 179 } 180 } 181 return 182 } 183 184 func (t *Table) AssignmentsByFieldValues(fieldValues FieldValues) (assignments Assignments) { 185 for fieldName, value := range fieldValues { 186 col := t.F(fieldName) 187 if col != nil { 188 assignments = append(assignments, col.ValueBy(value)) 189 } 190 } 191 return 192 } 193 194 func (t *Table) Diff(prevTable *Table, dialect Dialect) (exprList []SqlExpr) { 195 // diff columns 196 t.Columns.Range(func(col *Column, idx int) { 197 if prevTable.Col(col.Name) != nil { 198 currentCol := t.Col(col.Name) 199 if currentCol != nil { 200 if currentCol.DeprecatedActions != nil { 201 renameTo := currentCol.DeprecatedActions.RenameTo 202 if renameTo != "" { 203 prevCol := prevTable.Col(renameTo) 204 if prevCol != nil { 205 exprList = append(exprList, dialect.DropColumn(prevCol)) 206 } 207 targetCol := t.Col(renameTo) 208 if targetCol == nil { 209 panic(fmt.Errorf("col `%s` is not declared", renameTo)) 210 } 211 212 exprList = append(exprList, dialect.RenameColumn(col, targetCol)) 213 prevTable.AddCol(targetCol) 214 return 215 } 216 exprList = append(exprList, dialect.DropColumn(col)) 217 return 218 } 219 if ResolveExpr(col).Query() != ResolveExpr(currentCol).Query() { 220 exprList = append(exprList, dialect.ModifyColumn(col)) 221 } 222 return 223 } 224 exprList = append(exprList, dialect.DropColumn(col)) 225 return 226 } 227 228 if col.DeprecatedActions == nil { 229 exprList = append(exprList, dialect.AddColumn(col)) 230 } 231 }) 232 233 // indexes 234 indexes := map[string]bool{} 235 236 t.Keys.Range(func(key *Key, idx int) { 237 name := key.Name 238 if key.IsPrimary() { 239 name = dialect.PrimaryKeyName() 240 } 241 indexes[name] = true 242 243 prevKey := prevTable.Key(name) 244 if prevKey == nil { 245 exprList = append(exprList, dialect.AddIndex(key)) 246 } else { 247 if !key.IsPrimary() && ResolveExpr(key.Columns).Query() != ResolveExpr(prevKey.Columns).Query() { 248 exprList = append(exprList, dialect.DropIndex(key)) 249 exprList = append(exprList, dialect.AddIndex(key)) 250 } 251 } 252 }) 253 254 prevTable.Keys.Range(func(key *Key, idx int) { 255 if _, ok := indexes[strings.ToLower(key.Name)]; !ok { 256 exprList = append(exprList, dialect.DropIndex(key)) 257 } 258 }) 259 260 return 261 } 262 263 type Tables struct { 264 l *list.List 265 tables map[string]*list.Element 266 models map[string]*list.Element 267 } 268 269 func (tables *Tables) TableNames() (names []string) { 270 tables.Range(func(tab *Table, idx int) { 271 names = append(names, tab.Name) 272 }) 273 return 274 } 275 276 func (tables *Tables) Add(tabs ...*Table) { 277 if tables.tables == nil { 278 tables.tables = map[string]*list.Element{} 279 tables.models = map[string]*list.Element{} 280 tables.l = list.New() 281 } 282 283 for _, tab := range tabs { 284 if tab != nil { 285 if _, ok := tables.tables[tab.Name]; ok { 286 tables.Remove(tab.Name) 287 } 288 289 e := tables.l.PushBack(tab) 290 tables.tables[tab.Name] = e 291 if tab.ModelName != "" { 292 tables.models[tab.ModelName] = e 293 } 294 } 295 } 296 } 297 298 func (tables *Tables) Table(tableName string) *Table { 299 if tables.tables != nil { 300 if c, ok := tables.tables[tableName]; ok { 301 return c.Value.(*Table) 302 } 303 } 304 return nil 305 } 306 307 func (tables *Tables) Model(structName string) *Table { 308 if tables.models != nil { 309 if c, ok := tables.models[structName]; ok { 310 return c.Value.(*Table) 311 } 312 } 313 return nil 314 } 315 316 func (tables *Tables) Remove(name string) { 317 if tables.tables != nil { 318 if e, exists := tables.tables[name]; exists { 319 tables.l.Remove(e) 320 delete(tables.tables, name) 321 } 322 } 323 } 324 325 func (tables *Tables) Range(cb func(tab *Table, idx int)) { 326 if tables.l != nil { 327 i := 0 328 for e := tables.l.Front(); e != nil; e = e.Next() { 329 cb(e.Value.(*Table), i) 330 i++ 331 } 332 } 333 }