diff --git a/db.go b/db.go index e831455def6f6f0f107eec4b8bd6c4a6ecdb7fe1..84c39fc967029a01de81880cf23dd5f9420b6f4a 100644 --- a/db.go +++ b/db.go @@ -268,6 +268,15 @@ func newCompound(c ...Compound) *compound { return &compound{c} } +func defaultJoin(in ...Compound) []Compound { + for i := range in { + if cond, ok := in[i].(Cond); ok && len(cond) > 1 { + in[i] = And(cond) + } + } + return in +} + func (c *compound) Sentences() []Compound { return c.conds } @@ -292,7 +301,7 @@ type Union struct { // Or adds more terms to the compound. func (o *Union) Or(conds ...Compound) *Union { - o.compound.push(conds...) + o.compound.push(defaultJoin(conds...)...) return o } @@ -420,7 +429,7 @@ func And(conds ...Compound) *Intersection { // db.Cond{"year": 1987}, // ) func Or(conds ...Compound) *Union { - return &Union{compound: newCompound(conds...)} + return &Union{compound: newCompound(defaultJoin(conds...)...)} } // Raw marks chunks of data as protected, so they pass directly to the query diff --git a/lib/sqlbuilder/builder_test.go b/lib/sqlbuilder/builder_test.go index 1a2e5dbabb354b56461e4fdc86fe92cc2fdd9cd6..e96f80ac35d3e4d91c96290604db8434a58cec4b 100644 --- a/lib/sqlbuilder/builder_test.go +++ b/lib/sqlbuilder/builder_test.go @@ -154,6 +154,23 @@ func TestSelect(t *testing.T) { ).String(), ) + { + q := b.Select().From("artist").Where( + db.Or( + db.And(db.Cond{"a": 1}, db.Cond{"b": 2}, db.Cond{"c": 3}), + db.And(db.Cond{"d": 1}, db.Cond{"e": 2}, db.Cond{"f": 3}), + ), + ) + assert.Equal( + `SELECT * FROM "artist" WHERE ((("a" = $1 AND "b" = $2 AND "c" = $3) OR ("d" = $4 AND "e" = $5 AND "f" = $6)))`, + q.String(), + ) + assert.Equal( + []interface{}{1, 2, 3, 1, 2, 3}, + q.Arguments(), + ) + } + assert.Equal( `SELECT * FROM "artist" WHERE ((("id" = $1 OR "id" = $2 OR "id" IS NULL) OR ("name" = $3 OR "name" = $4)))`, b.Select().From("artist").Where(