github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/gormgen/field/export.go (about) 1 package field 2 3 import ( 4 "fmt" 5 "strings" 6 7 "gorm.io/gorm" 8 "gorm.io/gorm/clause" 9 ) 10 11 var ( 12 // Star a symbol of "*" 13 Star = NewAsterisk("") 14 // ALL same with Star 15 ALL = Star 16 ) 17 18 // Option field option 19 type Option func(clause.Column) clause.Column 20 21 var ( 22 banColumnRaw Option = func(col clause.Column) clause.Column { 23 col.Raw = false 24 return col 25 } 26 ) 27 28 // ======================== generic field ======================= 29 30 // NewField create new field 31 func NewField(table, column string, opts ...Option) Field { 32 return Field{expr: expr{col: toColumn(table, column, opts...)}} 33 } 34 35 // NewSerializer create new field2 36 func NewSerializer(table, column string, opts ...Option) Serializer { 37 return Serializer{expr: expr{col: toColumn(table, column, opts...)}} 38 } 39 40 // NewAsterisk create new * field 41 func NewAsterisk(table string, opts ...Option) Asterisk { 42 return Asterisk{asteriskExpr: asteriskExpr{expr{col: toColumn(table, "*", opts...)}}} 43 } 44 45 // ======================== integer ======================= 46 47 // NewInt create new Int 48 func NewInt(table, column string, opts ...Option) Int { 49 return Int{expr: expr{col: toColumn(table, column, opts...)}} 50 } 51 52 // NewInt8 create new Int8 53 func NewInt8(table, column string, opts ...Option) Int8 { 54 return Int8{expr: expr{col: toColumn(table, column, opts...)}} 55 } 56 57 // NewInt16 ... 58 func NewInt16(table, column string, opts ...Option) Int16 { 59 return Int16{expr: expr{col: toColumn(table, column, opts...)}} 60 } 61 62 // NewInt32 ... 63 func NewInt32(table, column string, opts ...Option) Int32 { 64 return Int32{expr: expr{col: toColumn(table, column, opts...)}} 65 } 66 67 // NewInt64 ... 68 func NewInt64(table, column string, opts ...Option) Int64 { 69 return Int64{expr: expr{col: toColumn(table, column, opts...)}} 70 } 71 72 // NewUint ... 73 func NewUint(table, column string, opts ...Option) Uint { 74 return Uint{expr: expr{col: toColumn(table, column, opts...)}} 75 } 76 77 // NewUint8 ... 78 func NewUint8(table, column string, opts ...Option) Uint8 { 79 return Uint8{expr: expr{col: toColumn(table, column, opts...)}} 80 } 81 82 // NewUint16 ... 83 func NewUint16(table, column string, opts ...Option) Uint16 { 84 return Uint16{expr: expr{col: toColumn(table, column, opts...)}} 85 } 86 87 // NewUint32 ... 88 func NewUint32(table, column string, opts ...Option) Uint32 { 89 return Uint32{expr: expr{col: toColumn(table, column, opts...)}} 90 } 91 92 // NewUint64 ... 93 func NewUint64(table, column string, opts ...Option) Uint64 { 94 return Uint64{expr: expr{col: toColumn(table, column, opts...)}} 95 } 96 97 // ======================== float ======================= 98 99 // NewFloat32 ... 100 func NewFloat32(table, column string, opts ...Option) Float32 { 101 return Float32{expr: expr{col: toColumn(table, column, opts...)}} 102 } 103 104 // NewFloat64 ... 105 func NewFloat64(table, column string, opts ...Option) Float64 { 106 return Float64{expr: expr{col: toColumn(table, column, opts...)}} 107 } 108 109 // ======================== string ======================= 110 111 // NewString ... 112 func NewString(table, column string, opts ...Option) String { 113 return String{expr: expr{col: toColumn(table, column, opts...)}} 114 } 115 116 // NewBytes ... 117 func NewBytes(table, column string, opts ...Option) Bytes { 118 return Bytes{expr: expr{col: toColumn(table, column, opts...)}} 119 } 120 121 // ======================== bool ======================= 122 123 // NewBool ... 124 func NewBool(table, column string, opts ...Option) Bool { 125 return Bool{expr: expr{col: toColumn(table, column, opts...)}} 126 } 127 128 // ======================== time ======================= 129 130 // NewTime ... 131 func NewTime(table, column string, opts ...Option) Time { 132 return Time{expr: expr{col: toColumn(table, column, opts...)}} 133 } 134 135 func toColumn(table, column string, opts ...Option) clause.Column { 136 col := clause.Column{Table: table, Name: column} 137 for _, opt := range opts { 138 col = opt(col) 139 } 140 return banColumnRaw(col) 141 } 142 143 // ======================== boolean operate ======================== 144 145 // Or return or condition 146 func Or(exprs ...Expr) Expr { 147 return &expr{e: clause.Or(toExpression(exprs...)...)} 148 } 149 150 // And return and condition 151 func And(exprs ...Expr) Expr { 152 return &expr{e: clause.And(toExpression(exprs...)...)} 153 } 154 155 // Not return not condition 156 func Not(exprs ...Expr) Expr { 157 return &expr{e: clause.Not(toExpression(exprs...)...)} 158 } 159 160 func toExpression(conds ...Expr) []clause.Expression { 161 exprs := make([]clause.Expression, len(conds)) 162 for i, cond := range conds { 163 exprs[i] = cond.expression() 164 } 165 return exprs 166 } 167 168 // ======================== subquery method ======================== 169 170 // ContainsSubQuery return contains subquery 171 // when len(columns) == 1, equal to columns[0] IN (subquery) 172 // when len(columns) > 1, equal to (columns[0], columns[1], ...) IN (subquery) 173 func ContainsSubQuery(columns []Expr, subQuery *gorm.DB) Expr { 174 switch len(columns) { 175 case 0: 176 return expr{e: clause.Expr{}} 177 case 1: 178 return expr{e: clause.Expr{ 179 SQL: "? IN (?)", 180 Vars: []interface{}{columns[0].RawExpr(), subQuery}, 181 }} 182 default: // len(columns) > 0 183 placeholders := make([]string, len(columns)) 184 cols := make([]interface{}, len(columns)) 185 for i, c := range columns { 186 placeholders[i], cols[i] = "?", c.RawExpr() 187 } 188 return expr{e: clause.Expr{ 189 SQL: fmt.Sprintf("(%s) IN (?)", strings.Join(placeholders, ",")), 190 Vars: append(cols, subQuery), 191 }} 192 } 193 } 194 195 // AssignSubQuery assign with subquery 196 func AssignSubQuery(columns []Expr, subQuery *gorm.DB) AssignExpr { 197 cols := make([]string, len(columns)) 198 for i, c := range columns { 199 cols[i] = string(c.BuildColumn(subQuery.Statement)) 200 } 201 202 name := cols[0] 203 if len(cols) > 1 { 204 name = "(" + strings.Join(cols, ",") + ")" 205 } 206 207 return expr{e: clause.Set{{ 208 Column: clause.Column{Name: name, Raw: true}, 209 Value: gorm.Expr("(?)", subQuery), 210 }}} 211 } 212 213 // CompareOperator compare operator 214 type CompareOperator string 215 216 const ( 217 // EqOp = 218 EqOp CompareOperator = " = " 219 // NeqOp <> 220 NeqOp CompareOperator = " <> " 221 // GtOp > 222 GtOp CompareOperator = " > " 223 // GteOp >= 224 GteOp CompareOperator = " >= " 225 // LtOp < 226 LtOp CompareOperator = " < " 227 // LteOp <= 228 LteOp CompareOperator = " <= " 229 // ExistsOp EXISTS 230 ExistsOp CompareOperator = "EXISTS " 231 ) 232 233 // CompareSubQuery compare with sub query 234 func CompareSubQuery(op CompareOperator, column Expr, subQuery *gorm.DB) Expr { 235 if op == ExistsOp { 236 return expr{e: clause.Expr{ 237 SQL: fmt.Sprint(op, "(?)"), 238 Vars: []interface{}{subQuery}, 239 }} 240 } 241 return expr{e: clause.Expr{ 242 SQL: fmt.Sprint("?", op, "(?)"), 243 Vars: []interface{}{column.RawExpr(), subQuery}, 244 }} 245 } 246 247 // Value ... 248 type Value interface { 249 expr() clause.Expr 250 251 // implement Condition 252 BeCond() interface{} 253 CondError() error 254 } 255 256 type val clause.Expr 257 258 func (v val) expr() clause.Expr { return clause.Expr(v) } 259 func (v val) BeCond() interface{} { return v } 260 func (val) CondError() error { return nil } 261 262 // Values convert value to expression which implement Value 263 func Values(value interface{}) Value { 264 return val(clause.Expr{ 265 SQL: "?", 266 Vars: []interface{}{value}, 267 WithoutParentheses: true, 268 }) 269 } 270 271 // ContainsValue return expression which compare with value 272 func ContainsValue(columns []Expr, value Value) Expr { 273 switch len(columns) { 274 case 0: 275 return expr{e: clause.Expr{}} 276 case 1: 277 return expr{e: clause.Expr{ 278 SQL: "? IN (?)", 279 Vars: []interface{}{columns[0].RawExpr(), value.expr()}, 280 }} 281 default: // len(columns) > 0 282 vars := make([]string, len(columns)) 283 queryCols := make([]interface{}, len(columns)) 284 for i, c := range columns { 285 vars[i], queryCols[i] = "?", c.RawExpr() 286 } 287 return expr{e: clause.Expr{ 288 SQL: fmt.Sprintf("(%s) IN (?)", strings.Join(vars, ", ")), 289 Vars: append(queryCols, value.expr()), 290 }} 291 } 292 } 293 294 // EmptyExpr return a empty expression 295 func EmptyExpr() Expr { return expr{e: clause.Expr{}} } 296 297 // AssociationFields all association 298 var AssociationFields Expr = NewString("", clause.Associations).appendBuildOpts(WithoutQuote) 299 300 // Associations ... 301 var Associations RelationField = NewRelation(clause.Associations, "") 302 303 // NewRelation return a new Relation for association 304 func NewRelation(fieldName string, fieldType string, relations ...Relation) *Relation { 305 return &Relation{ 306 fieldName: fieldName, 307 fieldPath: fieldName, 308 fieldType: fieldType, 309 childRelations: wrapPath(fieldName, relations), 310 } 311 } 312 313 // NewRelationWithType return a Relation with specified field type 314 func NewRelationWithType(relationship RelationshipType, fieldName string, fieldType string, relations ...Relation) *Relation { 315 return &Relation{ 316 relationship: relationship, 317 fieldName: fieldName, 318 fieldType: fieldType, 319 fieldPath: fieldName, 320 childRelations: wrapPath(fieldName, relations), 321 } 322 } 323 324 // NewRelationWithModel return a Relation with specified model struct 325 func NewRelationWithModel(relationship RelationshipType, fieldName string, fieldType string, fieldModel interface{}, relations ...Relation) *Relation { 326 return &Relation{ 327 relationship: relationship, 328 fieldName: fieldName, 329 fieldType: fieldType, 330 fieldPath: fieldName, 331 fieldModel: fieldModel, 332 } 333 }