diff --git a/boil/qm/query_mods.go b/boil/qm/query_mods.go index 22b3bf4..725b801 100644 --- a/boil/qm/query_mods.go +++ b/boil/qm/query_mods.go @@ -95,3 +95,38 @@ func From(from string) QueryMod { boil.AppendFrom(q, from) } } + +// Count turns the query into a counting calculation +func Count() QueryMod { + return func(q *boil.Query) { + boil.SetCount(q) + } +} + +// Avg turns the query into an average calculation +func Avg() QueryMod { + return func(q *boil.Query) { + boil.SetAvg(q) + } +} + +// Min turns the query into a minimum calculation +func Min() QueryMod { + return func(q *boil.Query) { + boil.SetMin(q) + } +} + +// Max turns the query into a maximum calculation +func Max() QueryMod { + return func(q *boil.Query) { + boil.SetMax(q) + } +} + +// Sum turns the query into a sum calculation +func Sum() QueryMod { + return func(q *boil.Query) { + boil.SetSum(q) + } +} diff --git a/boil/query.go b/boil/query.go index 9c865dd..5fa770d 100644 --- a/boil/query.go +++ b/boil/query.go @@ -7,20 +7,20 @@ import ( // Query holds the state for the built up query type Query struct { - executor Executor - plainSQL plainSQL - delete bool - update map[string]interface{} - selectCols []string - count bool - from []string - innerJoins []join - where []where - groupBy []string - orderBy []string - having []string - limit int - offset int + executor Executor + plainSQL plainSQL + delete bool + update map[string]interface{} + selectCols []string + modFunction string + from []string + innerJoins []join + where []where + groupBy []string + orderBy []string + having []string + limit int + offset int } type where struct { @@ -64,7 +64,27 @@ func SetSQL(q *Query, sql string, args ...interface{}) { // SetCount on the query. func SetCount(q *Query) { - q.count = true + q.modFunction = "COUNT" +} + +// SetAvg on the query. +func SetAvg(q *Query) { + q.modFunction = "AVG" +} + +// SetMax on the query. +func SetMax(q *Query) { + q.modFunction = "MAX" +} + +// SetMin on the query. +func SetMin(q *Query) { + q.modFunction = "MIN" +} + +// SetSum on the query. +func SetSum(q *Query) { + q.modFunction = "SUM" } // SetDelete on the query. diff --git a/boil/query_builders.go b/boil/query_builders.go index 6a1b023..7fa528a 100644 --- a/boil/query_builders.go +++ b/boil/query_builders.go @@ -37,22 +37,22 @@ func buildSelectQuery(q *Query) (*bytes.Buffer, []interface{}) { buf.WriteString("SELECT ") - if q.count { - buf.WriteString("COUNT(") + // Wrap the select in the modifier function + hasModFunc := len(q.modFunction) != 0 + if hasModFunc { + fmt.Fprintf(buf, "%s(", q.modFunction) } - if len(q.innerJoins) > 0 && !q.count { + hasSelectCols := len(q.selectCols) != 0 + if len(q.innerJoins) != 0 && hasSelectCols && !hasModFunc { writeComplexSelect(q, buf) + } else if hasSelectCols { + buf.WriteString(strings.Join(strmangle.IdentQuoteSlice(q.selectCols), `, `)) } else { - if len(q.selectCols) > 0 { - buf.WriteString(strings.Join(strmangle.IdentQuoteSlice(q.selectCols), `, `)) - } else { - buf.WriteByte('*') - } + buf.WriteByte('*') } - // close sql COUNT function - if q.count { + if hasModFunc { buf.WriteString(")") } @@ -78,6 +78,12 @@ func buildSelectQuery(q *Query) (*bytes.Buffer, []interface{}) { } func writeComplexSelect(q *Query, buf *bytes.Buffer) { + cols := make([]string, len(q.selectCols)) + for _, col := range q.selectCols { + if !rgxIdentifier.Match { + cols + } + } } func buildDeleteQuery(q *Query) (*bytes.Buffer, []interface{}) {