github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/gormgen/helper/clause.go (about)

     1  package helper
     2  
     3  import (
     4  	"strings"
     5  
     6  	"gorm.io/gorm/clause"
     7  )
     8  
     9  // Cond ...
    10  type Cond struct {
    11  	Cond   bool
    12  	Result string
    13  }
    14  
    15  // IfClause if clause
    16  func IfClause(conds []Cond) string {
    17  	judge := func(c Cond) string {
    18  		if c.Cond {
    19  			return c.Result
    20  		}
    21  		return ""
    22  	}
    23  
    24  	clauses := make([]string, len(conds))
    25  	for i, cond := range conds {
    26  		clauses[i] = strings.Trim(judge(cond), " ")
    27  	}
    28  	return " " + strings.Join(clauses, " ")
    29  }
    30  
    31  // WhereClause where clause
    32  func WhereClause(conds []string) string {
    33  	return joinClause(conds, "WHERE", whereValue, " ")
    34  }
    35  
    36  // SetClause set clause
    37  func SetClause(conds []string) string {
    38  	return joinClause(conds, "SET", setValue, ",")
    39  }
    40  
    41  func joinClause(conds []string, keyword string, deal func(string) string, sep string) string {
    42  	clauses := make([]string, len(conds))
    43  	for i, clause := range conds {
    44  		clauses[i] = deal(clause)
    45  	}
    46  
    47  	sql := trimAll(strings.Join(clauses, sep))
    48  	if sql != "" {
    49  		sql = " " + keyword + " " + sql
    50  	}
    51  	return sql
    52  }
    53  
    54  func trimAll(input string) string {
    55  	return trimRight(trimLeft(input))
    56  }
    57  
    58  func trimLeft(input string) string {
    59  	input = strings.TrimSpace(input)
    60  	lowercase := strings.ToLower(input)
    61  	switch {
    62  	case strings.HasPrefix(lowercase, "and "):
    63  		return input[4:]
    64  	case strings.HasPrefix(lowercase, "or "):
    65  		return input[3:]
    66  	case strings.HasPrefix(lowercase, "xor "):
    67  		return input[4:]
    68  	case strings.HasPrefix(lowercase, ","):
    69  		return input[1:]
    70  	default:
    71  		return input
    72  	}
    73  }
    74  func trimRight(input string) string {
    75  	input = strings.TrimSpace(input)
    76  	lowercase := strings.ToLower(input)
    77  	switch {
    78  	case strings.HasSuffix(lowercase, " and"):
    79  		return input[:len(input)-3]
    80  	case strings.HasSuffix(lowercase, " or"):
    81  		return input[:len(input)-2]
    82  	case strings.HasSuffix(lowercase, " xor"):
    83  		return input[:len(input)-3]
    84  	case strings.HasSuffix(lowercase, ","):
    85  		return input[:len(input)-1]
    86  	default:
    87  		return input
    88  	}
    89  }
    90  
    91  // whereValue append a new condition with prefix "AND"
    92  func whereValue(value string) string {
    93  	value = strings.Trim(value, " ")
    94  	lowercase := strings.ToLower(value)
    95  	switch {
    96  	case lowercase == "":
    97  		return ""
    98  	case strings.HasPrefix(lowercase, "and "):
    99  		return value
   100  	case strings.HasPrefix(lowercase, "or "):
   101  		return value
   102  	case strings.HasPrefix(lowercase, "xor "):
   103  		return value
   104  	default:
   105  		return "AND " + value
   106  	}
   107  }
   108  
   109  func setValue(value string) string {
   110  	return strings.Trim(value, ", ")
   111  }
   112  
   113  // JoinWhereBuilder join where builder
   114  func JoinWhereBuilder(src *strings.Builder, whereValue strings.Builder) {
   115  	value := trimAll(whereValue.String())
   116  	if value != "" {
   117  		src.WriteString("WHERE ")
   118  		src.WriteString(value)
   119  		src.WriteString(" ")
   120  	}
   121  }
   122  
   123  // JoinSetBuilder join set builder
   124  func JoinSetBuilder(src *strings.Builder, setValue strings.Builder) {
   125  	value := trimAll(setValue.String())
   126  	if value != "" {
   127  		src.WriteString("SET ")
   128  		src.WriteString(value)
   129  		src.WriteString(" ")
   130  	}
   131  }
   132  
   133  // JoinTrimAllBuilder join trim builder, will trim and,or,xor, `,`
   134  func JoinTrimAllBuilder(src *strings.Builder, setValue strings.Builder) {
   135  	src.WriteString(trimAll(setValue.String()))
   136  	src.WriteString(" ")
   137  }
   138  
   139  // JoinTblExpr join clause with table expression(sub query...)
   140  type JoinTblExpr struct {
   141  	clause.Join
   142  	TableExpr clause.Expression
   143  }
   144  
   145  // NewJoinTblExpr create new join table expr
   146  func NewJoinTblExpr(join clause.Join, tbExpr clause.Expression) JoinTblExpr {
   147  	return JoinTblExpr{Join: join, TableExpr: tbExpr}
   148  }
   149  
   150  // Build ...
   151  func (join JoinTblExpr) Build(builder clause.Builder) {
   152  	if builder == nil {
   153  		return
   154  	}
   155  	if join.Type != "" {
   156  		_, _ = builder.WriteString(string(join.Type))
   157  		_ = builder.WriteByte(' ')
   158  	}
   159  	_, _ = builder.WriteString("JOIN ")
   160  	if join.TableExpr != nil {
   161  		join.TableExpr.Build(builder)
   162  	}
   163  
   164  	if len(join.ON.Exprs) > 0 {
   165  		_, _ = builder.WriteString(" ON ")
   166  		join.ON.Build(builder)
   167  	} else if len(join.Using) > 0 {
   168  		_, _ = builder.WriteString(" USING (")
   169  		for idx, c := range join.Using {
   170  			if idx > 0 {
   171  				_ = builder.WriteByte(',')
   172  			}
   173  			builder.WriteQuoted(c)
   174  		}
   175  		_ = builder.WriteByte(')')
   176  	}
   177  }