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  }