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