From 4dec319adbbfc83f2247fd5e7577494abe8a9f45 Mon Sep 17 00:00:00 2001 From: David Banham Date: Wed, 11 Oct 2017 11:18:13 +1100 Subject: [PATCH 1/3] Add OrWhere clause alongside AndWhere --- select.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/select.go b/select.go index 872be1c..e88c42c 100644 --- a/select.go +++ b/select.go @@ -102,6 +102,24 @@ func (s *SelectStatement) AndWhere(where AsExpr) *SelectStatement { return c } +func (s *SelectStatement) OrWhere(where AsExpr) *SelectStatement { + c := s.clone() + + if c.where == nil { + c.where = where + } else { + expr := c.where + + if bexpr, ok := expr.(*BooleanOperatorExpr); ok && bexpr.operator == "OR" { + c.where = BooleanOperator("OR", append(bexpr.elements[:], where)...) + } else { + c.where = BooleanOperator("OR", expr, where) + } + } + + return c +} + func (s *SelectStatement) OrderBy(orderBy ...AsOrderingTerm) *SelectStatement { c := s.clone() c.orderBy = orderBy From 34f810672368e44747b4e1aef33bf4f10ec2b596 Mon Sep 17 00:00:00 2001 From: David Banham Date: Wed, 11 Oct 2017 11:23:47 +1100 Subject: [PATCH 2/3] DRY up AndOrWhere --- select.go | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/select.go b/select.go index e88c42c..a6e00ef 100644 --- a/select.go +++ b/select.go @@ -85,24 +85,14 @@ func (s *SelectStatement) Where(where AsExpr) *SelectStatement { } func (s *SelectStatement) AndWhere(where AsExpr) *SelectStatement { - c := s.clone() - - if c.where == nil { - c.where = where - } else { - expr := c.where - - if bexpr, ok := expr.(*BooleanOperatorExpr); ok && bexpr.operator == "AND" { - c.where = BooleanOperator("AND", append(bexpr.elements[:], where)...) - } else { - c.where = BooleanOperator("AND", expr, where) - } - } - - return c + return andOrWhere(where, s, "AND") } func (s *SelectStatement) OrWhere(where AsExpr) *SelectStatement { + return andOrWhere(where, s, "OR") +} + +func andOrWhere(where AsExpr, s *SelectStatement, operator string) *SelectStatement { c := s.clone() if c.where == nil { @@ -110,10 +100,10 @@ func (s *SelectStatement) OrWhere(where AsExpr) *SelectStatement { } else { expr := c.where - if bexpr, ok := expr.(*BooleanOperatorExpr); ok && bexpr.operator == "OR" { - c.where = BooleanOperator("OR", append(bexpr.elements[:], where)...) + if bexpr, ok := expr.(*BooleanOperatorExpr); ok && bexpr.operator == operator { + c.where = BooleanOperator(operator, append(bexpr.elements[:], where)...) } else { - c.where = BooleanOperator("OR", expr, where) + c.where = BooleanOperator(operator, expr, where) } } From 97b1e99753a5197f6dd1e7ac26f4fef0947be37d Mon Sep 17 00:00:00 2001 From: David Banham Date: Wed, 11 Oct 2017 11:35:17 +1100 Subject: [PATCH 3/3] Add AndWhere and OrWhere to test --- sqlbuilder_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sqlbuilder_test.go b/sqlbuilder_test.go index 2f6530b..d6b8613 100644 --- a/sqlbuilder_test.go +++ b/sqlbuilder_test.go @@ -78,6 +78,10 @@ func TestSelect(t *testing.T) { AliasColumn(InfixOperator("+", Literal("1"), Literal("2"), Literal("3")), "Five"), ).Where( In(tbl.C("PartNo"), s.BindAllAsExpr(1000, 1001, 1002)...), + ).AndWhere( + In(tbl.C("Grade"), s.BindAllAsExpr("A", "B")...), + ).OrWhere( + In(tbl.C("Finish"), s.BindAllAsExpr("HeapsGood", "TopNotch")...), ).OrderBy( OrderAsc(tbl.C("Type")), OrderAsc(tbl.C("Product")), @@ -94,8 +98,8 @@ func TestSelect(t *testing.T) { qs, qv, err := s.F(q.AsStatement).ToSQL() a.NoError(err) - a.Equal("SELECT p.PartNo, p.Type, p.Product, p.Grade, p.Coating, p.Finish, p.Thickness, p.Width, p.Length, p.Dim1, p.Dim2, p.ClassFBR, p.ClassFME, p.ClassFSY, @p3 AS ClassFHO, p.SLOB, dbo.productAvailablePlusALTOAmountOnHand(p.PartNo, @p1) AS OnHandAmount, dbo.productAvailableWeightOnHand(p.PartNo, @p1) AS OnHandWeight, dbo.productReservedAmount(p.PartNo, @p1) AS ReservedAmount, dbo.productALTOAmount(p.PartNo, @p1) AS ALTO, dbo.getPartAvgCost(p.PartNo) AS AverageCost, dbo.productOnOrderAmount(p.PartNo, @p1) AS OnOrderAmount, dbo.productOnOrderWeight(p.PartNo, @p1) AS OnOrderWeight, dbo.getListPriceGivenAvgCost(@p2, p.PartNo, dbo.getPartAvgCost(p.PartNo)) AS MinimumPrice, dbo.customerLastPrice(p.PartNo, @p2) AS CustomerLastPrice, CONVERT(VARCHAR(23), dbo.customerLastSoldDate(p.PartNo, @p2), 126) AS CustomerLastSoldDate, (1 + 2 + 3) AS Five FROM tblproducts p WHERE p.PartNo IN (@p4, @p5, @p6) ORDER BY p.Type ASC, p.Product ASC, p.Grade ASC, p.Coating ASC, p.Finish ASC, p.Thickness ASC, p.Width ASC, p.Dim1 ASC, p.Dim2 ASC, p.Length ASC OFFSET @p7 ROWS FETCH NEXT @p8 ROWS ONLY", qs) - a.Equal([]interface{}{"REGION_1", "CUSTOMER_1", "D", 1000, 1001, 1002, 30, 30}, qv) + a.Equal("SELECT p.PartNo, p.Type, p.Product, p.Grade, p.Coating, p.Finish, p.Thickness, p.Width, p.Length, p.Dim1, p.Dim2, p.ClassFBR, p.ClassFME, p.ClassFSY, @p3 AS ClassFHO, p.SLOB, dbo.productAvailablePlusALTOAmountOnHand(p.PartNo, @p1) AS OnHandAmount, dbo.productAvailableWeightOnHand(p.PartNo, @p1) AS OnHandWeight, dbo.productReservedAmount(p.PartNo, @p1) AS ReservedAmount, dbo.productALTOAmount(p.PartNo, @p1) AS ALTO, dbo.getPartAvgCost(p.PartNo) AS AverageCost, dbo.productOnOrderAmount(p.PartNo, @p1) AS OnOrderAmount, dbo.productOnOrderWeight(p.PartNo, @p1) AS OnOrderWeight, dbo.getListPriceGivenAvgCost(@p2, p.PartNo, dbo.getPartAvgCost(p.PartNo)) AS MinimumPrice, dbo.customerLastPrice(p.PartNo, @p2) AS CustomerLastPrice, CONVERT(VARCHAR(23), dbo.customerLastSoldDate(p.PartNo, @p2), 126) AS CustomerLastSoldDate, (1 + 2 + 3) AS Five FROM tblproducts p WHERE ((p.PartNo IN (@p4, @p5, @p6) AND p.Grade IN (@p7, @p8)) OR p.Finish IN (@p9, @p10)) ORDER BY p.Type ASC, p.Product ASC, p.Grade ASC, p.Coating ASC, p.Finish ASC, p.Thickness ASC, p.Width ASC, p.Dim1 ASC, p.Dim2 ASC, p.Length ASC OFFSET @p11 ROWS FETCH NEXT @p12 ROWS ONLY", qs) + a.Equal([]interface{}{"REGION_1", "CUSTOMER_1", "D", 1000, 1001, 1002, "A", "B", "HeapsGood", "TopNotch", 30, 30}, qv) } func TestJoin(t *testing.T) {