gitee.com/h79/goutils@v1.22.10/dao/wrapper/join.go (about) 1 package wrapper 2 3 import ( 4 commonoption "gitee.com/h79/goutils/common/option" 5 "strings" 6 ) 7 8 // 内连接(inner join…on…) 9 // 全外连接(full join…on…) 10 // 左连接(left join…on…) 11 // 右连接(right join…on…) 12 // 交叉连接(cross join …on…) 13 const ( 14 JoinLeft = "LEFT" 15 JoinRight = "RIGHT" 16 JoinInner = "INNER" 17 JoinFull = "FULL" 18 JonnCross = "CROSS" 19 ) 20 21 var _ IBuilder = (*Join)(nil) 22 23 type Join struct { 24 Type string `json:"type" yaml:"type"` 25 Table string `json:"table" yaml:"table"` 26 Alias string `json:"as" yaml:"as"` 27 ON string `json:"expr" yaml:"expr"` 28 Using []string `json:"using" yaml:"using"` 29 } 30 31 func (jn *Join) Is() bool { 32 if jn.Type == "" { 33 return false 34 } 35 if jn.Table == "" { 36 if jn.ON == "" { 37 return false 38 } 39 } else if jn.ON == "" && len(jn.Using) == 0 { 40 return false 41 } 42 return true 43 } 44 45 func (jn *Join) JoinType() (string, bool) { 46 jt := strings.ToUpper(jn.Type) 47 return jt, (jt == JoinLeft || 48 jt == JoinRight || 49 jt == JoinFull || 50 jt == JoinInner || 51 jt == JonnCross) && jn.Is() 52 } 53 54 func (jn *Join) Build(opts ...commonoption.Option) string { 55 joinType, ok := jn.JoinType() 56 if !ok { 57 return "" 58 } 59 var builder = strings.Builder{} 60 builder.WriteByte(' ') 61 builder.WriteString(joinType) 62 builder.WriteString(" JOIN ") 63 if jn.Table != "" { 64 AddQuoted(&builder, jn.Table) 65 AddAlias(&builder, jn.Alias) 66 if len(jn.ON) > 0 { 67 builder.WriteString(" ON ") 68 builder.WriteString(jn.ON) 69 } else if len(jn.Using) > 0 { 70 builder.WriteString(" USING (") 71 for idx, c := range jn.Using { 72 if idx > 0 { 73 builder.WriteByte(',') 74 } 75 builder.WriteByte('\'') 76 builder.WriteString(c) 77 builder.WriteByte('\'') 78 } 79 builder.WriteByte(')') 80 } 81 } else { 82 // 直接表达式 83 builder.WriteString(jn.ON) 84 } 85 return builder.String() 86 } 87 88 var _ IBuilder = (*MultiJoin)(nil) 89 90 type MultiJoin struct { 91 Joins []Join 92 } 93 94 func (j *MultiJoin) Add(join Join) { 95 j.Joins = append(j.Joins, join) 96 } 97 98 func (j *MultiJoin) Is() bool { 99 return len(j.Joins) > 0 100 } 101 102 func (j *MultiJoin) Query() string { 103 return "" 104 } 105 106 func (j *MultiJoin) Value() []interface{} { 107 return nil 108 } 109 110 func (j *MultiJoin) Build(opts ...commonoption.Option) string { 111 var b = strings.Builder{} 112 for i := range j.Joins { 113 b.WriteString(" ") 114 b.WriteString(j.Joins[i].Build(opts...)) 115 } 116 b.WriteString(" ") 117 return b.String() 118 }