1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
package cat
// On builds a SQL ON clause comparing two columns across tables.
// Formats as: "table1.column1 = table2.column2" with proper spacing.
// Useful in JOIN conditions to match keys between tables.
func On(table1, column1, table2, column2 string) string {
return With(space,
With(dot, table1, column1),
Pad(equal),
With(dot, table2, column2),
)
}
// Using builds a SQL condition comparing two aliased columns.
// Formats as: "alias1.column1 = alias2.column2" for JOINs or filters.
// Helps when working with table aliases in complex queries.
func Using(alias1, column1, alias2, column2 string) string {
return With(space,
With(dot, alias1, column1),
Pad(equal),
With(dot, alias2, column2),
)
}
// And joins multiple SQL conditions with the AND operator.
// Adds spacing to ensure clean SQL output (e.g., "cond1 AND cond2").
// Accepts variadic arguments for flexible condition chaining.
func And(conditions ...any) string {
return With(Pad(and), conditions...)
}
// In creates a SQL IN clause with properly quoted values
// Example: In("status", "active", "pending") → "status IN ('active', 'pending')"
// Handles value quoting and comma separation automatically
func In(column string, values ...string) string {
if len(values) == 0 {
return Concat(column, inOpen, inClose)
}
quotedValues := make([]string, len(values))
for i, v := range values {
quotedValues[i] = "'" + v + "'"
}
return Concat(column, inOpen, JoinWith(comma+space, quotedValues...), inClose)
}
// As creates an aliased SQL expression
// Example: As("COUNT(*)", "total_count") → "COUNT(*) AS total_count"
func As(expression, alias string) string {
return Concat(expression, asSQL, alias)
}
// Count creates a COUNT expression with optional alias
// Example: Count("id") → "COUNT(id)"
// Example: Count("id", "total") → "COUNT(id) AS total"
// Example: Count("DISTINCT user_id", "unique_users") → "COUNT(DISTINCT user_id) AS unique_users"
func Count(column string, alias ...string) string {
expression := Concat(count, column, parenClose)
if len(alias) == 0 {
return expression
}
return As(expression, alias[0])
}
// CountAll creates COUNT(*) with optional alias
// Example: CountAll() → "COUNT(*)"
// Example: CountAll("total") → "COUNT(*) AS total"
func CountAll(alias ...string) string {
if len(alias) == 0 {
return countAll
}
return As(countAll, alias[0])
}
// Sum creates a SUM expression with optional alias
// Example: Sum("amount") → "SUM(amount)"
// Example: Sum("amount", "total") → "SUM(amount) AS total"
func Sum(column string, alias ...string) string {
expression := Concat(sum, column, parenClose)
if len(alias) == 0 {
return expression
}
return As(expression, alias[0])
}
// Avg creates an AVG expression with optional alias
// Example: Avg("score") → "AVG(score)"
// Example: Avg("score", "average") → "AVG(score) AS average"
func Avg(column string, alias ...string) string {
expression := Concat(avg, column, parenClose)
if len(alias) == 0 {
return expression
}
return As(expression, alias[0])
}
// Max creates a MAX expression with optional alias
// Example: Max("price") → "MAX(price)"
// Example: Max("price", "max_price") → "MAX(price) AS max_price"
func Max(column string, alias ...string) string {
expression := Concat(maxOpen, column, parenClose)
if len(alias) == 0 {
return expression
}
return As(expression, alias[0])
}
// Min creates a MIN expression with optional alias
// Example: Min("price") → "MIN(price)"
// Example: Min("price", "min_price") → "MIN(price) AS min_price"
func Min(column string, alias ...string) string {
expression := Concat(minOpen, column, parenClose)
if len(alias) == 0 {
return expression
}
return As(expression, alias[0])
}
// Case creates a SQL CASE expression with optional alias
// Example: Case("WHEN status = 'active' THEN 1 ELSE 0 END", "is_active") → "CASE WHEN status = 'active' THEN 1 ELSE 0 END AS is_active"
func Case(expression string, alias ...string) string {
caseExpr := Concat(caseSQL, expression)
if len(alias) == 0 {
return caseExpr
}
return As(caseExpr, alias[0])
}
// CaseWhen creates a complete SQL CASE expression from individual parts with proper value handling
// Example: CaseWhen("status =", "'active'", "1", "0", "is_active") → "CASE WHEN status = 'active' THEN 1 ELSE 0 END AS is_active"
// Example: CaseWhen("age >", "18", "'adult'", "'minor'", "age_group") → "CASE WHEN age > 18 THEN 'adult' ELSE 'minor' END AS age_group"
func CaseWhen(conditionPart string, conditionValue, thenValue, elseValue any, alias ...string) string {
condition := Concat(conditionPart, valueToString(conditionValue))
expression := Concat(
when, condition, then, valueToString(thenValue), elseSQL, valueToString(elseValue), end,
)
return Case(expression, alias...)
}
// CaseWhenMulti creates a SQL CASE expression with multiple WHEN clauses
// Example: CaseWhenMulti([]string{"status =", "age >"}, []any{"'active'", 18}, []any{1, "'adult'"}, 0, "result") → "CASE WHEN status = 'active' THEN 1 WHEN age > 18 THEN 'adult' ELSE 0 END AS result"
func CaseWhenMulti(conditionParts []string, conditionValues, thenValues []any, elseValue any, alias ...string) string {
if len(conditionParts) != len(conditionValues) || len(conditionParts) != len(thenValues) {
return "" // or handle error
}
var whenClauses []string
for i := 0; i < len(conditionParts); i++ {
condition := Concat(conditionParts[i], valueToString(conditionValues[i]))
whenClause := Concat(when, condition, then, valueToString(thenValues[i]))
whenClauses = append(whenClauses, whenClause)
}
expression := Concat(
JoinWith(space, whenClauses...),
elseSQL,
valueToString(elseValue),
end,
)
return Case(expression, alias...)
}
|