Skip to content

Commit

Permalink
Merge pull request #17 from twharmon/having
Browse files Browse the repository at this point in the history
Having
  • Loading branch information
twharmon authored May 3, 2020
2 parents 623f1fc + f205e28 commit c6a8bb8
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 23 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ require (
github.com/DATA-DOG/go-sqlmock v1.4.1
github.com/go-sql-driver/mysql v1.5.0
github.com/mattn/go-sqlite3 v2.0.3+incompatible
google.golang.org/appengine v1.6.5 // indirect
)
87 changes: 72 additions & 15 deletions select_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,26 @@ type where struct {
condition string
}

type having struct {
conjunction string
condition string
}

// SelectQuery holds information for a select query.
type SelectQuery struct {
db *DB
model *model
fields []string
joins []string
wheres []*where
args []interface{}
order string
many bool
limit int64
offset int64
db *DB
model *model
fields []string
joins []string
wheres []*where
whereArgs []interface{}
havings []*having
havingArgs []interface{}
groupBy string
order string
many bool
limit int64
offset int64
}

// Join joins another table to this query.
Expand All @@ -40,7 +48,18 @@ func (sq *SelectQuery) Where(condition string, args ...interface{}) *SelectQuery
condition: condition,
}
sq.wheres = append(sq.wheres, w)
sq.args = append(sq.args, args...)
sq.whereArgs = append(sq.whereArgs, args...)
return sq
}

// Having specifies which rows will be returned.
func (sq *SelectQuery) Having(condition string, args ...interface{}) *SelectQuery {
h := &having{
conjunction: " and ",
condition: condition,
}
sq.havings = append(sq.havings, h)
sq.havingArgs = append(sq.havingArgs, args...)
return sq
}

Expand All @@ -51,7 +70,24 @@ func (sq *SelectQuery) OrWhere(condition string, args ...interface{}) *SelectQue
condition: condition,
}
sq.wheres = append(sq.wheres, w)
sq.args = append(sq.args, args...)
sq.whereArgs = append(sq.whereArgs, args...)
return sq
}

// OrHaving specifies which rows will be returned.
func (sq *SelectQuery) OrHaving(condition string, args ...interface{}) *SelectQuery {
h := &having{
conjunction: " or ",
condition: condition,
}
sq.havings = append(sq.havings, h)
sq.havingArgs = append(sq.havingArgs, args...)
return sq
}

// GroupBy specifies how to group the results.
func (sq *SelectQuery) GroupBy(bys ...string) *SelectQuery {
sq.groupBy = strings.Join(bys, ", ")
return sq
}

Expand Down Expand Up @@ -124,7 +160,9 @@ func (sq *SelectQuery) toOne(out interface{}) error {
if !e.IsValid() {
return errors.New("out must not be a nil pointer")
}
rows, err := sq.db.db.Query(sq.String(), sq.args...)
args := sq.whereArgs
args = append(args, sq.havingArgs...)
rows, err := sq.db.db.Query(sq.String(), args...)
if err != nil {
return err
}
Expand All @@ -150,7 +188,9 @@ func (sq *SelectQuery) toOne(out interface{}) error {

func (sq *SelectQuery) toMany(sliceType reflect.Type, outs interface{}) error {
sq.many = true
rows, err := sq.db.db.Query(sq.String(), sq.args...)
args := sq.whereArgs
args = append(args, sq.havingArgs...)
rows, err := sq.db.db.Query(sq.String(), args...)
if err != nil {
return err
}
Expand Down Expand Up @@ -183,7 +223,9 @@ func (sq *SelectQuery) toMany(sliceType reflect.Type, outs interface{}) error {

func (sq *SelectQuery) toManyValues(sliceType reflect.Type, outs interface{}) error {
sq.many = true
rows, err := sq.db.db.Query(sq.String(), sq.args...)
args := sq.whereArgs
args = append(args, sq.havingArgs...)
rows, err := sq.db.db.Query(sq.String(), args...)
if err != nil {
return err
}
Expand Down Expand Up @@ -237,6 +279,21 @@ func (sq *SelectQuery) String() string {
}
q.WriteString(where.condition)
}

if sq.groupBy != "" {
q.WriteString(" group by ")
q.WriteString(sq.groupBy)
}

for i, having := range sq.havings {
if i == 0 {
q.WriteString(" having ")
} else {
q.WriteString(having.conjunction)
}
q.WriteString(having.condition)
}

if sq.order != "" {
q.WriteString(" order by ")
q.WriteString(sq.order)
Expand Down
14 changes: 7 additions & 7 deletions select_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ func TestSelectQueryMany(t *testing.T) {
}
check(t, db.Register(T{}))
control := []*T{
&T{
{
ID: 5,
Name: "foo",
},
&T{
{
ID: 6,
Name: "bar",
},
Expand All @@ -67,11 +67,11 @@ func TestSelectQueryManyValues(t *testing.T) {
}
check(t, db.Register(T{}))
control := []T{
T{
{
ID: 5,
Name: "foo",
},
T{
{
ID: 6,
Name: "bar",
},
Expand Down Expand Up @@ -140,15 +140,15 @@ func TestSelectQueryOffset(t *testing.T) {
}
check(t, db.Register(T{}))
control := []T{
T{
{
ID: 6,
Name: "bar",
},
T{
{
ID: 7,
Name: "baz",
},
T{
{
ID: 5,
Name: "foo",
},
Expand Down

0 comments on commit c6a8bb8

Please sign in to comment.